diff --git a/builder/xenserver/common/ssh.go b/builder/xenserver/common/ssh.go index c484b31c..91d9eb30 100644 --- a/builder/xenserver/common/ssh.go +++ b/builder/xenserver/common/ssh.go @@ -157,8 +157,7 @@ func forward(local_conn net.Conn, config *gossh.ClientConfig, server string, ser return nil } -func ssh_port_forward(local_listener net.Listener, remote_port int, remote_dest, host string, host_ssh_port int, username, password string) error { - +func ssh_port_forward(local_listener net.Listener, remote_port int, host string, host_ssh_port int, username, password string, remote_dest_func func() (string, error)) error { config := &gossh.ClientConfig{ User: username, Auth: []gossh.AuthMethod{ @@ -175,6 +174,12 @@ func ssh_port_forward(local_listener net.Listener, remote_port int, remote_dest, return err } + remote_dest, err := remote_dest_func() + + if err != nil { + return err + } + // Forward to a remote port go forward(local_connection, config, host, host_ssh_port, remote_dest, uint(remote_port)) } diff --git a/builder/xenserver/common/step_forward_port_over_ssh.go b/builder/xenserver/common/step_forward_port_over_ssh.go index b573443f..64d5791c 100644 --- a/builder/xenserver/common/step_forward_port_over_ssh.go +++ b/builder/xenserver/common/step_forward_port_over_ssh.go @@ -39,7 +39,7 @@ func (self *StepForwardPortOverSSH) Run(ctx context.Context, state multistep.Sta remotePort, _ := self.RemotePort(state) remoteDest, _ := self.RemoteDest(state) - go ssh_port_forward(l, remotePort, remoteDest, hostAddress, hostSshPort, config.Username, config.Password) + go ssh_port_forward(l, remotePort, hostAddress, hostSshPort, config.Username, config.Password, func() (string, error) { return self.RemoteDest(state) }) ui.Say(fmt.Sprintf("Port forward setup. %d ---> %s:%d on %s", sshHostPort, remoteDest, remotePort, hostAddress)) // Provide the local port to future steps. diff --git a/builder/xenserver/common/step_wait_for_ip.go b/builder/xenserver/common/step_wait_for_ip.go index bed9735b..b06f9f37 100644 --- a/builder/xenserver/common/step_wait_for_ip.go +++ b/builder/xenserver/common/step_wait_for_ip.go @@ -29,47 +29,62 @@ func (self *StepWaitForIP) Run(ctx context.Context, state multistep.StateBag) mu return multistep.ActionHalt } - var ip string - err = InterruptibleWait{ - Timeout: self.Timeout, - PredicateInterval: 5 * time.Second, - Predicate: func() (result bool, err error) { + go func(c Connection, ui packer.Ui, config CommonConfig) { + state.Put("instance_ssh_address", "") + var ip string + for true { + time.Sleep(500 * time.Millisecond) 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 + case temp_ip := <-self.Chan: + if ip != temp_ip { + ip = temp_ip + ui.Message(fmt.Sprintf("Got IP '%s' from HTTP request", ip)) + state.Put("instance_ssh_address", ip) + } default: } - } if config.IPGetter == "auto" || config.IPGetter == "tools" { - // Look for PV IP m, err := c.client.VM.GetGuestMetrics(c.session, instance) if err != nil { - return false, err + continue } if m != "" { metrics, err := c.client.VMGuestMetrics.GetRecord(c.session, m) if err != nil { - return false, err + continue } networks := metrics.Networks - var ok bool - if ip, ok = networks["0/ip"]; ok { - if ip != "" { + if temp_ip, ok := networks["0/ip"]; ok { + if temp_ip != "" && ip != temp_ip { + ip = temp_ip ui.Message(fmt.Sprintf("Got IP '%s' from XenServer tools", ip)) - return true, nil + state.Put("instance_ssh_address", ip) } } } } + } + }(*c, ui, config) + + time.Sleep(500 * time.Millisecond) + + var ip string + + err = InterruptibleWait{ + Timeout: self.Timeout, + PredicateInterval: 5 * time.Second, + Predicate: func() (result bool, err error) { + var ok bool + if ip, ok = state.Get("instance_ssh_address").(string); ok && ip != "" { + return true, nil + } return false, nil },