Merge pull request #4564 from wtsi-hgi/fix/4551-openstack-builder-reuse-ips

add reuse_ips option for openstack builder
This commit is contained in:
Matthew Hooker 2017-02-21 15:20:10 -08:00 committed by GitHub
commit 3409ea76ee
4 changed files with 38 additions and 26 deletions

View File

@ -102,6 +102,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
&StepAllocateIp{
FloatingIpPool: b.config.FloatingIpPool,
FloatingIp: b.config.FloatingIp,
ReuseIps: b.config.ReuseIps,
},
&communicator.StepConnect{
Config: &b.config.RunConfig.Comm,

View File

@ -23,6 +23,7 @@ type RunConfig struct {
RackconnectWait bool `mapstructure:"rackconnect_wait"`
FloatingIpPool string `mapstructure:"floating_ip_pool"`
FloatingIp string `mapstructure:"floating_ip"`
ReuseIps bool `mapstructure:"reuse_ips"`
SecurityGroups []string `mapstructure:"security_groups"`
Networks []string `mapstructure:"networks"`
UserData string `mapstructure:"user_data"`

View File

@ -13,6 +13,7 @@ import (
type StepAllocateIp struct {
FloatingIpPool string
FloatingIp string
ReuseIps bool
}
func (s *StepAllocateIp) Run(state multistep.StateBag) multistep.StepAction {
@ -37,36 +38,38 @@ func (s *StepAllocateIp) Run(state multistep.StateBag) multistep.StepAction {
if s.FloatingIp != "" {
instanceIp.IP = s.FloatingIp
} else if s.FloatingIpPool != "" {
// If we have a free floating IP in the pool, use it first
// rather than creating one
ui.Say(fmt.Sprintf("Searching for unassociated floating IP in pool %s", s.FloatingIpPool))
pager := floatingips.List(client)
err := pager.EachPage(func(page pagination.Page) (bool, error) {
candidates, err := floatingips.ExtractFloatingIPs(page)
// If ReuseIps is set to true and we have a free floating IP in
// the pool, use it first rather than creating one
if s.ReuseIps {
ui.Say(fmt.Sprintf("Searching for unassociated floating IP in pool %s", s.FloatingIpPool))
pager := floatingips.List(client)
err := pager.EachPage(func(page pagination.Page) (bool, error) {
candidates, err := floatingips.ExtractFloatingIPs(page)
if err != nil {
return false, err // stop and throw error out
}
for _, candidate := range candidates {
if candidate.Pool != s.FloatingIpPool || candidate.InstanceID != "" {
continue // move to next in list
if err != nil {
return false, err // stop and throw error out
}
// In correct pool and able to be allocated
instanceIp.IP = candidate.IP
ui.Message(fmt.Sprintf("Selected floating IP: %s", instanceIp.IP))
state.Put("floatingip_istemp", false)
return false, nil // stop iterating over pages
}
return true, nil // try the next page
})
for _, candidate := range candidates {
if candidate.Pool != s.FloatingIpPool || candidate.InstanceID != "" {
continue // move to next in list
}
if err != nil {
err := fmt.Errorf("Error searching for floating ip from pool '%s'", s.FloatingIpPool)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
// In correct pool and able to be allocated
instanceIp.IP = candidate.IP
ui.Message(fmt.Sprintf("Selected floating IP: %s", instanceIp.IP))
state.Put("floatingip_istemp", false)
return false, nil // stop iterating over pages
}
return true, nil // try the next page
})
if err != nil {
err := fmt.Errorf("Error searching for floating ip from pool '%s'", s.FloatingIpPool)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
}
if instanceIp.IP == "" {

View File

@ -122,6 +122,13 @@ builder.
launch the server to create the AMI. If not specified, Packer will use the
environment variable `OS_REGION_NAME`, if set.
- `reuse_ips` (boolean) - Whether or not to attempt to reuse existing
unassigned floating ips in the project before allocating a new one. Note
that it is not possible to safely do this concurrently, so if you are
running multiple openstack builds concurrently, or if other processes are
assigning and using floating IPs in the same openstack project while packer
is running, you should not set this to true. Defaults to false.
- `security_groups` (array of strings) - A list of security groups by name to
add to this instance.