Try getting IP if reported by PV drivers
This commit is contained in:
parent
176c4ad7a3
commit
6ef9b70500
@ -491,21 +491,20 @@ func (self *VM) GetGuestMetricsRef() (ref string, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *VM) GetGuestMetrics() (metrics map[string]interface{}, err error) {
|
func (self *VM) GetGuestMetrics() (metrics map[string]interface{}, err error) {
|
||||||
metrics = make(map[string]interface{})
|
|
||||||
metrics_ref, err := self.GetGuestMetricsRef()
|
metrics_ref, err := self.GetGuestMetricsRef()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return metrics, err
|
return nil, err
|
||||||
|
}
|
||||||
|
if metrics_ref == "OpaqueRef:NULL" {
|
||||||
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
result := APIResult{}
|
result := APIResult{}
|
||||||
err = self.Client.APICall(&result, "VM_guest_metrics.get_record", metrics_ref)
|
err = self.Client.APICall(&result, "VM_guest_metrics.get_record", metrics_ref)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return metrics, nil
|
return nil, err
|
||||||
}
|
}
|
||||||
for k, v := range result.Value.(xmlrpc.Struct) {
|
return result.Value.(xmlrpc.Struct), nil
|
||||||
metrics[k] = v
|
|
||||||
}
|
|
||||||
return metrics, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *VM) SetStaticMemoryRange(min, max uint) (err error) {
|
func (self *VM) SetStaticMemoryRange(min, max uint) (err error) {
|
||||||
|
@ -1,45 +0,0 @@
|
|||||||
package common
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/mitchellh/multistep"
|
|
||||||
"github.com/mitchellh/packer/packer"
|
|
||||||
)
|
|
||||||
|
|
||||||
type StepWaitForHTTPRequest struct {
|
|
||||||
Chan <-chan string
|
|
||||||
Timeout time.Duration
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *StepWaitForHTTPRequest) Run(state multistep.StateBag) multistep.StepAction {
|
|
||||||
ui := state.Get("ui").(packer.Ui)
|
|
||||||
|
|
||||||
ui.Say("Step: Wait for install to complete.")
|
|
||||||
|
|
||||||
timeout := time.After(self.Timeout)
|
|
||||||
var ip string
|
|
||||||
select {
|
|
||||||
case ip = <-self.Chan:
|
|
||||||
case <-timeout:
|
|
||||||
ui.Error("Timed out. Giving up waiting for installation to complete.")
|
|
||||||
return multistep.ActionHalt
|
|
||||||
}
|
|
||||||
|
|
||||||
ui.Say(fmt.Sprintf("Got IP address '%s'", ip))
|
|
||||||
state.Put("instance_ssh_address", ip)
|
|
||||||
|
|
||||||
return multistep.ActionContinue
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *StepWaitForHTTPRequest) Cleanup(state multistep.StateBag) {}
|
|
||||||
|
|
||||||
func InstanceSSHIP(state multistep.StateBag) (string, error) {
|
|
||||||
ip := state.Get("instance_ssh_address").(string)
|
|
||||||
return ip, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func InstanceSSHPort(state multistep.StateBag) (uint, error) {
|
|
||||||
return 22, nil
|
|
||||||
}
|
|
82
builder/xenserver/common/step_wait_for_ip.go
Normal file
82
builder/xenserver/common/step_wait_for_ip.go
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/mitchellh/multistep"
|
||||||
|
"github.com/mitchellh/packer/packer"
|
||||||
|
"github.com/nilshell/xmlrpc"
|
||||||
|
)
|
||||||
|
|
||||||
|
type StepWaitForIP struct {
|
||||||
|
Chan <-chan string
|
||||||
|
Timeout time.Duration
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *StepWaitForIP) Run(state multistep.StateBag) multistep.StepAction {
|
||||||
|
ui := state.Get("ui").(packer.Ui)
|
||||||
|
client := state.Get("client").(XenAPIClient)
|
||||||
|
|
||||||
|
ui.Say("Step: Wait for VM's IP to become known to us.")
|
||||||
|
|
||||||
|
uuid := state.Get("instance_uuid").(string)
|
||||||
|
instance, err := client.GetVMByUuid(uuid)
|
||||||
|
if err != nil {
|
||||||
|
ui.Error(fmt.Sprintf("Unable to get VM from UUID '%s': %s", uuid, err.Error()))
|
||||||
|
return multistep.ActionHalt
|
||||||
|
}
|
||||||
|
|
||||||
|
var ip string
|
||||||
|
err = InterruptibleWait{
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, nil
|
||||||
|
},
|
||||||
|
}.Wait(state)
|
||||||
|
if err != nil {
|
||||||
|
ui.Error(fmt.Sprintf("Could not get IP address of VM: %s", err.Error()))
|
||||||
|
// @todo: give advice on what went wrong (no HTTP server? no PV drivers?)
|
||||||
|
return multistep.ActionHalt
|
||||||
|
}
|
||||||
|
|
||||||
|
ui.Say(fmt.Sprintf("Got IP address '%s'", ip))
|
||||||
|
state.Put("instance_ssh_address", ip)
|
||||||
|
|
||||||
|
return multistep.ActionContinue
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *StepWaitForIP) Cleanup(state multistep.StateBag) {}
|
||||||
|
|
||||||
|
func InstanceSSHIP(state multistep.StateBag) (string, error) {
|
||||||
|
ip := state.Get("instance_ssh_address").(string)
|
||||||
|
return ip, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func InstanceSSHPort(state multistep.StateBag) (uint, error) {
|
||||||
|
return 22, nil
|
||||||
|
}
|
@ -254,7 +254,7 @@ func (self *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (pa
|
|||||||
&xscommon.StepTypeBootCommand{
|
&xscommon.StepTypeBootCommand{
|
||||||
Tpl: self.config.tpl,
|
Tpl: self.config.tpl,
|
||||||
},
|
},
|
||||||
&xscommon.StepWaitForHTTPRequest{
|
&xscommon.StepWaitForIP{
|
||||||
Chan: httpReqChan,
|
Chan: httpReqChan,
|
||||||
Timeout: self.config.InstallTimeout, // @todo change this
|
Timeout: self.config.InstallTimeout, // @todo change this
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user