Adding an override for selecting how we obtain an IP for the created VM. In particular this helps disable HTTP snooping where the installers IP may differ from the IP obtained on firstboot.

Signed-off-by: Rob Dobson <rob.dobson@citrix.com>
This commit is contained in:
Rob Dobson 2015-04-27 17:44:38 +01:00
parent a0e9c97c89
commit a135a74946
2 changed files with 43 additions and 21 deletions

View File

@ -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
}

View File

@ -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
},