diff --git a/builder/virtualbox/common/guest_additions_config.go b/builder/virtualbox/common/guest_additions_config.go index e0f015dba..5b57c154c 100644 --- a/builder/virtualbox/common/guest_additions_config.go +++ b/builder/virtualbox/common/guest_additions_config.go @@ -4,6 +4,7 @@ package common import ( "fmt" + "strings" "github.com/hashicorp/packer/template/interpolate" ) @@ -19,13 +20,36 @@ const ( type GuestAdditionsConfig struct { Communicator string `mapstructure:"communicator"` // The method by which guest additions are - // made available to the guest for installation. Valid options are upload, - // attach, or disable. If the mode is attach the guest additions ISO will - // be attached as a CD device to the virtual machine. If the mode is upload + // made available to the guest for installation. Valid options are `upload`, + // `attach`, or `disable`. If the mode is `attach` the guest additions ISO will + // be attached as a CD device to the virtual machine. If the mode is `upload` // the guest additions ISO will be uploaded to the path specified by - // guest_additions_path. The default value is upload. If disable is used, + // `guest_additions_path`. The default value is `upload`. If `disable` is used, // guest additions won't be downloaded, either. - GuestAdditionsMode string `mapstructure:"guest_additions_mode" required:"false"` + GuestAdditionsMode string `mapstructure:"guest_additions_mode"` + // The interface type to use to mount guest additions when + // guest_additions_mode is set to attach. Will default to the value set in + // iso_interface, if iso_interface is set. Will default to "ide", if + // iso_interface is not set. Options are "ide" and "sata". + GuestAdditionsInterface string `mapstructure:"guest_additions_interface" required:"false"` + // The path on the guest virtual machine + // where the VirtualBox guest additions ISO will be uploaded. By default this + // is `VBoxGuestAdditions.iso` which should upload into the login directory of + // the user. This is a [configuration + // template](/docs/templates/engine) where the `Version` + // variable is replaced with the VirtualBox version. + GuestAdditionsPath string `mapstructure:"guest_additions_path"` + // The SHA256 checksum of the guest + // additions ISO that will be uploaded to the guest VM. By default the + // checksums will be downloaded from the VirtualBox website, so this only needs + // to be set if you want to be explicit about the checksum. + GuestAdditionsSHA256 string `mapstructure:"guest_additions_sha256"` + // The URL of the guest additions ISO + // to upload. This can also be a file URL if the ISO is at a local path. By + // default, the VirtualBox builder will attempt to find the guest additions ISO + // on the local file system. If it is not available locally, the builder will + // download the proper guest additions ISO from the internet. + GuestAdditionsURL string `mapstructure:"guest_additions_url" required:"false"` } func (c *GuestAdditionsConfig) Prepare(ctx *interpolate.Context) []error { @@ -36,5 +60,36 @@ func (c *GuestAdditionsConfig) Prepare(ctx *interpolate.Context) []error { "'disable' when communicator = 'none'.")) } + if c.GuestAdditionsMode == "" { + c.GuestAdditionsMode = "upload" + } + + if c.GuestAdditionsPath == "" { + c.GuestAdditionsPath = "VBoxGuestAdditions.iso" + } + + if c.GuestAdditionsSHA256 != "" { + c.GuestAdditionsSHA256 = strings.ToLower(c.GuestAdditionsSHA256) + } + + validMode := false + validModes := []string{ + GuestAdditionsModeDisable, + GuestAdditionsModeAttach, + GuestAdditionsModeUpload, + } + + for _, mode := range validModes { + if c.GuestAdditionsMode == mode { + validMode = true + break + } + } + + if !validMode { + errs = append(errs, + fmt.Errorf("guest_additions_mode is invalid. Must be one of: %v", validModes)) + } + return errs } diff --git a/builder/virtualbox/common/step_attach_guest_additions.go b/builder/virtualbox/common/step_attach_guest_additions.go deleted file mode 100644 index 484b074c2..000000000 --- a/builder/virtualbox/common/step_attach_guest_additions.go +++ /dev/null @@ -1,105 +0,0 @@ -package common - -import ( - "context" - "fmt" - "log" - - "github.com/hashicorp/packer/helper/multistep" - "github.com/hashicorp/packer/packer" -) - -// This step attaches the VirtualBox guest additions as a inserted CD onto -// the virtual machine. -// -// Uses: -// config *config -// driver Driver -// guest_additions_path string -// ui packer.Ui -// vmName string -// -// Produces: -type StepAttachGuestAdditions struct { - attachedPath string - GuestAdditionsMode string - GuestAdditionsInterface string -} - -func (s *StepAttachGuestAdditions) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { - driver := state.Get("driver").(Driver) - ui := state.Get("ui").(packer.Ui) - vmName := state.Get("vmName").(string) - - // If we're not attaching the guest additions then just return - if s.GuestAdditionsMode != GuestAdditionsModeAttach { - log.Println("Not attaching guest additions since we're uploading.") - return multistep.ActionContinue - } - - // Get the guest additions path since we're doing it - guestAdditionsPath := state.Get("guest_additions_path").(string) - - // Attach the guest additions to the computer - - controllerName := "IDE Controller" - port := "1" - device := "0" - if s.GuestAdditionsInterface == "sata" { - controllerName = "SATA Controller" - port = "2" - device = "0" - } - - log.Println("Attaching guest additions ISO onto IDE controller...") - command := []string{ - "storageattach", vmName, - "--storagectl", controllerName, - "--port", port, - "--device", device, - "--type", "dvddrive", - "--medium", guestAdditionsPath, - } - if err := driver.VBoxManage(command...); err != nil { - err := fmt.Errorf("Error attaching guest additions: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } - - // Track the path so that we can unregister it from VirtualBox later - s.attachedPath = guestAdditionsPath - state.Put("guest_additions_attached", true) - - return multistep.ActionContinue -} - -func (s *StepAttachGuestAdditions) Cleanup(state multistep.StateBag) { - if s.attachedPath == "" { - return - } - - driver := state.Get("driver").(Driver) - vmName := state.Get("vmName").(string) - - controllerName := "IDE Controller" - port := "1" - device := "0" - if s.GuestAdditionsInterface == "sata" { - controllerName = "SATA Controller" - port = "2" - device = "0" - } - - command := []string{ - "storageattach", vmName, - "--storagectl", controllerName, - "--port", port, - "--device", device, - "--medium", "none", - } - - // Remove the ISO. Note that this will probably fail since - // stepRemoveDevices does this as well. No big deal. - driver.VBoxManage(command...) -} diff --git a/builder/virtualbox/common/step_attach_isos.go b/builder/virtualbox/common/step_attach_isos.go new file mode 100644 index 000000000..b381b3657 --- /dev/null +++ b/builder/virtualbox/common/step_attach_isos.go @@ -0,0 +1,158 @@ +package common + +import ( + "context" + "fmt" + "log" + "path/filepath" + + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" +) + +// This step attaches the boot ISO, cd_files iso, and guest additions to the +// virtual machine, if present. +type StepAttachISOs struct { + AttachBootIso bool + ISOInterface string + GuestAdditionsMode string + GuestAdditionsInterface string + diskUnmountCommands map[string][]string +} + +func (s *StepAttachISOs) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { + // Check whether there is anything to attach + ui := state.Get("ui").(packer.Ui) + + ui.Say("Mounting ISOs...") + diskMountMap := map[string]string{} + s.diskUnmountCommands = map[string][]string{} + // Track the bootable iso (only used in virtualbox-iso builder. ) + if s.AttachBootIso { + isoPath := state.Get("iso_path").(string) + diskMountMap["boot_iso"] = isoPath + } + + // Determine if we even have a cd_files disk to attach + if cdPathRaw, ok := state.GetOk("cd_path"); ok { + cdFilesPath := cdPathRaw.(string) + diskMountMap["cd_files"] = cdFilesPath + } + + // Determine if we have guest additions to attach + if s.GuestAdditionsMode != GuestAdditionsModeAttach { + log.Println("Not attaching guest additions since we're uploading.") + } else { + // Get the guest additions path since we're doing it + guestAdditionsPath := state.Get("guest_additions_path").(string) + diskMountMap["guest_additions"] = guestAdditionsPath + } + + if len(diskMountMap) == 0 { + ui.Message("No ISOs to mount; continuing...") + return multistep.ActionContinue + } + + driver := state.Get("driver").(Driver) + vmName := state.Get("vmName").(string) + + for diskCategory, isoPath := range diskMountMap { + // If it's a symlink, resolve it to its target. + resolvedIsoPath, err := filepath.EvalSymlinks(isoPath) + if err != nil { + err := fmt.Errorf("Error resolving symlink for ISO: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + isoPath = resolvedIsoPath + + // We have three different potential isos we can attach, so let's + // assign each one its own spot so they don't conflict. + var controllerName, device, port string + switch diskCategory { + case "boot_iso": + // figure out controller path + controllerName = "IDE Controller" + port = "0" + device = "1" + if s.ISOInterface == "sata" { + controllerName = "SATA Controller" + port = "1" + device = "0" + } + ui.Message("Mounting boot ISO...") + case "guest_additions": + controllerName = "IDE Controller" + port = "1" + device = "0" + if s.GuestAdditionsInterface == "sata" { + controllerName = "SATA Controller" + port = "2" + device = "0" + } + ui.Message("Mounting guest additions ISO...") + case "cd_files": + controllerName = "IDE Controller" + port = "1" + device = "1" + if s.ISOInterface == "sata" { + controllerName = "SATA Controller" + port = "3" + device = "0" + } + ui.Message("Mounting cd_files ISO...") + } + + // Attach the disk to the controller + command := []string{ + "storageattach", vmName, + "--storagectl", controllerName, + "--port", port, + "--device", device, + "--type", "dvddrive", + "--medium", isoPath, + } + if err := driver.VBoxManage(command...); err != nil { + err := fmt.Errorf("Error attaching ISO: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + // Track the disks we've mounted so we can remove them without having + // to re-derive what was mounted where + unmountCommand := []string{ + "storageattach", vmName, + "--storagectl", controllerName, + "--port", port, + "--device", device, + "--type", "dvddrive", + "--medium", "none", + } + + s.diskUnmountCommands[diskCategory] = unmountCommand + } + + state.Put("disk_unmount_commands", s.diskUnmountCommands) + + return multistep.ActionContinue +} + +func (s *StepAttachISOs) Cleanup(state multistep.StateBag) { + if len(s.diskUnmountCommands) == 0 { + return + } + + driver := state.Get("driver").(Driver) + + for _, command := range s.diskUnmountCommands { + // Remove the ISO. Note that this will probably fail since + // stepRemoveDevices does this as well. No big deal. + err := driver.VBoxManage(command...) + if err != nil { + log.Printf("error detaching iso; probably was already detached " + + "in step_remove_devices") + } + } +} diff --git a/builder/virtualbox/common/step_remove_devices.go b/builder/virtualbox/common/step_remove_devices.go index de6b70853..9c9ace57e 100644 --- a/builder/virtualbox/common/step_remove_devices.go +++ b/builder/virtualbox/common/step_remove_devices.go @@ -21,8 +21,7 @@ import ( // // Produces: type StepRemoveDevices struct { - Bundling VBoxBundleConfig - GuestAdditionsInterface string + Bundling VBoxBundleConfig } func (s *StepRemoveDevices) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { @@ -73,53 +72,23 @@ func (s *StepRemoveDevices) Run(ctx context.Context, state multistep.StateBag) m } } - if !s.Bundling.BundleISO { - if _, ok := state.GetOk("attachedIso"); ok { - controllerName := "IDE Controller" - port := "0" - device := "1" - if _, ok := state.GetOk("attachedIsoOnSata"); ok { - controllerName = "SATA Controller" - port = "1" - device = "0" - } - - command := []string{ - "storageattach", vmName, - "--storagectl", controllerName, - "--port", port, - "--device", device, - "--medium", "none", - } - - if err := driver.VBoxManage(command...); err != nil { - err := fmt.Errorf("Error detaching ISO: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } - } + var isoUnmountCommands map[string][]string + isoUnmountCommandsRaw, ok := state.GetOk("disk_unmount_commands") + if !ok { + // No disks to unmount + return multistep.ActionContinue + } else { + isoUnmountCommands = isoUnmountCommandsRaw.(map[string][]string) } - if _, ok := state.GetOk("guest_additions_attached"); ok { - ui.Message("Removing guest additions drive...") - controllerName := "IDE Controller" - port := "1" - device := "0" - if s.GuestAdditionsInterface == "sata" { - controllerName = "SATA Controller" - port = "2" - device = "0" + for diskCategory, unmountCommand := range isoUnmountCommands { + if diskCategory == "boot_iso" && s.Bundling.BundleISO { + // skip the unmount if user wants to bundle the iso + continue } - command := []string{ - "storageattach", vmName, - "--storagectl", controllerName, - "--port", port, - "--device", device, - "--medium", "none", - } - if err := driver.VBoxManage(command...); err != nil { - err := fmt.Errorf("Error removing guest additions: %s", err) + + if err := driver.VBoxManage(unmountCommand...); err != nil { + err := fmt.Errorf("Error detaching ISO: %s", err) state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt diff --git a/builder/virtualbox/common/step_remove_devices_test.go b/builder/virtualbox/common/step_remove_devices_test.go index 0a548bbd2..d28de98c4 100644 --- a/builder/virtualbox/common/step_remove_devices_test.go +++ b/builder/virtualbox/common/step_remove_devices_test.go @@ -37,7 +37,17 @@ func TestStepRemoveDevices_attachedIso(t *testing.T) { state := testState(t) step := new(StepRemoveDevices) - state.Put("attachedIso", true) + diskUnmountCommands := map[string][]string{ + "boot_iso": []string{ + "storageattach", "myvm", + "--storagectl", "IDE Controller", + "--port", "0", + "--device", "1", + "--type", "dvddrive", + "--medium", "none", + }, + } + state.Put("disk_unmount_commands", diskUnmountCommands) state.Put("vmName", "foo") driver := state.Get("driver").(*DriverMock) @@ -63,8 +73,17 @@ func TestStepRemoveDevices_attachedIsoOnSata(t *testing.T) { state := testState(t) step := new(StepRemoveDevices) - state.Put("attachedIso", true) - state.Put("attachedIsoOnSata", true) + diskUnmountCommands := map[string][]string{ + "boot_iso": []string{ + "storageattach", "myvm", + "--storagectl", "SATA Controller", + "--port", "0", + "--device", "1", + "--type", "dvddrive", + "--medium", "none", + }, + } + state.Put("disk_unmount_commands", diskUnmountCommands) state.Put("vmName", "foo") driver := state.Get("driver").(*DriverMock) diff --git a/builder/virtualbox/iso/builder.go b/builder/virtualbox/iso/builder.go index cc7c74e14..6d753c433 100644 --- a/builder/virtualbox/iso/builder.go +++ b/builder/virtualbox/iso/builder.go @@ -7,7 +7,6 @@ import ( "context" "errors" "fmt" - "strings" "github.com/hashicorp/hcl/v2/hcldec" vboxcommon "github.com/hashicorp/packer/builder/virtualbox/common" @@ -32,6 +31,7 @@ type Config struct { common.HTTPConfig `mapstructure:",squash"` common.ISOConfig `mapstructure:",squash"` common.FloppyConfig `mapstructure:",squash"` + common.CDConfig `mapstructure:",squash"` bootcommand.BootConfig `mapstructure:",squash"` vboxcommon.ExportConfig `mapstructure:",squash"` vboxcommon.OutputConfig `mapstructure:",squash"` @@ -46,29 +46,6 @@ type Config struct { // 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"` - // The path on the guest virtual machine where the VirtualBox guest - // additions ISO will be uploaded. By default this is - // VBoxGuestAdditions.iso which should upload into the login directory of - // the user. This is a configuration template where the `{{ .Version }}` - // variable is replaced with the VirtualBox version. - GuestAdditionsPath string `mapstructure:"guest_additions_path" required:"false"` - // The SHA256 checksum of the guest additions ISO that will be uploaded to - // the guest VM. By default the checksums will be downloaded from the - // VirtualBox website, so this only needs to be set if you want to be - // explicit about the checksum. - GuestAdditionsSHA256 string `mapstructure:"guest_additions_sha256" required:"false"` - // The URL to the guest additions ISO to upload. This can also be a file - // URL if the ISO is at a local path. By default, the VirtualBox builder - // will attempt to find the guest additions ISO on the local file system. - // If it is not available locally, the builder will download the proper - // guest additions ISO from the internet. This is a template engine, and you - // have access to the variable `{{ .Version }}`. - GuestAdditionsURL string `mapstructure:"guest_additions_url" required:"false"` - // The interface type to use to mount guest additions when - // guest_additions_mode is set to attach. Will default to the value set in - // iso_interface, if iso_interface is set. Will default to "ide", if - // iso_interface is not set. Options are "ide" and "sata". - GuestAdditionsInterface string `mapstructure:"guest_additions_interface" 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 @@ -167,6 +144,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) { errs = packer.MultiErrorAppend(errs, b.config.ExportConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.ExportConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.FloppyConfig.Prepare(&b.config.ctx)...) + errs = packer.MultiErrorAppend(errs, b.config.CDConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend( errs, b.config.OutputConfig.Prepare(&b.config.ctx, &b.config.PackerConfig)...) errs = packer.MultiErrorAppend(errs, b.config.HTTPConfig.Prepare(&b.config.ctx)...) @@ -184,14 +162,6 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) { b.config.DiskSize = 40000 } - if b.config.GuestAdditionsMode == "" { - b.config.GuestAdditionsMode = "upload" - } - - if b.config.GuestAdditionsPath == "" { - b.config.GuestAdditionsPath = "VBoxGuestAdditions.iso" - } - if b.config.HardDriveInterface == "" { b.config.HardDriveInterface = "ide" } @@ -244,29 +214,6 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) { errs, errors.New("iso_interface can only be ide or sata")) } - validMode := false - validModes := []string{ - vboxcommon.GuestAdditionsModeDisable, - vboxcommon.GuestAdditionsModeAttach, - vboxcommon.GuestAdditionsModeUpload, - } - - for _, mode := range validModes { - if b.config.GuestAdditionsMode == mode { - validMode = true - break - } - } - - if !validMode { - errs = packer.MultiErrorAppend(errs, - fmt.Errorf("guest_additions_mode is invalid. Must be one of: %v", validModes)) - } - - if b.config.GuestAdditionsSHA256 != "" { - b.config.GuestAdditionsSHA256 = strings.ToLower(b.config.GuestAdditionsSHA256) - } - // Warnings if b.config.ShutdownCommand == "" { warnings = append(warnings, @@ -312,6 +259,10 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack Directories: b.config.FloppyConfig.FloppyDirectories, Label: b.config.FloppyConfig.FloppyLabel, }, + &common.StepCreateCD{ + Files: b.config.CDConfig.CDFiles, + Label: b.config.CDConfig.CDLabel, + }, new(vboxcommon.StepHTTPIPDiscover), &common.StepHTTPServer{ HTTPDir: b.config.HTTPDir, @@ -327,8 +278,9 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack new(vboxcommon.StepSuppressMessages), new(stepCreateVM), new(stepCreateDisk), - new(stepAttachISO), - &vboxcommon.StepAttachGuestAdditions{ + &vboxcommon.StepAttachISOs{ + AttachBootIso: true, + ISOInterface: b.config.ISOInterface, GuestAdditionsMode: b.config.GuestAdditionsMode, GuestAdditionsInterface: b.config.GuestAdditionsInterface, }, @@ -386,8 +338,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack ACPIShutdown: b.config.ACPIShutdown, }, &vboxcommon.StepRemoveDevices{ - Bundling: b.config.VBoxBundleConfig, - GuestAdditionsInterface: b.config.GuestAdditionsInterface, + Bundling: b.config.VBoxBundleConfig, }, &vboxcommon.StepVBoxManage{ Commands: b.config.VBoxManagePost, diff --git a/builder/virtualbox/iso/builder.hcl2spec.go b/builder/virtualbox/iso/builder.hcl2spec.go index ecad9a9f1..c67e1fd66 100644 --- a/builder/virtualbox/iso/builder.hcl2spec.go +++ b/builder/virtualbox/iso/builder.hcl2spec.go @@ -28,6 +28,8 @@ type FlatConfig struct { FloppyFiles []string `mapstructure:"floppy_files" cty:"floppy_files" hcl:"floppy_files"` FloppyDirectories []string `mapstructure:"floppy_dirs" cty:"floppy_dirs" hcl:"floppy_dirs"` FloppyLabel *string `mapstructure:"floppy_label" cty:"floppy_label" hcl:"floppy_label"` + CDFiles []string `mapstructure:"cd_files" cty:"cd_files" hcl:"cd_files"` + CDLabel *string `mapstructure:"cd_label" cty:"cd_label" hcl:"cd_label"` BootGroupInterval *string `mapstructure:"boot_keygroup_interval" cty:"boot_keygroup_interval" hcl:"boot_keygroup_interval"` BootWait *string `mapstructure:"boot_wait" cty:"boot_wait" hcl:"boot_wait"` BootCommand []string `mapstructure:"boot_command" cty:"boot_command" hcl:"boot_command"` @@ -105,12 +107,12 @@ type FlatConfig struct { VBoxManagePost [][]string `mapstructure:"vboxmanage_post" required:"false" cty:"vboxmanage_post" hcl:"vboxmanage_post"` VBoxVersionFile *string `mapstructure:"virtualbox_version_file" required:"false" cty:"virtualbox_version_file" hcl:"virtualbox_version_file"` BundleISO *bool `mapstructure:"bundle_iso" required:"false" cty:"bundle_iso" hcl:"bundle_iso"` - GuestAdditionsMode *string `mapstructure:"guest_additions_mode" required:"false" cty:"guest_additions_mode" hcl:"guest_additions_mode"` - DiskSize *uint `mapstructure:"disk_size" required:"false" cty:"disk_size" hcl:"disk_size"` - GuestAdditionsPath *string `mapstructure:"guest_additions_path" required:"false" cty:"guest_additions_path" hcl:"guest_additions_path"` - GuestAdditionsSHA256 *string `mapstructure:"guest_additions_sha256" required:"false" cty:"guest_additions_sha256" hcl:"guest_additions_sha256"` - GuestAdditionsURL *string `mapstructure:"guest_additions_url" required:"false" cty:"guest_additions_url" hcl:"guest_additions_url"` + GuestAdditionsMode *string `mapstructure:"guest_additions_mode" cty:"guest_additions_mode" hcl:"guest_additions_mode"` GuestAdditionsInterface *string `mapstructure:"guest_additions_interface" required:"false" cty:"guest_additions_interface" hcl:"guest_additions_interface"` + GuestAdditionsPath *string `mapstructure:"guest_additions_path" cty:"guest_additions_path" hcl:"guest_additions_path"` + GuestAdditionsSHA256 *string `mapstructure:"guest_additions_sha256" cty:"guest_additions_sha256" hcl:"guest_additions_sha256"` + GuestAdditionsURL *string `mapstructure:"guest_additions_url" required:"false" cty:"guest_additions_url" hcl:"guest_additions_url"` + DiskSize *uint `mapstructure:"disk_size" required:"false" cty:"disk_size" hcl:"disk_size"` 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"` @@ -154,6 +156,8 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "floppy_files": &hcldec.AttrSpec{Name: "floppy_files", Type: cty.List(cty.String), Required: false}, "floppy_dirs": &hcldec.AttrSpec{Name: "floppy_dirs", Type: cty.List(cty.String), Required: false}, "floppy_label": &hcldec.AttrSpec{Name: "floppy_label", Type: cty.String, Required: false}, + "cd_files": &hcldec.AttrSpec{Name: "cd_files", Type: cty.List(cty.String), Required: false}, + "cd_label": &hcldec.AttrSpec{Name: "cd_label", Type: cty.String, Required: false}, "boot_keygroup_interval": &hcldec.AttrSpec{Name: "boot_keygroup_interval", Type: cty.String, Required: false}, "boot_wait": &hcldec.AttrSpec{Name: "boot_wait", Type: cty.String, Required: false}, "boot_command": &hcldec.AttrSpec{Name: "boot_command", Type: cty.List(cty.String), Required: false}, @@ -232,11 +236,11 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "virtualbox_version_file": &hcldec.AttrSpec{Name: "virtualbox_version_file", Type: cty.String, Required: false}, "bundle_iso": &hcldec.AttrSpec{Name: "bundle_iso", Type: cty.Bool, Required: false}, "guest_additions_mode": &hcldec.AttrSpec{Name: "guest_additions_mode", Type: cty.String, Required: false}, - "disk_size": &hcldec.AttrSpec{Name: "disk_size", Type: cty.Number, Required: false}, + "guest_additions_interface": &hcldec.AttrSpec{Name: "guest_additions_interface", Type: cty.String, Required: false}, "guest_additions_path": &hcldec.AttrSpec{Name: "guest_additions_path", Type: cty.String, Required: false}, "guest_additions_sha256": &hcldec.AttrSpec{Name: "guest_additions_sha256", Type: cty.String, Required: false}, "guest_additions_url": &hcldec.AttrSpec{Name: "guest_additions_url", Type: cty.String, Required: false}, - "guest_additions_interface": &hcldec.AttrSpec{Name: "guest_additions_interface", Type: cty.String, Required: false}, + "disk_size": &hcldec.AttrSpec{Name: "disk_size", Type: cty.Number, 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_attach_iso.go b/builder/virtualbox/iso/step_attach_iso.go deleted file mode 100644 index 0c36f8e92..000000000 --- a/builder/virtualbox/iso/step_attach_iso.go +++ /dev/null @@ -1,105 +0,0 @@ -package iso - -import ( - "context" - "fmt" - "path/filepath" - - vboxcommon "github.com/hashicorp/packer/builder/virtualbox/common" - "github.com/hashicorp/packer/helper/multistep" - "github.com/hashicorp/packer/packer" -) - -// This step attaches the ISO to the virtual machine. -// -// Uses: -// -// Produces: -type stepAttachISO struct { - diskPath string -} - -func (s *stepAttachISO) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { - config := state.Get("config").(*Config) - driver := state.Get("driver").(vboxcommon.Driver) - isoPath := state.Get("iso_path").(string) - ui := state.Get("ui").(packer.Ui) - vmName := state.Get("vmName").(string) - - controllerName := "IDE Controller" - port := "0" - device := "1" - if config.ISOInterface == "sata" { - controllerName = "SATA Controller" - port = "1" - device = "0" - } - - // If it's a symlink, resolve it to it's target. - resolvedIsoPath, err := filepath.EvalSymlinks(isoPath) - if err != nil { - err := fmt.Errorf("Error resolving symlink for ISO: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } - isoPath = resolvedIsoPath - - // Attach the disk to the controller - command := []string{ - "storageattach", vmName, - "--storagectl", controllerName, - "--port", port, - "--device", device, - "--type", "dvddrive", - "--medium", isoPath, - } - if err := driver.VBoxManage(command...); err != nil { - err := fmt.Errorf("Error attaching ISO: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } - - // Track the path so that we can unregister it from VirtualBox later - s.diskPath = isoPath - - // Set some state so we know to remove - state.Put("attachedIso", true) - if controllerName == "SATA Controller" { - state.Put("attachedIsoOnSata", true) - } - - return multistep.ActionContinue -} - -func (s *stepAttachISO) Cleanup(state multistep.StateBag) { - if s.diskPath == "" { - return - } - - config := state.Get("config").(*Config) - driver := state.Get("driver").(vboxcommon.Driver) - vmName := state.Get("vmName").(string) - - controllerName := "IDE Controller" - port := "0" - device := "1" - if config.ISOInterface == "sata" { - controllerName = "SATA Controller" - port = "1" - device = "0" - } - - command := []string{ - "storageattach", vmName, - "--storagectl", controllerName, - "--port", port, - "--device", device, - "--medium", "none", - } - - // Remove the ISO. Note that this will probably fail since - // stepRemoveDevices does this as well. No big deal. - driver.VBoxManage(command...) -} diff --git a/builder/virtualbox/ovf/builder.go b/builder/virtualbox/ovf/builder.go index 64485c3bb..df75fa1d6 100644 --- a/builder/virtualbox/ovf/builder.go +++ b/builder/virtualbox/ovf/builder.go @@ -60,6 +60,10 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack Directories: b.config.FloppyConfig.FloppyDirectories, Label: b.config.FloppyConfig.FloppyLabel, }, + &common.StepCreateCD{ + Files: b.config.CDConfig.CDFiles, + Label: b.config.CDConfig.CDLabel, + }, new(vboxcommon.StepHTTPIPDiscover), &common.StepHTTPServer{ HTTPDir: b.config.HTTPDir, @@ -91,7 +95,9 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack ImportFlags: b.config.ImportFlags, KeepRegistered: b.config.KeepRegistered, }, - &vboxcommon.StepAttachGuestAdditions{ + &vboxcommon.StepAttachISOs{ + AttachBootIso: false, + ISOInterface: b.config.GuestAdditionsInterface, GuestAdditionsMode: b.config.GuestAdditionsMode, GuestAdditionsInterface: b.config.GuestAdditionsInterface, }, @@ -148,9 +154,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack DisableShutdown: b.config.DisableShutdown, ACPIShutdown: b.config.ACPIShutdown, }, - &vboxcommon.StepRemoveDevices{ - GuestAdditionsInterface: b.config.GuestAdditionsInterface, - }, + &vboxcommon.StepRemoveDevices{}, &vboxcommon.StepVBoxManage{ Commands: b.config.VBoxManagePost, Ctx: b.config.ctx, diff --git a/builder/virtualbox/ovf/config.go b/builder/virtualbox/ovf/config.go index df9f69cce..40e47ad56 100644 --- a/builder/virtualbox/ovf/config.go +++ b/builder/virtualbox/ovf/config.go @@ -5,7 +5,6 @@ package ovf import ( "fmt" - "strings" vboxcommon "github.com/hashicorp/packer/builder/virtualbox/common" "github.com/hashicorp/packer/common" @@ -20,6 +19,7 @@ type Config struct { common.PackerConfig `mapstructure:",squash"` common.HTTPConfig `mapstructure:",squash"` common.FloppyConfig `mapstructure:",squash"` + common.CDConfig `mapstructure:",squash"` bootcommand.BootConfig `mapstructure:",squash"` vboxcommon.ExportConfig `mapstructure:",squash"` vboxcommon.OutputConfig `mapstructure:",squash"` @@ -50,38 +50,6 @@ type Config struct { // this is not recommended since these files can be very large and // corruption does happen from time to time. Checksum string `mapstructure:"checksum" required:"true"` - // The method by which guest additions are - // made available to the guest for installation. Valid options are upload, - // attach, or disable. If the mode is attach the guest additions ISO will - // be attached as a CD device to the virtual machine. If the mode is upload - // the guest additions ISO will be uploaded to the path specified by - // guest_additions_path. The default value is upload. If disable is used, - // guest additions won't be downloaded, either. - GuestAdditionsMode string `mapstructure:"guest_additions_mode" required:"false"` - // The path on the guest virtual machine - // where the VirtualBox guest additions ISO will be uploaded. By default this - // is VBoxGuestAdditions.iso which should upload into the login directory of - // the user. This is a configuration - // template where the Version - // variable is replaced with the VirtualBox version. - GuestAdditionsPath string `mapstructure:"guest_additions_path" required:"false"` - // The interface type to use to mount - // guest additions when guest_additions_mode is set to attach. Will - // default to the value set in iso_interface, if iso_interface is set. - // Will default to "ide", if iso_interface is not set. Options are "ide" and - // "sata". - GuestAdditionsInterface string `mapstructure:"guest_additions_interface" required:"false"` - // The SHA256 checksum of the guest - // additions ISO that will be uploaded to the guest VM. By default the - // checksums will be downloaded from the VirtualBox website, so this only needs - // to be set if you want to be explicit about the checksum. - GuestAdditionsSHA256 string `mapstructure:"guest_additions_sha256" required:"false"` - // The URL to the guest additions ISO - // to upload. This can also be a file URL if the ISO is at a local path. By - // default, the VirtualBox builder will attempt to find the guest additions ISO - // on the local file system. If it is not available locally, the builder will - // download the proper guest additions ISO from the internet. - GuestAdditionsURL string `mapstructure:"guest_additions_url" required:"false"` // Additional flags to pass to // VBoxManage import. This can be used to add additional command-line flags // such as --eula-accept to accept a EULA in the OVF. @@ -131,17 +99,6 @@ func (c *Config) Prepare(raws ...interface{}) ([]string, error) { } // Defaults - if c.GuestAdditionsMode == "" { - c.GuestAdditionsMode = "upload" - } - - if c.GuestAdditionsPath == "" { - c.GuestAdditionsPath = "VBoxGuestAdditions.iso" - } - if c.GuestAdditionsInterface == "" { - c.GuestAdditionsInterface = "ide" - } - if c.VMName == "" { c.VMName = fmt.Sprintf( "packer-%s-%d", c.PackerBuildName, interpolate.InitTime.Unix()) @@ -152,6 +109,7 @@ func (c *Config) Prepare(raws ...interface{}) ([]string, error) { errs = packer.MultiErrorAppend(errs, c.ExportConfig.Prepare(&c.ctx)...) errs = packer.MultiErrorAppend(errs, c.ExportConfig.Prepare(&c.ctx)...) errs = packer.MultiErrorAppend(errs, c.FloppyConfig.Prepare(&c.ctx)...) + errs = packer.MultiErrorAppend(errs, c.CDConfig.Prepare(&c.ctx)...) errs = packer.MultiErrorAppend(errs, c.HTTPConfig.Prepare(&c.ctx)...) errs = packer.MultiErrorAppend(errs, c.OutputConfig.Prepare(&c.ctx, &c.PackerConfig)...) errs = packer.MultiErrorAppend(errs, c.RunConfig.Prepare(&c.ctx)...) @@ -166,27 +124,8 @@ func (c *Config) Prepare(raws ...interface{}) ([]string, error) { errs = packer.MultiErrorAppend(errs, fmt.Errorf("source_path is required")) } - validMode := false - validModes := []string{ - vboxcommon.GuestAdditionsModeDisable, - vboxcommon.GuestAdditionsModeAttach, - vboxcommon.GuestAdditionsModeUpload, - } - - for _, mode := range validModes { - if c.GuestAdditionsMode == mode { - validMode = true - break - } - } - - if !validMode { - errs = packer.MultiErrorAppend(errs, - fmt.Errorf("guest_additions_mode is invalid. Must be one of: %v", validModes)) - } - - if c.GuestAdditionsSHA256 != "" { - c.GuestAdditionsSHA256 = strings.ToLower(c.GuestAdditionsSHA256) + if c.GuestAdditionsInterface == "" { + c.GuestAdditionsInterface = "ide" } // Warnings diff --git a/builder/virtualbox/ovf/config.hcl2spec.go b/builder/virtualbox/ovf/config.hcl2spec.go index 6a9f7862d..f66a9cb1c 100644 --- a/builder/virtualbox/ovf/config.hcl2spec.go +++ b/builder/virtualbox/ovf/config.hcl2spec.go @@ -23,6 +23,8 @@ type FlatConfig struct { FloppyFiles []string `mapstructure:"floppy_files" cty:"floppy_files" hcl:"floppy_files"` FloppyDirectories []string `mapstructure:"floppy_dirs" cty:"floppy_dirs" hcl:"floppy_dirs"` FloppyLabel *string `mapstructure:"floppy_label" cty:"floppy_label" hcl:"floppy_label"` + CDFiles []string `mapstructure:"cd_files" cty:"cd_files" hcl:"cd_files"` + CDLabel *string `mapstructure:"cd_label" cty:"cd_label" hcl:"cd_label"` BootGroupInterval *string `mapstructure:"boot_keygroup_interval" cty:"boot_keygroup_interval" hcl:"boot_keygroup_interval"` BootWait *string `mapstructure:"boot_wait" cty:"boot_wait" hcl:"boot_wait"` BootCommand []string `mapstructure:"boot_command" cty:"boot_command" hcl:"boot_command"` @@ -95,12 +97,12 @@ type FlatConfig struct { VBoxManage [][]string `mapstructure:"vboxmanage" required:"false" cty:"vboxmanage" hcl:"vboxmanage"` VBoxManagePost [][]string `mapstructure:"vboxmanage_post" required:"false" cty:"vboxmanage_post" hcl:"vboxmanage_post"` VBoxVersionFile *string `mapstructure:"virtualbox_version_file" required:"false" cty:"virtualbox_version_file" hcl:"virtualbox_version_file"` - GuestAdditionsMode *string `mapstructure:"guest_additions_mode" required:"false" cty:"guest_additions_mode" hcl:"guest_additions_mode"` - Checksum *string `mapstructure:"checksum" required:"true" cty:"checksum" hcl:"checksum"` - GuestAdditionsPath *string `mapstructure:"guest_additions_path" required:"false" cty:"guest_additions_path" hcl:"guest_additions_path"` + GuestAdditionsMode *string `mapstructure:"guest_additions_mode" cty:"guest_additions_mode" hcl:"guest_additions_mode"` GuestAdditionsInterface *string `mapstructure:"guest_additions_interface" required:"false" cty:"guest_additions_interface" hcl:"guest_additions_interface"` - GuestAdditionsSHA256 *string `mapstructure:"guest_additions_sha256" required:"false" cty:"guest_additions_sha256" hcl:"guest_additions_sha256"` + GuestAdditionsPath *string `mapstructure:"guest_additions_path" cty:"guest_additions_path" hcl:"guest_additions_path"` + GuestAdditionsSHA256 *string `mapstructure:"guest_additions_sha256" cty:"guest_additions_sha256" hcl:"guest_additions_sha256"` GuestAdditionsURL *string `mapstructure:"guest_additions_url" required:"false" cty:"guest_additions_url" hcl:"guest_additions_url"` + Checksum *string `mapstructure:"checksum" required:"true" cty:"checksum" hcl:"checksum"` ImportFlags []string `mapstructure:"import_flags" required:"false" cty:"import_flags" hcl:"import_flags"` ImportOpts *string `mapstructure:"import_opts" required:"false" cty:"import_opts" hcl:"import_opts"` SourcePath *string `mapstructure:"source_path" required:"true" cty:"source_path" hcl:"source_path"` @@ -136,6 +138,8 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "floppy_files": &hcldec.AttrSpec{Name: "floppy_files", Type: cty.List(cty.String), Required: false}, "floppy_dirs": &hcldec.AttrSpec{Name: "floppy_dirs", Type: cty.List(cty.String), Required: false}, "floppy_label": &hcldec.AttrSpec{Name: "floppy_label", Type: cty.String, Required: false}, + "cd_files": &hcldec.AttrSpec{Name: "cd_files", Type: cty.List(cty.String), Required: false}, + "cd_label": &hcldec.AttrSpec{Name: "cd_label", Type: cty.String, Required: false}, "boot_keygroup_interval": &hcldec.AttrSpec{Name: "boot_keygroup_interval", Type: cty.String, Required: false}, "boot_wait": &hcldec.AttrSpec{Name: "boot_wait", Type: cty.String, Required: false}, "boot_command": &hcldec.AttrSpec{Name: "boot_command", Type: cty.List(cty.String), Required: false}, @@ -209,11 +213,11 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "vboxmanage_post": &hcldec.AttrSpec{Name: "vboxmanage_post", Type: cty.List(cty.List(cty.String)), Required: false}, "virtualbox_version_file": &hcldec.AttrSpec{Name: "virtualbox_version_file", Type: cty.String, Required: false}, "guest_additions_mode": &hcldec.AttrSpec{Name: "guest_additions_mode", Type: cty.String, Required: false}, - "checksum": &hcldec.AttrSpec{Name: "checksum", Type: cty.String, Required: false}, - "guest_additions_path": &hcldec.AttrSpec{Name: "guest_additions_path", Type: cty.String, Required: false}, "guest_additions_interface": &hcldec.AttrSpec{Name: "guest_additions_interface", Type: cty.String, Required: false}, + "guest_additions_path": &hcldec.AttrSpec{Name: "guest_additions_path", Type: cty.String, Required: false}, "guest_additions_sha256": &hcldec.AttrSpec{Name: "guest_additions_sha256", Type: cty.String, Required: false}, "guest_additions_url": &hcldec.AttrSpec{Name: "guest_additions_url", Type: cty.String, Required: false}, + "checksum": &hcldec.AttrSpec{Name: "checksum", Type: cty.String, Required: false}, "import_flags": &hcldec.AttrSpec{Name: "import_flags", Type: cty.List(cty.String), Required: false}, "import_opts": &hcldec.AttrSpec{Name: "import_opts", Type: cty.String, Required: false}, "source_path": &hcldec.AttrSpec{Name: "source_path", Type: cty.String, Required: false}, diff --git a/builder/virtualbox/vm/builder.go b/builder/virtualbox/vm/builder.go index 4eadfce49..a0911e968 100644 --- a/builder/virtualbox/vm/builder.go +++ b/builder/virtualbox/vm/builder.go @@ -54,6 +54,10 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack Files: b.config.FloppyConfig.FloppyFiles, Directories: b.config.FloppyConfig.FloppyDirectories, }, + &common.StepCreateCD{ + Files: b.config.CDConfig.CDFiles, + Label: b.config.CDConfig.CDLabel, + }, &StepSetSnapshot{ Name: b.config.VMName, AttachSnapshot: b.config.AttachSnapshot, @@ -75,8 +79,11 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack &StepImport{ Name: b.config.VMName, }, - &vboxcommon.StepAttachGuestAdditions{ - GuestAdditionsMode: b.config.GuestAdditionsMode, + &vboxcommon.StepAttachISOs{ + AttachBootIso: false, + ISOInterface: b.config.GuestAdditionsInterface, + GuestAdditionsMode: b.config.GuestAdditionsMode, + GuestAdditionsInterface: b.config.GuestAdditionsInterface, }, &vboxcommon.StepConfigureVRDP{ VRDPBindAddress: b.config.VRDPBindAddress, @@ -131,6 +138,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack DisableShutdown: b.config.DisableShutdown, ACPIShutdown: b.config.ACPIShutdown, }, + &vboxcommon.StepRemoveDevices{}, &vboxcommon.StepVBoxManage{ Commands: b.config.VBoxManagePost, Ctx: b.config.ctx, diff --git a/builder/virtualbox/vm/config.go b/builder/virtualbox/vm/config.go index 41ef57d20..973be08ed 100644 --- a/builder/virtualbox/vm/config.go +++ b/builder/virtualbox/vm/config.go @@ -6,7 +6,6 @@ package vm import ( "fmt" "log" - "strings" "time" vboxcommon "github.com/hashicorp/packer/builder/virtualbox/common" @@ -19,44 +18,19 @@ import ( // Config is the configuration structure for the builder. type Config struct { - common.PackerConfig `mapstructure:",squash"` - common.HTTPConfig `mapstructure:",squash"` - common.FloppyConfig `mapstructure:",squash"` - bootcommand.BootConfig `mapstructure:",squash"` - vboxcommon.ExportConfig `mapstructure:",squash"` - vboxcommon.OutputConfig `mapstructure:",squash"` - vboxcommon.RunConfig `mapstructure:",squash"` - vboxcommon.CommConfig `mapstructure:",squash"` - vboxcommon.ShutdownConfig `mapstructure:",squash"` - vboxcommon.VBoxManageConfig `mapstructure:",squash"` - vboxcommon.VBoxVersionConfig `mapstructure:",squash"` - - // The method by which guest additions are - // made available to the guest for installation. Valid options are `upload`, - // `attach`, or `disable`. If the mode is `attach` the guest additions ISO will - // be attached as a CD device to the virtual machine. If the mode is `upload` - // the guest additions ISO will be uploaded to the path specified by - // `guest_additions_path`. The default value is `upload`. If `disable` is used, - // guest additions won't be downloaded, either. - GuestAdditionsMode string `mapstructure:"guest_additions_mode"` - // The path on the guest virtual machine - // where the VirtualBox guest additions ISO will be uploaded. By default this - // is `VBoxGuestAdditions.iso` which should upload into the login directory of - // the user. This is a [configuration - // template](/docs/templates/engine) where the `Version` - // variable is replaced with the VirtualBox version. - GuestAdditionsPath string `mapstructure:"guest_additions_path"` - // The SHA256 checksum of the guest - // additions ISO that will be uploaded to the guest VM. By default the - // checksums will be downloaded from the VirtualBox website, so this only needs - // to be set if you want to be explicit about the checksum. - GuestAdditionsSHA256 string `mapstructure:"guest_additions_sha256"` - // The URL to the guest additions ISO - // to upload. This can also be a file URL if the ISO is at a local path. By - // default, the VirtualBox builder will attempt to find the guest additions ISO - // on the local file system. If it is not available locally, the builder will - // download the proper guest additions ISO from the internet. - GuestAdditionsURL string `mapstructure:"guest_additions_url" required:"false"` + common.PackerConfig `mapstructure:",squash"` + common.HTTPConfig `mapstructure:",squash"` + common.FloppyConfig `mapstructure:",squash"` + common.CDConfig `mapstructure:",squash"` + bootcommand.BootConfig `mapstructure:",squash"` + vboxcommon.ExportConfig `mapstructure:",squash"` + vboxcommon.OutputConfig `mapstructure:",squash"` + vboxcommon.RunConfig `mapstructure:",squash"` + vboxcommon.CommConfig `mapstructure:",squash"` + vboxcommon.ShutdownConfig `mapstructure:",squash"` + vboxcommon.VBoxManageConfig `mapstructure:",squash"` + vboxcommon.VBoxVersionConfig `mapstructure:",squash"` + vboxcommon.GuestAdditionsConfig `mapstructure:",squash"` // This is the name of the virtual machine to which the // builder shall attach. VMName string `mapstructure:"vm_name" required:"true"` @@ -109,14 +83,6 @@ func (c *Config) Prepare(raws ...interface{}) ([]string, error) { } // Defaults - if c.GuestAdditionsMode == "" { - c.GuestAdditionsMode = "upload" - } - - if c.GuestAdditionsPath == "" { - c.GuestAdditionsPath = "VBoxGuestAdditions.iso" - } - if c.PostShutdownDelay == 0 { c.PostShutdownDelay = 2 * time.Second } @@ -125,6 +91,7 @@ func (c *Config) Prepare(raws ...interface{}) ([]string, error) { var errs *packer.MultiError errs = packer.MultiErrorAppend(errs, c.ExportConfig.Prepare(&c.ctx)...) errs = packer.MultiErrorAppend(errs, c.FloppyConfig.Prepare(&c.ctx)...) + errs = packer.MultiErrorAppend(errs, c.CDConfig.Prepare(&c.ctx)...) errs = packer.MultiErrorAppend(errs, c.HTTPConfig.Prepare(&c.ctx)...) errs = packer.MultiErrorAppend(errs, c.OutputConfig.Prepare(&c.ctx, &c.PackerConfig)...) errs = packer.MultiErrorAppend(errs, c.RunConfig.Prepare(&c.ctx)...) @@ -133,6 +100,11 @@ func (c *Config) Prepare(raws ...interface{}) ([]string, error) { errs = packer.MultiErrorAppend(errs, c.VBoxManageConfig.Prepare(&c.ctx)...) errs = packer.MultiErrorAppend(errs, c.VBoxVersionConfig.Prepare(&c.ctx)...) errs = packer.MultiErrorAppend(errs, c.BootConfig.Prepare(&c.ctx)...) + errs = packer.MultiErrorAppend(errs, c.GuestAdditionsConfig.Prepare(&c.ctx)...) + + if c.GuestAdditionsInterface == "" { + c.GuestAdditionsInterface = "ide" + } log.Printf("PostShutdownDelay: %s", c.PostShutdownDelay) @@ -141,29 +113,6 @@ func (c *Config) Prepare(raws ...interface{}) ([]string, error) { fmt.Errorf("vm_name is required")) } - validMode := false - validModes := []string{ - vboxcommon.GuestAdditionsModeDisable, - vboxcommon.GuestAdditionsModeAttach, - vboxcommon.GuestAdditionsModeUpload, - } - - for _, mode := range validModes { - if c.GuestAdditionsMode == mode { - validMode = true - break - } - } - - if !validMode { - errs = packer.MultiErrorAppend(errs, - fmt.Errorf("guest_additions_mode is invalid. Must be one of: %v", validModes)) - } - - if c.GuestAdditionsSHA256 != "" { - c.GuestAdditionsSHA256 = strings.ToLower(c.GuestAdditionsSHA256) - } - // Warnings var warnings []string if c.TargetSnapshot == "" && c.SkipExport { diff --git a/builder/virtualbox/vm/config.hcl2spec.go b/builder/virtualbox/vm/config.hcl2spec.go index 9153b92b6..553921640 100644 --- a/builder/virtualbox/vm/config.hcl2spec.go +++ b/builder/virtualbox/vm/config.hcl2spec.go @@ -23,6 +23,8 @@ type FlatConfig struct { FloppyFiles []string `mapstructure:"floppy_files" cty:"floppy_files" hcl:"floppy_files"` FloppyDirectories []string `mapstructure:"floppy_dirs" cty:"floppy_dirs" hcl:"floppy_dirs"` FloppyLabel *string `mapstructure:"floppy_label" cty:"floppy_label" hcl:"floppy_label"` + CDFiles []string `mapstructure:"cd_files" cty:"cd_files" hcl:"cd_files"` + CDLabel *string `mapstructure:"cd_label" cty:"cd_label" hcl:"cd_label"` BootGroupInterval *string `mapstructure:"boot_keygroup_interval" cty:"boot_keygroup_interval" hcl:"boot_keygroup_interval"` BootWait *string `mapstructure:"boot_wait" cty:"boot_wait" hcl:"boot_wait"` BootCommand []string `mapstructure:"boot_command" cty:"boot_command" hcl:"boot_command"` @@ -96,6 +98,7 @@ type FlatConfig struct { VBoxManagePost [][]string `mapstructure:"vboxmanage_post" required:"false" cty:"vboxmanage_post" hcl:"vboxmanage_post"` VBoxVersionFile *string `mapstructure:"virtualbox_version_file" required:"false" cty:"virtualbox_version_file" hcl:"virtualbox_version_file"` GuestAdditionsMode *string `mapstructure:"guest_additions_mode" cty:"guest_additions_mode" hcl:"guest_additions_mode"` + GuestAdditionsInterface *string `mapstructure:"guest_additions_interface" required:"false" cty:"guest_additions_interface" hcl:"guest_additions_interface"` GuestAdditionsPath *string `mapstructure:"guest_additions_path" cty:"guest_additions_path" hcl:"guest_additions_path"` GuestAdditionsSHA256 *string `mapstructure:"guest_additions_sha256" cty:"guest_additions_sha256" hcl:"guest_additions_sha256"` GuestAdditionsURL *string `mapstructure:"guest_additions_url" required:"false" cty:"guest_additions_url" hcl:"guest_additions_url"` @@ -133,6 +136,8 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "floppy_files": &hcldec.AttrSpec{Name: "floppy_files", Type: cty.List(cty.String), Required: false}, "floppy_dirs": &hcldec.AttrSpec{Name: "floppy_dirs", Type: cty.List(cty.String), Required: false}, "floppy_label": &hcldec.AttrSpec{Name: "floppy_label", Type: cty.String, Required: false}, + "cd_files": &hcldec.AttrSpec{Name: "cd_files", Type: cty.List(cty.String), Required: false}, + "cd_label": &hcldec.AttrSpec{Name: "cd_label", Type: cty.String, Required: false}, "boot_keygroup_interval": &hcldec.AttrSpec{Name: "boot_keygroup_interval", Type: cty.String, Required: false}, "boot_wait": &hcldec.AttrSpec{Name: "boot_wait", Type: cty.String, Required: false}, "boot_command": &hcldec.AttrSpec{Name: "boot_command", Type: cty.List(cty.String), Required: false}, @@ -206,6 +211,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "vboxmanage_post": &hcldec.AttrSpec{Name: "vboxmanage_post", Type: cty.List(cty.List(cty.String)), Required: false}, "virtualbox_version_file": &hcldec.AttrSpec{Name: "virtualbox_version_file", Type: cty.String, Required: false}, "guest_additions_mode": &hcldec.AttrSpec{Name: "guest_additions_mode", Type: cty.String, Required: false}, + "guest_additions_interface": &hcldec.AttrSpec{Name: "guest_additions_interface", Type: cty.String, Required: false}, "guest_additions_path": &hcldec.AttrSpec{Name: "guest_additions_path", Type: cty.String, Required: false}, "guest_additions_sha256": &hcldec.AttrSpec{Name: "guest_additions_sha256", Type: cty.String, Required: false}, "guest_additions_url": &hcldec.AttrSpec{Name: "guest_additions_url", Type: cty.String, Required: false}, diff --git a/website/pages/partials/builder/virtualbox/common/GuestAdditionsConfig-not-required.mdx b/website/pages/partials/builder/virtualbox/common/GuestAdditionsConfig-not-required.mdx index 7fbe8a29c..0c57a3f70 100644 --- a/website/pages/partials/builder/virtualbox/common/GuestAdditionsConfig-not-required.mdx +++ b/website/pages/partials/builder/virtualbox/common/GuestAdditionsConfig-not-required.mdx @@ -3,9 +3,32 @@ - `communicator` (string) - Communicator - `guest_additions_mode` (string) - The method by which guest additions are - made available to the guest for installation. Valid options are upload, - attach, or disable. If the mode is attach the guest additions ISO will - be attached as a CD device to the virtual machine. If the mode is upload + made available to the guest for installation. Valid options are `upload`, + `attach`, or `disable`. If the mode is `attach` the guest additions ISO will + be attached as a CD device to the virtual machine. If the mode is `upload` the guest additions ISO will be uploaded to the path specified by - guest_additions_path. The default value is upload. If disable is used, + `guest_additions_path`. The default value is `upload`. If `disable` is used, guest additions won't be downloaded, either. + +- `guest_additions_interface` (string) - The interface type to use to mount guest additions when + guest_additions_mode is set to attach. Will default to the value set in + iso_interface, if iso_interface is set. Will default to "ide", if + iso_interface is not set. Options are "ide" and "sata". + +- `guest_additions_path` (string) - The path on the guest virtual machine + where the VirtualBox guest additions ISO will be uploaded. By default this + is `VBoxGuestAdditions.iso` which should upload into the login directory of + the user. This is a [configuration + template](/docs/templates/engine) where the `Version` + variable is replaced with the VirtualBox version. + +- `guest_additions_sha256` (string) - The SHA256 checksum of the guest + additions ISO that will be uploaded to the guest VM. By default the + checksums will be downloaded from the VirtualBox website, so this only needs + to be set if you want to be explicit about the checksum. + +- `guest_additions_url` (string) - The URL of the guest additions ISO + to upload. This can also be a file URL if the ISO is at a local path. By + default, the VirtualBox builder will attempt to find the guest additions ISO + on the local file system. If it is not available locally, the builder will + download the proper guest additions ISO from the internet. diff --git a/website/pages/partials/builder/virtualbox/iso/Config-not-required.mdx b/website/pages/partials/builder/virtualbox/iso/Config-not-required.mdx index 89b15859b..55e348ac2 100644 --- a/website/pages/partials/builder/virtualbox/iso/Config-not-required.mdx +++ b/website/pages/partials/builder/virtualbox/iso/Config-not-required.mdx @@ -3,29 +3,6 @@ - `disk_size` (uint) - The size, in megabytes, of the hard disk to create for the VM. By default, this is 40000 (about 40 GB). -- `guest_additions_path` (string) - The path on the guest virtual machine where the VirtualBox guest - additions ISO will be uploaded. By default this is - VBoxGuestAdditions.iso which should upload into the login directory of - the user. This is a configuration template where the `{{ .Version }}` - variable is replaced with the VirtualBox version. - -- `guest_additions_sha256` (string) - The SHA256 checksum of the guest additions ISO that will be uploaded to - the guest VM. By default the checksums will be downloaded from the - VirtualBox website, so this only needs to be set if you want to be - explicit about the checksum. - -- `guest_additions_url` (string) - The URL to the guest additions ISO to upload. This can also be a file - URL if the ISO is at a local path. By default, the VirtualBox builder - will attempt to find the guest additions ISO on the local file system. - If it is not available locally, the builder will download the proper - guest additions ISO from the internet. This is a template engine, and you - have access to the variable `{{ .Version }}`. - -- `guest_additions_interface` (string) - The interface type to use to mount guest additions when - guest_additions_mode is set to attach. Will default to the value set in - iso_interface, if iso_interface is set. Will default to "ide", if - iso_interface is not set. Options are "ide" and "sata". - - `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 diff --git a/website/pages/partials/builder/virtualbox/ovf/Config-not-required.mdx b/website/pages/partials/builder/virtualbox/ovf/Config-not-required.mdx index a565af078..a5bd3d5f9 100644 --- a/website/pages/partials/builder/virtualbox/ovf/Config-not-required.mdx +++ b/website/pages/partials/builder/virtualbox/ovf/Config-not-required.mdx @@ -1,37 +1,5 @@ -- `guest_additions_mode` (string) - The method by which guest additions are - made available to the guest for installation. Valid options are upload, - attach, or disable. If the mode is attach the guest additions ISO will - be attached as a CD device to the virtual machine. If the mode is upload - the guest additions ISO will be uploaded to the path specified by - guest_additions_path. The default value is upload. If disable is used, - guest additions won't be downloaded, either. - -- `guest_additions_path` (string) - The path on the guest virtual machine - where the VirtualBox guest additions ISO will be uploaded. By default this - is VBoxGuestAdditions.iso which should upload into the login directory of - the user. This is a configuration - template where the Version - variable is replaced with the VirtualBox version. - -- `guest_additions_interface` (string) - The interface type to use to mount - guest additions when guest_additions_mode is set to attach. Will - default to the value set in iso_interface, if iso_interface is set. - Will default to "ide", if iso_interface is not set. Options are "ide" and - "sata". - -- `guest_additions_sha256` (string) - The SHA256 checksum of the guest - additions ISO that will be uploaded to the guest VM. By default the - checksums will be downloaded from the VirtualBox website, so this only needs - to be set if you want to be explicit about the checksum. - -- `guest_additions_url` (string) - The URL to the guest additions ISO - to upload. This can also be a file URL if the ISO is at a local path. By - default, the VirtualBox builder will attempt to find the guest additions ISO - on the local file system. If it is not available locally, the builder will - download the proper guest additions ISO from the internet. - - `import_flags` ([]string) - Additional flags to pass to VBoxManage import. This can be used to add additional command-line flags such as --eula-accept to accept a EULA in the OVF. diff --git a/website/pages/partials/builder/virtualbox/vm/Config-not-required.mdx b/website/pages/partials/builder/virtualbox/vm/Config-not-required.mdx index 2318c7817..2990f94a8 100644 --- a/website/pages/partials/builder/virtualbox/vm/Config-not-required.mdx +++ b/website/pages/partials/builder/virtualbox/vm/Config-not-required.mdx @@ -1,31 +1,5 @@ -- `guest_additions_mode` (string) - The method by which guest additions are - made available to the guest for installation. Valid options are `upload`, - `attach`, or `disable`. If the mode is `attach` the guest additions ISO will - be attached as a CD device to the virtual machine. If the mode is `upload` - the guest additions ISO will be uploaded to the path specified by - `guest_additions_path`. The default value is `upload`. If `disable` is used, - guest additions won't be downloaded, either. - -- `guest_additions_path` (string) - The path on the guest virtual machine - where the VirtualBox guest additions ISO will be uploaded. By default this - is `VBoxGuestAdditions.iso` which should upload into the login directory of - the user. This is a [configuration - template](/docs/templates/engine) where the `Version` - variable is replaced with the VirtualBox version. - -- `guest_additions_sha256` (string) - The SHA256 checksum of the guest - additions ISO that will be uploaded to the guest VM. By default the - checksums will be downloaded from the VirtualBox website, so this only needs - to be set if you want to be explicit about the checksum. - -- `guest_additions_url` (string) - The URL to the guest additions ISO - to upload. This can also be a file URL if the ISO is at a local path. By - default, the VirtualBox builder will attempt to find the guest additions ISO - on the local file system. If it is not available locally, the builder will - download the proper guest additions ISO from the internet. - - `attach_snapshot` (string) - Default to `null/empty`. The name of an **existing** snapshot to which the builder shall attach the VM before starting it. If no snapshot is specified the builder will simply start the