From 322ce4978d6410aca30e48b1255a5ddd4733e868 Mon Sep 17 00:00:00 2001 From: Jacob Carlborg Date: Mon, 7 Nov 2022 20:38:15 +0100 Subject: [PATCH] fixup! Add boot steps configuration option --- builder/qemu/config.go | 39 +++++++++++++++++++ builder/qemu/config.hcl2spec.go | 4 +- builder/qemu/step_type_boot_command.go | 7 ++++ .../builder/qemu/Config-not-required.mdx | 39 +++++++++++++++++++ 4 files changed, 87 insertions(+), 2 deletions(-) diff --git a/builder/qemu/config.go b/builder/qemu/config.go index b716123..b7fa26b 100644 --- a/builder/qemu/config.go +++ b/builder/qemu/config.go @@ -520,6 +520,45 @@ type Config struct { // * ARM: tpm-tis-device // * PPC (p-series): tpm-spapr TPMType string `mapstructure:"tpm_device_type" required:"false"` + // This is an array of tuples of boot commands, to type when the virtual + // machine is booted. The first element of the tuple is the actual boot + // command. The second element of the tuple, which is optional, is a + // description of what the boot command does. This is intended to be used for + // interactive installers that requires many commands to complete the + // installation. Both the command and the description will be printed when + // logging is enabled. When debug mode is enabled Packer will pause after + // typing each boot command. This will make it easier to follow along the + // installation process and make sure the Packer and the installer are in + // sync. `boot_steps` and `boot_commands` are mutually exclusive. + // + // Example: + // + // In HCL: + // ```hcl + // boot_steps = [ + // ["1", "Install NetBSD"], + // ["a", "Installation messages in English"], + // ["a", "Keyboard type: unchanged"], + // + // ["a", "Install NetBSD to hard disk"], + // ["b", "Yes"] + // ] + // ``` + // + // In JSON: + // ```json + // { + // "boot_steps": [ + // ["1", "Install NetBSD"], + // ["a", "Installation messages in English"], + // ["a", "Keyboard type: unchanged"], + // + // ["a", "Install NetBSD to hard disk"], + // ["b", "Yes"] + // ] + // } + // ``` + BootSteps [][]string `mapstructure:"boot_steps" required:"false"` // TODO(mitchellh): deprecate RunOnce bool `mapstructure:"run_once"` diff --git a/builder/qemu/config.hcl2spec.go b/builder/qemu/config.hcl2spec.go index 9e630e3..5135595 100644 --- a/builder/qemu/config.hcl2spec.go +++ b/builder/qemu/config.hcl2spec.go @@ -32,7 +32,6 @@ type FlatConfig struct { 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"` - BootSteps [][]string `mapstructure:"boot_steps" required:"false" cty:"boot_steps" hcl:"boot_steps"` DisableVNC *bool `mapstructure:"disable_vnc" cty:"disable_vnc" hcl:"disable_vnc"` BootKeyInterval *string `mapstructure:"boot_key_interval" cty:"boot_key_interval" hcl:"boot_key_interval"` ShutdownCommand *string `mapstructure:"shutdown_command" required:"false" cty:"shutdown_command" hcl:"shutdown_command"` @@ -140,6 +139,7 @@ type FlatConfig struct { VTPM *bool `mapstructure:"vtpm" required:"false" cty:"vtpm" hcl:"vtpm"` VTPMUseTPM1 *bool `mapstructure:"use_tpm1" required:"false" cty:"use_tpm1" hcl:"use_tpm1"` TPMType *string `mapstructure:"tpm_device_type" required:"false" cty:"tpm_device_type" hcl:"tpm_device_type"` + BootSteps [][]string `mapstructure:"boot_steps" required:"false" cty:"boot_steps" hcl:"boot_steps"` RunOnce *bool `mapstructure:"run_once" cty:"run_once" hcl:"run_once"` } @@ -177,7 +177,6 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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}, - "boot_steps": &hcldec.AttrSpec{Name: "boot_steps", Type: cty.List(cty.List(cty.String)), Required: false}, "disable_vnc": &hcldec.AttrSpec{Name: "disable_vnc", Type: cty.Bool, Required: false}, "boot_key_interval": &hcldec.AttrSpec{Name: "boot_key_interval", Type: cty.String, Required: false}, "shutdown_command": &hcldec.AttrSpec{Name: "shutdown_command", Type: cty.String, Required: false}, @@ -285,6 +284,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "vtpm": &hcldec.AttrSpec{Name: "vtpm", Type: cty.Bool, Required: false}, "use_tpm1": &hcldec.AttrSpec{Name: "use_tpm1", Type: cty.Bool, Required: false}, "tpm_device_type": &hcldec.AttrSpec{Name: "tpm_device_type", Type: cty.String, Required: false}, + "boot_steps": &hcldec.AttrSpec{Name: "boot_steps", Type: cty.List(cty.List(cty.String)), Required: false}, "run_once": &hcldec.AttrSpec{Name: "run_once", Type: cty.Bool, Required: false}, } return s diff --git a/builder/qemu/step_type_boot_command.go b/builder/qemu/step_type_boot_command.go index 510a5b6..e459f4d 100644 --- a/builder/qemu/step_type_boot_command.go +++ b/builder/qemu/step_type_boot_command.go @@ -35,10 +35,17 @@ type bootCommandTemplateData struct { type stepTypeBootCommand struct{} func (s *stepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { + ui := state.Get("ui").(packersdk.Ui) config := state.Get("config").(*Config) command := config.VNCConfig.FlatBootCommand() bootSteps := config.BootSteps + if len(command) > 0 && len(bootSteps) > 0 { + err := fmt.Errorf("Both boot command and boot steps cannot be used.") + ui.Error(err.Error()) + return multistep.ActionHalt + } + if len(command) > 0 { bootSteps = [][]string{{command}} } diff --git a/docs-partials/builder/qemu/Config-not-required.mdx b/docs-partials/builder/qemu/Config-not-required.mdx index ef5797d..57207f4 100644 --- a/docs-partials/builder/qemu/Config-not-required.mdx +++ b/docs-partials/builder/qemu/Config-not-required.mdx @@ -350,4 +350,43 @@ * ARM: tpm-tis-device * PPC (p-series): tpm-spapr +- `boot_steps` ([][]string) - This is an array of tuples of boot commands, to type when the virtual + machine is booted. The first element of the tuple is the actual boot + command. The second element of the tuple, which is optional, is a + description of what the boot command does. This is intended to be used for + interactive installers that requires many commands to complete the + installation. Both the command and the description will be printed when + logging is enabled. When debug mode is enabled Packer will pause after + typing each boot command. This will make it easier to follow along the + installation process and make sure the Packer and the installer are in + sync. `boot_steps` and `boot_commands` are mutually exclusive. + + Example: + + In HCL: + ```hcl + boot_steps = [ + ["1", "Install NetBSD"], + ["a", "Installation messages in English"], + ["a", "Keyboard type: unchanged"], + + ["a", "Install NetBSD to hard disk"], + ["b", "Yes"] + ] + ``` + + In JSON: + ```json + { + "boot_steps": [ + ["1", "Install NetBSD"], + ["a", "Installation messages in English"], + ["a", "Keyboard type: unchanged"], + + ["a", "Install NetBSD to hard disk"], + ["b", "Yes"] + ] + } + ``` +