From eae3fda9017c3c8a7efe544ada7b11dfb23d646b Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Thu, 10 Sep 2020 15:38:28 -0700 Subject: [PATCH] refactor out disk defaulting so it can be used to default the vmx cdrom too --- builder/vmware/common/step_configure_vmx.go | 102 +++++++++++++++++++- builder/vmware/iso/builder.go | 8 +- builder/vmware/iso/config.go | 9 ++ builder/vmware/iso/step_create_vmx.go | 96 +----------------- builder/vmware/vmx/builder.go | 12 ++- builder/vmware/vmx/config.go | 2 + 6 files changed, 126 insertions(+), 103 deletions(-) diff --git a/builder/vmware/common/step_configure_vmx.go b/builder/vmware/common/step_configure_vmx.go index 2e48e0574..833008291 100644 --- a/builder/vmware/common/step_configure_vmx.go +++ b/builder/vmware/common/step_configure_vmx.go @@ -20,10 +20,12 @@ import ( // Produces: // display_name string - Value of the displayName key set in the VMX file type StepConfigureVMX struct { - CustomData map[string]string - DisplayName string - SkipFloppy bool - VMName string + CustomData map[string]string + DisplayName string + SkipFloppy bool + VMName string + DiskAdapterType string + CDROMAdapterType string } func (s *StepConfigureVMX) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { @@ -83,6 +85,17 @@ func (s *StepConfigureVMX) Run(ctx context.Context, state multistep.StateBag) mu state.Put("temporaryDevices", tmpBuildDevices) } + // Add our custom CD, if it exists + if cdPath, ok := state.GetOk("cd_path"); ok { + if cdPath != "" { + diskAndCDConfigData := DefaultDiskAndCDROMTypes(s.DiskAdapterType, s.CDROMAdapterType) + cdromPrefix := diskAndCDConfigData.CDROMType + "1:" + diskAndCDConfigData.CDROMType_PrimarySecondary + vmxData[cdromPrefix+".present"] = "TRUE" + vmxData[cdromPrefix+".fileName"] = cdPath.(string) + vmxData[cdromPrefix+".deviceType"] = "cdrom-image" + } + } + // If the build is taking place on a remote ESX server, the displayName // will be needed for discovery of the VM's IP address and for export // of the VM. The displayName key should always be set in the VMX file, @@ -125,5 +138,86 @@ func (s *StepConfigureVMX) Run(ctx context.Context, state multistep.StateBag) mu return multistep.ActionContinue } +type DiskAndCDConfigData struct { + SCSI_Present string + SCSI_diskAdapterType string + SATA_Present string + NVME_Present string + + DiskType string + CDROMType string + CDROMType_PrimarySecondary string + CDROM_PATH string +} + +// DefaultDiskAndCDROMTypes takes the disk adapter type and cdrom adapter type from the config and converts them +// into template interpolation data for creating or configuring a vmx. +func DefaultDiskAndCDROMTypes(diskAdapterType string, cdromAdapterType string) DiskAndCDConfigData { + diskData := DiskAndCDConfigData{ + SCSI_Present: "FALSE", + SCSI_diskAdapterType: "lsilogic", + SATA_Present: "FALSE", + NVME_Present: "FALSE", + + DiskType: "scsi", + CDROMType: "ide", + CDROMType_PrimarySecondary: "0", + } + /// Use the disk adapter type that the user specified to tweak the .vmx + // Also sync the cdrom adapter type according to what's common for that disk type. + // XXX: If the cdrom type is modified, make sure to update common/step_clean_vmx.go + // so that it will regex the correct cdrom device for removal. + diskAdapterType = strings.ToLower(diskAdapterType) + switch diskAdapterType { + case "ide": + diskData.DiskType = "ide" + diskData.CDROMType = "ide" + diskData.CDROMType_PrimarySecondary = "1" + case "sata": + diskData.SATA_Present = "TRUE" + diskData.DiskType = "sata" + diskData.CDROMType = "sata" + diskData.CDROMType_PrimarySecondary = "1" + case "nvme": + diskData.NVME_Present = "TRUE" + diskData.DiskType = "nvme" + diskData.SATA_Present = "TRUE" + diskData.CDROMType = "sata" + diskData.CDROMType_PrimarySecondary = "0" + case "scsi": + diskAdapterType = "lsilogic" + fallthrough + default: + diskData.SCSI_Present = "TRUE" + diskData.SCSI_diskAdapterType = diskAdapterType // defaults to lsilogic + diskData.DiskType = "scsi" + diskData.CDROMType = "ide" + diskData.CDROMType_PrimarySecondary = "0" + } + + /// Handle the cdrom adapter type. If the disk adapter type and the + // cdrom adapter type are the same, then ensure that the cdrom is the + // secondary device on whatever bus the disk adapter is on. + if cdromAdapterType == "" { + cdromAdapterType = diskData.CDROMType + } else if cdromAdapterType == diskAdapterType { + diskData.CDROMType_PrimarySecondary = "1" + } else { + diskData.CDROMType_PrimarySecondary = "0" + } + + switch cdromAdapterType { + case "ide": + diskData.CDROMType = "ide" + case "sata": + diskData.SATA_Present = "TRUE" + diskData.CDROMType = "sata" + case "scsi": + diskData.SCSI_Present = "TRUE" + diskData.CDROMType = "scsi" + } + return diskData +} + func (s *StepConfigureVMX) Cleanup(state multistep.StateBag) { } diff --git a/builder/vmware/iso/builder.go b/builder/vmware/iso/builder.go index f366f0a0d..f8f3bf8fc 100644 --- a/builder/vmware/iso/builder.go +++ b/builder/vmware/iso/builder.go @@ -123,9 +123,11 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack }, &stepCreateVMX{}, &vmwcommon.StepConfigureVMX{ - CustomData: b.config.VMXData, - VMName: b.config.VMName, - DisplayName: b.config.VMXDisplayName, + CustomData: b.config.VMXData, + VMName: b.config.VMName, + DisplayName: b.config.VMXDisplayName, + DiskAdapterType: b.config.DiskAdapterType, + CDROMAdapterType: b.config.CdromAdapterType, }, &vmwcommon.StepSuppressMessages{}, &vmwcommon.StepHTTPIPDiscover{}, diff --git a/builder/vmware/iso/config.go b/builder/vmware/iso/config.go index 319d5fdb5..976203872 100644 --- a/builder/vmware/iso/config.go +++ b/builder/vmware/iso/config.go @@ -193,6 +193,15 @@ func (c *Config) Prepare(raws ...interface{}) ([]string, error) { errs = packer.MultiErrorAppend(errs, err) } + if c.CdromAdapterType != "" { + c.CdromAdapterType = strings.ToLower(c.CdromAdapterType) + if c.CdromAdapterType != "ide" && c.CdromAdapterType != "sata" && c.CdromAdapterType != "scsi" { + errs = packer.MultiErrorAppend(errs, + fmt.Errorf("cdrom_adapter_type must be one of ide, sata, or scsi")) + } + } + + // Warnings if c.ShutdownCommand == "" { warnings = append(warnings, "A shutdown_command was not specified. Without a shutdown command, Packer\n"+ diff --git a/builder/vmware/iso/step_create_vmx.go b/builder/vmware/iso/step_create_vmx.go index d73336a9a..6ecfd8d10 100644 --- a/builder/vmware/iso/step_create_vmx.go +++ b/builder/vmware/iso/step_create_vmx.go @@ -25,16 +25,8 @@ type vmxTemplateData struct { CpuCount string MemorySize string - SCSI_Present string - SCSI_diskAdapterType string - SATA_Present string - NVME_Present string - - DiskName string - DiskType string - CDROMType string - CDROMType_PrimarySecondary string - CDROM_PATH string + DiskName string + vmwcommon.DiskAndCDConfigData Network_Type string Network_Device string @@ -162,15 +154,6 @@ func (s *stepCreateVMX) Run(ctx context.Context, state multistep.StateBag) multi Version: config.Version, ISOPath: isoPath, - SCSI_Present: "FALSE", - SCSI_diskAdapterType: "lsilogic", - SATA_Present: "FALSE", - NVME_Present: "FALSE", - - DiskType: "scsi", - CDROMType: "ide", - CDROMType_PrimarySecondary: "0", - Network_Adapter: "e1000", Sound_Present: map[bool]string{true: "TRUE", false: "FALSE"}[bool(config.HWConfig.Sound)], @@ -180,74 +163,7 @@ func (s *stepCreateVMX) Run(ctx context.Context, state multistep.StateBag) multi Parallel_Present: "FALSE", } - /// Use the disk adapter type that the user specified to tweak the .vmx - // Also sync the cdrom adapter type according to what's common for that disk type. - // XXX: If the cdrom type is modified, make sure to update common/step_clean_vmx.go - // so that it will regex the correct cdrom device for removal. - diskAdapterType := strings.ToLower(config.DiskAdapterType) - switch diskAdapterType { - case "ide": - templateData.DiskType = "ide" - templateData.CDROMType = "ide" - templateData.CDROMType_PrimarySecondary = "1" - case "sata": - templateData.SATA_Present = "TRUE" - templateData.DiskType = "sata" - templateData.CDROMType = "sata" - templateData.CDROMType_PrimarySecondary = "1" - case "nvme": - templateData.NVME_Present = "TRUE" - templateData.DiskType = "nvme" - templateData.SATA_Present = "TRUE" - templateData.CDROMType = "sata" - templateData.CDROMType_PrimarySecondary = "0" - case "scsi": - diskAdapterType = "lsilogic" - fallthrough - default: - templateData.SCSI_Present = "TRUE" - templateData.SCSI_diskAdapterType = diskAdapterType - templateData.DiskType = "scsi" - templateData.CDROMType = "ide" - templateData.CDROMType_PrimarySecondary = "0" - } - - /// Handle the cdrom adapter type. If the disk adapter type and the - // cdrom adapter type are the same, then ensure that the cdrom is the - // secondary device on whatever bus the disk adapter is on. - cdromAdapterType := strings.ToLower(config.CdromAdapterType) - if cdromAdapterType == "" { - cdromAdapterType = templateData.CDROMType - } else if cdromAdapterType == diskAdapterType { - templateData.CDROMType_PrimarySecondary = "1" - } else { - templateData.CDROMType_PrimarySecondary = "0" - } - - switch cdromAdapterType { - case "ide": - templateData.CDROMType = "ide" - case "sata": - templateData.SATA_Present = "TRUE" - templateData.CDROMType = "sata" - case "scsi": - templateData.SCSI_Present = "TRUE" - templateData.CDROMType = "scsi" - default: - err := fmt.Errorf("Error processing VMX template: %s", cdromAdapterType) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } - - // Add our custom CD, if it exists - cd_path, ok := state.Get("cd_path").(string) - if ok { - if cd_path != "" { - vmxTemplate += ExtraCDRomTemplate - templateData.CDROM_PATH = cd_path - } - } + templateData.DiskAndCDConfigData = vmwcommon.DefaultDiskAndCDROMTypes(config.DiskAdapterType, config.CdromAdapterType) /// Now that we figured out the CDROM device to add, store it /// to the list of temporary build devices in our statebag @@ -607,9 +523,3 @@ scsi0:{{ .DiskNumber }}.fileName = "{{ .DiskName}}-{{ .DiskNumber }}.vmdk" scsi0:{{ .DiskNumber }}.present = "TRUE" scsi0:{{ .DiskNumber }}.redo = "" ` - -const ExtraCDRomTemplate = ` -{{ .CDROMType }}1:{{ .CDROMType_PrimarySecondary }}.present = "TRUE" -{{ .CDROMType }}1:{{ .CDROMType_PrimarySecondary }}.fileName = "{{ .CDROM_PATH }}" -{{ .CDROMType }}1:{{ .CDROMType_PrimarySecondary }}.deviceType = "cdrom-image" -` diff --git a/builder/vmware/vmx/builder.go b/builder/vmware/vmx/builder.go index bf216a60a..d31870d41 100644 --- a/builder/vmware/vmx/builder.go +++ b/builder/vmware/vmx/builder.go @@ -87,6 +87,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, + }, &vmwcommon.StepRemoteUpload{ Key: "floppy_path", Message: "Uploading Floppy to remote machine...", @@ -109,9 +113,11 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack Linked: b.config.Linked, }, &vmwcommon.StepConfigureVMX{ - CustomData: b.config.VMXData, - VMName: b.config.VMName, - DisplayName: b.config.VMXDisplayName, + CustomData: b.config.VMXData, + VMName: b.config.VMName, + DisplayName: b.config.VMXDisplayName, + DiskAdapterType: b.config.DiskAdapterType, + CDROMAdapterType: "", }, &vmwcommon.StepSuppressMessages{}, &vmwcommon.StepHTTPIPDiscover{}, diff --git a/builder/vmware/vmx/config.go b/builder/vmware/vmx/config.go index 269de35ce..aa6d60f0f 100644 --- a/builder/vmware/vmx/config.go +++ b/builder/vmware/vmx/config.go @@ -21,6 +21,7 @@ type Config struct { common.HTTPConfig `mapstructure:",squash"` common.FloppyConfig `mapstructure:",squash"` vmwcommon.BootConfigWrapper `mapstructure:",squash"` + common.CDConfig `mapstructure:",squash"` vmwcommon.DriverConfig `mapstructure:",squash"` vmwcommon.OutputConfig `mapstructure:",squash"` vmwcommon.RunConfig `mapstructure:",squash"` @@ -91,6 +92,7 @@ func (c *Config) Prepare(raws ...interface{}) ([]string, error) { errs = packer.MultiErrorAppend(errs, c.SSHConfig.Prepare(&c.ctx)...) errs = packer.MultiErrorAppend(errs, c.ToolsConfig.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.VNCConfig.Prepare(&c.ctx)...) errs = packer.MultiErrorAppend(errs, c.ExportConfig.Prepare(&c.ctx)...) errs = packer.MultiErrorAppend(errs, c.DiskConfig.Prepare(&c.ctx)...)