added new template variables to replace PACKER_KEY_INTERVAL with tunable key and keygroup intervals depending on driver used

This commit is contained in:
Megan Marsh 2018-08-22 11:25:43 -07:00
parent 41898ec7ba
commit 918db58604
23 changed files with 153 additions and 47 deletions

View File

@ -21,10 +21,11 @@ type bootCommandTemplateData struct {
// This step "types" the boot command into the VM via the Hyper-V virtual keyboard
type StepTypeBootCommand struct {
BootCommand string
BootWait time.Duration
SwitchName string
Ctx interpolate.Context
BootCommand string
BootWait time.Duration
SwitchName string
Ctx interpolate.Context
GroupInterval int
}
func (s *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
@ -66,7 +67,7 @@ func (s *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag)
scanCodesToSendString := strings.Join(codes, " ")
return driver.TypeScanCodes(vmName, scanCodesToSendString)
}
d := bootcommand.NewPCXTDriver(sendCodes, -1)
d := bootcommand.NewPCXTDriver(sendCodes, -1, s.GroupInterval)
ui.Say("Typing the boot command...")
command, err := interpolate.Render(s.BootCommand, &s.Ctx)

View File

@ -434,10 +434,11 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
},
&hypervcommon.StepTypeBootCommand{
BootCommand: b.config.FlatBootCommand(),
BootWait: b.config.BootWait,
SwitchName: b.config.SwitchName,
Ctx: b.config.ctx,
BootCommand: b.config.FlatBootCommand(),
BootWait: b.config.BootWait,
SwitchName: b.config.SwitchName,
Ctx: b.config.ctx,
GroupInterval: b.config.BootConfig.BootGroupInterval,
},
// configure the communicator ssh, winrm

View File

@ -443,10 +443,11 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
},
&hypervcommon.StepTypeBootCommand{
BootCommand: b.config.FlatBootCommand(),
BootWait: b.config.BootWait,
SwitchName: b.config.SwitchName,
Ctx: b.config.ctx,
BootCommand: b.config.FlatBootCommand(),
BootWait: b.config.BootWait,
SwitchName: b.config.SwitchName,
Ctx: b.config.ctx,
GroupInterval: b.config.BootConfig.BootGroupInterval,
},
// configure the communicator ssh, winrm

View File

@ -26,6 +26,7 @@ type StepTypeBootCommand struct {
HostInterfaces []string
VMName string
Ctx interpolate.Context
GroupInterval int
}
// Run types the boot command by sending key scancodes into the VM.
@ -79,7 +80,7 @@ func (s *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag)
sendCodes := func(codes []string) error {
return driver.SendKeyScanCodes(s.VMName, codes...)
}
d := bootcommand.NewPCXTDriver(sendCodes, -1)
d := bootcommand.NewPCXTDriver(sendCodes, -1, s.GroupInterval)
ui.Say("Typing the boot command...")
command, err := interpolate.Render(s.BootCommand, &s.Ctx)

View File

@ -192,6 +192,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
HostInterfaces: b.config.HostInterfaces,
VMName: b.config.VMName,
Ctx: b.config.ctx,
GroupInterval: b.config.BootConfig.BootGroupInterval,
},
&communicator.StepConnect{
Config: &b.config.SSHConfig.Comm,

View File

@ -81,6 +81,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
HostInterfaces: []string{},
VMName: b.config.VMName,
Ctx: b.config.ctx,
GroupInterval: b.config.BootConfig.BootGroupInterval,
},
&communicator.StepConnect{
Config: &b.config.SSHConfig.Comm,

View File

@ -95,7 +95,7 @@ func (s *stepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag)
config.VMName,
}
d := bootcommand.NewVNCDriver(c)
d := bootcommand.NewVNCDriver(c, config.VNCConfig.BootKeyInterval)
ui.Say("Typing the boot command over VNC...")
command, err := interpolate.Render(config.VNCConfig.FlatBootCommand(), &configCtx)

View File

