Skip to content

Commit

Permalink
Add boot steps configuration option
Browse files Browse the repository at this point in the history
Adds a new configuration option called `boot_steps`. 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.
  • Loading branch information
jacob-carlborg committed Oct 28, 2022
1 parent 33e82fa commit 88d411b
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 0 deletions.
44 changes: 44 additions & 0 deletions bootcommand/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,45 @@ type BootConfig struct {
// well, and are covered in the section below on the boot command. If this
// is not specified, it is assumed the installer will start itself.
BootCommand []string `mapstructure:"boot_command"`
// 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<enter><wait5>", "Install NetBSD"],
// ["a<enter><wait5>", "Installation messages in English"],
// ["a<enter><wait5>", "Keyboard type: unchanged"],
//
// ["a<enter><wait5>", "Install NetBSD to hard disk"],
// ["b<enter><wait5>", "Yes"]
// ]
// ```
//
// In JSON:
// ```json
// {
// "boot_steps": [
// ["1<enter><wait5>", "Install NetBSD"],
// ["a<enter><wait5>", "Installation messages in English"],
// ["a<enter><wait5>", "Keyboard type: unchanged"],
//
// ["a<enter><wait5>", "Install NetBSD to hard disk"],
// ["b<enter><wait5>", "Yes"]
// ]
// }
// ```
BootSteps [][]string `mapstructure:"boot_steps" required:"false"`
}

// The boot command "typed" character for character over a VNC connection to
Expand All @@ -184,6 +223,11 @@ type VNCConfig struct {
}

func (c *BootConfig) Prepare(ctx *interpolate.Context) (errs []error) {
if len(c.BootCommand) > 0 && len(c.BootSteps) > 0 {
errs = append(errs,
fmt.Errorf("Both boot command and boot steps cannot be used."))
}

if c.BootWait == 0 {
c.BootWait = 10 * time.Second
}
Expand Down
9 changes: 9 additions & 0 deletions bootcommand/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ func TestConfigPrepare(t *testing.T) {
if len(errs) > 0 {
t.Fatalf("bad: %#v", errs)
}

// Test boot command and boot steps
c = new(BootConfig)
c.BootCommand = []string{"a", "b"}
c.BootSteps = [][]string{{"a"}, {"b"}}
errs = c.Prepare(&interpolate.Context{})
if len(errs) == 0 {
t.Fatal("should error")
}
}

func TestVNCConfigPrepare(t *testing.T) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,43 @@
well, and are covered in the section below on the boot command. If this
is not specified, it is assumed the installer will start itself.

- `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<enter><wait5>", "Install NetBSD"],
["a<enter><wait5>", "Installation messages in English"],
["a<enter><wait5>", "Keyboard type: unchanged"],

["a<enter><wait5>", "Install NetBSD to hard disk"],
["b<enter><wait5>", "Yes"]
]
```

In JSON:
```json
{
"boot_steps": [
["1<enter><wait5>", "Install NetBSD"],
["a<enter><wait5>", "Installation messages in English"],
["a<enter><wait5>", "Keyboard type: unchanged"],

["a<enter><wait5>", "Install NetBSD to hard disk"],
["b<enter><wait5>", "Yes"]
]
}
```

<!-- End of code generated from the comments of the BootConfig struct in bootcommand/config.go; -->

0 comments on commit 88d411b

Please sign in to comment.