Remove usb_keyboard option (#9945)

This commit is contained in:
Sylvia Moss 2020-09-17 10:38:33 +02:00 committed by GitHub
parent b4be598148
commit 9737b85bbc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 81 additions and 441 deletions

View File

@ -1,43 +0,0 @@
//go:generate struct-markdown
package common
import (
"fmt"
"github.com/hashicorp/packer/common/bootcommand"
"github.com/hashicorp/packer/template/interpolate"
)
type BootConfigWrapper struct {
bootcommand.VNCConfig `mapstructure:",squash"`
// If set to true, Packer will use USB HID Keyboard scan codes to send the boot command to the VM and
// the [disable_vnc](#disable_vnc) option will be ignored and automatically set to true.
// This option is not supported by hosts running a free VMware license. As alternative please use [vnc_over_websocket](#vnc_over_websocket) instead.
//
// ~> **Note:** The ESXi 6.7+ removes support to VNC. In this case, the `usb_keyboard` or [vnc_over_websocket](#vnc_over_websocket)
// should be set to true in order to send boot command keystrokes to the VM. If both are set, `usb_keyboard` will be ignored
// and set to false.
USBKeyBoard bool `mapstructure:"usb_keyboard"`
}
func (c *BootConfigWrapper) Prepare(ctx *interpolate.Context, driverConfig *DriverConfig) (warnings []string, errs []error) {
if c.USBKeyBoard {
if driverConfig.RemoteType == "" {
warnings = append(warnings, "[WARN] `usb_keyboard` can only be used with remote VMWare builds. "+
"The `usb_keyboard` option will be ignored and automatically set to false.")
c.USBKeyBoard = false
} else if !c.DisableVNC {
warnings = append(warnings, "[WARN] `usb_keyboard` is set to true then the remote VMWare builds "+
"will not use VNC to connect to the host. The `disable_vnc` option will be ignored and automatically set to true.")
c.DisableVNC = true
return
}
}
if len(c.BootCommand) > 0 && c.DisableVNC {
errs = append(errs,
fmt.Errorf("A boot command cannot be used when vnc is disabled."))
}
errs = append(errs, c.BootConfig.Prepare(ctx)...)
return
}

View File

@ -1,106 +0,0 @@
package common
import (
"fmt"
"reflect"
"testing"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/hashicorp/packer/common/bootcommand"
"github.com/hashicorp/packer/template/interpolate"
)
func TestVNCConfigWrapper_Prepare(t *testing.T) {
tc := []struct {
name string
config *BootConfigWrapper
expectedConfig *BootConfigWrapper
driver *DriverConfig
errs []error
warnings []string
}{
{
name: "VNC and boot command for local build",
config: &BootConfigWrapper{
VNCConfig: bootcommand.VNCConfig{
BootConfig: bootcommand.BootConfig{
BootCommand: []string{"<boot><command>"},
},
DisableVNC: true,
},
USBKeyBoard: false,
},
expectedConfig: nil,
driver: new(DriverConfig),
errs: []error{fmt.Errorf("A boot command cannot be used when vnc is disabled.")},
warnings: nil,
},
{
name: "Disable VNC warning for remote build",
config: &BootConfigWrapper{
VNCConfig: bootcommand.VNCConfig{
BootConfig: bootcommand.BootConfig{
BootCommand: []string{"<boot><command>"},
},
DisableVNC: false,
},
USBKeyBoard: true,
},
expectedConfig: &BootConfigWrapper{
VNCConfig: bootcommand.VNCConfig{
DisableVNC: true,
},
USBKeyBoard: true,
},
driver: &DriverConfig{
RemoteType: "esxi",
},
errs: nil,
warnings: []string{"[WARN] `usb_keyboard` is set to true then the remote VMWare builds " +
"will not use VNC to connect to the host. The `disable_vnc` option will be ignored and automatically set to true."},
},
{
name: "Disable USBKeyBoard warning for local build",
config: &BootConfigWrapper{
VNCConfig: bootcommand.VNCConfig{
BootConfig: bootcommand.BootConfig{
BootCommand: []string{"<boot><command>"},
},
DisableVNC: false,
},
USBKeyBoard: true,
},
expectedConfig: &BootConfigWrapper{
VNCConfig: bootcommand.VNCConfig{
DisableVNC: false,
},
USBKeyBoard: false,
},
driver: &DriverConfig{},
errs: nil,
warnings: []string{"[WARN] `usb_keyboard` can only be used with remote VMWare builds. " +
"The `usb_keyboard` option will be ignored and automatically set to false."},
},
}
for _, c := range tc {
t.Run(c.name, func(t *testing.T) {
warnings, errs := c.config.Prepare(interpolate.NewContext(), c.driver)
if !reflect.DeepEqual(errs, c.errs) {
t.Fatalf("bad: \n expected '%v' \nactual '%v'", c.errs, errs)
}
if diff := cmp.Diff(warnings, c.warnings); diff != "" {
t.Fatalf("unexpected warnings: %s", diff)
}
if len(c.errs) == 0 {
if diff := cmp.Diff(c.config, c.expectedConfig,
cmpopts.IgnoreFields(bootcommand.VNCConfig{},
"BootConfig",
)); diff != "" {
t.Fatalf("unexpected config: %s", diff)
}
}
})
}
}

View File

@ -101,37 +101,17 @@ func NewDriver(dconfig *DriverConfig, config *SSHConfig, vmName string) (Driver,
switch runtime.GOOS {
case "darwin":
drivers = []Driver{
&Fusion6Driver{
Fusion5Driver: Fusion5Driver{
AppPath: dconfig.FusionAppPath,
SSHConfig: config,
},
},
&Fusion5Driver{
AppPath: dconfig.FusionAppPath,
SSHConfig: config,
},
NewFusion6Driver(dconfig, config),
NewFusion5Driver(dconfig, config),
}
case "linux":
fallthrough
case "windows":
drivers = []Driver{
&Workstation10Driver{
Workstation9Driver: Workstation9Driver{
SSHConfig: config,
},
},
&Workstation9Driver{
SSHConfig: config,
},
&Player6Driver{
Player5Driver: Player5Driver{
SSHConfig: config,
},
},
&Player5Driver{
SSHConfig: config,
},
NewWorkstation10Driver(config),
NewWorkstation9Driver(config),
NewPlayer6Driver(config),
NewPlayer5Driver(config),
}
default:
return nil, fmt.Errorf("can't find driver for OS: %s", runtime.GOOS)

View File

@ -20,21 +20,20 @@ import (
"strings"
"time"
"github.com/vmware/govmomi"
"github.com/vmware/govmomi/find"
"github.com/vmware/govmomi/session"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
"github.com/hashicorp/go-getter/v2"
"github.com/hashicorp/packer/communicator/ssh"
"github.com/hashicorp/packer/helper/communicator"
"github.com/hashicorp/packer/helper/multistep"
helperssh "github.com/hashicorp/packer/helper/ssh"
"github.com/hashicorp/packer/packer"
"github.com/vmware/govmomi"
"github.com/vmware/govmomi/find"
"github.com/vmware/govmomi/session"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
gossh "golang.org/x/crypto/ssh"
"golang.org/x/mobile/event/key"
)
// ESX5 driver talks to an ESXi5 hypervisor remotely over SSH to build
@ -951,41 +950,6 @@ func (r *esxcliReader) find(key, val string) (map[string]string, error) {
}
}
type KeyInput struct {
Scancode key.Code
Alt bool
Ctrl bool
Shift bool
}
func (d *ESX5Driver) TypeOnKeyboard(input KeyInput) (int32, error) {
vm, err := d.finder.VirtualMachine(d.ctx, d.VMName)
if err != nil {
return 0, err
}
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{
This: vm.Reference(),
Spec: spec,
}
resp, err := methods.PutUsbScanCodes(d.ctx, d.client.RoundTripper, req)
if err != nil {
return 0, err
}
return resp.Returnval, nil
}
func (d *ESX5Driver) AcquireVNCOverWebsocketTicket() (*types.VirtualMachineTicket, error) {
vm, err := d.finder.VirtualMachine(d.ctx, d.VMName)
if err != nil {

View File

@ -24,6 +24,13 @@ type Fusion5Driver struct {
SSHConfig *SSHConfig
}
func NewFusion5Driver(dconfig *DriverConfig, config *SSHConfig) Driver {
return &Fusion5Driver{
AppPath: dconfig.FusionAppPath,
SSHConfig: config,
}
}
func (d *Fusion5Driver) Clone(dst, src string, linked bool) error {
return errors.New("Cloning is not supported with Fusion 5. Please use Fusion 6+.")
}

View File

@ -18,6 +18,15 @@ type Fusion6Driver struct {
Fusion5Driver
}
func NewFusion6Driver(dconfig *DriverConfig, config *SSHConfig) Driver {
return &Fusion6Driver{
Fusion5Driver: Fusion5Driver{
AppPath: dconfig.FusionAppPath,
SSHConfig: config,
},
}
}
func (d *Fusion6Driver) Clone(dst, src string, linked bool) error {
var cloneType string

View File

@ -25,6 +25,12 @@ type Player5Driver struct {
SSHConfig *SSHConfig
}
func NewPlayer5Driver(config *SSHConfig) Driver {
return &Player5Driver{
SSHConfig: config,
}
}
func (d *Player5Driver) Clone(dst, src string, linked bool) error {
return errors.New("Cloning is not supported with VMWare Player version 5. Please use VMWare Player version 6, or greater.")
}

View File

@ -13,6 +13,14 @@ type Player6Driver struct {
Player5Driver
}
func NewPlayer6Driver(config *SSHConfig) Driver {
return &Player6Driver{
Player5Driver: Player5Driver{
SSHConfig: config,
},
}
}
func (d *Player6Driver) Clone(dst, src string, linked bool) error {
// TODO(rasa) check if running player+, not just player

View File

@ -13,6 +13,14 @@ type Workstation10Driver struct {
Workstation9Driver
}
func NewWorkstation10Driver(config *SSHConfig) Driver {
return &Workstation10Driver{
Workstation9Driver: Workstation9Driver{
SSHConfig: config,
},
}
}
func (d *Workstation10Driver) Clone(dst, src string, linked bool) error {
var cloneType string

View File

@ -24,6 +24,12 @@ type Workstation9Driver struct {
SSHConfig *SSHConfig
}
func NewWorkstation9Driver(config *SSHConfig) Driver {
return &Workstation9Driver{
SSHConfig: config,
}
}
func (d *Workstation9Driver) Clone(dst, src string, linked bool) error {
return errors.New("Cloning is not supported with VMware WS version 9. Please use VMware WS version 10, or greater.")
}

View File

@ -8,9 +8,7 @@ import (
"github.com/hashicorp/packer/template/interpolate"
)
// ~> **Note:** If [usb_keyboard](#usb_keyboard) or [vnc_over_websocket](#vnc_over_websocket) is set to true,
// any other VNC configuration will be ignored. If both are set to true, [usb_keyboard](#usb_keyboard) will be ignored
// and Packer will connect to the VM with VNC over websocket.
// ~> **Note:** If [vnc_over_websocket](#vnc_over_websocket) is set to true, any other VNC configuration will be ignored.
type RunConfig struct {
// Packer defaults to building VMware virtual machines
// by launching a GUI that shows the console of the machine being built. When
@ -44,27 +42,19 @@ type RunConfig struct {
// and any other VNC configuration option will be ignored.
// Remote builds using ESXi 6.7+ allows to connect to the VNC server only over websocket,
// for these the `vnc_over_websocket` must be set to true.
// If [usb_keyboard](#usb_keyboard) is also set to true, `usb_keyboard` will be ignored and set to false.
VNCOverWebsocket bool `mapstructure:"vnc_over_websocket" required:"false"`
// Do not validate VNC over websocket server's TLS certificate. Defaults to `false`.
InsecureConnection bool `mapstructure:"insecure_connection" required:"false"`
}
func (c *RunConfig) Prepare(_ *interpolate.Context, bootConfig *BootConfigWrapper, driverConfig *DriverConfig) (warnings []string, errs []error) {
func (c *RunConfig) Prepare(_ *interpolate.Context, driverConfig *DriverConfig) (warnings []string, errs []error) {
if c.VNCOverWebsocket {
if driverConfig.RemoteType == "" {
errs = append(errs, fmt.Errorf("'vnc_over_websocket' can only be used with remote VMWare builds."))
return
}
if bootConfig.USBKeyBoard {
warnings = append(warnings, "[WARN] Both 'usb_keyboard' and 'vnc_over_websocket' are set. "+
"The `usb_keyboard` option will be ignored and automatically set to false.")
bootConfig.USBKeyBoard = false
}
}
if bootConfig.USBKeyBoard || c.VNCOverWebsocket {
if c.VNCPortMin != 0 || c.VNCPortMax != 0 || c.VNCBindAddress != "" || c.VNCDisablePassword {
warnings = append(warnings, "[WARN] When one of 'usb_keyboard' and 'vnc_over_websocket' is set "+
warnings = append(warnings, "[WARN] When 'vnc_over_websocket' is set "+
"any other VNC configuration will be ignored.")
}
return

View File

@ -16,7 +16,6 @@ func TestRunConfig_Prepare(t *testing.T) {
name string
config *RunConfig
expectedConfig *RunConfig
boot *BootConfigWrapper
driver *DriverConfig
errs []error
warnings []string
@ -29,7 +28,6 @@ func TestRunConfig_Prepare(t *testing.T) {
VNCPortMax: 6000,
VNCBindAddress: "127.0.0.1",
},
boot: new(BootConfigWrapper),
driver: new(DriverConfig),
errs: nil,
warnings: nil,
@ -45,7 +43,6 @@ func TestRunConfig_Prepare(t *testing.T) {
VNCPortMax: 5900,
VNCBindAddress: "127.0.0.1",
},
boot: new(BootConfigWrapper),
driver: new(DriverConfig),
errs: nil,
warnings: nil,
@ -57,7 +54,6 @@ func TestRunConfig_Prepare(t *testing.T) {
VNCPortMax: 5000,
},
expectedConfig: nil,
boot: new(BootConfigWrapper),
driver: new(DriverConfig),
errs: []error{fmt.Errorf("vnc_port_min must be less than vnc_port_max")},
warnings: nil,
@ -68,7 +64,6 @@ func TestRunConfig_Prepare(t *testing.T) {
VNCPortMin: -1,
},
expectedConfig: nil,
boot: new(BootConfigWrapper),
driver: new(DriverConfig),
errs: []error{fmt.Errorf("vnc_port_min must be positive")},
warnings: nil,
@ -79,25 +74,10 @@ func TestRunConfig_Prepare(t *testing.T) {
VNCOverWebsocket: true,
},
expectedConfig: nil,
boot: new(BootConfigWrapper),
driver: new(DriverConfig),
errs: []error{fmt.Errorf("'vnc_over_websocket' can only be used with remote VMWare builds.")},
warnings: nil,
},
{
name: "choose vnc_over_websocket usb_keyboard",
config: &RunConfig{
VNCOverWebsocket: true,
},
expectedConfig: &RunConfig{
VNCOverWebsocket: true,
},
boot: &BootConfigWrapper{USBKeyBoard: true},
driver: &DriverConfig{RemoteType: "esxi"},
errs: nil,
warnings: []string{"[WARN] Both 'usb_keyboard' and 'vnc_over_websocket' are set. " +
"The `usb_keyboard` option will be ignored and automatically set to false."},
},
{
name: "warn about ignored vnc configuration",
config: &RunConfig{
@ -110,17 +90,16 @@ func TestRunConfig_Prepare(t *testing.T) {
VNCPortMin: 5000,
VNCPortMax: 5900,
},
boot: new(BootConfigWrapper),
driver: &DriverConfig{RemoteType: "esxi"},
errs: nil,
warnings: []string{"[WARN] When one of 'usb_keyboard' and 'vnc_over_websocket' is set " +
warnings: []string{"[WARN] When 'vnc_over_websocket' is set " +
"any other VNC configuration will be ignored."},
},
}
for _, c := range tc {
t.Run(c.name, func(t *testing.T) {
warnings, errs := c.config.Prepare(interpolate.NewContext(), c.boot, c.driver)
warnings, errs := c.config.Prepare(interpolate.NewContext(), c.driver)
if !reflect.DeepEqual(errs, c.errs) {
t.Fatalf("bad: \n expected '%v' \nactual '%v'", c.errs, errs)
}

View File

@ -1,126 +0,0 @@
package common
import (
"context"
"fmt"
"time"
"github.com/hashicorp/packer/common/bootcommand"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/template/interpolate"
"golang.org/x/mobile/event/key"
)
// This step "types" the boot command into the VM using USB Scan Codes.
type StepUSBBootCommand struct {
Config bootcommand.BootConfig
KeyInterval time.Duration
VMName string
Ctx interpolate.Context
}
type USBBootCommandTemplateData struct {
HTTPIP string
HTTPPort int
Name string
}
func (s *StepUSBBootCommand) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
debug := state.Get("debug").(bool)
ui := state.Get("ui").(packer.Ui)
driver := state.Get("driver").(*ESX5Driver)
if s.Config.BootCommand == nil {
return multistep.ActionContinue
}
// Wait the for the vm to boot.
if int64(s.Config.BootWait) > 0 {
ui.Say(fmt.Sprintf("Waiting %s for boot...", s.Config.BootWait.String()))
select {
case <-time.After(s.Config.BootWait):
break
case <-ctx.Done():
return multistep.ActionHalt
}
}
var pauseFn multistep.DebugPauseFn
if debug {
pauseFn = state.Get("pauseFn").(multistep.DebugPauseFn)
}
port := state.Get("http_port").(int)
if port > 0 {
ip := state.Get("http_ip").(string)
s.Ctx.Data = &USBBootCommandTemplateData{
HTTPIP: ip,
HTTPPort: port,
Name: s.VMName,
}
ui.Say(fmt.Sprintf("HTTP server is working at http://%v:%v/", ip, port))
}
var keyAlt, keyCtrl, keyShift bool
sendCodes := func(code key.Code, down bool) error {
switch code {
case key.CodeLeftAlt:
keyAlt = down
case key.CodeLeftControl:
keyCtrl = down
case key.CodeLeftShift:
keyShift = down
}
shift := down
if keyShift {
shift = keyShift
}
_, err := driver.TypeOnKeyboard(KeyInput{
Scancode: code,
Ctrl: keyCtrl,
Alt: keyAlt,
Shift: shift,
})
if err != nil {
return fmt.Errorf("error typing a boot command (code, down) `%d, %t`: %w", code, down, err)
}
return nil
}
d := bootcommand.NewUSBDriver(sendCodes, s.KeyInterval)
ui.Say("Typing boot command...")
flatBootCommand := s.Config.FlatBootCommand()
command, err := interpolate.Render(flatBootCommand, &s.Ctx)
if err != nil {
err := fmt.Errorf("Error preparing boot command: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
seq, err := bootcommand.GenerateExpressionSequence(command)
if err != nil {
err := fmt.Errorf("Error generating boot command: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
if err := seq.Do(ctx, d); err != nil {
err := fmt.Errorf("Error running boot command: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
if pauseFn != nil {
pauseFn(multistep.DebugLocationAfterRun, fmt.Sprintf("boot_command: %s", command), state)
}
return multistep.ActionContinue
}
func (*StepUSBBootCommand) Cleanup(multistep.StateBag) {}

View File

@ -52,20 +52,6 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
state.Put("driverConfig", &b.config.DriverConfig)
state.Put("temporaryDevices", []string{}) // Devices (in .vmx) created by packer during building
var stepBootCommand multistep.Step = &vmwcommon.StepVNCBootCommand{
Config: b.config.VNCConfig,
VMName: b.config.VMName,
Ctx: b.config.ctx,
}
if b.config.USBKeyBoard {
stepBootCommand = &vmwcommon.StepUSBBootCommand{
Config: b.config.VNCConfig.BootConfig,
KeyInterval: b.config.VNCConfig.BootKeyInterval,
VMName: b.config.VMName,
Ctx: b.config.ctx,
}
}
steps := []multistep.Step{
&vmwcommon.StepPrepareTools{
RemoteType: b.config.RemoteType,
@ -159,7 +145,11 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
InsecureConnection: b.config.InsecureConnection,
DriverConfig: &b.config.DriverConfig,
},
stepBootCommand,
&vmwcommon.StepVNCBootCommand{
Config: b.config.VNCConfig,
VMName: b.config.VMName,
Ctx: b.config.ctx,
},
&communicator.StepConnect{
Config: &b.config.SSHConfig.Comm,
Host: driver.CommHost,

View File

@ -11,6 +11,7 @@ import (
vmwcommon "github.com/hashicorp/packer/builder/vmware/common"
"github.com/hashicorp/packer/common"
"github.com/hashicorp/packer/common/bootcommand"
"github.com/hashicorp/packer/common/shutdowncommand"
"github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/packer"
@ -23,7 +24,7 @@ type Config struct {
common.ISOConfig `mapstructure:",squash"`
common.FloppyConfig `mapstructure:",squash"`
common.CDConfig `mapstructure:",squash"`
vmwcommon.BootConfigWrapper `mapstructure:",squash"`
bootcommand.VNCConfig `mapstructure:",squash"`
vmwcommon.DriverConfig `mapstructure:",squash"`
vmwcommon.HWConfig `mapstructure:",squash"`
vmwcommon.OutputConfig `mapstructure:",squash"`
@ -96,10 +97,7 @@ func (c *Config) Prepare(raws ...interface{}) ([]string, error) {
var warnings []string
var errs *packer.MultiError
vncWarnings, vncErrs := c.BootConfigWrapper.Prepare(&c.ctx, &c.DriverConfig)
warnings = append(warnings, vncWarnings...)
errs = packer.MultiErrorAppend(errs, vncErrs...)
runConfigWarnings, runConfigErrs := c.RunConfig.Prepare(&c.ctx, &c.BootConfigWrapper, &c.DriverConfig)
runConfigWarnings, runConfigErrs := c.RunConfig.Prepare(&c.ctx, &c.DriverConfig)
warnings = append(warnings, runConfigWarnings...)
errs = packer.MultiErrorAppend(errs, runConfigErrs...)
isoWarnings, isoErrs := c.ISOConfig.Prepare(&c.ctx)
@ -113,6 +111,7 @@ func (c *Config) Prepare(raws ...interface{}) ([]string, error) {
errs = packer.MultiErrorAppend(errs, c.SSHConfig.Prepare(&c.ctx)...)
errs = packer.MultiErrorAppend(errs, c.ToolsConfig.Prepare(&c.ctx)...)
errs = packer.MultiErrorAppend(errs, c.CDConfig.Prepare(&c.ctx)...)
errs = packer.MultiErrorAppend(errs, c.VNCConfig.Prepare(&c.ctx)...)
errs = packer.MultiErrorAppend(errs, c.VMXConfig.Prepare(&c.ctx)...)
errs = packer.MultiErrorAppend(errs, c.FloppyConfig.Prepare(&c.ctx)...)
errs = packer.MultiErrorAppend(errs, c.ExportConfig.Prepare(&c.ctx)...)

View File

@ -36,7 +36,6 @@ type FlatConfig struct {
BootCommand []string `mapstructure:"boot_command" cty:"boot_command" hcl:"boot_command"`
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"`
USBKeyBoard *bool `mapstructure:"usb_keyboard" cty:"usb_keyboard" hcl:"usb_keyboard"`
CleanUpRemoteCache *bool `mapstructure:"cleanup_remote_cache" required:"false" cty:"cleanup_remote_cache" hcl:"cleanup_remote_cache"`
FusionAppPath *string `mapstructure:"fusion_app_path" required:"false" cty:"fusion_app_path" hcl:"fusion_app_path"`
RemoteType *string `mapstructure:"remote_type" required:"false" cty:"remote_type" hcl:"remote_type"`
@ -181,7 +180,6 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"boot_command": &hcldec.AttrSpec{Name: "boot_command", Type: 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},
"usb_keyboard": &hcldec.AttrSpec{Name: "usb_keyboard", Type: cty.Bool, Required: false},
"cleanup_remote_cache": &hcldec.AttrSpec{Name: "cleanup_remote_cache", Type: cty.Bool, Required: false},
"fusion_app_path": &hcldec.AttrSpec{Name: "fusion_app_path", Type: cty.String, Required: false},
"remote_type": &hcldec.AttrSpec{Name: "remote_type", Type: cty.String, Required: false},

View File

@ -56,20 +56,6 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
state.Put("driverConfig", &b.config.DriverConfig)
state.Put("temporaryDevices", []string{}) // Devices (in .vmx) created by packer during building
var stepBootCommand multistep.Step = &vmwcommon.StepVNCBootCommand{
Config: b.config.VNCConfig,
VMName: b.config.VMName,
Ctx: b.config.ctx,
}
if b.config.USBKeyBoard {
stepBootCommand = &vmwcommon.StepUSBBootCommand{
Config: b.config.VNCConfig.BootConfig,
KeyInterval: b.config.VNCConfig.BootKeyInterval,
VMName: b.config.VMName,
Ctx: b.config.ctx,
}
}
// Build the steps.
steps := []multistep.Step{
&vmwcommon.StepPrepareTools{
@ -152,7 +138,11 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
InsecureConnection: b.config.InsecureConnection,
DriverConfig: &b.config.DriverConfig,
},
stepBootCommand,
&vmwcommon.StepVNCBootCommand{
Config: b.config.VNCConfig,
VMName: b.config.VMName,
Ctx: b.config.ctx,
},
&communicator.StepConnect{
Config: &b.config.SSHConfig.Comm,
Host: driver.CommHost,

View File

@ -9,6 +9,7 @@ import (
vmwcommon "github.com/hashicorp/packer/builder/vmware/common"
"github.com/hashicorp/packer/common"
"github.com/hashicorp/packer/common/bootcommand"
"github.com/hashicorp/packer/common/shutdowncommand"
"github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/packer"
@ -20,7 +21,7 @@ type Config struct {
common.PackerConfig `mapstructure:",squash"`
common.HTTPConfig `mapstructure:",squash"`
common.FloppyConfig `mapstructure:",squash"`
vmwcommon.BootConfigWrapper `mapstructure:",squash"`
bootcommand.VNCConfig `mapstructure:",squash"`
common.CDConfig `mapstructure:",squash"`
vmwcommon.DriverConfig `mapstructure:",squash"`
vmwcommon.OutputConfig `mapstructure:",squash"`
@ -81,10 +82,7 @@ func (c *Config) Prepare(raws ...interface{}) ([]string, error) {
var warnings []string
var errs *packer.MultiError
vncWarnings, vncErrs := c.BootConfigWrapper.Prepare(&c.ctx, &c.DriverConfig)
warnings = append(warnings, vncWarnings...)
errs = packer.MultiErrorAppend(errs, vncErrs...)
runConfigWarnings, runConfigErrs := c.RunConfig.Prepare(&c.ctx, &c.BootConfigWrapper, &c.DriverConfig)
runConfigWarnings, runConfigErrs := c.RunConfig.Prepare(&c.ctx, &c.DriverConfig)
warnings = append(warnings, runConfigWarnings...)
errs = packer.MultiErrorAppend(errs, runConfigErrs...)
errs = packer.MultiErrorAppend(errs, c.DriverConfig.Prepare(&c.ctx)...)
@ -96,6 +94,7 @@ func (c *Config) Prepare(raws ...interface{}) ([]string, error) {
errs = packer.MultiErrorAppend(errs, c.FloppyConfig.Prepare(&c.ctx)...)
errs = packer.MultiErrorAppend(errs, c.CDConfig.Prepare(&c.ctx)...)
errs = packer.MultiErrorAppend(errs, c.VNCConfig.Prepare(&c.ctx)...)
errs = packer.MultiErrorAppend(errs, c.VNCConfig.Prepare(&c.ctx)...)
errs = packer.MultiErrorAppend(errs, c.ExportConfig.Prepare(&c.ctx)...)
errs = packer.MultiErrorAppend(errs, c.DiskConfig.Prepare(&c.ctx)...)

View File

@ -29,7 +29,6 @@ type FlatConfig struct {
BootCommand []string `mapstructure:"boot_command" cty:"boot_command" hcl:"boot_command"`
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"`
USBKeyBoard *bool `mapstructure:"usb_keyboard" cty:"usb_keyboard" hcl:"usb_keyboard"`
CDFiles []string `mapstructure:"cd_files" cty:"cd_files" hcl:"cd_files"`
CDLabel *string `mapstructure:"cd_label" cty:"cd_label" hcl:"cd_label"`
CleanUpRemoteCache *bool `mapstructure:"cleanup_remote_cache" required:"false" cty:"cleanup_remote_cache" hcl:"cleanup_remote_cache"`
@ -155,7 +154,6 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"boot_command": &hcldec.AttrSpec{Name: "boot_command", Type: 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},
"usb_keyboard": &hcldec.AttrSpec{Name: "usb_keyboard", Type: cty.Bool, Required: false},
"cd_files": &hcldec.AttrSpec{Name: "cd_files", Type: cty.List(cty.String), Required: false},
"cd_label": &hcldec.AttrSpec{Name: "cd_label", Type: cty.String, Required: false},
"cleanup_remote_cache": &hcldec.AttrSpec{Name: "cleanup_remote_cache", Type: cty.Bool, Required: false},

View File

@ -201,8 +201,6 @@ necessary for this build to succeed and can be found further down the page.
@include 'common/bootcommand/BootConfig.mdx'
@include 'builder/vmware/common/BootConfigWrapper-not-required.mdx'
@include 'common/bootcommand/VNCConfig.mdx'
-> **Note**: for the `HTTPIP` to be resolved correctly, your VM's network

View File

@ -187,8 +187,6 @@ necessary for this build to succeed and can be found further down the page.
@include 'common/bootcommand/BootConfig.mdx'
@include 'builder/vmware/common/BootConfigWrapper-not-required.mdx'
@include 'common/bootcommand/VNCConfig.mdx'
-> **Note**: for the `HTTPIP` to be resolved correctly, your VM's network

View File

@ -1,9 +0,0 @@
<!-- Code generated from the comments of the BootConfigWrapper struct in builder/vmware/common/boot_config.go; DO NOT EDIT MANUALLY -->
- `usb_keyboard` (bool) - If set to true, Packer will use USB HID Keyboard scan codes to send the boot command to the VM and
the [disable_vnc](#disable_vnc) option will be ignored and automatically set to true.
This option is not supported by hosts running a free VMware license. As alternative please use [vnc_over_websocket](#vnc_over_websocket) instead.
~> **Note:** The ESXi 6.7+ removes support to VNC. In this case, the `usb_keyboard` or [vnc_over_websocket](#vnc_over_websocket)
should be set to true in order to send boot command keystrokes to the VM. If both are set, `usb_keyboard` will be ignored
and set to false.

View File

@ -33,6 +33,5 @@
and any other VNC configuration option will be ignored.
Remote builds using ESXi 6.7+ allows to connect to the VNC server only over websocket,
for these the `vnc_over_websocket` must be set to true.
If [usb_keyboard](#usb_keyboard) is also set to true, `usb_keyboard` will be ignored and set to false.
- `insecure_connection` (bool) - Do not validate VNC over websocket server's TLS certificate. Defaults to `false`.

View File

@ -1,5 +1,3 @@
<!-- Code generated from the comments of the RunConfig struct in builder/vmware/common/run_config.go; DO NOT EDIT MANUALLY -->
~> **Note:** If [usb_keyboard](#usb_keyboard) or [vnc_over_websocket](#vnc_over_websocket) is set to true,
any other VNC configuration will be ignored. If both are set to true, [usb_keyboard](#usb_keyboard) will be ignored
and Packer will connect to the VM with VNC over websocket.
~> **Note:** If [vnc_over_websocket](#vnc_over_websocket) is set to true, any other VNC configuration will be ignored.