From 4875b82d12f3f82452a80645c56992a53c506dfc Mon Sep 17 00:00:00 2001 From: Andrei Tonkikh Date: Mon, 12 Feb 2018 15:56:29 +0300 Subject: [PATCH] Make waiting for IP address interruptible fixes #24 --- clone/builder.go | 1 + common/step_run.go | 9 ------- common/step_wait_for_ip.go | 49 ++++++++++++++++++++++++++++++++++++++ iso/builder.go | 1 + 4 files changed, 51 insertions(+), 9 deletions(-) create mode 100644 common/step_wait_for_ip.go diff --git a/clone/builder.go b/clone/builder.go index c4838efdf..51b54d3e5 100644 --- a/clone/builder.go +++ b/clone/builder.go @@ -50,6 +50,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe &common.StepRun{ Config: &b.config.RunConfig, }, + &common.StepWaitForIp{}, &communicator.StepConnect{ Config: &b.config.Comm, Host: common.CommHost, diff --git a/common/step_run.go b/common/step_run.go index e4210b2ce..305acdc05 100644 --- a/common/step_run.go +++ b/common/step_run.go @@ -39,15 +39,6 @@ func (s *StepRun) Run(state multistep.StateBag) multistep.StepAction { return multistep.ActionHalt } - ui.Say("Waiting for IP...") - ip, err := vm.WaitForIP() - if err != nil { - state.Put("error", err) - return multistep.ActionHalt - } - state.Put("ip", ip) - ui.Say(fmt.Sprintf("IP address: %v", ip)) - return multistep.ActionContinue } diff --git a/common/step_wait_for_ip.go b/common/step_wait_for_ip.go new file mode 100644 index 000000000..da33b0b91 --- /dev/null +++ b/common/step_wait_for_ip.go @@ -0,0 +1,49 @@ +package common + +import ( + "github.com/mitchellh/multistep" + "fmt" + "github.com/hashicorp/packer/packer" + "github.com/jetbrains-infra/packer-builder-vsphere/driver" + "time" +) + +type StepWaitForIp struct{} + +func (s *StepWaitForIp) Run(state multistep.StateBag) multistep.StepAction { + ui := state.Get("ui").(packer.Ui) + vm := state.Get("vm").(*driver.VirtualMachine) + + ui.Say("Waiting for IP...") + + ipChan := make(chan string) + errChan := make(chan error) + go func() { + ip, err := vm.WaitForIP() + if err != nil { + errChan <- err + } else { + ipChan <- ip + } + }() + + for { + select { + case err := <-errChan: + state.Put("error", err) + return multistep.ActionHalt + case ip := <-ipChan: + state.Put("ip", ip) + ui.Say(fmt.Sprintf("IP address: %v", ip)) + return multistep.ActionContinue + case <-time.After(1 * time.Second): + if _, ok := state.GetOk(multistep.StateCancelled); ok { + return multistep.ActionHalt + } + } + } +} + +func (s *StepWaitForIp) Cleanup(state multistep.StateBag) { + // nothing +} diff --git a/iso/builder.go b/iso/builder.go index b726b57a5..2e9307190 100644 --- a/iso/builder.go +++ b/iso/builder.go @@ -57,6 +57,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe &common.StepRun{ Config: &b.config.RunConfig, }, + &common.StepWaitForIp{}, &communicator.StepConnect{ Config: &b.config.Comm, Host: common.CommHost,