github.com/alouche/packer@v0.3.7/builder/virtualbox/step_shutdown.go (about) 1 package virtualbox 2 3 import ( 4 "errors" 5 "fmt" 6 "github.com/mitchellh/multistep" 7 "github.com/mitchellh/packer/packer" 8 "log" 9 "time" 10 ) 11 12 // This step shuts down the machine. It first attempts to do so gracefully, 13 // but ultimately forcefully shuts it down if that fails. 14 // 15 // Uses: 16 // communicator packer.Communicator 17 // config *config 18 // driver Driver 19 // ui packer.Ui 20 // vmName string 21 // 22 // Produces: 23 // <nothing> 24 type stepShutdown struct{} 25 26 func (s *stepShutdown) Run(state multistep.StateBag) multistep.StepAction { 27 comm := state.Get("communicator").(packer.Communicator) 28 config := state.Get("config").(*config) 29 driver := state.Get("driver").(Driver) 30 ui := state.Get("ui").(packer.Ui) 31 vmName := state.Get("vmName").(string) 32 33 if config.ShutdownCommand != "" { 34 ui.Say("Gracefully halting virtual machine...") 35 log.Printf("Executing shutdown command: %s", config.ShutdownCommand) 36 cmd := &packer.RemoteCmd{Command: config.ShutdownCommand} 37 if err := cmd.StartWithUi(comm, ui); err != nil { 38 err := fmt.Errorf("Failed to send shutdown command: %s", err) 39 state.Put("error", err) 40 ui.Error(err.Error()) 41 return multistep.ActionHalt 42 } 43 44 // Wait for the machine to actually shut down 45 log.Printf("Waiting max %s for shutdown to complete", config.shutdownTimeout) 46 shutdownTimer := time.After(config.shutdownTimeout) 47 for { 48 running, _ := driver.IsRunning(vmName) 49 if !running { 50 break 51 } 52 53 select { 54 case <-shutdownTimer: 55 err := errors.New("Timeout while waiting for machine to shut down.") 56 state.Put("error", err) 57 ui.Error(err.Error()) 58 return multistep.ActionHalt 59 default: 60 time.Sleep(1 * time.Second) 61 } 62 } 63 } else { 64 ui.Say("Halting the virtual machine...") 65 if err := driver.Stop(vmName); err != nil { 66 err := fmt.Errorf("Error stopping VM: %s", err) 67 state.Put("error", err) 68 ui.Error(err.Error()) 69 return multistep.ActionHalt 70 } 71 } 72 73 log.Println("VM shut down.") 74 return multistep.ActionContinue 75 } 76 77 func (s *stepShutdown) Cleanup(state multistep.StateBag) {}