Skip to content

Commit 2376943

Browse files
committed
Add support for IP address changes
This commit improves upon the existing "Wait for IP step", by continuously checking for changes to the IP address for the VM, even after the IP address has been retrieved. The implementation is using a simple goroutine which encapsulates the existing method used to wait for the IP address. When an IP address has been found, the goroutine will put the IP address directly in the state, which will be queried when the IP address should be retrieved.
1 parent bc21b3c commit 2376943

File tree

3 files changed

+40
-20
lines changed

3 files changed

+40
-20
lines changed

builder/xenserver/common/ssh.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,7 @@ func forward(local_conn net.Conn, config *gossh.ClientConfig, server string, ser
157157
return nil
158158
}
159159

160-
func ssh_port_forward(local_listener net.Listener, remote_port int, remote_dest, host string, host_ssh_port int, username, password string) error {
161-
160+
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 {
162161
config := &gossh.ClientConfig{
163162
User: username,
164163
Auth: []gossh.AuthMethod{
@@ -175,6 +174,12 @@ func ssh_port_forward(local_listener net.Listener, remote_port int, remote_dest,
175174
return err
176175
}
177176

177+
remote_dest, err := remote_dest_func()
178+
179+
if err != nil {
180+
return err
181+
}
182+
178183
// Forward to a remote port
179184
go forward(local_connection, config, host, host_ssh_port, remote_dest, uint(remote_port))
180185
}

builder/xenserver/common/step_forward_port_over_ssh.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ func (self *StepForwardPortOverSSH) Run(ctx context.Context, state multistep.Sta
3939
remotePort, _ := self.RemotePort(state)
4040
remoteDest, _ := self.RemoteDest(state)
4141

42-
go ssh_port_forward(l, remotePort, remoteDest, hostAddress, hostSshPort, config.Username, config.Password)
42+
go ssh_port_forward(l, remotePort, hostAddress, hostSshPort, config.Username, config.Password, func() (string, error) { return self.RemoteDest(state) })
4343
ui.Say(fmt.Sprintf("Port forward setup. %d ---> %s:%d on %s", sshHostPort, remoteDest, remotePort, hostAddress))
4444

4545
// Provide the local port to future steps.

builder/xenserver/common/step_wait_for_ip.go

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -29,47 +29,62 @@ func (self *StepWaitForIP) Run(ctx context.Context, state multistep.StateBag) mu
2929
return multistep.ActionHalt
3030
}
3131

32-
var ip string
33-
err = InterruptibleWait{
34-
Timeout: self.Timeout,
35-
PredicateInterval: 5 * time.Second,
36-
Predicate: func() (result bool, err error) {
32+
go func(c Connection, ui packer.Ui, config CommonConfig) {
33+
state.Put("instance_ssh_address", "")
34+
var ip string
3735

36+
for true {
37+
time.Sleep(500 * time.Millisecond)
3838
if config.IPGetter == "auto" || config.IPGetter == "http" {
39-
4039
// Snoop IP from HTTP fetch
4140
select {
42-
case ip = <-self.Chan:
43-
ui.Message(fmt.Sprintf("Got IP '%s' from HTTP request", ip))
44-
return true, nil
41+
case temp_ip := <-self.Chan:
42+
if ip != temp_ip {
43+
ip = temp_ip
44+
ui.Message(fmt.Sprintf("Got IP '%s' from HTTP request", ip))
45+
state.Put("instance_ssh_address", ip)
46+
}
4547
default:
4648
}
47-
4849
}
4950

5051
if config.IPGetter == "auto" || config.IPGetter == "tools" {
51-
5252
// Look for PV IP
5353
m, err := c.client.VM.GetGuestMetrics(c.session, instance)
5454
if err != nil {
55-
return false, err
55+
continue
5656
}
5757
if m != "" {
5858
metrics, err := c.client.VMGuestMetrics.GetRecord(c.session, m)
5959
if err != nil {
60-
return false, err
60+
continue
6161
}
6262
networks := metrics.Networks
63-
var ok bool
64-
if ip, ok = networks["0/ip"]; ok {
65-
if ip != "" {
63+
if temp_ip, ok := networks["0/ip"]; ok {
64+
if temp_ip != "" && ip != temp_ip {
65+
ip = temp_ip
6666
ui.Message(fmt.Sprintf("Got IP '%s' from XenServer tools", ip))
67-
return true, nil
67+
state.Put("instance_ssh_address", ip)
6868
}
6969
}
7070
}
7171

7272
}
73+
}
74+
}(*c, ui, config)
75+
76+
time.Sleep(500 * time.Millisecond)
77+
78+
var ip string
79+
80+
err = InterruptibleWait{
81+
Timeout: self.Timeout,
82+
PredicateInterval: 5 * time.Second,
83+
Predicate: func() (result bool, err error) {
84+
var ok bool
85+
if ip, ok = state.Get("instance_ssh_address").(string); ok && ip != "" {
86+
return true, nil
87+
}
7388

7489
return false, nil
7590
},

0 commit comments

Comments
 (0)