Fix boot_command and update docs
This commit is contained in:
parent
ba767d1663
commit
65cfb880fd
|
@ -7,14 +7,24 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type KeyInput struct {
|
type KeyInput struct {
|
||||||
Message string
|
|
||||||
Scancode key.Code
|
Scancode key.Code
|
||||||
Alt bool
|
Alt bool
|
||||||
Ctrl bool
|
Ctrl bool
|
||||||
Shift bool
|
Shift bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vm *VirtualMachine) TypeOnKeyboard(spec types.UsbScanCodeSpec) (int32, error) {
|
func (vm *VirtualMachine) TypeOnKeyboard(input KeyInput) (int32, error) {
|
||||||
|
var spec types.UsbScanCodeSpec
|
||||||
|
|
||||||
|
spec.KeyEvents = append(spec.KeyEvents, types.UsbScanCodeSpecKeyEvent{
|
||||||
|
UsbHidCode: int32(input.Scancode)<<16 | 7,
|
||||||
|
Modifiers: &types.UsbScanCodeSpecModifierType{
|
||||||
|
LeftControl: &input.Ctrl,
|
||||||
|
LeftAlt: &input.Alt,
|
||||||
|
LeftShift: &input.Shift,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
req := &types.PutUsbScanCodes{
|
req := &types.PutUsbScanCodes{
|
||||||
This: vm.vm.Reference(),
|
This: vm.vm.Reference(),
|
||||||
Spec: spec,
|
Spec: spec,
|
||||||
|
|
|
@ -69,8 +69,9 @@ type FlatConfig struct {
|
||||||
FloppyDirectories []string `mapstructure:"floppy_dirs" cty:"floppy_dirs" hcl:"floppy_dirs"`
|
FloppyDirectories []string `mapstructure:"floppy_dirs" cty:"floppy_dirs" hcl:"floppy_dirs"`
|
||||||
FloppyLabel *string `mapstructure:"floppy_label" cty:"floppy_label" hcl:"floppy_label"`
|
FloppyLabel *string `mapstructure:"floppy_label" cty:"floppy_label" hcl:"floppy_label"`
|
||||||
BootOrder *string `mapstructure:"boot_order" cty:"boot_order" hcl:"boot_order"`
|
BootOrder *string `mapstructure:"boot_order" cty:"boot_order" hcl:"boot_order"`
|
||||||
BootCommand []string `mapstructure:"boot_command" cty:"boot_command" hcl:"boot_command"`
|
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"`
|
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"`
|
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"`
|
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"`
|
SettleTimeout *string `mapstructure:"ip_settle_timeout" cty:"ip_settle_timeout" hcl:"ip_settle_timeout"`
|
||||||
|
@ -196,8 +197,9 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
||||||
"floppy_dirs": &hcldec.AttrSpec{Name: "floppy_dirs", Type: cty.List(cty.String), Required: false},
|
"floppy_dirs": &hcldec.AttrSpec{Name: "floppy_dirs", Type: cty.List(cty.String), Required: false},
|
||||||
"floppy_label": &hcldec.AttrSpec{Name: "floppy_label", Type: cty.String, Required: false},
|
"floppy_label": &hcldec.AttrSpec{Name: "floppy_label", Type: cty.String, Required: false},
|
||||||
"boot_order": &hcldec.AttrSpec{Name: "boot_order", Type: cty.String, Required: false},
|
"boot_order": &hcldec.AttrSpec{Name: "boot_order", Type: cty.String, Required: false},
|
||||||
"boot_command": &hcldec.AttrSpec{Name: "boot_command", Type: cty.List(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_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},
|
"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_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_settle_timeout": &hcldec.AttrSpec{Name: "ip_settle_timeout", Type: cty.String, Required: false},
|
||||||
|
|
|
@ -8,9 +8,7 @@ import (
|
||||||
"github.com/hashicorp/packer/helper/multistep"
|
"github.com/hashicorp/packer/helper/multistep"
|
||||||
"github.com/hashicorp/packer/packer"
|
"github.com/hashicorp/packer/packer"
|
||||||
"github.com/hashicorp/packer/template/interpolate"
|
"github.com/hashicorp/packer/template/interpolate"
|
||||||
"github.com/vmware/govmomi/vim25/types"
|
|
||||||
"golang.org/x/mobile/event/key"
|
"golang.org/x/mobile/event/key"
|
||||||
"log"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -79,35 +77,26 @@ func (s *StepBootCommand) Run(ctx context.Context, state multistep.StateBag) mul
|
||||||
ui.Say(fmt.Sprintf("HTTP server is working at http://%v:%v/", ip, port))
|
ui.Say(fmt.Sprintf("HTTP server is working at http://%v:%v/", ip, port))
|
||||||
}
|
}
|
||||||
|
|
||||||
sendCodes := func(codes []key.Code, downs []bool) error {
|
sendCodes := func(code key.Code, down bool) error {
|
||||||
var spec types.UsbScanCodeSpec
|
|
||||||
|
|
||||||
for i, code := range codes {
|
|
||||||
var keyAlt, keyCtrl, keyShift bool
|
var keyAlt, keyCtrl, keyShift bool
|
||||||
|
|
||||||
switch code {
|
switch code {
|
||||||
case key.CodeLeftAlt:
|
case key.CodeLeftAlt:
|
||||||
// <leftAltOn>
|
// <leftAltOn>
|
||||||
keyAlt = downs[i]
|
keyAlt = down
|
||||||
case key.CodeLeftControl:
|
case key.CodeLeftControl:
|
||||||
// <leftCtrlOn>
|
// <leftCtrlOn>
|
||||||
keyCtrl = downs[i]
|
keyCtrl = down
|
||||||
default:
|
default:
|
||||||
keyShift = downs[i]
|
keyShift = down
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("Sending code %s, shift %v", code, downs[i])
|
_, err := vm.TypeOnKeyboard(driver.KeyInput{
|
||||||
spec.KeyEvents = append(spec.KeyEvents, types.UsbScanCodeSpecKeyEvent{
|
Scancode: code,
|
||||||
UsbHidCode: int32(code)<<16 | 7,
|
Ctrl: keyCtrl,
|
||||||
Modifiers: &types.UsbScanCodeSpecModifierType{
|
Alt: keyAlt,
|
||||||
LeftControl: &keyCtrl,
|
Shift: keyShift,
|
||||||
LeftAlt: &keyAlt,
|
|
||||||
LeftShift: &keyShift,
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
}
|
|
||||||
|
|
||||||
_, err := vm.TypeOnKeyboard(spec)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error typing a boot command: %v", err)
|
return fmt.Errorf("error typing a boot command: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,52 +0,0 @@
|
||||||
package iso
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"context"
|
|
||||||
"github.com/hashicorp/packer/builder/vsphere/driver"
|
|
||||||
"github.com/hashicorp/packer/common/bootcommand"
|
|
||||||
"github.com/hashicorp/packer/helper/multistep"
|
|
||||||
"github.com/hashicorp/packer/packer"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestStepBootCommand_Run(t *testing.T) {
|
|
||||||
state := new(multistep.BasicStateBag)
|
|
||||||
state.Put("ui", &packer.BasicUi{
|
|
||||||
Reader: new(bytes.Buffer),
|
|
||||||
Writer: new(bytes.Buffer),
|
|
||||||
})
|
|
||||||
state.Put("debug", false)
|
|
||||||
state.Put("vm", new(driver.VirtualMachine))
|
|
||||||
|
|
||||||
state.Put("http_port", 2222)
|
|
||||||
state.Put("http_ip", "0.0.0.0")
|
|
||||||
|
|
||||||
step := &StepBootCommand{
|
|
||||||
Config: &BootConfig{
|
|
||||||
BootConfig: bootcommand.BootConfig{
|
|
||||||
BootCommand: []string{
|
|
||||||
"<leftShiftOn><enter><wait><f6><wait><esc><wait>",
|
|
||||||
"<bs><bs><bs><bs><bs><bs><bs><bs><bs><bs>",
|
|
||||||
"<bs><bs><bs><bs><bs><bs><bs><bs><bs><bs>",
|
|
||||||
"<bs><bs><bs><bs><bs><bs><bs><bs><bs><bs>",
|
|
||||||
"<bs><bs><bs><bs><bs><bs><bs><bs><bs><bs>",
|
|
||||||
"<bs><bs><bs><bs><bs><bs><bs><bs><bs><bs>",
|
|
||||||
"<bs><bs><bs><bs><bs><bs><bs><bs><bs><bs>",
|
|
||||||
"<bs><bs><bs><bs><bs><bs><bs><bs><bs><bs>",
|
|
||||||
"<bs><bs><bs><bs><bs><bs><bs><bs><bs><bs>",
|
|
||||||
"<bs><bs><bs>",
|
|
||||||
"/install/vmlinuz",
|
|
||||||
" initrd=/install/initrd.gz",
|
|
||||||
" priority=critical",
|
|
||||||
" locale=en_US",
|
|
||||||
" file=/media/preseed_hardcoded_ip.cfg",
|
|
||||||
" netcfg/get_ipaddress=0.0.0.0",
|
|
||||||
" netcfg/get_gateway=0.0.0.0",
|
|
||||||
"<enter>",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
step.Run(context.TODO(), state)
|
|
||||||
}
|
|
|
@ -2,18 +2,19 @@ package bootcommand
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/hashicorp/packer/builder/vsphere/driver"
|
|
||||||
"github.com/hashicorp/packer/common"
|
|
||||||
"golang.org/x/mobile/event/key"
|
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
|
"github.com/hashicorp/packer/builder/vsphere/driver"
|
||||||
|
"github.com/hashicorp/packer/common"
|
||||||
|
"golang.org/x/mobile/event/key"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SendUsbScanCodes will be called to send codes to the VM
|
// SendUsbScanCodes will be called to send codes to the VM
|
||||||
type SendUsbScanCodes func([]key.Code, []bool) error
|
type SendUsbScanCodes func(k key.Code, down bool) error
|
||||||
|
|
||||||
type usbDriver struct {
|
type usbDriver struct {
|
||||||
vm *driver.VirtualMachine
|
vm *driver.VirtualMachine
|
||||||
|
@ -23,9 +24,6 @@ type usbDriver struct {
|
||||||
specialMap map[string]key.Code
|
specialMap map[string]key.Code
|
||||||
scancodeMap map[rune]key.Code
|
scancodeMap map[rune]key.Code
|
||||||
|
|
||||||
codeBuffer []key.Code
|
|
||||||
downBuffer []bool
|
|
||||||
|
|
||||||
// keyEvent can set this error which will prevent it from continuing
|
// keyEvent can set this error which will prevent it from continuing
|
||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
|
@ -103,25 +101,27 @@ func NewUSBDriver(send SendUsbScanCodes, interval time.Duration) *usbDriver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flush sends codes to the vm
|
func (d *usbDriver) keyEvent(k key.Code, down bool) error {
|
||||||
func (d *usbDriver) Flush() error {
|
if d.err != nil {
|
||||||
defer func() {
|
return d.err
|
||||||
d.codeBuffer = nil
|
}
|
||||||
}()
|
if err := d.sendImpl(k, down); err != nil {
|
||||||
|
d.err = err
|
||||||
if err := d.sendImpl(d.codeBuffer, d.downBuffer); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
time.Sleep(d.interval)
|
time.Sleep(d.interval)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *usbDriver) Flush() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (d *usbDriver) SendKey(k rune, action KeyAction) error {
|
func (d *usbDriver) SendKey(k rune, action KeyAction) error {
|
||||||
keyShift := unicode.IsUpper(k) || strings.ContainsRune(shiftedChars, k)
|
keyShift := unicode.IsUpper(k) || strings.ContainsRune(shiftedChars, k)
|
||||||
keyCode := d.scancodeMap[k]
|
keyCode := d.scancodeMap[k]
|
||||||
log.Printf("Sending char '%c', code %s, shift %v", k, keyCode, keyShift)
|
log.Printf("Sending char '%c', code %s, shift %v", k, keyCode, keyShift)
|
||||||
d.send(keyCode, keyShift)
|
return d.keyEvent(keyCode, keyShift)
|
||||||
return d.err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *usbDriver) SendSpecial(special string, action KeyAction) error {
|
func (d *usbDriver) SendSpecial(special string, action KeyAction) error {
|
||||||
|
@ -133,18 +133,10 @@ func (d *usbDriver) SendSpecial(special string, action KeyAction) error {
|
||||||
|
|
||||||
switch action {
|
switch action {
|
||||||
case KeyOn:
|
case KeyOn:
|
||||||
d.send(keyCode, true)
|
d.keyEvent(keyCode, true)
|
||||||
case KeyOff, KeyPress:
|
case KeyOff, KeyPress:
|
||||||
d.send(keyCode, false)
|
d.keyEvent(keyCode, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
return d.err
|
return d.err
|
||||||
}
|
}
|
||||||
|
|
||||||
// send stores the codes in an internal buffer. Use Flush to send them.
|
|
||||||
func (d *usbDriver) send(code key.Code, down bool) {
|
|
||||||
// slices to keep the input order
|
|
||||||
d.codeBuffer = append(d.codeBuffer, code)
|
|
||||||
d.downBuffer = append(d.downBuffer, down)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -154,6 +154,11 @@ necessary for this build to succeed and can be found further down the page.
|
||||||
|
|
||||||
@include 'common/bootcommand/BootConfig.mdx'
|
@include 'common/bootcommand/BootConfig.mdx'
|
||||||
|
|
||||||
|
Please note that for the Virtuabox builder, the IP address of the HTTP server
|
||||||
|
Packer launches for you to access files like the preseed file in the example
|
||||||
|
above (`{{ .HTTPIP }}`) is hardcoded to 10.0.2.2. If you change the network
|
||||||
|
of your VM you must guarantee that you can still access this HTTP server.
|
||||||
|
|
||||||
The boot command is sent to the VM through the `VBoxManage` utility in as few
|
The boot command is sent to the VM through the `VBoxManage` utility in as few
|
||||||
invocations as possible. We send each character in groups of 25, with a default
|
invocations as possible. We send each character in groups of 25, with a default
|
||||||
delay of 100ms between groups. The delay alleviates issues with latency and CPU
|
delay of 100ms between groups. The delay alleviates issues with latency and CPU
|
||||||
|
@ -176,35 +181,8 @@ contention. If you notice missing keys, you can tune this delay by specifying
|
||||||
|
|
||||||
@include 'common/bootcommand/BootConfig-not-required.mdx'
|
@include 'common/bootcommand/BootConfig-not-required.mdx'
|
||||||
|
|
||||||
@include 'builders/boot-command.mdx'
|
|
||||||
|
|
||||||
@include 'builders/virtualbox-ssh-key-pair.mdx'
|
@include 'builders/virtualbox-ssh-key-pair.mdx'
|
||||||
|
|
||||||
Example boot command. This is actually a working boot command used to start an
|
|
||||||
Ubuntu 12.04 installer:
|
|
||||||
|
|
||||||
```text
|
|
||||||
[
|
|
||||||
"<esc><esc><enter><wait>",
|
|
||||||
"/install/vmlinuz noapic ",
|
|
||||||
"preseed/url=http://{{ .HTTPIP }}:{{ .HTTPPort }}/preseed.cfg ",
|
|
||||||
"debian-installer=en_US auto locale=en_US kbd-chooser/method=us ",
|
|
||||||
"hostname={{ .Name }} ",
|
|
||||||
"fb=false debconf/frontend=noninteractive ",
|
|
||||||
"keyboard-configuration/modelcode=SKIP keyboard-configuration/layout=USA ",
|
|
||||||
"keyboard-configuration/variant=USA console-setup/ask_detect=false ",
|
|
||||||
"initrd=/install/initrd.gz -- <enter>"
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
Please note that for the Virtuabox builder, the IP address of the HTTP server
|
|
||||||
Packer launches for you to access files like the preseed file in the example
|
|
||||||
above (`{{ .HTTPIP }}`) is hardcoded to 10.0.2.2. If you change the network
|
|
||||||
of your VM you must guarantee that you can still access this HTTP server.
|
|
||||||
|
|
||||||
For more examples of various boot commands, see the sample projects from our
|
|
||||||
[community templates page](/community-tools#templates).
|
|
||||||
|
|
||||||
## Guest Additions
|
## Guest Additions
|
||||||
|
|
||||||
Packer will automatically download the proper guest additions for the version of
|
Packer will automatically download the proper guest additions for the version of
|
||||||
|
|
|
@ -145,6 +145,11 @@ necessary for this build to succeed and can be found further down the page.
|
||||||
|
|
||||||
@include 'common/bootcommand/BootConfig.mdx'
|
@include 'common/bootcommand/BootConfig.mdx'
|
||||||
|
|
||||||
|
Please note that for the Virtuabox builder, the IP address of the HTTP server
|
||||||
|
Packer launches for you to access files like the preseed file in the example
|
||||||
|
above (`{{ .HTTPIP }}`) is hardcoded to 10.0.2.2. If you change the network
|
||||||
|
of your VM you must guarantee that you can still access this HTTP server.
|
||||||
|
|
||||||
The boot command is sent to the VM through the `VBoxManage` utility in as few
|
The boot command is sent to the VM through the `VBoxManage` utility in as few
|
||||||
invocations as possible. We send each character in groups of 25, with a default
|
invocations as possible. We send each character in groups of 25, with a default
|
||||||
delay of 100ms between groups. The delay alleviates issues with latency and CPU
|
delay of 100ms between groups. The delay alleviates issues with latency and CPU
|
||||||
|
@ -167,30 +172,8 @@ contention. If you notice missing keys, you can tune this delay by specifying
|
||||||
|
|
||||||
@include 'common/bootcommand/BootConfig-not-required.mdx'
|
@include 'common/bootcommand/BootConfig-not-required.mdx'
|
||||||
|
|
||||||
@include 'builders/boot-command.mdx'
|
|
||||||
|
|
||||||
@include 'builders/virtualbox-ssh-key-pair.mdx'
|
@include 'builders/virtualbox-ssh-key-pair.mdx'
|
||||||
|
|
||||||
Example boot command. This is actually a working boot command used to start an
|
|
||||||
Ubuntu 12.04 installer:
|
|
||||||
|
|
||||||
```text
|
|
||||||
[
|
|
||||||
"<esc><esc><enter><wait>",
|
|
||||||
"/install/vmlinuz noapic ",
|
|
||||||
"preseed/url=http://{{ .HTTPIP }}:{{ .HTTPPort }}/preseed.cfg ",
|
|
||||||
"debian-installer=en_US auto locale=en_US kbd-chooser/method=us ",
|
|
||||||
"hostname={{ .Name }} ",
|
|
||||||
"fb=false debconf/frontend=noninteractive ",
|
|
||||||
"keyboard-configuration/modelcode=SKIP keyboard-configuration/layout=USA ",
|
|
||||||
"keyboard-configuration/variant=USA console-setup/ask_detect=false ",
|
|
||||||
"initrd=/install/initrd.gz -- <enter>"
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
For more examples of various boot commands, see the sample projects from our
|
|
||||||
[community templates page](/community-tools#templates).
|
|
||||||
|
|
||||||
## Guest Additions
|
## Guest Additions
|
||||||
|
|
||||||
Packer will automatically download the proper guest additions for the version of
|
Packer will automatically download the proper guest additions for the version of
|
||||||
|
|
|
@ -159,6 +159,11 @@ builder.
|
||||||
|
|
||||||
@include 'common/bootcommand/BootConfig.mdx'
|
@include 'common/bootcommand/BootConfig.mdx'
|
||||||
|
|
||||||
|
Please note that for the Virtuabox builder, the IP address of the HTTP server
|
||||||
|
Packer launches for you to access files like the preseed file in the example
|
||||||
|
above (`{{ .HTTPIP }}`) is hardcoded to 10.0.2.2. If you change the network
|
||||||
|
of your VM you must guarantee that you can still access this HTTP server.
|
||||||
|
|
||||||
The boot command is sent to the VM through the `VBoxManage` utility in as few
|
The boot command is sent to the VM through the `VBoxManage` utility in as few
|
||||||
invocations as possible. We send each character in groups of 25, with a default
|
invocations as possible. We send each character in groups of 25, with a default
|
||||||
delay of 100ms between groups. The delay alleviates issues with latency and CPU
|
delay of 100ms between groups. The delay alleviates issues with latency and CPU
|
||||||
|
@ -181,34 +186,8 @@ contention. If you notice missing keys, you can tune this delay by specifying
|
||||||
|
|
||||||
@include 'common/bootcommand/BootConfig-not-required.mdx'
|
@include 'common/bootcommand/BootConfig-not-required.mdx'
|
||||||
|
|
||||||
@include 'builders/boot-command.mdx'
|
|
||||||
|
|
||||||
@include 'builders/virtualbox-ssh-key-pair.mdx'
|
@include 'builders/virtualbox-ssh-key-pair.mdx'
|
||||||
|
|
||||||
Example boot command. This is actually a working boot command used to start an
|
|
||||||
Ubuntu 12.04 installer:
|
|
||||||
|
|
||||||
```text
|
|
||||||
[
|
|
||||||
"<esc><esc><enter><wait>",
|
|
||||||
"/install/vmlinuz noapic ",
|
|
||||||
"preseed/url=http://{{ .HTTPIP }}:{{ .HTTPPort }}/preseed.cfg ",
|
|
||||||
"debian-installer=en_US auto locale=en_US kbd-chooser/method=us ",
|
|
||||||
"hostname={{ .Name }} ",
|
|
||||||
"fb=false debconf/frontend=noninteractive ",
|
|
||||||
"keyboard-configuration/modelcode=SKIP keyboard-configuration/layout=USA ",
|
|
||||||
"keyboard-configuration/variant=USA console-setup/ask_detect=false ",
|
|
||||||
"initrd=/install/initrd.gz -- <enter>"
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
Please note that for the Virtuabox builder, the IP address of the HTTP server
|
|
||||||
Packer launches for you to access files like the preseed file in the example
|
|
||||||
above (`{{ .HTTPIP }}`) is hardcoded to 10.0.2.2. If you change the network
|
|
||||||
of your VM you must guarantee that you can still access this HTTP server.
|
|
||||||
|
|
||||||
For more examples of various boot commands, see the sample projects from our
|
|
||||||
[community templates page](/community-tools#templates).
|
|
||||||
|
|
||||||
## Guest Additions
|
## Guest Additions
|
||||||
|
|
||||||
|
|
|
@ -162,6 +162,31 @@ from the datastore. Example:
|
||||||
|
|
||||||
@include 'helper/communicator/WinRM-not-required.mdx'
|
@include 'helper/communicator/WinRM-not-required.mdx'
|
||||||
|
|
||||||
|
## Boot Configuration
|
||||||
|
|
||||||
|
@include 'common/bootcommand/BootConfig.mdx'
|
||||||
|
|
||||||
|
We send each character to the VM with a default delay of 100ms between groups.
|
||||||
|
The delay alleviates possible issues with latency and CPU
|
||||||
|
contention. If you notice missing keys, you can tune this delay by specifying
|
||||||
|
"boot_keygroup_interval" in your Packer template, for example:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"builders": [
|
||||||
|
{
|
||||||
|
"type": "vsphere-iso",
|
||||||
|
"boot_keygroup_interval": "500ms"
|
||||||
|
...
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Optional:
|
||||||
|
|
||||||
|
@include 'common/bootcommand/BootConfig-not-required.mdx'
|
||||||
|
|
||||||
## Working with Clusters
|
## Working with Clusters
|
||||||
|
|
||||||
#### Standalone Hosts
|
#### Standalone Hosts
|
||||||
|
|
Loading…
Reference in New Issue