diff --git a/builder/xenserver/common/common_config.go b/builder/xenserver/common/common_config.go index df0d805..4807a84 100644 --- a/builder/xenserver/common/common_config.go +++ b/builder/xenserver/common/common_config.go @@ -50,6 +50,7 @@ type CommonConfig struct { OutputDir string `mapstructure:"output_directory"` Format string `mapstructure:"format"` KeepVM string `mapstructure:"keep_vm"` + IPGetter string `mapstructure:"ip_getter"` } func (c *CommonConfig) Prepare(t *packer.ConfigTemplate, pc *common.PackerConfig) []error { @@ -123,6 +124,10 @@ func (c *CommonConfig) Prepare(t *packer.ConfigTemplate, pc *common.PackerConfig c.KeepVM = "never" } + if c.IPGetter == "" { + c.IPGetter = "auto" + } + // Template substitution templates := map[string]*string{ @@ -142,6 +147,7 @@ func (c *CommonConfig) Prepare(t *packer.ConfigTemplate, pc *common.PackerConfig "output_directory": &c.OutputDir, "format": &c.Format, "keep_vm": &c.KeepVM, + "ip_getter": &c.IPGetter, } for i := range c.FloppyFiles { templates[fmt.Sprintf("floppy_files[%d]", i)] = &c.FloppyFiles[i] @@ -225,6 +231,12 @@ func (c *CommonConfig) Prepare(t *packer.ConfigTemplate, pc *common.PackerConfig errs = append(errs, errors.New("keep_vm must be one of 'always', 'never', 'on_success'")) } + switch c.IPGetter { + case "auto", "tools", "http": + default: + errs = append(errs, errors.New("ip_getter must be one of 'auto', 'tools', 'http'")) + } + return errs } diff --git a/builder/xenserver/common/step_wait_for_ip.go b/builder/xenserver/common/step_wait_for_ip.go index eeb6d1a..84099cd 100644 --- a/builder/xenserver/common/step_wait_for_ip.go +++ b/builder/xenserver/common/step_wait_for_ip.go @@ -18,6 +18,7 @@ type StepWaitForIP struct { func (self *StepWaitForIP) Run(state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) client := state.Get("client").(xsclient.XenAPIClient) + config := state.Get("commonconfig").(CommonConfig) ui.Say("Step: Wait for VM's IP to become known to us.") @@ -33,28 +34,37 @@ func (self *StepWaitForIP) Run(state multistep.StateBag) multistep.StepAction { Timeout: self.Timeout, PredicateInterval: 5 * time.Second, Predicate: func() (result bool, err error) { - // first check if we got any HTTP requests - select { - case ip = <-self.Chan: - ui.Message(fmt.Sprintf("Got IP '%s' from HTTP request", ip)) - return true, nil - default: - } - // failing that, look for PV IP - metrics, err := instance.GetGuestMetrics() - if err != nil { - return false, err - } - if metrics != nil { - networks := metrics["networks"].(xmlrpc.Struct) - if ipRaw, ok := networks["0/ip"]; ok { - if ip = ipRaw.(string); ip != "" { - ui.Message(fmt.Sprintf("Got IP '%s' from XenServer tools", ip)) - return true, nil - } - } - } + if (config.IPGetter == "auto" || config.IPGetter == "http") { + + // Snoop IP from HTTP fetch + select { + case ip = <-self.Chan: + ui.Message(fmt.Sprintf("Got IP '%s' from HTTP request", ip)) + return true, nil + default: + } + + } + + if (config.IPGetter == "auto" || config.IPGetter == "tools") { + + // Look for PV IP + metrics, err := instance.GetGuestMetrics() + if err != nil { + return false, err + } + if metrics != nil { + networks := metrics["networks"].(xmlrpc.Struct) + if ipRaw, ok := networks["0/ip"]; ok { + if ip = ipRaw.(string); ip != "" { + ui.Message(fmt.Sprintf("Got IP '%s' from XenServer tools", ip)) + return true, nil + } + } + } + + } return false, nil },