diff --git a/builder/virtualbox/iso/builder.go b/builder/virtualbox/iso/builder.go index edb29f67..db976ac1 100644 --- a/builder/virtualbox/iso/builder.go +++ b/builder/virtualbox/iso/builder.go @@ -51,6 +51,8 @@ type Config struct { // The chipset to be used: PIIX3 or ICH9. // When set to piix3, the firmare is PIIX3. This is the default. // When set to ich9, the firmare is ICH9. + // When set to armv8, the firmare is ARMv8. + // When set to armv8virtual, the firmare is ARMv8 Virtual. Chipset string `mapstructure:"chipset" required:"false"` // The firmware to be used: BIOS or EFI. // When set to bios, the firmare is BIOS. This is the default. @@ -75,16 +77,36 @@ type Config struct { // When set to Am79C973, the NICs are AMD PCNet-FAST III network card (Am79C973). // When set to Am79C960, the NICs are AMD PCnet-ISA/NE2100 (Am79C960). // When set to virtio, the NICs are VirtIO. + // When set to usbnet, the NICs are USB Network. NICType string `mapstructure:"nic_type" required:"false"` // The audio controller type to be used. // When set to ac97, the audio controller is ICH AC97. This is the default. // When set to hda, the audio controller is Intel HD Audio. // When set to sb16, the audio controller is SoundBlaster 16. + // When set to none, the audio controller is disabled. AudioController string `mapstructure:"audio_controller" required:"false"` + // The USB controller type to be used. + // When set to ohci, the USB controller is USB 1.1 (OHCI). + // When set to ehci, the USB controller is USB 2.0 (EHCI). This is the default when usb is enabled. + // When set to xhci, the USB controller is USB 3.0 (xHCI). + // When set to none, no USB controller is configured even if usb is enabled. + // This setting is only used when usb is set to true. + USBController string `mapstructure:"usb_controller" required:"false"` + // The mouse device type to be used. + // When set to ps2, a PS/2 mouse is emulated. This is the default. + // When set to usb, a USB mouse is emulated (requires USB to be enabled). + // When set to usbtablet, a USB tablet device is emulated (absolute positioning, requires USB). + // When set to usbmultitouch, a USB multi-touch device is emulated (requires USB). + Mouse string `mapstructure:"mouse" required:"false"` + // The keyboard device type to be used. + // When set to ps2, a PS/2 keyboard is emulated. This is the default. + // When set to usb, a USB keyboard is emulated (requires USB to be enabled). + Keyboard string `mapstructure:"keyboard" required:"false"` // The graphics controller type to be used. // When set to vboxvga, the graphics controller is VirtualBox VGA. This is the default. // When set to vboxsvga, the graphics controller is VirtualBox SVGA. // When set to vmsvga, the graphics controller is VMware SVGA. + // When set to qemuramfb, the graphics controller is QEMU RAMFB. // When set to none, the graphics controller is disabled. // When this configuration is omitted, the default value is determined by VirtualBox. GfxController string `mapstructure:"gfx_controller" required:"false"` @@ -224,11 +246,11 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) { b.config.Chipset = "piix3" } switch b.config.Chipset { - case "piix3", "ich9": + case "piix3", "ich9", "armv8", "armv8virtual": // do nothing default: errs = packersdk.MultiErrorAppend( - errs, errors.New("chipset can only be piix3 or ich9")) + errs, errors.New("chipset can only be piix3, ich9, armv8, or armv8virtual")) } if b.config.Firmware == "" { @@ -265,19 +287,19 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) { b.config.NICType = "82540EM" } switch b.config.NICType { - case "82540EM", "82543GC", "82545EM", "Am79C970A", "Am79C973", "Am79C960", "virtio": + case "82540EM", "82543GC", "82545EM", "Am79C970A", "Am79C973", "Am79C960", "virtio", "usbnet": // do nothing default: errs = packersdk.MultiErrorAppend( - errs, errors.New("NIC type can only be 82540EM, 82543GC, 82545EM, Am79C970A, Am79C973, Am79C960 or virtio")) + errs, errors.New("NIC type can only be 82540EM, 82543GC, 82545EM, Am79C970A, Am79C973, Am79C960, usbnet, virtio")) } switch b.config.GfxController { - case "vboxvga", "vboxsvga", "vmsvga", "none", "": + case "vboxvga", "vboxsvga", "vmsvga", "qemuramfb", "none", "": // do nothing default: errs = packersdk.MultiErrorAppend( - errs, errors.New("Graphics controller type can only be vboxvga, vboxsvga, vmsvga, none")) + errs, errors.New("Graphics controller type can only be vboxvga, vboxsvga, vmsvga, qemuramfb, none")) } if b.config.GfxVramSize == 0 { @@ -302,13 +324,46 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) { b.config.AudioController = "ac97" } switch b.config.AudioController { - case "ac97", "hda", "sb16": + case "ac97", "hda", "sb16", "none": // do nothing default: errs = packersdk.MultiErrorAppend( errs, errors.New("Audio controller type can only be ac97, hda or sb16")) } + if b.config.USBController == "" { + b.config.USBController = "ehci" + } + switch b.config.USBController { + case "ohci", "ehci", "xhci", "none": + // do nothing + default: + errs = packersdk.MultiErrorAppend( + errs, errors.New("USB controller type can only be ohci, ehci, xhci, or none")) + } + + if b.config.Mouse == "" { + b.config.Mouse = "ps2" + } + switch b.config.Mouse { + case "ps2", "usb", "usbtablet", "usbmultitouch": + // do nothing + default: + errs = packersdk.MultiErrorAppend( + errs, errors.New("Mouse type can only be ps2, usb, usbtablet, or usbmultitouch")) + } + + if b.config.Keyboard == "" { + b.config.Keyboard = "ps2" + } + switch b.config.Keyboard { + case "ps2", "usb": + // do nothing + default: + errs = packersdk.MultiErrorAppend( + errs, errors.New("Keyboard type can only be ps2 or usb")) + } + if b.config.GuestOSType == "" { b.config.GuestOSType = "Other" } diff --git a/builder/virtualbox/iso/builder.hcl2spec.go b/builder/virtualbox/iso/builder.hcl2spec.go index 471630cd..79956685 100644 --- a/builder/virtualbox/iso/builder.hcl2spec.go +++ b/builder/virtualbox/iso/builder.hcl2spec.go @@ -128,6 +128,9 @@ type FlatConfig struct { DiskSize *uint `mapstructure:"disk_size" required:"false" cty:"disk_size" hcl:"disk_size"` NICType *string `mapstructure:"nic_type" required:"false" cty:"nic_type" hcl:"nic_type"` AudioController *string `mapstructure:"audio_controller" required:"false" cty:"audio_controller" hcl:"audio_controller"` + USBController *string `mapstructure:"usb_controller" required:"false" cty:"usb_controller" hcl:"usb_controller"` + Mouse *string `mapstructure:"mouse" required:"false" cty:"mouse" hcl:"mouse"` + Keyboard *string `mapstructure:"keyboard" required:"false" cty:"keyboard" hcl:"keyboard"` GfxController *string `mapstructure:"gfx_controller" required:"false" cty:"gfx_controller" hcl:"gfx_controller"` GfxVramSize *uint `mapstructure:"gfx_vram_size" required:"false" cty:"gfx_vram_size" hcl:"gfx_vram_size"` GfxAccelerate3D *bool `mapstructure:"gfx_accelerate_3d" required:"false" cty:"gfx_accelerate_3d" hcl:"gfx_accelerate_3d"` @@ -275,6 +278,9 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "disk_size": &hcldec.AttrSpec{Name: "disk_size", Type: cty.Number, Required: false}, "nic_type": &hcldec.AttrSpec{Name: "nic_type", Type: cty.String, Required: false}, "audio_controller": &hcldec.AttrSpec{Name: "audio_controller", Type: cty.String, Required: false}, + "usb_controller": &hcldec.AttrSpec{Name: "usb_controller", Type: cty.String, Required: false}, + "mouse": &hcldec.AttrSpec{Name: "mouse", Type: cty.String, Required: false}, + "keyboard": &hcldec.AttrSpec{Name: "keyboard", Type: cty.String, Required: false}, "gfx_controller": &hcldec.AttrSpec{Name: "gfx_controller", Type: cty.String, Required: false}, "gfx_vram_size": &hcldec.AttrSpec{Name: "gfx_vram_size", Type: cty.Number, Required: false}, "gfx_accelerate_3d": &hcldec.AttrSpec{Name: "gfx_accelerate_3d", Type: cty.Bool, Required: false}, diff --git a/builder/virtualbox/iso/step_create_vm.go b/builder/virtualbox/iso/step_create_vm.go index 2d48455b..474b6b82 100644 --- a/builder/virtualbox/iso/step_create_vm.go +++ b/builder/virtualbox/iso/step_create_vm.go @@ -46,16 +46,55 @@ func (s *stepCreateVM) Run(ctx context.Context, state multistep.StateBag) multis commands = append(commands, []string{"modifyvm", name, "--ioapic", "on"}) } commands = append(commands, []string{"modifyvm", name, "--memory", strconv.Itoa(config.HWConfig.MemorySize)}) - commands = append(commands, []string{"modifyvm", name, "--usb", map[bool]string{true: "on", false: "off"}[config.HWConfig.USB]}) + // Configure USB controller + if config.HWConfig.USB && strings.ToLower(config.USBController) != "none" { + commands = append(commands, []string{"modifyvm", name, "--usb", "on"}) + commands = append(commands, []string{"modifyvm", name, "--usbohci", "off", "--usbehci", "off", "--usbxhci", "off"}) + switch strings.ToLower(config.USBController) { + case "ohci": + commands = append(commands, []string{"modifyvm", name, "--usbohci", "on"}) + case "ehci": + commands = append(commands, []string{"modifyvm", name, "--usbehci", "on"}) + case "xhci": + commands = append(commands, []string{"modifyvm", name, "--usbxhci", "on"}) + } + } else { + commands = append(commands, []string{"modifyvm", name, "--usb", "off"}) + } vboxVersion, _ := driver.Version() audioDriverArg := audioDriverConfigurationArg(vboxVersion) - if strings.ToLower(config.HWConfig.Sound) == "none" { - commands = append(commands, []string{"modifyvm", name, audioDriverArg, config.HWConfig.Sound, - "--audiocontroller", config.AudioController}) + // Only configure audio if the audio controller is not set to "none" + if strings.ToLower(config.AudioController) == "none" { + commands = append(commands, []string{"modifyvm", name, "--audio-enabled", "off"}) } else { - commands = append(commands, []string{"modifyvm", name, audioDriverArg, config.HWConfig.Sound, "--audioin", "on", "--audioout", "on", - "--audiocontroller", config.AudioController}) + if strings.ToLower(config.HWConfig.Sound) == "none" { + commands = append(commands, []string{"modifyvm", name, audioDriverArg, config.HWConfig.Sound, + "--audiocontroller", config.AudioController}) + } else { + commands = append(commands, []string{"modifyvm", name, audioDriverArg, config.HWConfig.Sound, "--audioin", "on", "--audioout", "on", + "--audiocontroller", config.AudioController}) + } + } + + // Configure mouse device + switch strings.ToLower(config.Mouse) { + case "ps2": + commands = append(commands, []string{"modifyvm", name, "--mouse", "ps2"}) + case "usb": + commands = append(commands, []string{"modifyvm", name, "--mouse", "usb"}) + case "usbtablet": + commands = append(commands, []string{"modifyvm", name, "--mouse", "usbtablet"}) + case "usbmultitouch": + commands = append(commands, []string{"modifyvm", name, "--mouse", "usbmultitouch"}) + } + + // Configure keyboard device + switch strings.ToLower(config.Keyboard) { + case "ps2": + commands = append(commands, []string{"modifyvm", name, "--keyboard", "ps2"}) + case "usb": + commands = append(commands, []string{"modifyvm", name, "--keyboard", "usb"}) } commands = append(commands, []string{"modifyvm", name, "--chipset", config.Chipset}) @@ -71,9 +110,9 @@ func (s *stepCreateVM) Run(ctx context.Context, state multistep.StateBag) multis "--nictype7", config.NICType, "--nictype8", config.NICType}) - // Set the graphics controller, defaulting to "vboxvga" unless overridden by "vmDefaults" or config. + // Set the graphics controller, defaulting to "vboxsvga" unless overridden by "vmDefaults" or config. if config.GfxController == "" { - config.GfxController = "vboxvga" + config.GfxController = "vboxsvga" vmDefaultConfigs, defaultConfigsOk := state.GetOk("vmDefaults") if defaultConfigsOk { vmDefaultConfigs := vmDefaultConfigs.(map[string]string) diff --git a/docs-partials/builder/virtualbox/iso/Config-not-required.mdx b/docs-partials/builder/virtualbox/iso/Config-not-required.mdx index 5936da6f..6779639a 100644 --- a/docs-partials/builder/virtualbox/iso/Config-not-required.mdx +++ b/docs-partials/builder/virtualbox/iso/Config-not-required.mdx @@ -3,6 +3,8 @@ - `chipset` (string) - The chipset to be used: PIIX3 or ICH9. When set to piix3, the firmare is PIIX3. This is the default. When set to ich9, the firmare is ICH9. + When set to armv8, the firmare is ARMv8. + When set to armv8virtual, the firmare is ARMv8 Virtual. - `firmware` (string) - The firmware to be used: BIOS or EFI. When set to bios, the firmare is BIOS. This is the default. @@ -27,16 +29,36 @@ When set to Am79C973, the NICs are AMD PCNet-FAST III network card (Am79C973). When set to Am79C960, the NICs are AMD PCnet-ISA/NE2100 (Am79C960). When set to virtio, the NICs are VirtIO. + When set to usbnet, the NICs are USB Network. - `audio_controller` (string) - The audio controller type to be used. When set to ac97, the audio controller is ICH AC97. This is the default. When set to hda, the audio controller is Intel HD Audio. When set to sb16, the audio controller is SoundBlaster 16. + When set to none, the audio controller is disabled. + +- `usb_controller` (string) - The USB controller type to be used. + When set to ohci, the USB controller is USB 1.1 (OHCI). + When set to ehci, the USB controller is USB 2.0 (EHCI). This is the default when usb is enabled. + When set to xhci, the USB controller is USB 3.0 (xHCI). + When set to none, no USB controller is configured even if usb is enabled. + This setting is only used when usb is set to true. + +- `mouse` (string) - The mouse device type to be used. + When set to ps2, a PS/2 mouse is emulated. This is the default. + When set to usb, a USB mouse is emulated (requires USB to be enabled). + When set to usbtablet, a USB tablet device is emulated (absolute positioning, requires USB). + When set to usbmultitouch, a USB multi-touch device is emulated (requires USB). + +- `keyboard` (string) - The keyboard device type to be used. + When set to ps2, a PS/2 keyboard is emulated. This is the default. + When set to usb, a USB keyboard is emulated (requires USB to be enabled). - `gfx_controller` (string) - The graphics controller type to be used. When set to vboxvga, the graphics controller is VirtualBox VGA. This is the default. When set to vboxsvga, the graphics controller is VirtualBox SVGA. When set to vmsvga, the graphics controller is VMware SVGA. + When set to qemuramfb, the graphics controller is QEMU RAMFB. When set to none, the graphics controller is disabled. When this configuration is omitted, the default value is determined by VirtualBox. @@ -71,14 +93,14 @@ Virtualbox 6, install an [extension pack](https://www.virtualbox.org/wiki/Downloads#VirtualBox6.0.14OracleVMVirtualBoxExtensionPack) and you will need to enable EFI mode for nvme to work, ex: - + In JSON: ```json "vboxmanage": [ [ "modifyvm", "{{.Name}}", "--firmware", "EFI" ], ] ``` - + In HCL2: ```hcl vboxmanage = [