Pause between boot_commands when debugging a QEMU build

When debugging a build (or maintaining an existing packer template), teach `packer build -debug` how to step through individual `boot_command`s in order to triage the packer template.
This commit is contained in:
Sean Chittenden 2016-05-17 17:14:50 -04:00
parent d0fd698fb5
commit 98bae9c98e
No known key found for this signature in database
GPG Key ID: 4EBC9DC16C2E5E16
2 changed files with 15 additions and 2 deletions

View File

@ -379,15 +379,18 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
state := new(multistep.BasicStateBag) state := new(multistep.BasicStateBag)
state.Put("cache", cache) state.Put("cache", cache)
state.Put("config", &b.config) state.Put("config", &b.config)
state.Put("debug", b.config.PackerDebug)
state.Put("driver", driver) state.Put("driver", driver)
state.Put("hook", hook) state.Put("hook", hook)
state.Put("ui", ui) state.Put("ui", ui)
// Run // Run
if b.config.PackerDebug { if b.config.PackerDebug {
pauseFn := common.MultistepDebugFn(ui)
state.Put("pauseFn", pauseFn)
b.runner = &multistep.DebugRunner{ b.runner = &multistep.DebugRunner{
Steps: steps, Steps: steps,
PauseFn: common.MultistepDebugFn(ui), PauseFn: pauseFn,
} }
} else { } else {
b.runner = &multistep.BasicRunner{Steps: steps} b.runner = &multistep.BasicRunner{Steps: steps}

View File

@ -38,10 +38,16 @@ type stepTypeBootCommand struct{}
func (s *stepTypeBootCommand) Run(state multistep.StateBag) multistep.StepAction { func (s *stepTypeBootCommand) Run(state multistep.StateBag) multistep.StepAction {
config := state.Get("config").(*Config) config := state.Get("config").(*Config)
debug := state.Get("debug").(bool)
httpPort := state.Get("http_port").(uint) httpPort := state.Get("http_port").(uint)
ui := state.Get("ui").(packer.Ui) ui := state.Get("ui").(packer.Ui)
vncPort := state.Get("vnc_port").(uint) vncPort := state.Get("vnc_port").(uint)
var pauseFn multistep.DebugPauseFn
if debug {
pauseFn = state.Get("pauseFn").(multistep.DebugPauseFn)
}
// Connect to VNC // Connect to VNC
ui.Say("Connecting to VM via VNC") ui.Say("Connecting to VM via VNC")
nc, err := net.Dial("tcp", fmt.Sprintf("127.0.0.1:%d", vncPort)) nc, err := net.Dial("tcp", fmt.Sprintf("127.0.0.1:%d", vncPort))
@ -72,7 +78,7 @@ func (s *stepTypeBootCommand) Run(state multistep.StateBag) multistep.StepAction
} }
ui.Say("Typing the boot command over VNC...") ui.Say("Typing the boot command over VNC...")
for _, command := range config.BootCommand { for i, command := range config.BootCommand {
command, err := interpolate.Render(command, &ctx) command, err := interpolate.Render(command, &ctx)
if err != nil { if err != nil {
err := fmt.Errorf("Error preparing boot command: %s", err) err := fmt.Errorf("Error preparing boot command: %s", err)
@ -87,6 +93,10 @@ func (s *stepTypeBootCommand) Run(state multistep.StateBag) multistep.StepAction
return multistep.ActionHalt return multistep.ActionHalt
} }
if pauseFn != nil {
pauseFn(multistep.DebugLocationAfterRun, fmt.Sprintf("boot_command[%d]: %s", i, command), state)
}
vncSendString(c, command) vncSendString(c, command)
} }