Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 62 additions & 7 deletions builder/virtualbox/iso/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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"`
Expand Down Expand Up @@ -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 == "" {
Expand Down Expand Up @@ -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 {
Expand All @@ -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"
}
Expand Down
6 changes: 6 additions & 0 deletions builder/virtualbox/iso/builder.hcl2spec.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

55 changes: 47 additions & 8 deletions builder/virtualbox/iso/step_create_vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -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})
Expand All @@ -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"
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason why this is being changed from vboxvga to vboxsvga. I have observed that for linux guests the vboxvga works correctly in my host as compared to vboxsvga.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In settings for a Linux vm it will show an orange triangle warning in ui and states invalid settings detected and recommends switching to vboxsvga. New box setup via wizard also defaults to vboxsvga. So this aligns to what vbox recommends.

Copy link
Copy Markdown
Author

@Stromweld Stromweld Dec 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just checked it and it looks like for linux it actually recommends VMSVGA and for windows it recommends VboxSVGA.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it helps to get this reviewed and merged, I'd be happy to change it back.

vmDefaultConfigs, defaultConfigsOk := state.GetOk("vmDefaults")
if defaultConfigsOk {
vmDefaultConfigs := vmDefaultConfigs.(map[string]string)
Expand Down
26 changes: 24 additions & 2 deletions docs-partials/builder/virtualbox/iso/Config-not-required.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.

Expand Down Expand Up @@ -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 = [
Expand Down