diff --git a/CHANGELOG.md b/CHANGELOG.md index c3218f87c..66754aacd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ ## 1.6.1 (Upcoming) ### IMPROVEMENTS: +* builder/vsphere-clone: Add `boot_command` support to vsphere-clone builder, + including support for starting an HTTP server * builder/proxmox: Update Proxmox storagePoolTypes [GH-9418] * builder/vsphere: Create vm output folders if they don't exist [GH-9402] * builder/vsphere: Update vsphere boot_command to bring it in line with other diff --git a/builder/vsphere/clone/builder.go b/builder/vsphere/clone/builder.go index 359b0fbf5..0f68d33c3 100644 --- a/builder/vsphere/clone/builder.go +++ b/builder/vsphere/clone/builder.go @@ -30,6 +30,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) { func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (packer.Artifact, error) { state := new(multistep.BasicStateBag) + state.Put("debug", b.config.PackerDebug) state.Put("hook", hook) state.Put("ui", ui) @@ -54,10 +55,25 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack if b.config.Comm.Type != "none" { steps = append(steps, + &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: false, }, + &common.StepBootCommand{ + Config: &b.config.BootConfig, + Ctx: b.config.ctx, + VMName: b.config.VMName, + }, &common.StepWaitForIp{ Config: &b.config.WaitIpConfig, }, @@ -93,7 +109,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack }) } - b.runner = packerCommon.NewRunner(steps, b.config.PackerConfig, ui) + b.runner = packerCommon.NewRunnerWithPauseFn(steps, b.config.PackerConfig, ui, state) b.runner.Run(ctx, state) if rawErr, ok := state.GetOk("error"); ok { diff --git a/builder/vsphere/clone/config.go b/builder/vsphere/clone/config.go index 89c5bb67f..44fb1cc21 100644 --- a/builder/vsphere/clone/config.go +++ b/builder/vsphere/clone/config.go @@ -14,6 +14,7 @@ import ( type Config struct { packerCommon.PackerConfig `mapstructure:",squash"` + packerCommon.HTTPConfig `mapstructure:",squash"` common.ConnectConfig `mapstructure:",squash"` CloneConfig `mapstructure:",squash"` @@ -22,6 +23,7 @@ type Config struct { common.ConfigParamsConfig `mapstructure:",squash"` common.RunConfig `mapstructure:",squash"` + common.BootConfig `mapstructure:",squash"` common.WaitIpConfig `mapstructure:",squash"` Comm communicator.Config `mapstructure:",squash"` common.ShutdownConfig `mapstructure:",squash"` @@ -41,6 +43,11 @@ func (c *Config) Prepare(raws ...interface{}) ([]string, error) { err := config.Decode(c, &config.DecodeOpts{ Interpolate: true, InterpolateContext: &c.ctx, + InterpolateFilter: &interpolate.RenderFilter{ + Exclude: []string{ + "boot_command", + }, + }, }, raws...) if err != nil { return nil, err @@ -51,7 +58,9 @@ func (c *Config) Prepare(raws ...interface{}) ([]string, error) { errs = packer.MultiErrorAppend(errs, c.CloneConfig.Prepare()...) errs = packer.MultiErrorAppend(errs, c.LocationConfig.Prepare()...) errs = packer.MultiErrorAppend(errs, c.HardwareConfig.Prepare()...) + errs = packer.MultiErrorAppend(errs, c.HTTPConfig.Prepare(&c.ctx)...) + 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()...) diff --git a/builder/vsphere/clone/config.hcl2spec.go b/builder/vsphere/clone/config.hcl2spec.go index 11d7a9a0a..1decc7cd9 100644 --- a/builder/vsphere/clone/config.hcl2spec.go +++ b/builder/vsphere/clone/config.hcl2spec.go @@ -17,6 +17,10 @@ type FlatConfig struct { PackerOnError *string `mapstructure:"packer_on_error" cty:"packer_on_error" hcl:"packer_on_error"` PackerUserVars map[string]string `mapstructure:"packer_user_variables" cty:"packer_user_variables" hcl:"packer_user_variables"` PackerSensitiveVars []string `mapstructure:"packer_sensitive_variables" cty:"packer_sensitive_variables" hcl:"packer_sensitive_variables"` + HTTPDir *string `mapstructure:"http_directory" cty:"http_directory" hcl:"http_directory"` + HTTPPortMin *int `mapstructure:"http_port_min" cty:"http_port_min" hcl:"http_port_min"` + HTTPPortMax *int `mapstructure:"http_port_max" cty:"http_port_max" hcl:"http_port_max"` + HTTPAddress *string `mapstructure:"http_bind_address" cty:"http_bind_address" hcl:"http_bind_address"` VCenterServer *string `mapstructure:"vcenter_server" cty:"vcenter_server" hcl:"vcenter_server"` Username *string `mapstructure:"username" cty:"username" hcl:"username"` Password *string `mapstructure:"password" cty:"password" hcl:"password"` @@ -51,6 +55,10 @@ type FlatConfig struct { ToolsSyncTime *bool `mapstructure:"tools_sync_time" cty:"tools_sync_time" hcl:"tools_sync_time"` ToolsUpgradePolicy *bool `mapstructure:"tools_upgrade_policy" cty:"tools_upgrade_policy" hcl:"tools_upgrade_policy"` BootOrder *string `mapstructure:"boot_order" cty:"boot_order" hcl:"boot_order"` + BootGroupInterval *string `mapstructure:"boot_keygroup_interval" cty:"boot_keygroup_interval" hcl:"boot_keygroup_interval"` + BootWait *string `mapstructure:"boot_wait" cty:"boot_wait" hcl:"boot_wait"` + BootCommand []string `mapstructure:"boot_command" cty:"boot_command" hcl:"boot_command"` + HTTPIP *string `mapstructure:"http_ip" cty:"http_ip" hcl:"http_ip"` WaitTimeout *string `mapstructure:"ip_wait_timeout" cty:"ip_wait_timeout" hcl:"ip_wait_timeout"` SettleTimeout *string `mapstructure:"ip_settle_timeout" cty:"ip_settle_timeout" hcl:"ip_settle_timeout"` WaitAddress *string `mapstructure:"ip_wait_address" cty:"ip_wait_address" hcl:"ip_wait_address"` @@ -125,6 +133,10 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "packer_on_error": &hcldec.AttrSpec{Name: "packer_on_error", Type: cty.String, Required: false}, "packer_user_variables": &hcldec.AttrSpec{Name: "packer_user_variables", Type: cty.Map(cty.String), Required: false}, "packer_sensitive_variables": &hcldec.AttrSpec{Name: "packer_sensitive_variables", Type: cty.List(cty.String), Required: false}, + "http_directory": &hcldec.AttrSpec{Name: "http_directory", Type: cty.String, Required: false}, + "http_port_min": &hcldec.AttrSpec{Name: "http_port_min", Type: cty.Number, Required: false}, + "http_port_max": &hcldec.AttrSpec{Name: "http_port_max", Type: cty.Number, Required: false}, + "http_bind_address": &hcldec.AttrSpec{Name: "http_bind_address", Type: cty.String, Required: false}, "vcenter_server": &hcldec.AttrSpec{Name: "vcenter_server", Type: cty.String, Required: false}, "username": &hcldec.AttrSpec{Name: "username", Type: cty.String, Required: false}, "password": &hcldec.AttrSpec{Name: "password", Type: cty.String, Required: false}, @@ -159,6 +171,10 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "tools_sync_time": &hcldec.AttrSpec{Name: "tools_sync_time", Type: cty.Bool, Required: false}, "tools_upgrade_policy": &hcldec.AttrSpec{Name: "tools_upgrade_policy", Type: cty.Bool, Required: false}, "boot_order": &hcldec.AttrSpec{Name: "boot_order", Type: cty.String, Required: false}, + "boot_keygroup_interval": &hcldec.AttrSpec{Name: "boot_keygroup_interval", Type: cty.String, Required: false}, + "boot_wait": &hcldec.AttrSpec{Name: "boot_wait", Type: cty.String, Required: false}, + "boot_command": &hcldec.AttrSpec{Name: "boot_command", Type: cty.List(cty.String), Required: false}, + "http_ip": &hcldec.AttrSpec{Name: "http_ip", Type: cty.String, Required: false}, "ip_wait_timeout": &hcldec.AttrSpec{Name: "ip_wait_timeout", Type: cty.String, Required: false}, "ip_settle_timeout": &hcldec.AttrSpec{Name: "ip_settle_timeout", Type: cty.String, Required: false}, "ip_wait_address": &hcldec.AttrSpec{Name: "ip_wait_address", Type: cty.String, Required: false}, diff --git a/builder/vsphere/iso/step_boot_command.go b/builder/vsphere/common/step_boot_command.go similarity index 99% rename from builder/vsphere/iso/step_boot_command.go rename to builder/vsphere/common/step_boot_command.go index 805b89113..c7aceaf4e 100644 --- a/builder/vsphere/iso/step_boot_command.go +++ b/builder/vsphere/common/step_boot_command.go @@ -1,4 +1,4 @@ -package iso +package common import ( "context" diff --git a/builder/vsphere/iso/builder.go b/builder/vsphere/iso/builder.go index f755f2367..1ae3fc1f0 100644 --- a/builder/vsphere/iso/builder.go +++ b/builder/vsphere/iso/builder.go @@ -104,7 +104,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack Config: &b.config.RunConfig, SetOrder: true, }, - &StepBootCommand{ + &common.StepBootCommand{ Config: &b.config.BootConfig, Ctx: b.config.ctx, VMName: b.config.VMName, @@ -151,7 +151,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack }) } - b.runner = packerCommon.NewRunner(steps, b.config.PackerConfig, ui) + b.runner = packerCommon.NewRunnerWithPauseFn(steps, b.config.PackerConfig, ui, state) b.runner.Run(ctx, state) if rawErr, ok := state.GetOk("error"); ok { diff --git a/builder/vsphere/iso/config.go b/builder/vsphere/iso/config.go index a705d329e..0dd7b393f 100644 --- a/builder/vsphere/iso/config.go +++ b/builder/vsphere/iso/config.go @@ -28,7 +28,7 @@ type Config struct { RemoveCDRomConfig `mapstructure:",squash"` FloppyConfig `mapstructure:",squash"` common.RunConfig `mapstructure:",squash"` - BootConfig `mapstructure:",squash"` + common.BootConfig `mapstructure:",squash"` common.WaitIpConfig `mapstructure:",squash"` Comm communicator.Config `mapstructure:",squash"` diff --git a/website/pages/docs/builders/vmware/vsphere-clone.mdx b/website/pages/docs/builders/vmware/vsphere-clone.mdx index 78ea2c3be..ee39316f4 100644 --- a/website/pages/docs/builders/vmware/vsphere-clone.mdx +++ b/website/pages/docs/builders/vmware/vsphere-clone.mdx @@ -28,6 +28,7 @@ There are many configuration options available for this builder. In addition to the items listed here, you will want to look at the general configuration references for [Hardware](#hardware-configuration), [Output](#output-configuration), +[Boot](#boot-configuration), [Run](#run-configuration), [Shutdown](#shutdown-configuration), [Communicator](#communicator-configuration), @@ -45,6 +46,25 @@ necessary for this build to succeed and can be found further down the page. @include 'builder/vsphere/common/ConfigParamsConfig-not-required.mdx' +### Boot configuration + +@include 'common/bootcommand/BootConfig.mdx' + +#### Optional: + +@include 'common/bootcommand/BootConfig-not-required.mdx' + +For more examples of various boot commands, see the sample projects from our +[community templates page](/community-tools#templates). + +### Http directory configuration + +@include 'common/HTTPConfig.mdx' + +#### Optional: + +@include 'common/HTTPConfig-not-required.mdx' + ### Connection Configuration @include 'builder/vsphere/common/ConnectConfig-not-required.mdx'