From 23c918d00a4fa4aa59e580389169d173143dcc79 Mon Sep 17 00:00:00 2001 From: Michael Kuzmin Date: Wed, 16 May 2018 16:05:08 +0300 Subject: [PATCH] Fix build cancellation (#101) --- clone/step_clone.go | 7 +++++-- common/step_connect.go | 4 ++-- common/step_shutdown.go | 4 ++-- common/step_wait_for_ip.go | 6 ++++-- driver/driver.go | 3 ++- driver/vm.go | 18 +++++++++++++----- 6 files changed, 28 insertions(+), 14 deletions(-) diff --git a/clone/step_clone.go b/clone/step_clone.go index f8a28dd42..b588e17cb 100644 --- a/clone/step_clone.go +++ b/clone/step_clone.go @@ -34,7 +34,7 @@ type StepCloneVM struct { Location *common.LocationConfig } -func (s *StepCloneVM) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { +func (s *StepCloneVM) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) d := state.Get("driver").(*driver.Driver) @@ -46,7 +46,7 @@ func (s *StepCloneVM) Run(_ context.Context, state multistep.StateBag) multistep return multistep.ActionHalt } - vm, err := template.Clone(&driver.CloneConfig{ + vm, err := template.Clone(ctx, &driver.CloneConfig{ Name: s.Location.VMName, Folder: s.Location.Folder, Cluster: s.Location.Cluster, @@ -59,6 +59,9 @@ func (s *StepCloneVM) Run(_ context.Context, state multistep.StateBag) multistep state.Put("error", err) return multistep.ActionHalt } + if vm == nil { + return multistep.ActionHalt + } state.Put("vm", vm) if s.Config.DiskSize > 0 { diff --git a/common/step_connect.go b/common/step_connect.go index 774df9d74..6891247d7 100644 --- a/common/step_connect.go +++ b/common/step_connect.go @@ -35,8 +35,8 @@ type StepConnect struct { Config *ConnectConfig } -func (s *StepConnect) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { - d, err := driver.NewDriver(ctx, &driver.ConnectConfig{ +func (s *StepConnect) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + d, err := driver.NewDriver(&driver.ConnectConfig{ VCenterServer: s.Config.VCenterServer, Username: s.Config.Username, Password: s.Config.Password, diff --git a/common/step_shutdown.go b/common/step_shutdown.go index 0c51da084..5fe9996fc 100644 --- a/common/step_shutdown.go +++ b/common/step_shutdown.go @@ -39,7 +39,7 @@ type StepShutdown struct { Config *ShutdownConfig } -func (s *StepShutdown) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { +func (s *StepShutdown) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) comm := state.Get("communicator").(packer.Communicator) vm := state.Get("vm").(*driver.VirtualMachine) @@ -70,7 +70,7 @@ func (s *StepShutdown) Run(_ context.Context, state multistep.StateBag) multiste } log.Printf("Waiting max %s for shutdown to complete", s.Config.Timeout) - err := vm.WaitForShutdown(s.Config.Timeout) + err := vm.WaitForShutdown(ctx, s.Config.Timeout) if err != nil { state.Put("error", err) return multistep.ActionHalt diff --git a/common/step_wait_for_ip.go b/common/step_wait_for_ip.go index 400d03559..a3485bd5d 100644 --- a/common/step_wait_for_ip.go +++ b/common/step_wait_for_ip.go @@ -11,7 +11,7 @@ import ( type StepWaitForIp struct{} -func (s *StepWaitForIp) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { +func (s *StepWaitForIp) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) vm := state.Get("vm").(*driver.VirtualMachine) @@ -20,7 +20,7 @@ func (s *StepWaitForIp) Run(_ context.Context, state multistep.StateBag) multist ipChan := make(chan string) errChan := make(chan error) go func() { - ip, err := vm.WaitForIP() + ip, err := vm.WaitForIP(ctx) if err != nil { errChan <- err } else { @@ -33,6 +33,8 @@ func (s *StepWaitForIp) Run(_ context.Context, state multistep.StateBag) multist case err := <-errChan: state.Put("error", err) return multistep.ActionHalt + case <-ctx.Done(): + return multistep.ActionHalt case ip := <-ipChan: state.Put("ip", ip) ui.Say(fmt.Sprintf("IP address: %v", ip)) diff --git a/driver/driver.go b/driver/driver.go index 324bcc148..30ddcce72 100644 --- a/driver/driver.go +++ b/driver/driver.go @@ -28,7 +28,8 @@ type ConnectConfig struct { Datacenter string } -func NewDriver(ctx context.Context, config *ConnectConfig) (*Driver, error) { +func NewDriver(config *ConnectConfig) (*Driver, error) { + ctx := context.TODO() vcenter_url, err := url.Parse(fmt.Sprintf("https://%v/sdk", config.VCenterServer)) if err != nil { diff --git a/driver/vm.go b/driver/vm.go index db3eb4d66..e896a65cc 100644 --- a/driver/vm.go +++ b/driver/vm.go @@ -8,6 +8,7 @@ import ( "github.com/vmware/govmomi/vim25/types" "time" "strings" + "context" ) type VirtualMachine struct { @@ -178,7 +179,7 @@ func (vm *VirtualMachine) Devices() (object.VirtualDeviceList, error) { return vmInfo.Config.Hardware.Device, nil } -func (template *VirtualMachine) Clone(config *CloneConfig) (*VirtualMachine, error) { +func (template *VirtualMachine) Clone(ctx context.Context, config *CloneConfig) (*VirtualMachine, error) { folder, err := template.driver.FindFolder(config.Folder) if err != nil { return nil, err @@ -223,8 +224,13 @@ func (template *VirtualMachine) Clone(config *CloneConfig) (*VirtualMachine, err return nil, err } - info, err := task.WaitForResult(template.driver.ctx, nil) + info, err := task.WaitForResult(ctx, nil) if err != nil { + if ctx.Err() == context.Canceled { + err = task.Cancel(context.TODO()) + return nil, err + } + return nil, err } @@ -329,8 +335,8 @@ func (vm *VirtualMachine) PowerOn() error { return err } -func (vm *VirtualMachine) WaitForIP() (string, error) { - return vm.vm.WaitForIP(vm.driver.ctx) +func (vm *VirtualMachine) WaitForIP(ctx context.Context) (string, error) { + return vm.vm.WaitForIP(ctx) } func (vm *VirtualMachine) PowerOff() error { @@ -356,7 +362,7 @@ func (vm *VirtualMachine) StartShutdown() error { return err } -func (vm *VirtualMachine) WaitForShutdown(timeout time.Duration) error { +func (vm *VirtualMachine) WaitForShutdown(ctx context.Context, timeout time.Duration) error { shutdownTimer := time.After(timeout) for { powerState, err := vm.vm.PowerState(vm.driver.ctx) @@ -371,6 +377,8 @@ func (vm *VirtualMachine) WaitForShutdown(timeout time.Duration) error { case <-shutdownTimer: err := errors.New("Timeout while waiting for machine to shut down.") return err + case <-ctx.Done(): + return nil default: time.Sleep(1 * time.Second) }