diff --git a/builder/virtualbox/iso/builder.go b/builder/virtualbox/iso/builder.go index c82c435e0..0643370de 100644 --- a/builder/virtualbox/iso/builder.go +++ b/builder/virtualbox/iso/builder.go @@ -7,6 +7,7 @@ import ( "context" "errors" "fmt" + "regexp" "github.com/hashicorp/hcl/v2/hcldec" "github.com/hashicorp/packer-plugin-sdk/bootcommand" @@ -52,6 +53,14 @@ type Config struct { // When set to bios, the firmare is BIOS. This is the default. // When set to efi, the firmare is EFI. Firmware string `mapstructure:"firmware" required:"false"` + // Nested virtualization: false or true. + // When set to true, nested virtualisation (VT-x/AMD-V) is enabled. + // When set to false, nested virtualisation is disabled. This is the default. + NestedVirt bool `mapstructure:"nested_virt" required:"false"` + // RTC time base: UTC or local. + // When set to true, the RTC is set as UTC time. + // When set to false, the RTC is set as local time. This is the default. + RTCTimeBase string `mapstructure:"rtc_time_base" required:"false"` // The size, in megabytes, of the hard disk to create for the VM. By // default, this is 40000 (about 40 GB). DiskSize uint `mapstructure:"disk_size" required:"false"` @@ -75,6 +84,17 @@ type Config struct { // When set to vmsvga, the graphics controller is VMware SVGA. // When set to none, the graphics controller is disabled. GfxController string `mapstructure:"gfx_controller" required:"false"` + // The VRAM size to be used. By default, this is 4 MiB. + GfxVramSize uint `mapstructure:"gfx_vram_size" required:"false"` + // 3D acceleration: true or false. + // When set to true, 3D acceleration is enabled. + // When set to false, 3D acceleration is disabled. This is the default. + GfxAccelerate3D bool `mapstructure:"gfx_accelerate_3d" required:"false"` + // Screen resolution in EFI mode: WIDTHxHEIGHT. + // When set to WIDTHxHEIGHT, it provides the given width and height as screen resolution + // to EFI, for example 1920x1080 for Full-HD resolution. By default, no screen resolution + // is set. Note, that this option only affects EFI boot, not the (default) BIOS boot. + GfxEFIResolution string `mapstructure:"gfx_efi_resolution" required:"false"` // The guest OS type being installed. By default this is other, but you can // get dramatic performance improvements by setting this to the proper // value. To view all available values for this run VBoxManage list @@ -212,6 +232,17 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) { errs, errors.New("firmware can only be bios or efi")) } + if b.config.RTCTimeBase == "" { + b.config.RTCTimeBase = "local" + } + switch b.config.RTCTimeBase { + case "UTC", "local": + // do nothing + default: + errs = packersdk.MultiErrorAppend( + errs, errors.New("rtc_time_base can only be UTC or local")) + } + if b.config.DiskSize == 0 { b.config.DiskSize = 40000 } @@ -242,6 +273,24 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) { errs, errors.New("Graphics controller type can only be vboxvga, vboxsvga, vmsvga, none")) } + if b.config.GfxVramSize == 0 { + b.config.GfxVramSize = 4 + } else { + if b.config.GfxVramSize < 1 || b.config.GfxVramSize > 128 { + errs = packersdk.MultiErrorAppend( + errs, errors.New("VGRAM size must be from 0 (use default) to 128")) + } + } + + if b.config.GfxEFIResolution != "" { + re := regexp.MustCompile(`^[\d]+x[\d]+$`) + matched := re.MatchString(b.config.GfxEFIResolution) + if !matched { + errs = packersdk.MultiErrorAppend( + errs, errors.New("EFI resolution must be in the format WIDTHxHEIGHT, e.g. 1920x1080")) + } + } + if b.config.AudioController == "" { b.config.AudioController = "ac97" } diff --git a/builder/virtualbox/iso/builder.hcl2spec.go b/builder/virtualbox/iso/builder.hcl2spec.go index 88a880458..f453a721d 100644 --- a/builder/virtualbox/iso/builder.hcl2spec.go +++ b/builder/virtualbox/iso/builder.hcl2spec.go @@ -119,10 +119,15 @@ type FlatConfig struct { GuestAdditionsURL *string `mapstructure:"guest_additions_url" required:"false" cty:"guest_additions_url" hcl:"guest_additions_url"` Chipset *string `mapstructure:"chipset" required:"false" cty:"chipset" hcl:"chipset"` Firmware *string `mapstructure:"firmware" required:"false" cty:"firmware" hcl:"firmware"` + NestedVirt *bool `mapstructure:"nested_virt" required:"false" cty:"nested_virt" hcl:"nested_virt"` + RTCTimeBase *string `mapstructure:"rtc_time_base" required:"false" cty:"rtc_time_base" hcl:"rtc_time_base"` 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"` 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"` + GfxEFIResolution *string `mapstructure:"gfx_efi_resolution" required:"false" cty:"gfx_efi_resolution" hcl:"gfx_efi_resolution"` GuestOSType *string `mapstructure:"guest_os_type" required:"false" cty:"guest_os_type" hcl:"guest_os_type"` HardDriveDiscard *bool `mapstructure:"hard_drive_discard" required:"false" cty:"hard_drive_discard" hcl:"hard_drive_discard"` HardDriveInterface *string `mapstructure:"hard_drive_interface" required:"false" cty:"hard_drive_interface" hcl:"hard_drive_interface"` @@ -256,10 +261,15 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "guest_additions_url": &hcldec.AttrSpec{Name: "guest_additions_url", Type: cty.String, Required: false}, "chipset": &hcldec.AttrSpec{Name: "chipset", Type: cty.String, Required: false}, "firmware": &hcldec.AttrSpec{Name: "firmware", Type: cty.String, Required: false}, + "nested_virt": &hcldec.AttrSpec{Name: "nested_virt", Type: cty.Bool, Required: false}, + "rtc_time_base": &hcldec.AttrSpec{Name: "rtc_time_base", Type: cty.String, Required: false}, "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}, "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}, + "gfx_efi_resolution": &hcldec.AttrSpec{Name: "gfx_efi_resolution", Type: cty.String, Required: false}, "guest_os_type": &hcldec.AttrSpec{Name: "guest_os_type", Type: cty.String, Required: false}, "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}, diff --git a/builder/virtualbox/iso/step_create_vm.go b/builder/virtualbox/iso/step_create_vm.go index bcef33a64..645d93087 100644 --- a/builder/virtualbox/iso/step_create_vm.go +++ b/builder/virtualbox/iso/step_create_vm.go @@ -26,7 +26,7 @@ func (s *stepCreateVM) Run(ctx context.Context, state multistep.StateBag) multis name := config.VMName - commands := make([][]string, 10) + commands := make([][]string, 14) commands[0] = []string{ "createvm", "--name", name, "--ostype", config.GuestOSType, "--register", @@ -59,7 +59,26 @@ func (s *stepCreateVM) Run(ctx context.Context, state multistep.StateBag) multis "--nictype6", config.NICType, "--nictype7", config.NICType, "--nictype8", config.NICType} - commands[9] = []string{"modifyvm", name, "--graphicscontroller", config.GfxController} + commands[9] = []string{"modifyvm", name, "--graphicscontroller", config.GfxController, "--vram", strconv.FormatUint(uint64(config.GfxVramSize), 10)} + if config.RTCTimeBase == "UTC" { + commands[10] = []string{"modifyvm", name, "--rtcuseutc", "on"} + } else { + commands[10] = []string{"modifyvm", name, "--rtcuseutc", "off"} + } + if config.NestedVirt == true { + commands[11] = []string{"modifyvm", name, "--nested-hw-virt", "on"} + } else { + commands[11] = []string{"modifyvm", name, "--nested-hw-virt", "off"} + } + + if config.GfxAccelerate3D { + commands[12] = []string{"modifyvm", name, "--accelerate3d", "on"} + } else { + commands[12] = []string{"modifyvm", name, "--accelerate3d", "off"} + } + if config.GfxEFIResolution != "" { + commands[13] = []string{"setextradata", name, "VBoxInternal2/EfiGraphicsResolution", config.GfxEFIResolution} + } ui.Say("Creating virtual machine...") for _, command := range commands { 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 d77c4048c..95520e65d 100644 --- a/website/content/partials/builder/virtualbox/iso/Config-not-required.mdx +++ b/website/content/partials/builder/virtualbox/iso/Config-not-required.mdx @@ -8,6 +8,14 @@ When set to bios, the firmare is BIOS. This is the default. When set to efi, the firmare is EFI. +- `nested_virt` (bool) - Nested virtualization: false or true. + When set to true, nested virtualisation (VT-x/AMD-V) is enabled. + When set to false, nested virtualisation is disabled. This is the default. + +- `rtc_time_base` (string) - RTC time base: UTC or local. + When set to true, the RTC is set as UTC time. + When set to false, the RTC is set as local time. This is the default. + - `disk_size` (uint) - The size, in megabytes, of the hard disk to create for the VM. By default, this is 40000 (about 40 GB). @@ -31,6 +39,17 @@ When set to vmsvga, the graphics controller is VMware SVGA. When set to none, the graphics controller is disabled. +- `gfx_vram_size` (uint) - The VRAM size to be used. By default, this is 4 MiB. + +- `gfx_accelerate_3d` (bool) - 3D acceleration: true or false. + When set to true, 3D acceleration is enabled. + When set to false, 3D acceleration is disabled. This is the default. + +- `gfx_efi_resolution` (string) - Screen resolution in EFI mode: WIDTHxHEIGHT. + When set to WIDTHxHEIGHT, it provides the given width and height as screen resolution + to EFI, for example 1920x1080 for Full-HD resolution. By default, no screen resolution + is set. Note, that this option only affects EFI boot, not the (default) BIOS boot. + - `guest_os_type` (string) - The guest OS type being installed. By default this is other, but you can get dramatic performance improvements by setting this to the proper value. To view all available values for this run VBoxManage list