diff --git a/builder/virtualbox/common/driver.go b/builder/virtualbox/common/driver.go index dcb036a26..9f09dcf6a 100644 --- a/builder/virtualbox/common/driver.go +++ b/builder/virtualbox/common/driver.go @@ -22,6 +22,9 @@ type Driver interface { // Create a SCSI controller. CreateSCSIController(vm string, controller string) error + // Create a VirtIO controller. + CreateVirtIOController(vm string, controller string) error + // Create an NVME controller CreateNVMeController(vm string, controller string, portcount int) error diff --git a/builder/virtualbox/common/driver_4_2.go b/builder/virtualbox/common/driver_4_2.go index 92ba12acf..56d0b5e49 100644 --- a/builder/virtualbox/common/driver_4_2.go +++ b/builder/virtualbox/common/driver_4_2.go @@ -64,7 +64,6 @@ func (d *VBox42Driver) CreateNVMeController(vmName string, name string, portcoun } func (d *VBox42Driver) CreateSCSIController(vmName string, name string) error { - command := []string{ "storagectl", vmName, "--name", name, @@ -75,6 +74,17 @@ func (d *VBox42Driver) CreateSCSIController(vmName string, name string) error { return d.VBoxManage(command...) } +func (d *VBox42Driver) CreateVirtIOController(vmName string, name string) error { + command := []string{ + "storagectl", vmName, + "--name", name, + "--add", "VirtIO", + "--controller", "VirtIO", + } + + return d.VBoxManage(command...) +} + func (d *VBox42Driver) RemoveFloppyControllers(vmName string) error { var stdout bytes.Buffer diff --git a/builder/virtualbox/common/driver_mock.go b/builder/virtualbox/common/driver_mock.go index 58dc5f749..a8e73a44f 100644 --- a/builder/virtualbox/common/driver_mock.go +++ b/builder/virtualbox/common/driver_mock.go @@ -13,6 +13,10 @@ type DriverMock struct { CreateSCSIControllerController string CreateSCSIControllerErr error + CreateVirtIOControllerVM string + CreateVirtIOControllerController string + CreateVirtIOControllerErr error + CreateNVMeControllerVM string CreateNVMeControllerController string CreateNVMeControllerErr error @@ -78,6 +82,12 @@ func (d *DriverMock) CreateSCSIController(vm string, controller string) error { return d.CreateSCSIControllerErr } +func (d *DriverMock) CreateVirtIOController(vm string, controller string) error { + d.CreateVirtIOControllerVM = vm + d.CreateVirtIOControllerController = vm + return d.CreateVirtIOControllerErr +} + func (d *DriverMock) CreateNVMeController(vm string, controller string, portcount int) error { d.CreateNVMeControllerVM = vm d.CreateNVMeControllerController = vm diff --git a/builder/virtualbox/common/step_attach_isos.go b/builder/virtualbox/common/step_attach_isos.go index fe1156d67..897cdbd06 100644 --- a/builder/virtualbox/common/step_attach_isos.go +++ b/builder/virtualbox/common/step_attach_isos.go @@ -80,6 +80,10 @@ func (s *StepAttachISOs) Run(ctx context.Context, state multistep.StateBag) mult controllerName = "SATA Controller" port = "1" device = "0" + } else if s.ISOInterface == "virtio" { + controllerName = "VirtIO Controller" + port = "1" + device = "0" } ui.Message("Mounting boot ISO...") case "guest_additions": @@ -90,6 +94,10 @@ func (s *StepAttachISOs) Run(ctx context.Context, state multistep.StateBag) mult controllerName = "SATA Controller" port = "2" device = "0" + } else if s.GuestAdditionsInterface == "virtio" { + controllerName = "VirtIO Controller" + port = "2" + device = "0" } ui.Message("Mounting guest additions ISO...") case "cd_files": @@ -100,6 +108,10 @@ func (s *StepAttachISOs) Run(ctx context.Context, state multistep.StateBag) mult controllerName = "SATA Controller" port = "3" device = "0" + } else if s.ISOInterface == "virtio" { + controllerName = "VirtIO Controller" + port = "3" + device = "0" } ui.Message("Mounting cd_files ISO...") } diff --git a/builder/virtualbox/iso/builder.go b/builder/virtualbox/iso/builder.go index 5cc5541f1..14cbafb22 100644 --- a/builder/virtualbox/iso/builder.go +++ b/builder/virtualbox/iso/builder.go @@ -62,6 +62,7 @@ type Config struct { // defaults to ide. When set to sata, the drive is attached to an AHCI SATA // controller. When set to scsi, the drive is attached to an LsiLogic SCSI // controller. When set to pcie, the drive is attached to an NVMe + // controller. When set to virtio, the drive is attached to a VirtIO // controller. Please note that when you use "pcie", you'll need to have // Virtualbox 6, install an [extension // pack](https://www.virtualbox.org/wiki/Downloads#VirtualBox6.0.14OracleVMVirtualBoxExtensionPack) @@ -98,6 +99,7 @@ type Config struct { HardDriveNonrotational bool `mapstructure:"hard_drive_nonrotational" required:"false"` // The type of controller that the ISO is attached to, defaults to ide. // When set to sata, the drive is attached to an AHCI SATA controller. + // When set to virtio, the drive is attached to a VirtIO controller. ISOInterface string `mapstructure:"iso_interface" required:"false"` // Set this to true if you would like to keep the VM registered with // virtualbox. Defaults to false. @@ -186,11 +188,11 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) { } switch b.config.HardDriveInterface { - case "ide", "sata", "scsi", "pcie": + case "ide", "sata", "scsi", "pcie", "virtio": // do nothing default: errs = packersdk.MultiErrorAppend( - errs, errors.New("hard_drive_interface can only be ide, sata, pcie or scsi")) + errs, errors.New("hard_drive_interface can only be ide, sata, pcie, scsi or virtio")) } if b.config.SATAPortCount == 0 { @@ -211,9 +213,9 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) { errs, errors.New("nvme_port_count cannot be greater than 255")) } - if b.config.ISOInterface != "ide" && b.config.ISOInterface != "sata" { + if b.config.ISOInterface != "ide" && b.config.ISOInterface != "sata" && b.config.ISOInterface != "virtio" { errs = packersdk.MultiErrorAppend( - errs, errors.New("iso_interface can only be ide or sata")) + errs, errors.New("iso_interface can only be ide, sata or virtio")) } // Warnings diff --git a/builder/virtualbox/iso/step_create_disk.go b/builder/virtualbox/iso/step_create_disk.go index 6b3c620dc..b23418d5f 100644 --- a/builder/virtualbox/iso/step_create_disk.go +++ b/builder/virtualbox/iso/step_create_disk.go @@ -66,6 +66,18 @@ func (s *stepCreateDisk) Run(ctx context.Context, state multistep.StateBag) mult } } + // Add a VirtIO controller if we were asked to use VirtIO. We still attach + // the VirtIO controller above because some other things (disks) require + // that. + if config.HardDriveInterface == "virtio" || config.ISOInterface == "virtio" { + if err := driver.CreateVirtIOController(vmName, "VirtIO Controller"); err != nil { + err := fmt.Errorf("Error creating disk controller: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + } + if config.HardDriveInterface == "scsi" { if err := driver.CreateSCSIController(vmName, "SCSI Controller"); err != nil { err := fmt.Errorf("Error creating disk controller: %s", err) @@ -86,13 +98,11 @@ func (s *stepCreateDisk) Run(ctx context.Context, state multistep.StateBag) mult controllerName := "IDE Controller" if config.HardDriveInterface == "sata" { controllerName = "SATA Controller" - } - - if config.HardDriveInterface == "scsi" { + } else if config.HardDriveInterface == "scsi" { controllerName = "SCSI Controller" - } - - if config.HardDriveInterface == "pcie" { + } else if config.HardDriveInterface == "virtio" { + controllerName = "VirtIO Controller" + } else if config.HardDriveInterface == "pcie" { controllerName = "NVMe Controller" } diff --git a/website/content/partials/builder/virtualbox/iso/Config-not-required.mdx b/website/content/partials/builder/virtualbox/iso/Config-not-required.mdx index 55e348ac2..8afdf7544 100644 --- a/website/content/partials/builder/virtualbox/iso/Config-not-required.mdx +++ b/website/content/partials/builder/virtualbox/iso/Config-not-required.mdx @@ -18,6 +18,7 @@ defaults to ide. When set to sata, the drive is attached to an AHCI SATA controller. When set to scsi, the drive is attached to an LsiLogic SCSI controller. When set to pcie, the drive is attached to an NVMe + controller. When set to virtio, the drive is attached to a VirtIO controller. Please note that when you use "pcie", you'll need to have Virtualbox 6, install an [extension pack](https://www.virtualbox.org/wiki/Downloads#VirtualBox6.0.14OracleVMVirtualBoxExtensionPack) @@ -53,6 +54,7 @@ - `iso_interface` (string) - The type of controller that the ISO is attached to, defaults to ide. When set to sata, the drive is attached to an AHCI SATA controller. + When set to virtio, the drive is attached to a VirtIO controller. - `keep_registered` (bool) - Set this to true if you would like to keep the VM registered with virtualbox. Defaults to false.