diff --git a/builder/vsphere/clone/config.go b/builder/vsphere/clone/config.go index c841b5a56..f7b2fd588 100644 --- a/builder/vsphere/clone/config.go +++ b/builder/vsphere/clone/config.go @@ -65,7 +65,9 @@ func (c *Config) Prepare(raws ...interface{}) ([]string, error) { return nil, err } + // warnings := make([]string, 0) errs := new(packer.MultiError) + errs = packer.MultiErrorAppend(errs, c.ConnectConfig.Prepare()...) errs = packer.MultiErrorAppend(errs, c.CloneConfig.Prepare()...) errs = packer.MultiErrorAppend(errs, c.LocationConfig.Prepare()...) @@ -77,7 +79,12 @@ func (c *Config) Prepare(raws ...interface{}) ([]string, error) { errs = packer.MultiErrorAppend(errs, c.BootConfig.Prepare(&c.ctx)...) errs = packer.MultiErrorAppend(errs, c.WaitIpConfig.Prepare()...) errs = packer.MultiErrorAppend(errs, c.Comm.Prepare(&c.ctx)...) - errs = packer.MultiErrorAppend(errs, c.ShutdownConfig.Prepare()...) + + _, shutdownErrs := c.ShutdownConfig.Prepare(c.Comm) + // shutdownWarnings, shutdownErrs := c.ShutdownConfig.Prepare(c.Comm) + // warnings = append(warnings, shutdownWarnings...) + errs = packer.MultiErrorAppend(errs, shutdownErrs...) + if c.Export != nil { errs = packer.MultiErrorAppend(errs, c.Export.Prepare(&c.ctx, &c.LocationConfig, &c.PackerConfig)...) } diff --git a/builder/vsphere/common/step_shutdown.go b/builder/vsphere/common/step_shutdown.go index f85749f40..8c71cc2d3 100644 --- a/builder/vsphere/common/step_shutdown.go +++ b/builder/vsphere/common/step_shutdown.go @@ -11,34 +11,40 @@ import ( "time" "github.com/hashicorp/packer/builder/vsphere/driver" + "github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" ) type ShutdownConfig struct { - // Specify a VM guest shutdown command. VMware guest tools are used by - // default. + // Specify a VM guest shutdown command. This command will be executed using + // the `communicator`. Otherwise the VMware guest tools are used to gracefully + // shutdown the VM guest. Command string `mapstructure:"shutdown_command"` // Amount of time to wait for graceful VM shutdown. // Defaults to 5m or five minutes. + // This will likely need to be modified if the `communicator` is 'none'. Timeout time.Duration `mapstructure:"shutdown_timeout"` // Packer normally halts the virtual machine after all provisioners have // run when no `shutdown_command` is defined. If this is set to `true`, Packer // *will not* halt the virtual machine but will assume that you will send the stop - // signal yourself through the preseed.cfg or your final provisioner. + // signal yourself through a preseed.cfg, a script or the final provisioner. // Packer will wait for a default of five minutes until the virtual machine is shutdown. // The timeout can be changed using `shutdown_timeout` option. DisableShutdown bool `mapstructure:"disable_shutdown"` } -func (c *ShutdownConfig) Prepare() []error { - var errs []error +func (c *ShutdownConfig) Prepare(comm communicator.Config) (warnings []string, errs []error) { if c.Timeout == 0 { c.Timeout = 5 * time.Minute } - return errs + if comm.Type == "none" && c.Command != "" { + warnings = append(warnings, "The parameter `shutdown_command` is ignored as it requires a `communicator`.") + } + + return } type StepShutdown struct { @@ -47,7 +53,6 @@ type StepShutdown struct { 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.VirtualMachineDriver) if off, _ := vm.IsPoweredOff(); off { @@ -56,9 +61,17 @@ func (s *StepShutdown) Run(ctx context.Context, state multistep.StateBag) multis return multistep.ActionContinue } - if s.Config.DisableShutdown { + comm, _ := state.Get("communicator").(packer.Communicator) + if comm == nil { + + msg := fmt.Sprintf("Please shutdown virtual machine within %s.", s.Config.Timeout) + ui.Message(msg) + + } else if s.Config.DisableShutdown { ui.Say("Automatic shutdown disabled. Please shutdown virtual machine.") } else if s.Config.Command != "" { + // Communicator is not needed unless shutdown_command is populated + ui.Say("Executing shutdown command...") log.Printf("Shutdown command: %s", s.Config.Command) diff --git a/builder/vsphere/iso/builder.go b/builder/vsphere/iso/builder.go index a7f6f29cb..45fe1ca0b 100644 --- a/builder/vsphere/iso/builder.go +++ b/builder/vsphere/iso/builder.go @@ -77,40 +77,40 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack &common.StepConfigParams{ Config: &b.config.ConfigParamsConfig, }, + &packerCommon.StepCreateFloppy{ + Files: b.config.FloppyFiles, + Directories: b.config.FloppyDirectories, + Label: b.config.FloppyLabel, + }, + &common.StepAddFloppy{ + Config: &b.config.FloppyConfig, + Datastore: b.config.Datastore, + Host: b.config.Host, + SetHostForDatastoreUploads: b.config.SetHostForDatastoreUploads, + }, + &common.StepHTTPIPDiscover{ + HTTPIP: b.config.BootConfig.HTTPIP, + Network: b.config.WaitIpConfig.GetIPNet(), + }, + &packerCommon.StepHTTPServer{ + HTTPDir: b.config.HTTPDir, + HTTPPortMin: b.config.HTTPPortMin, + HTTPPortMax: b.config.HTTPPortMax, + HTTPAddress: b.config.HTTPAddress, + }, + &common.StepRun{ + Config: &b.config.RunConfig, + SetOrder: true, + }, + &common.StepBootCommand{ + Config: &b.config.BootConfig, + Ctx: b.config.ctx, + VMName: b.config.VMName, + }, ) if b.config.Comm.Type != "none" { steps = append(steps, - &packerCommon.StepCreateFloppy{ - Files: b.config.FloppyFiles, - Directories: b.config.FloppyDirectories, - Label: b.config.FloppyLabel, - }, - &common.StepAddFloppy{ - Config: &b.config.FloppyConfig, - Datastore: b.config.Datastore, - Host: b.config.Host, - SetHostForDatastoreUploads: b.config.SetHostForDatastoreUploads, - }, - &common.StepHTTPIPDiscover{ - HTTPIP: b.config.BootConfig.HTTPIP, - Network: b.config.WaitIpConfig.GetIPNet(), - }, - &packerCommon.StepHTTPServer{ - HTTPDir: b.config.HTTPDir, - HTTPPortMin: b.config.HTTPPortMin, - HTTPPortMax: b.config.HTTPPortMax, - HTTPAddress: b.config.HTTPAddress, - }, - &common.StepRun{ - Config: &b.config.RunConfig, - SetOrder: true, - }, - &common.StepBootCommand{ - Config: &b.config.BootConfig, - Ctx: b.config.ctx, - VMName: b.config.VMName, - }, &common.StepWaitForIp{ Config: &b.config.WaitIpConfig, }, @@ -120,17 +120,17 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack SSHConfig: b.config.Comm.SSHConfigFunc(), }, &packerCommon.StepProvision{}, - &common.StepShutdown{ - Config: &b.config.ShutdownConfig, - }, - &common.StepRemoveFloppy{ - Datastore: b.config.Datastore, - Host: b.config.Host, - }, ) } steps = append(steps, + &common.StepShutdown{ + Config: &b.config.ShutdownConfig, + }, + &common.StepRemoveFloppy{ + Datastore: b.config.Datastore, + Host: b.config.Host, + }, &common.StepRemoveCDRom{ Config: &b.config.RemoveCDRomConfig, }, diff --git a/builder/vsphere/iso/config.go b/builder/vsphere/iso/config.go index 3d9601524..791f80cc9 100644 --- a/builder/vsphere/iso/config.go +++ b/builder/vsphere/iso/config.go @@ -86,7 +86,11 @@ func (c *Config) Prepare(raws ...interface{}) ([]string, error) { errs = packer.MultiErrorAppend(errs, c.BootConfig.Prepare(&c.ctx)...) errs = packer.MultiErrorAppend(errs, c.WaitIpConfig.Prepare()...) errs = packer.MultiErrorAppend(errs, c.Comm.Prepare(&c.ctx)...) - errs = packer.MultiErrorAppend(errs, c.ShutdownConfig.Prepare()...) + + shutdownWarnings, shutdownErrs := c.ShutdownConfig.Prepare(c.Comm) + warnings = append(warnings, shutdownWarnings...) + errs = packer.MultiErrorAppend(errs, shutdownErrs...) + if c.Export != nil { errs = packer.MultiErrorAppend(errs, c.Export.Prepare(&c.ctx, &c.LocationConfig, &c.PackerConfig)...) } diff --git a/website/pages/partials/builder/vsphere/common/ShutdownConfig-not-required.mdx b/website/pages/partials/builder/vsphere/common/ShutdownConfig-not-required.mdx index 85915de71..1b950c176 100644 --- a/website/pages/partials/builder/vsphere/common/ShutdownConfig-not-required.mdx +++ b/website/pages/partials/builder/vsphere/common/ShutdownConfig-not-required.mdx @@ -1,14 +1,16 @@ -- `shutdown_command` (string) - Specify a VM guest shutdown command. VMware guest tools are used by - default. +- `shutdown_command` (string) - Specify a VM guest shutdown command. This command will be executed using + the `communicator`. Otherwise the VMware guest tools are used to gracefully + shutdown the VM guest. - `shutdown_timeout` (duration string | ex: "1h5m2s") - Amount of time to wait for graceful VM shutdown. Defaults to 5m or five minutes. + This will likely need to be modified if the `communicator` is 'none'. - `disable_shutdown` (bool) - Packer normally halts the virtual machine after all provisioners have run when no `shutdown_command` is defined. If this is set to `true`, Packer *will not* halt the virtual machine but will assume that you will send the stop - signal yourself through the preseed.cfg or your final provisioner. + signal yourself through a preseed.cfg, a script or the final provisioner. Packer will wait for a default of five minutes until the virtual machine is shutdown. The timeout can be changed using `shutdown_timeout` option.