From d2867c47f0f6b044775dd260b47f3b15df6bead1 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Thu, 31 Oct 2019 14:43:46 -0700 Subject: [PATCH 1/7] allow nvme, since virtualbox 6.0 allows it --- builder/virtualbox/iso/builder.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/builder/virtualbox/iso/builder.go b/builder/virtualbox/iso/builder.go index 5ff62c54e..11d5784c5 100644 --- a/builder/virtualbox/iso/builder.go +++ b/builder/virtualbox/iso/builder.go @@ -193,9 +193,12 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { "packer-%s-%d", b.config.PackerBuildName, interpolate.InitTime.Unix()) } - if b.config.HardDriveInterface != "ide" && b.config.HardDriveInterface != "sata" && b.config.HardDriveInterface != "scsi" { + switch b.config.HardDriveInterface { + case "ide", "sata", "scsi", "nvme": + // do nothing + default: errs = packer.MultiErrorAppend( - errs, errors.New("hard_drive_interface can only be ide, sata, or scsi")) + errs, errors.New("hard_drive_interface can only be ide, sata, nvme or scsi")) } if b.config.SATAPortCount == 0 { From 9343a230211492caac60ad4d9bbbe83989de2350 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Thu, 31 Oct 2019 15:21:52 -0700 Subject: [PATCH 2/7] add driver calls to enable nvme controller --- builder/virtualbox/common/driver.go | 3 +++ builder/virtualbox/common/driver_4_2.go | 12 ++++++++++++ builder/virtualbox/iso/builder.go | 19 +++++++++++++++++-- builder/virtualbox/iso/step_create_disk.go | 7 +++++++ 4 files changed, 39 insertions(+), 2 deletions(-) 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 From 65ad3105b33049c37cb2fd8141c2e29bdb78521a Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Thu, 31 Oct 2019 15:28:36 -0700 Subject: [PATCH 3/7] udpdate generated code --- builder/virtualbox/iso/builder.hcl2spec.go | 2 ++ .../builder/virtualbox/iso/_Config-not-required.html.md | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/builder/virtualbox/iso/builder.hcl2spec.go b/builder/virtualbox/iso/builder.hcl2spec.go index af6d5027f..a38d52f95 100644 --- a/builder/virtualbox/iso/builder.hcl2spec.go +++ b/builder/virtualbox/iso/builder.hcl2spec.go @@ -105,6 +105,7 @@ type FlatConfig struct { HardDriveDiscard *bool `mapstructure:"hard_drive_discard" required:"false" cty:"hard_drive_discard"` HardDriveInterface *string `mapstructure:"hard_drive_interface" required:"false" cty:"hard_drive_interface"` SATAPortCount *int `mapstructure:"sata_port_count" required:"false" cty:"sata_port_count"` + NVMePortCount *int `mapstructure:"nvme_port_count" required:"false" cty:"nvme_port_count"` HardDriveNonrotational *bool `mapstructure:"hard_drive_nonrotational" required:"false" cty:"hard_drive_nonrotational"` ISOInterface *string `mapstructure:"iso_interface" required:"false" cty:"iso_interface"` KeepRegistered *bool `mapstructure:"keep_registered" required:"false" cty:"keep_registered"` @@ -217,6 +218,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "hard_drive_discard": &hcldec.AttrSpec{Name: "hard_drive_discard", Type: cty.Bool, Required: false}, "hard_drive_interface": &hcldec.AttrSpec{Name: "hard_drive_interface", Type: cty.String, Required: false}, "sata_port_count": &hcldec.AttrSpec{Name: "sata_port_count", Type: cty.Number, Required: false}, + "nvme_port_count": &hcldec.AttrSpec{Name: "nvme_port_count", Type: cty.Number, Required: false}, "hard_drive_nonrotational": &hcldec.AttrSpec{Name: "hard_drive_nonrotational", Type: cty.Bool, Required: false}, "iso_interface": &hcldec.AttrSpec{Name: "iso_interface", Type: cty.String, Required: false}, "keep_registered": &hcldec.AttrSpec{Name: "keep_registered", Type: cty.Bool, Required: false}, diff --git a/website/source/partials/builder/virtualbox/iso/_Config-not-required.html.md b/website/source/partials/builder/virtualbox/iso/_Config-not-required.html.md index 951f63183..486b19023 100644 --- a/website/source/partials/builder/virtualbox/iso/_Config-not-required.html.md +++ b/website/source/partials/builder/virtualbox/iso/_Config-not-required.html.md @@ -47,6 +47,7 @@ - `hard_drive_interface` (string) - 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. - `sata_port_count` (int) - The number of ports available on any SATA controller created, defaults @@ -54,6 +55,11 @@ controller. Increasing this value can be useful if you want to attach additional drives. +- `nvme_port_count` (int) - 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. + - `hard_drive_nonrotational` (bool) - 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. From 6f54468dd589d6e5fd336671fe61a034f42550b4 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Thu, 31 Oct 2019 15:36:22 -0700 Subject: [PATCH 4/7] fix mocks --- builder/virtualbox/common/driver_mock.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/builder/virtualbox/common/driver_mock.go b/builder/virtualbox/common/driver_mock.go index 68d57fa64..6ff9e80b8 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 + CreateNVMeControllerVM string + CreateNVMeControllerController string + CreateNVMeControllerErr error + DeleteCalled bool DeleteName string DeleteErr error @@ -70,6 +74,12 @@ func (d *DriverMock) CreateSCSIController(vm string, controller string) error { return d.CreateSCSIControllerErr } +func (d *DriverMock) CreateNVMeController(vm string, controller string, portcount int) error { + d.CreateNVMeControllerVM = vm + d.CreateNVMeControllerController = vm + return d.CreateNVMeControllerErr +} + func (d *DriverMock) Delete(name string) error { d.DeleteCalled = true d.DeleteName = name From b7907760969e98233796bdfde82cf18e27c96596 Mon Sep 17 00:00:00 2001 From: Adrien Delorme Date: Fri, 1 Nov 2019 14:43:59 +0100 Subject: [PATCH 5/7] vbox iso: use NVMe Controller when the hard drive interface if pcie --- builder/virtualbox/iso/step_create_disk.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/builder/virtualbox/iso/step_create_disk.go b/builder/virtualbox/iso/step_create_disk.go index b70a65b93..1a8a80ad6 100644 --- a/builder/virtualbox/iso/step_create_disk.go +++ b/builder/virtualbox/iso/step_create_disk.go @@ -92,6 +92,10 @@ func (s *stepCreateDisk) Run(ctx context.Context, state multistep.StateBag) mult controllerName = "SCSI Controller" } + if config.HardDriveInterface == "pcie" { + controllerName = "NVMe Controller" + } + nonrotational := "off" if config.HardDriveNonrotational { nonrotational = "on" From 974eba443a9a2c3447ce6af80314263e854bc87a Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Fri, 1 Nov 2019 09:48:35 -0700 Subject: [PATCH 6/7] update docs to include warning about extension pack --- builder/virtualbox/iso/builder.go | 3 ++- .../builder/virtualbox/iso/_Config-not-required.html.md | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/builder/virtualbox/iso/builder.go b/builder/virtualbox/iso/builder.go index b20b0b70f..bf1953b84 100644 --- a/builder/virtualbox/iso/builder.go +++ b/builder/virtualbox/iso/builder.go @@ -90,7 +90,8 @@ 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. + // controller. (Please note that when you use "pcie", you'll need to have + // Virtualbox 6 and an [extension pack](https://www.virtualbox.org/wiki/Downloads#VirtualBox6.0.14OracleVMVirtualBoxExtensionPack)) HardDriveInterface string `mapstructure:"hard_drive_interface" required:"false"` // The number of ports available on any SATA controller created, defaults // to 1. VirtualBox supports up to 30 ports on a maximum of 1 SATA diff --git a/website/source/partials/builder/virtualbox/iso/_Config-not-required.html.md b/website/source/partials/builder/virtualbox/iso/_Config-not-required.html.md index 486b19023..64ff6c34c 100644 --- a/website/source/partials/builder/virtualbox/iso/_Config-not-required.html.md +++ b/website/source/partials/builder/virtualbox/iso/_Config-not-required.html.md @@ -48,7 +48,8 @@ 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. + controller. (Please note that when you use "pcie", you'll need to have + Virtualbox 6 and an [extension pack](https://www.virtualbox.org/wiki/Downloads#VirtualBox6.0.14OracleVMVirtualBoxExtensionPack)) - `sata_port_count` (int) - The number of ports available on any SATA controller created, defaults to 1. VirtualBox supports up to 30 ports on a maximum of 1 SATA From a23801d4a96397a1804ed4cf070b22d8c924c4ec Mon Sep 17 00:00:00 2001 From: Adrien Delorme Date: Mon, 4 Nov 2019 14:30:59 +0100 Subject: [PATCH 7/7] builder.virtualbox.iso: document that EFI mode needs to be enabled for pcie/nvme to work too --- builder/virtualbox/iso/builder.go | 9 +++++++-- .../builder/virtualbox/iso/_Config-not-required.html.md | 9 +++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/builder/virtualbox/iso/builder.go b/builder/virtualbox/iso/builder.go index bf1953b84..2f3c52a23 100644 --- a/builder/virtualbox/iso/builder.go +++ b/builder/virtualbox/iso/builder.go @@ -90,8 +90,13 @@ 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. (Please note that when you use "pcie", you'll need to have - // Virtualbox 6 and an [extension pack](https://www.virtualbox.org/wiki/Downloads#VirtualBox6.0.14OracleVMVirtualBoxExtensionPack)) + // 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) + // and you will need to enable EFI mode for nvme to work, ex: + // "vboxmanage": [ + // [ "modifyvm", "{{.Name}}", "--firmware", "EFI" ], + // ] HardDriveInterface string `mapstructure:"hard_drive_interface" required:"false"` // The number of ports available on any SATA controller created, defaults // to 1. VirtualBox supports up to 30 ports on a maximum of 1 SATA diff --git a/website/source/partials/builder/virtualbox/iso/_Config-not-required.html.md b/website/source/partials/builder/virtualbox/iso/_Config-not-required.html.md index 64ff6c34c..c636ed567 100644 --- a/website/source/partials/builder/virtualbox/iso/_Config-not-required.html.md +++ b/website/source/partials/builder/virtualbox/iso/_Config-not-required.html.md @@ -48,8 +48,13 @@ 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. (Please note that when you use "pcie", you'll need to have - Virtualbox 6 and an [extension pack](https://www.virtualbox.org/wiki/Downloads#VirtualBox6.0.14OracleVMVirtualBoxExtensionPack)) + 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) + and you will need to enable EFI mode for nvme to work, ex: + "vboxmanage": [ + [ "modifyvm", "{{.Name}}", "--firmware", "EFI" ], + ] - `sata_port_count` (int) - The number of ports available on any SATA controller created, defaults to 1. VirtualBox supports up to 30 ports on a maximum of 1 SATA