@ -21,10 +21,11 @@ type bootCommandTemplateData struct {
}
type StepTypeBootCommand struct {
BootCommand string
BootWait time.Duration
VMName string
Ctx interpolate.Context
BootCommand string
BootWait time.Duration
VMName string
Ctx interpolate.Context
GroupInterval int
}
func (s *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
@ -64,7 +65,7 @@ func (s *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag)
return driver.VBoxManage(args...)
}
d := bootcommand.NewPCXTDriver(sendCodes, 25)
d := bootcommand.NewPCXTDriver(sendCodes, 25, s.GroupInterval)
ui.Say("Typing the boot command...")
command, err := interpolate.Render(s.BootCommand, &s.Ctx)

View File

@ -53,6 +53,7 @@ type Config struct {
KeepRegistered bool `mapstructure:"keep_registered"`
SkipExport bool `mapstructure:"skip_export"`
VMName string `mapstructure:"vm_name"`
KeyInterval int `mapstructure:"key_interval"`
ctx interpolate.Context
}
@ -121,6 +122,10 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
b.config.ISOInterface = "ide"
}
if b.config.KeyInterval == 0 {
b.config.KeyInterval = -1
}
if b.config.VMName == "" {
b.config.VMName = fmt.Sprintf(
"packer-%s-%d", b.config.PackerBuildName, interpolate.InitTime.Unix())
@ -245,10 +250,11 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
Headless: b.config.Headless,
},
&vboxcommon.StepTypeBootCommand{
BootWait: b.config.BootWait,
BootCommand: b.config.FlatBootCommand(),
VMName: b.config.VMName,
Ctx: b.config.ctx,
BootWait: b.config.BootWait,
BootCommand: b.config.FlatBootCommand(),
VMName: b.config.VMName,
Ctx: b.config.ctx,
GroupInterval: b.config.BootConfig.BootGroupInterval,
},
&communicator.StepConnect{
Config: &b.config.SSHConfig.Comm,

View File

@ -106,10 +106,11 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
Headless: b.config.Headless,
},
&vboxcommon.StepTypeBootCommand{
BootWait: b.config.BootWait,
BootCommand: b.config.FlatBootCommand(),
VMName: b.config.VMName,
Ctx: b.config.ctx,
BootWait: b.config.BootWait,
BootCommand: b.config.FlatBootCommand(),
VMName: b.config.VMName,
Ctx: b.config.ctx,
GroupInterval: b.config.BootConfig.BootGroupInterval,
},
&communicator.StepConnect{
Config: &b.config.SSHConfig.Comm,

View File

@ -30,6 +30,7 @@ type StepTypeBootCommand struct {
BootWait time.Duration
VMName string
Ctx interpolate.Context
KeyInterval int
}
type bootCommandTemplateData struct {
HTTPIP string
@ -115,7 +116,7 @@ func (s *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag)
s.VMName,
}
d := bootcommand.NewVNCDriver(c)
d := bootcommand.NewVNCDriver(c, s.KeyInterval)
ui.Say("Typing the boot command over VNC...")
command, err := interpolate.Render(s.BootCommand, &s.Ctx)

View File

@ -339,6 +339,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
BootCommand: b.config.FlatBootCommand(),
VMName: b.config.VMName,
Ctx: b.config.ctx,
KeyInterval: b.config.VNCConfig.BootKeyInterval,
},
&communicator.StepConnect{
Config: &b.config.SSHConfig.Comm,

View File

@ -97,6 +97,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
BootCommand: b.config.FlatBootCommand(),
VMName: b.config.VMName,
Ctx: b.config.ctx,
KeyInterval: b.config.VNCConfig.BootKeyInterval,
},
&communicator.StepConnect{
Config: &b.config.SSHConfig.Comm,

View File

@ -11,6 +11,8 @@ import (
type BootConfig struct {
RawBootWait string `mapstructure:"boot_wait"`
BootCommand []string `mapstructure:"boot_command"`
// time in ms to wait between each group of 25 key presses
BootGroupInterval int `mapstructure:"boot_keygroup_interval"`
BootWait time.Duration ``
}
@ -18,12 +20,17 @@ type BootConfig struct {
type VNCConfig struct {
BootConfig `mapstructure:",squash"`
DisableVNC bool `mapstructure:"disable_vnc"`
// time in ms to wait between each key press
BootKeyInterval int `mapstructure:"boot_key_interval"`
}
func (c *BootConfig) Prepare(ctx *interpolate.Context) (errs []error) {
if c.RawBootWait == "" {
c.RawBootWait = "10s"
}
if c.BootGroupInterval == 0 {
c.BootGroupInterval = -1
}
if c.RawBootWait != "" {
bw, err := time.ParseDuration(c.RawBootWait)
if err != nil {
@ -55,6 +62,9 @@ func (c *VNCConfig) Prepare(ctx *interpolate.Context) (errs []error) {
errs = append(errs,
fmt.Errorf("A boot command cannot be used when vnc is disabled."))
}
if c.BootKeyInterval == 0 {
c.BootKeyInterval = -1
}
errs = append(errs, c.BootConfig.Prepare(ctx)...)
return
}

View File

@ -38,13 +38,17 @@ func (sc *scancode) makeBreak() []string {
// NewPCXTDriver creates a new boot command driver for VMs that expect PC-XT
// keyboard codes. `send` should send its argument to the VM. `chunkSize` should
// be the maximum number of keyboard codes to send to `send` at one time.
func NewPCXTDriver(send SendCodeFunc, chunkSize int) *pcXTDriver {
func NewPCXTDriver(send SendCodeFunc, chunkSize int, interval int) *pcXTDriver {
// We delay (default 100ms) between each input event to allow for CPU or
// network latency. See PackerKeyEnv for tuning.
keyInterval := common.PackerKeyDefault
if delay, err := time.ParseDuration(os.Getenv(common.PackerKeyEnv)); err == nil {
keyInterval = delay
}
// Override interval based on builder-specific override
if interval >= 0 {
keyInterval = time.Duration(interval) * time.Millisecond
}
// Scancodes reference: https://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html
// https://www.win.tue.nl/~aeb/linux/kbd/scancodes-10.html
//

View File

@ -79,7 +79,7 @@ func Test_pcxtSpecialOnOff(t *testing.T) {
codes = c
return nil
}
d := NewPCXTDriver(sendCodes, -1)
d := NewPCXTDriver(sendCodes, -1, -1)
seq, err := GenerateExpressionSequence(in)
assert.NoError(t, err)
err = seq.Do(context.Background(), d)
@ -95,7 +95,7 @@ func Test_pcxtSpecial(t *testing.T) {
codes = c
return nil
}
d := NewPCXTDriver(sendCodes, -1)
d := NewPCXTDriver(sendCodes, -1, -1)
seq, err := GenerateExpressionSequence(in)
assert.NoError(t, err)
err = seq.Do(context.Background(), d)
@ -114,7 +114,7 @@ func Test_flushes(t *testing.T) {
actual = append(actual, c)
return nil
}
d := NewPCXTDriver(sendCodes, -1)
d := NewPCXTDriver(sendCodes, -1, -1)
seq, err := GenerateExpressionSequence(in)
assert.NoError(t, err)
err = seq.Do(context.Background(), d)

View File

@ -25,13 +25,17 @@ type vncDriver struct {
err error
}
func NewVNCDriver(c VNCKeyEvent) *vncDriver {
func NewVNCDriver(c VNCKeyEvent, interval int) *vncDriver {
// We delay (default 100ms) between each key event to allow for CPU or
// network latency. See PackerKeyEnv for tuning.
keyInterval := common.PackerKeyDefault
if delay, err := time.ParseDuration(os.Getenv(common.PackerKeyEnv)); err == nil {
keyInterval = delay
}
// override interval based on builder-specific override.
if interval >= 0 {
keyInterval = time.Duration(interval) * time.Millisecond
}
// Scancodes reference: https://github.com/qemu/qemu/blob/master/ui/vnc_keysym.h
sMap := make(map[string]uint32)

View File

@ -30,7 +30,7 @@ func Test_vncSpecialLookup(t *testing.T) {
{0xFFE2, true},
}
s := &sender{}
d := NewVNCDriver(s)
d := NewVNCDriver(s, -1)
seq, err := GenerateExpressionSequence(in)
assert.NoError(t, err)
err = seq.Do(context.Background(), d)

View File

@ -121,7 +121,7 @@ Linux server and have not enabled X11 forwarding (`ssh -X`).
upstream issue which can be tracked
[here](https://github.com/intel/haxm/issues/20).
-> The `hvf` accelerator is new and experimental as of
-> The `hvf` accelerator is new and experimental as of
[QEMU 2.12.0](https://wiki.qemu.org/ChangeLog/2.12#Host_support).
You may encounter issues unrelated to Packer when using it. You may need to
add [ "-global", "virtio-pci.disable-modern=on" ] to `qemuargs` depending on the
@ -386,8 +386,22 @@ machine, simulating a human actually typing the keyboard.
-> Keystrokes are typed as separate key up/down events over VNC with a
default 100ms delay. The delay alleviates issues with latency and CPU
contention. For local builds you can tune this delay by specifying
e.g. `PACKER_KEY_INTERVAL=10ms` to speed through the boot command.
contention. You can tune this delay on a per-builder basis by specifying
"boot_key_interval" in your Packer template, for example:
```
{
"builders": [
{
"type": "qemu",
"boot_key_interval": "10"
...
}
]
}
```
Note that this option will always be measured in milliseconds.
<%= partial "partials/builders/boot-command" %>

View File

@ -337,8 +337,22 @@ template.
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
delay of 100ms between groups. The delay alleviates issues with latency and CPU
contention. If you notice missing keys, you can tune this delay by specifying e.g.
`PACKER_KEY_INTERVAL=500ms` to wait longer between each group of characters.
contention. If you notice missing keys, you can tune this delay by specifying
"boot_keygroup_interval" in your Packer template, for example:
```
{
"builders": [
{
"type": "virtualbox",
"boot_keygroup_interval": "500"
...
}
]
}
```
Note that this option will always be measured in milliseconds.
<%= partial "partials/builders/boot-command" %>

View File

@ -300,8 +300,23 @@ template.
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
delay of 100ms between groups. The delay alleviates issues with latency and CPU
contention. If you notice missing keys, you can tune this delay by specifying e.g.
`PACKER_KEY_INTERVAL=500ms` to wait longer between each group of characters.
contention. If you notice missing keys, you can tune this delay by specifying
"boot_keygroup_interval" in your Packer template, for example:
```
{
"builders": [
{
"type": "virtualbox",
"boot_keygroup_interval": "500"
...
}
]
}
```
Note that this option will always be measured in milliseconds.
<%= partial "partials/builders/boot-command" %>

View File

@ -412,7 +412,7 @@ builder.
wish to bind to all interfaces use `0.0.0.0`.
- `vnc_disable_password` (boolean) - Don't auto-generate a VNC password that
is used to secure the VNC communication with the VM. This must be set to
is used to secure the VNC communication with the VM. This must be set to
`true` if building on ESXi 6.5 and 6.7 with VNC enabled. Defaults to
`false`.
@ -439,8 +439,22 @@ machine, simulating a human actually typing the keyboard.
-&gt; Keystrokes are typed as separate key up/down events over VNC with a
default 100ms delay. The delay alleviates issues with latency and CPU
contention. For local builds you can tune this delay by specifying
e.g. `PACKER_KEY_INTERVAL=10ms` to speed through the boot command.
contention. You can tune this delay on a per-builder basis by specifying
"boot_key_interval" in your Packer template, for example:
```
{
"builders": [
{
"type": "vmware-iso",
"boot_key_interval": "10"
...
}
]
}
```
Note that this option will always be measured in milliseconds.
<%= partial "partials/builders/boot-command" %>

View File

@ -215,8 +215,22 @@ machine, simulating a human actually typing the keyboard.
-&gt; Keystrokes are typed as separate key up/down events over VNC with a
default 100ms delay. The delay alleviates issues with latency and CPU
contention. For local builds you can tune this delay by specifying
e.g. `PACKER_KEY_INTERVAL=10ms` to speed through the boot command.
contention. You can tune this delay on a per-builder basis by specifying
"boot_key_interval" in your Packer template, for example:
```
{
"builders": [
{
"type": "vmware-vmx",
"boot_key_interval": "10"
...
}
]
}
```
Note that this option will always be measured in milliseconds.
<%= partial "partials/builders/boot-command" %>