From 9b3f8a4be92e920545c3b9f13601bab15c358f32 Mon Sep 17 00:00:00 2001 From: Sean Chittenden Date: Tue, 17 May 2016 03:50:00 -0400 Subject: [PATCH] Pause between boot_commands when debugging a VMware build When debugging a build (or maintaining an existing packer file), teach `packer build -debug` how to step through individual `boot_command`s in order to triage the packer file. ``` ==> vmware-iso: Typing the boot command over VNC... ==> vmware-iso: Pausing after run of step 'boot_command[0]: '. Press enter to continue. ==> vmware-iso: Pausing after run of step 'boot_command[1]: '. Press enter to continue. ==> vmware-iso: Pausing after run of step 'boot_command[2]: freebsd-vagrant'. Press enter to continue. ==> vmware-iso: Pausing after run of step 'boot_command[3]: '. Press enter to continue. ^C ``` --- builder/vmware/common/step_type_boot_command.go | 12 +++++++++++- builder/vmware/iso/builder.go | 5 ++++- builder/vmware/vmx/builder.go | 5 ++++- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/builder/vmware/common/step_type_boot_command.go b/builder/vmware/common/step_type_boot_command.go index 3959e5517..9750aaa71 100644 --- a/builder/vmware/common/step_type_boot_command.go +++ b/builder/vmware/common/step_type_boot_command.go @@ -40,12 +40,18 @@ type StepTypeBootCommand struct { } func (s *StepTypeBootCommand) Run(state multistep.StateBag) multistep.StepAction { + debug := state.Get("debug").(bool) driver := state.Get("driver").(Driver) httpPort := state.Get("http_port").(uint) ui := state.Get("ui").(packer.Ui) vncIp := state.Get("vnc_ip").(string) vncPort := state.Get("vnc_port").(uint) + var pauseFn multistep.DebugPauseFn + if debug { + pauseFn = state.Get("pauseFn").(multistep.DebugPauseFn) + } + // Connect to VNC ui.Say("Connecting to VM via VNC") nc, err := net.Dial("tcp", fmt.Sprintf("%s:%d", vncIp, vncPort)) @@ -95,7 +101,7 @@ func (s *StepTypeBootCommand) Run(state multistep.StateBag) multistep.StepAction } ui.Say("Typing the boot command over VNC...") - for _, command := range s.BootCommand { + for i, command := range s.BootCommand { command, err := interpolate.Render(command, &s.Ctx) if err != nil { err := fmt.Errorf("Error preparing boot command: %s", err) @@ -110,6 +116,10 @@ func (s *StepTypeBootCommand) Run(state multistep.StateBag) multistep.StepAction return multistep.ActionHalt } + if pauseFn != nil { + pauseFn(multistep.DebugLocationAfterRun, fmt.Sprintf("boot_command[%d]: %s", i, command), state) + } + vncSendString(c, command) } diff --git a/builder/vmware/iso/builder.go b/builder/vmware/iso/builder.go index b70f6b800..d1e5fd1fe 100755 --- a/builder/vmware/iso/builder.go +++ b/builder/vmware/iso/builder.go @@ -208,6 +208,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe state := new(multistep.BasicStateBag) state.Put("cache", cache) state.Put("config", &b.config) + state.Put("debug", b.config.PackerDebug) state.Put("dir", dir) state.Put("driver", driver) state.Put("hook", hook) @@ -304,9 +305,11 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe // Run! if b.config.PackerDebug { + pauseFn := common.MultistepDebugFn(ui) + state.Put("pauseFn", pauseFn) b.runner = &multistep.DebugRunner{ Steps: steps, - PauseFn: common.MultistepDebugFn(ui), + PauseFn: pauseFn, } } else { b.runner = &multistep.BasicRunner{Steps: steps} diff --git a/builder/vmware/vmx/builder.go b/builder/vmware/vmx/builder.go index 218edfa34..2de9de5f7 100644 --- a/builder/vmware/vmx/builder.go +++ b/builder/vmware/vmx/builder.go @@ -46,6 +46,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe // Set up the state. state := new(multistep.BasicStateBag) state.Put("config", b.config) + state.Put("debug", b.config.PackerDebug) state.Put("dir", dir) state.Put("driver", driver) state.Put("hook", hook) @@ -120,9 +121,11 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe // Run the steps. if b.config.PackerDebug { + pauseFn := common.MultistepDebugFn(ui) + state.Put("pauseFn", pauseFn) b.runner = &multistep.DebugRunner{ Steps: steps, - PauseFn: common.MultistepDebugFn(ui), + PauseFn: pauseFn, } } else { b.runner = &multistep.BasicRunner{Steps: steps}