diff --git a/builder/virtualbox/common/driver.go b/builder/virtualbox/common/driver.go index bfe8069ac..3cfd1f6b9 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 an NVME controller + CreateNVMeController(vm string, controller string, portcount int) error + // Delete a VM by name Delete(string) error diff --git a/builder/virtualbox/common/driver_4_2.go b/builder/virtualbox/common/driver_4_2.go index 03f119e94..86edd9174 100644 --- a/builder/virtualbox/common/driver_4_2.go +++ b/builder/virtualbox/common/driver_4_2.go @@ -51,6 +51,18 @@ func (d *VBox42Driver) CreateSATAController(vmName string, name string, portcoun return d.VBoxManage(command...) } +func (d *VBox42Driver) CreateNVMeController(vmName string, name string, portcount int) error { + command := []string{ + "storagectl", vmName, + "--name", name, + "--add", "pcie", + "--controller", "NVMe", + "--portcount", strconv.Itoa(portcount), + } + + return d.VBoxManage(command...) +} + func (d *VBox42Driver) CreateSCSIController(vmName string, name string) error { command := []string{ diff --git a/builder/virtualbox/iso/builder.go b/builder/virtualbox/iso/builder.go index 11d5784c5..b20b0b70f 100644 --- a/builder/virtualbox/iso/builder.go +++ b/builder/virtualbox/iso/builder.go @@ -89,6 +89,7 @@ type Config struct { // The type of controller that the primary hard drive is attached to, // 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. HardDriveInterface string `mapstructure:"hard_drive_interface" required:"false"` // The number of ports available on any SATA controller created, defaults @@ -96,6 +97,11 @@ type Config struct { // controller. Increasing this value can be useful if you want to attach // additional drives. SATAPortCount int `mapstructure:"sata_port_count" required:"false"` + // The number of ports available on any NVMe controller created, defaults + // to 1. VirtualBox supports up to 255 ports on a maximum of 1 NVMe + // controller. Increasing this value can be useful if you want to attach + // additional drives. + NVMePortCount int `mapstructure:"nvme_port_count" required:"false"` // Forces some guests (i.e. Windows 7+) to treat disks as SSDs and stops // them from performing disk fragmentation. Also set hard_drive_discard to // true to enable TRIM support. @@ -194,11 +200,11 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { } switch b.config.HardDriveInterface { - case "ide", "sata", "scsi", "nvme": + case "ide", "sata", "scsi", "pcie": // do nothing default: errs = packer.MultiErrorAppend( - errs, errors.New("hard_drive_interface can only be ide, sata, nvme or scsi")) + errs, errors.New("hard_drive_interface can only be ide, sata, pcie or scsi")) } if b.config.SATAPortCount == 0 { @@ -210,6 +216,15 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { errs, errors.New("sata_port_count cannot be greater than 30")) } + if b.config.NVMePortCount == 0 { + b.config.NVMePortCount = 1 + } + + if b.config.NVMePortCount > 255 { + errs = packer.MultiErrorAppend( + errs, errors.New("nvme_port_count cannot be greater than 255")) + } + if b.config.ISOInterface != "ide" && b.config.ISOInterface != "sata" { errs = packer.MultiErrorAppend( errs, errors.New("iso_interface can only be ide or sata")) diff --git a/builder/virtualbox/iso/step_create_disk.go b/builder/virtualbox/iso/step_create_disk.go index 6a00ea4fa..b70a65b93 100644 --- a/builder/virtualbox/iso/step_create_disk.go +++ b/builder/virtualbox/iso/step_create_disk.go @@ -73,6 +73,13 @@ func (s *stepCreateDisk) Run(ctx context.Context, state multistep.StateBag) mult ui.Error(err.Error()) return multistep.ActionHalt } + } else if config.HardDriveInterface == "pcie" { + if err := driver.CreateNVMeController(vmName, "NVMe Controller", config.NVMePortCount); err != nil { + err := fmt.Errorf("Error creating NVMe controller: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } } // Attach the disk to the controller