From 9b99696754ca5fabbd14a13c26a4649e5f8cfe96 Mon Sep 17 00:00:00 2001 From: Christophe Jauffret Date: Fri, 3 Jan 2025 18:05:29 +0100 Subject: [PATCH] implement boot_priority option --- .../components/builder/nutanix/README.md | 3 ++- builder/nutanix/config.go | 17 +++++++++++++ builder/nutanix/config.hcl2spec.go | 4 +++ builder/nutanix/driver.go | 25 ++++++++++++++++++- docs/builders/nutanix.mdx | 3 ++- example/README.md | 2 +- example/source.nutanix.pkr.hcl | 4 +++ test/e2e/centos-iso/source.pkr.hcl | 1 + 8 files changed, 55 insertions(+), 4 deletions(-) diff --git a/.web-docs/components/builder/nutanix/README.md b/.web-docs/components/builder/nutanix/README.md index 613de6a..3f70dc7 100644 --- a/.web-docs/components/builder/nutanix/README.md +++ b/.web-docs/components/builder/nutanix/README.md @@ -21,7 +21,8 @@ These parameters allow to define information about platform and temporary VM use - `memory_mb` (number) - Size of vRAM for temporary VM (in megabytes). - `cd_files` (array of strings) - A list of files to place onto a CD that is attached when the VM is booted. This can include either files or directories; any directories will be copied onto the CD recursively, preserving directory structure hierarchy. - `cd_label` (string) - Label of this CD Drive. - - `boot_type` (string) - Type of boot used on the temporary VM ("legacy" or "uefi"). + - `boot_type` (string) - Type of boot used on the temporary VM ("legacy" or "uefi", default is "legacy"). + - `boot_priority` (string) - Priority of boot device ("cdrom" or "disk", default is "cdrom"). - `ip_wait_timeout` (duration string | ex: "0h42m0s") - Amount of time to wait for VM's IP, similar to 'ssh_timeout'. Defaults to 15m (15 minutes). See the Golang [ParseDuration](https://golang.org/pkg/time/#ParseDuration) documentation for full details. - `vm_categories` ([]Category) - Assign Categories to the vm. - `project` (string) - Assign Project to the vm. diff --git a/builder/nutanix/config.go b/builder/nutanix/config.go index eba737e..44270ca 100644 --- a/builder/nutanix/config.go +++ b/builder/nutanix/config.go @@ -24,6 +24,12 @@ const ( // NutanixIdentifierBootTypeUEFI is a resource identifier identifying the UEFI boot type for virtual machines. NutanixIdentifierBootTypeUEFI string = "uefi" + + // NutanixIdentifierBootPriorityDisk is a resource identifier identifying the boot priority as disk for virtual machines. + NutanixIdentifierBootPriorityDisk string = "disk" + + // NutanixIdentifierBootPriorityCDROM is a resource identifier identifying the boot priority as cdrom for virtual machines. + NutanixIdentifierBootPriorityCDROM string = "cdrom" ) type Config struct { @@ -79,6 +85,7 @@ type VmConfig struct { VMName string `mapstructure:"vm_name" json:"vm_name" required:"false"` OSType string `mapstructure:"os_type" json:"os_type" required:"true"` BootType string `mapstructure:"boot_type" json:"boot_type" required:"false"` + BootPriority string `mapstructure:"boot_priority" json:"boot_priority" required:"false"` VmDisks []VmDisk `mapstructure:"vm_disks"` VmNICs []VmNIC `mapstructure:"vm_nics"` ImageName string `mapstructure:"image_name" json:"image_name" required:"false"` @@ -135,6 +142,16 @@ func (c *Config) Prepare(raws ...interface{}) ([]string, error) { c.BootType = string(NutanixIdentifierBootTypeLegacy) } + if c.BootType == NutanixIdentifierBootTypeUEFI && c.BootPriority != "" { + log.Println("Boot Priority is not supported for UEFI boot type") + errs = packersdk.MultiErrorAppend(errs, fmt.Errorf("UEFI does not support boot priority")) + } + + if c.BootPriority != NutanixIdentifierBootPriorityDisk && c.BootPriority != NutanixIdentifierBootPriorityCDROM { + log.Println("No correct VM Boot Priority configured, defaulting to 'cdrom'") + c.BootPriority = string(NutanixIdentifierBootPriorityCDROM) + } + // Validate Cluster Endpoint if c.ClusterConfig.Endpoint == "" { log.Println("Nutanix Endpoint missing from configuration") diff --git a/builder/nutanix/config.hcl2spec.go b/builder/nutanix/config.hcl2spec.go index 357c95b..8e96503 100644 --- a/builder/nutanix/config.hcl2spec.go +++ b/builder/nutanix/config.hcl2spec.go @@ -136,6 +136,7 @@ type FlatConfig struct { VMName *string `mapstructure:"vm_name" json:"vm_name" required:"false" cty:"vm_name" hcl:"vm_name"` OSType *string `mapstructure:"os_type" json:"os_type" required:"true" cty:"os_type" hcl:"os_type"` BootType *string `mapstructure:"boot_type" json:"boot_type" required:"false" cty:"boot_type" hcl:"boot_type"` + BootPriority *string `mapstructure:"boot_priority" json:"boot_priority" required:"false" cty:"boot_priority" hcl:"boot_priority"` VmDisks []FlatVmDisk `mapstructure:"vm_disks" cty:"vm_disks" hcl:"vm_disks"` VmNICs []FlatVmNIC `mapstructure:"vm_nics" cty:"vm_nics" hcl:"vm_nics"` ImageName *string `mapstructure:"image_name" json:"image_name" required:"false" cty:"image_name" hcl:"image_name"` @@ -238,6 +239,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "vm_name": &hcldec.AttrSpec{Name: "vm_name", Type: cty.String, Required: false}, "os_type": &hcldec.AttrSpec{Name: "os_type", Type: cty.String, Required: false}, "boot_type": &hcldec.AttrSpec{Name: "boot_type", Type: cty.String, Required: false}, + "boot_priority": &hcldec.AttrSpec{Name: "boot_priority", Type: cty.String, Required: false}, "vm_disks": &hcldec.BlockListSpec{TypeName: "vm_disks", Nested: hcldec.ObjectSpec((*FlatVmDisk)(nil).HCL2Spec())}, "vm_nics": &hcldec.BlockListSpec{TypeName: "vm_nics", Nested: hcldec.ObjectSpec((*FlatVmNIC)(nil).HCL2Spec())}, "image_name": &hcldec.AttrSpec{Name: "image_name", Type: cty.String, Required: false}, @@ -289,6 +291,7 @@ type FlatVmConfig struct { VMName *string `mapstructure:"vm_name" json:"vm_name" required:"false" cty:"vm_name" hcl:"vm_name"` OSType *string `mapstructure:"os_type" json:"os_type" required:"true" cty:"os_type" hcl:"os_type"` BootType *string `mapstructure:"boot_type" json:"boot_type" required:"false" cty:"boot_type" hcl:"boot_type"` + BootPriority *string `mapstructure:"boot_priority" json:"boot_priority" required:"false" cty:"boot_priority" hcl:"boot_priority"` VmDisks []FlatVmDisk `mapstructure:"vm_disks" cty:"vm_disks" hcl:"vm_disks"` VmNICs []FlatVmNIC `mapstructure:"vm_nics" cty:"vm_nics" hcl:"vm_nics"` ImageName *string `mapstructure:"image_name" json:"image_name" required:"false" cty:"image_name" hcl:"image_name"` @@ -317,6 +320,7 @@ func (*FlatVmConfig) HCL2Spec() map[string]hcldec.Spec { "vm_name": &hcldec.AttrSpec{Name: "vm_name", Type: cty.String, Required: false}, "os_type": &hcldec.AttrSpec{Name: "os_type", Type: cty.String, Required: false}, "boot_type": &hcldec.AttrSpec{Name: "boot_type", Type: cty.String, Required: false}, + "boot_priority": &hcldec.AttrSpec{Name: "boot_priority", Type: cty.String, Required: false}, "vm_disks": &hcldec.BlockListSpec{TypeName: "vm_disks", Nested: hcldec.ObjectSpec((*FlatVmDisk)(nil).HCL2Spec())}, "vm_nics": &hcldec.BlockListSpec{TypeName: "vm_nics", Nested: hcldec.ObjectSpec((*FlatVmNIC)(nil).HCL2Spec())}, "image_name": &hcldec.AttrSpec{Name: "image_name", Type: cty.String, Required: false}, diff --git a/builder/nutanix/driver.go b/builder/nutanix/driver.go index 26af831..0c4a259 100644 --- a/builder/nutanix/driver.go +++ b/builder/nutanix/driver.go @@ -536,11 +536,34 @@ func (d *NutanixDriver) CreateRequest(ctx context.Context, vm VmConfig, state mu } if vm.BootType == NutanixIdentifierBootTypeUEFI { - bootType := strings.ToUpper(vm.BootType) + bootType := strings.ToUpper(NutanixIdentifierBootTypeUEFI) req.Spec.Resources.BootConfig = &v3.VMBootConfig{ BootType: &bootType, } + } else { + bootType := strings.ToUpper(NutanixIdentifierBootTypeLegacy) + + var bootDeviceOrderList []*string + + if vm.BootPriority == "cdrom" { + bootDeviceOrderList = []*string{ + StringPtr("CDROM"), + StringPtr("DISK"), + StringPtr("NETWORK"), + } + } else { + bootDeviceOrderList = []*string{ + StringPtr("DISK"), + StringPtr("CDROM"), + StringPtr("NETWORK"), + } + } + req.Spec.Resources.BootConfig = &v3.VMBootConfig{ + BootType: &bootType, + BootDeviceOrderList: bootDeviceOrderList, + } + } if len(vm.VMCategories) != 0 { diff --git a/docs/builders/nutanix.mdx b/docs/builders/nutanix.mdx index bba6237..0054e66 100644 --- a/docs/builders/nutanix.mdx +++ b/docs/builders/nutanix.mdx @@ -30,7 +30,8 @@ These parameters allow to define information about platform and temporary VM use - `memory_mb` (number) - Size of vRAM for temporary VM (in megabytes). - `cd_files` (array of strings) - A list of files to place onto a CD that is attached when the VM is booted. This can include either files or directories; any directories will be copied onto the CD recursively, preserving directory structure hierarchy. - `cd_label` (string) - Label of this CD Drive. - - `boot_type` (string) - Type of boot used on the temporary VM ("legacy" or "uefi"). + - `boot_type` (string) - Type of boot used on the temporary VM ("legacy" or "uefi", default is "legacy"). + - `boot_priority` (string) - Priority of boot device ("cdrom" or "disk", default is "cdrom"). - `ip_wait_timeout` (duration string | ex: "0h42m0s") - Amount of time to wait for VM's IP, similar to 'ssh_timeout'. Defaults to 15m (15 minutes). See the Golang [ParseDuration](https://golang.org/pkg/time/#ParseDuration) documentation for full details. - `vm_categories` ([]Category) - Assign Categories to the vm. - `project` (string) - Assign Project to the vm. diff --git a/example/README.md b/example/README.md index ff4680b..b4a99ec 100644 --- a/example/README.md +++ b/example/README.md @@ -9,7 +9,7 @@ Creating Ubuntu from Upstream Image and running Provisioner: packer build -only nutanix.ubuntu . Creating from ISO with Kickstart-File: -packer build -only nutanix.centos-kickerstart . +packer build -only nutanix.centos-kickstart . Windows Image (ISO Boot, VirtIO Drivers, cd_files) packer build -only nutanix.windows . diff --git a/example/source.nutanix.pkr.hcl b/example/source.nutanix.pkr.hcl index a301b8d..c399b0f 100644 --- a/example/source.nutanix.pkr.hcl +++ b/example/source.nutanix.pkr.hcl @@ -96,6 +96,8 @@ source "nutanix" "centos-kickstart" { cd_files = ["scripts/ks.cfg"] cd_label = "OEMDRV" + boot_priority = "disk" + image_name ="centos8-{{isotime `Jan-_2-15:04:05`}}" shutdown_command = "echo 'packer' | sudo -S shutdown -P now" shutdown_timeout = "2m" @@ -131,6 +133,8 @@ source "nutanix" "windows" { cd_files = ["scripts/gui/autounattend.xml","scripts/win-update.ps1"] + boot_priority = "disk" + image_name ="win-{{isotime `Jan-_2-15:04:05`}}" shutdown_command = "shutdown /s /t 10 /f /d p:4:1 /c \"Packer Shutdown\"" shutdown_timeout = "3m" diff --git a/test/e2e/centos-iso/source.pkr.hcl b/test/e2e/centos-iso/source.pkr.hcl index 3b85b29..34ab827 100644 --- a/test/e2e/centos-iso/source.pkr.hcl +++ b/test/e2e/centos-iso/source.pkr.hcl @@ -43,6 +43,7 @@ source "nutanix" "centos" { image_name = "e2e-packer-${var.test}-${formatdate("MDYYhms", timestamp())}" image_delete = true + boot_priority = "disk" force_deregister = true