Remove usb_keyboard option (#9945)
This commit is contained in:
parent
b4be598148
commit
9737b85bbc
|
@ -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
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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+.")
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.")
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.")
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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) {}
|
|
@ -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,
|
||||
|
|
|
@ -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)...)
|
||||
|
|
|
@ -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},
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)...)
|
||||
|
||||
|
|
|
@ -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},
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
|
@ -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`.
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue