diff --git a/builder/proxmox/clone/config.hcl2spec.go b/builder/proxmox/clone/config.hcl2spec.go index aa0fc988..9567c68d 100644 --- a/builder/proxmox/clone/config.hcl2spec.go +++ b/builder/proxmox/clone/config.hcl2spec.go @@ -95,7 +95,8 @@ type FlatConfig struct { Sockets *int `mapstructure:"sockets" cty:"sockets" hcl:"sockets"` OS *string `mapstructure:"os" cty:"os" hcl:"os"` BIOS *string `mapstructure:"bios" cty:"bios" hcl:"bios"` - EFIDisk *proxmox.FlatefiConfig `mapstructure:"efidisk" cty:"efidisk" hcl:"efidisk"` + EFIConfig *proxmox.FlatefiConfig `mapstructure:"efi_config" cty:"efi_config" hcl:"efi_config"` + EFIDisk *string `mapstructure:"efidisk" cty:"efidisk" hcl:"efidisk"` Machine *string `mapstructure:"machine" cty:"machine" hcl:"machine"` VGA *proxmox.FlatvgaConfig `mapstructure:"vga" cty:"vga" hcl:"vga"` NICs []proxmox.FlatnicConfig `mapstructure:"network_adapters" cty:"network_adapters" hcl:"network_adapters"` @@ -210,7 +211,8 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "sockets": &hcldec.AttrSpec{Name: "sockets", Type: cty.Number, Required: false}, "os": &hcldec.AttrSpec{Name: "os", Type: cty.String, Required: false}, "bios": &hcldec.AttrSpec{Name: "bios", Type: cty.String, Required: false}, - "efidisk": &hcldec.BlockSpec{TypeName: "efidisk", Nested: hcldec.ObjectSpec((*proxmox.FlatefiConfig)(nil).HCL2Spec())}, + "efi_config": &hcldec.BlockSpec{TypeName: "efi_config", Nested: hcldec.ObjectSpec((*proxmox.FlatefiConfig)(nil).HCL2Spec())}, + "efidisk": &hcldec.AttrSpec{Name: "efidisk", Type: cty.String, Required: false}, "machine": &hcldec.AttrSpec{Name: "machine", Type: cty.String, Required: false}, "vga": &hcldec.BlockSpec{TypeName: "vga", Nested: hcldec.ObjectSpec((*proxmox.FlatvgaConfig)(nil).HCL2Spec())}, "network_adapters": &hcldec.BlockListSpec{TypeName: "network_adapters", Nested: hcldec.ObjectSpec((*proxmox.FlatnicConfig)(nil).HCL2Spec())}, diff --git a/builder/proxmox/common/config.go b/builder/proxmox/common/config.go index f0bc098f..583c688b 100644 --- a/builder/proxmox/common/config.go +++ b/builder/proxmox/common/config.go @@ -52,7 +52,8 @@ type Config struct { Sockets int `mapstructure:"sockets"` OS string `mapstructure:"os"` BIOS string `mapstructure:"bios"` - EFIDisk efiConfig `mapstructure:"efidisk"` + EFIConfig efiConfig `mapstructure:"efi_config"` + EFIDisk string `mapstructure:"efidisk"` Machine string `mapstructure:"machine"` VGA vgaConfig `mapstructure:"vga"` NICs []nicConfig `mapstructure:"network_adapters"` @@ -103,9 +104,9 @@ type diskConfig struct { IOThread bool `mapstructure:"io_thread"` } type efiConfig struct { - Storage string `mapstructure:"storage"` - PreEnrolledKeys int `mapstructure:"pre_enrolled_keys"` - EfiType string `mapstructure:"efitype"` + EFIStoragePool string `mapstructure:"efi_storage_pool"` + PreEnrolledKeys bool `mapstructure:"pre_enrolled_keys"` + EFIType string `mapstructure:"efi_type"` } type vgaConfig struct { Type string `mapstructure:"type"` @@ -351,6 +352,24 @@ func (c *Config) Prepare(upper interface{}, raws ...interface{}) ([]string, []st errs = packersdk.MultiErrorAppend(errs, fmt.Errorf("one of iso_file, iso_url, or a combination of cd_files and cd_content must be specified for AdditionalISO file %s", c.AdditionalISOFiles[idx].Device)) } } + if c.EFIDisk != "" { + if c.EFIConfig != (efiConfig{}) { + errs = packersdk.MultiErrorAppend(errs, fmt.Errorf("both efi_config and efidisk cannot be set at the same time, consider defining only efi_config as efidisk is deprecated")) + } else { + warnings = append(warnings, "efidisk is deprecated, please use efi_config instead") + c.EFIConfig.EFIStoragePool = c.EFIDisk + } + } + if c.EFIConfig.EFIStoragePool != "" { + if c.EFIConfig.EFIType == "" { + log.Printf("EFI disk defined, but no efi_type given, using 4m") + c.EFIConfig.EFIType = "4m" + } + } else { + if c.EFIConfig.EFIType != "" || c.EFIConfig.PreEnrolledKeys { + errs = packersdk.MultiErrorAppend(errs, errors.New("efi_storage_pool not set for efi_config")) + } + } if errs != nil && len(errs.Errors) > 0 { return nil, warnings, errs diff --git a/builder/proxmox/common/config.hcl2spec.go b/builder/proxmox/common/config.hcl2spec.go index 0b32e1e8..00c8551e 100644 --- a/builder/proxmox/common/config.hcl2spec.go +++ b/builder/proxmox/common/config.hcl2spec.go @@ -94,7 +94,8 @@ type FlatConfig struct { Sockets *int `mapstructure:"sockets" cty:"sockets" hcl:"sockets"` OS *string `mapstructure:"os" cty:"os" hcl:"os"` BIOS *string `mapstructure:"bios" cty:"bios" hcl:"bios"` - EFIDisk *FlatefiConfig `mapstructure:"efidisk" cty:"efidisk" hcl:"efidisk"` + EFIConfig *FlatefiConfig `mapstructure:"efi_config" cty:"efi_config" hcl:"efi_config"` + EFIDisk *string `mapstructure:"efidisk" cty:"efidisk" hcl:"efidisk"` Machine *string `mapstructure:"machine" cty:"machine" hcl:"machine"` VGA *FlatvgaConfig `mapstructure:"vga" cty:"vga" hcl:"vga"` NICs []FlatnicConfig `mapstructure:"network_adapters" cty:"network_adapters" hcl:"network_adapters"` @@ -207,7 +208,8 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "sockets": &hcldec.AttrSpec{Name: "sockets", Type: cty.Number, Required: false}, "os": &hcldec.AttrSpec{Name: "os", Type: cty.String, Required: false}, "bios": &hcldec.AttrSpec{Name: "bios", Type: cty.String, Required: false}, - "efidisk": &hcldec.BlockSpec{TypeName: "efidisk", Nested: hcldec.ObjectSpec((*FlatefiConfig)(nil).HCL2Spec())}, + "efi_config": &hcldec.BlockSpec{TypeName: "efi_config", Nested: hcldec.ObjectSpec((*FlatefiConfig)(nil).HCL2Spec())}, + "efidisk": &hcldec.AttrSpec{Name: "efidisk", Type: cty.String, Required: false}, "machine": &hcldec.AttrSpec{Name: "machine", Type: cty.String, Required: false}, "vga": &hcldec.BlockSpec{TypeName: "vga", Nested: hcldec.ObjectSpec((*FlatvgaConfig)(nil).HCL2Spec())}, "network_adapters": &hcldec.BlockListSpec{TypeName: "network_adapters", Nested: hcldec.ObjectSpec((*FlatnicConfig)(nil).HCL2Spec())}, @@ -309,9 +311,9 @@ func (*FlatdiskConfig) HCL2Spec() map[string]hcldec.Spec { // FlatefiConfig is an auto-generated flat version of efiConfig. // Where the contents of a field with a `mapstructure:,squash` tag are bubbled up. type FlatefiConfig struct { - Storage *string `mapstructure:"storage" cty:"storage" hcl:"storage"` - PreEnrolledKeys *int `mapstructure:"pre_enrolled_keys" cty:"pre_enrolled_keys" hcl:"pre_enrolled_keys"` - EfiType *string `mapstructure:"efitype" cty:"efitype" hcl:"efitype"` + EFIStoragePool *string `mapstructure:"efi_storage_pool" cty:"efi_storage_pool" hcl:"efi_storage_pool"` + PreEnrolledKeys *bool `mapstructure:"pre_enrolled_keys" cty:"pre_enrolled_keys" hcl:"pre_enrolled_keys"` + EFIType *string `mapstructure:"efi_type" cty:"efi_type" hcl:"efi_type"` } // FlatMapstructure returns a new FlatefiConfig. @@ -326,9 +328,9 @@ func (*efiConfig) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spe // The decoded values from this spec will then be applied to a FlatefiConfig. func (*FlatefiConfig) HCL2Spec() map[string]hcldec.Spec { s := map[string]hcldec.Spec{ - "storage": &hcldec.AttrSpec{Name: "storage", Type: cty.String, Required: false}, - "pre_enrolled_keys": &hcldec.AttrSpec{Name: "pre_enrolled_keys", Type: cty.Number, Required: false}, - "efitype": &hcldec.AttrSpec{Name: "efitype", Type: cty.String, Required: false}, + "efi_storage_pool": &hcldec.AttrSpec{Name: "efi_storage_pool", Type: cty.String, Required: false}, + "pre_enrolled_keys": &hcldec.AttrSpec{Name: "pre_enrolled_keys", Type: cty.Bool, Required: false}, + "efi_type": &hcldec.AttrSpec{Name: "efi_type", Type: cty.String, Required: false}, } return s } diff --git a/builder/proxmox/common/step_start_vm.go b/builder/proxmox/common/step_start_vm.go index ccf7da47..2c458b05 100644 --- a/builder/proxmox/common/step_start_vm.go +++ b/builder/proxmox/common/step_start_vm.go @@ -60,7 +60,7 @@ func (s *stepStartVM) Run(ctx context.Context, state multistep.StateBag) multist QemuSockets: c.Sockets, QemuOs: c.OS, Bios: c.BIOS, - EFIDisk: generateProxmoxEfi(c.EFIDisk), + EFIDisk: generateProxmoxEfi(c.EFIConfig), Machine: c.Machine, QemuVga: generateProxmoxVga(c.VGA), QemuNetworks: generateProxmoxNetworkAdapters(c.NICs), @@ -124,6 +124,25 @@ func (s *stepStartVM) Run(ctx context.Context, state multistep.StateBag) multist } } + // The EFI disk doesn't get created reliably during initial VM creation, + // so let's make sure it's there. + if c.EFIConfig != (efiConfig{}) { + addEFIConfig := make(map[string]interface{}) + err := config.CreateQemuEfiParams(addEFIConfig) + if err != nil { + err := fmt.Errorf("error creating EFI parameters: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + } + _, err = client.SetVmConfig(vmRef, addEFIConfig) + if err != nil { + err := fmt.Errorf("error updating template: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + } + // Store the vm id for later state.Put("vmRef", vmRef) // instance_id is the generic term used so that users can have access to the @@ -190,9 +209,17 @@ func generateProxmoxVga(vga vgaConfig) proxmox.QemuDevice { func generateProxmoxEfi(efi efiConfig) proxmox.QemuDevice { dev := make(proxmox.QemuDevice) - setDeviceParamIfDefined(dev, "storage", efi.Storage) - dev["pre-enrolled-keys"] = efi.PreEnrolledKeys - setDeviceParamIfDefined(dev, "efitype", efi.EfiType) + setDeviceParamIfDefined(dev, "storage", efi.EFIStoragePool) + setDeviceParamIfDefined(dev, "efitype", efi.EFIType) + // efi.PreEnrolledKeys can be false, but we only want to set pre-enrolled-keys=0 + // when other EFI options are set. + if len(dev) > 0 { + if efi.PreEnrolledKeys { + dev["pre-enrolled-keys"] = "1" + } else { + dev["pre-enrolled-keys"] = "0" + } + } return dev } diff --git a/builder/proxmox/iso/config.hcl2spec.go b/builder/proxmox/iso/config.hcl2spec.go index 8a05f095..9a087339 100644 --- a/builder/proxmox/iso/config.hcl2spec.go +++ b/builder/proxmox/iso/config.hcl2spec.go @@ -95,7 +95,8 @@ type FlatConfig struct { Sockets *int `mapstructure:"sockets" cty:"sockets" hcl:"sockets"` OS *string `mapstructure:"os" cty:"os" hcl:"os"` BIOS *string `mapstructure:"bios" cty:"bios" hcl:"bios"` - EFIDisk *proxmox.FlatefiConfig `mapstructure:"efidisk" cty:"efidisk" hcl:"efidisk"` + EFIConfig *proxmox.FlatefiConfig `mapstructure:"efi_config" cty:"efi_config" hcl:"efi_config"` + EFIDisk *string `mapstructure:"efidisk" cty:"efidisk" hcl:"efidisk"` Machine *string `mapstructure:"machine" cty:"machine" hcl:"machine"` VGA *proxmox.FlatvgaConfig `mapstructure:"vga" cty:"vga" hcl:"vga"` NICs []proxmox.FlatnicConfig `mapstructure:"network_adapters" cty:"network_adapters" hcl:"network_adapters"` @@ -216,7 +217,8 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "sockets": &hcldec.AttrSpec{Name: "sockets", Type: cty.Number, Required: false}, "os": &hcldec.AttrSpec{Name: "os", Type: cty.String, Required: false}, "bios": &hcldec.AttrSpec{Name: "bios", Type: cty.String, Required: false}, - "efidisk": &hcldec.BlockSpec{TypeName: "efidisk", Nested: hcldec.ObjectSpec((*proxmox.FlatefiConfig)(nil).HCL2Spec())}, + "efi_config": &hcldec.BlockSpec{TypeName: "efi_config", Nested: hcldec.ObjectSpec((*proxmox.FlatefiConfig)(nil).HCL2Spec())}, + "efidisk": &hcldec.AttrSpec{Name: "efidisk", Type: cty.String, Required: false}, "machine": &hcldec.AttrSpec{Name: "machine", Type: cty.String, Required: false}, "vga": &hcldec.BlockSpec{TypeName: "vga", Nested: hcldec.ObjectSpec((*proxmox.FlatvgaConfig)(nil).HCL2Spec())}, "network_adapters": &hcldec.BlockListSpec{TypeName: "network_adapters", Nested: hcldec.ObjectSpec((*proxmox.FlatnicConfig)(nil).HCL2Spec())}, diff --git a/docs-partials/builder/proxmox/common/Config-not-required.mdx b/docs-partials/builder/proxmox/common/Config-not-required.mdx index ca6c753f..43eac5dc 100644 --- a/docs-partials/builder/proxmox/common/Config-not-required.mdx +++ b/docs-partials/builder/proxmox/common/Config-not-required.mdx @@ -36,7 +36,9 @@ - `bios` (string) - BIOS -- `efidisk` (efiConfig) - EFI Disk +- `efi_config` (efiConfig) - EFI Config + +- `efidisk` (string) - EFI Disk - `machine` (string) - Machine diff --git a/docs-partials/builder/proxmox/common/efiConfig-not-required.mdx b/docs-partials/builder/proxmox/common/efiConfig-not-required.mdx index 283e5ec1..9598602f 100644 --- a/docs-partials/builder/proxmox/common/efiConfig-not-required.mdx +++ b/docs-partials/builder/proxmox/common/efiConfig-not-required.mdx @@ -1,9 +1,9 @@ -- `storage` (string) - Storage +- `efi_storage_pool` (string) - EFI Storage Pool -- `pre_enrolled_keys` (int) - Pre Enrolled Keys +- `pre_enrolled_keys` (bool) - Pre Enrolled Keys -- `efitype` (string) - Efi Type +- `efi_type` (string) - EFI Type diff --git a/docs/builders/clone.mdx b/docs/builders/clone.mdx index c78651fe..33ccb018 100644 --- a/docs/builders/clone.mdx +++ b/docs/builders/clone.mdx @@ -267,17 +267,29 @@ in the image's Cloud-Init settings for provisioning. - `bios` - (string) - Set the machine bios. This can be set to ovmf or seabios. The default value is seabios. -- `efidisk` - (object) - Set the efidisk storage parameters. This need to be set if you use ovmf uefi. +- `efi_config` - (object) - Set the efidisk storage options. This needs to be set if you use ovmf uefi boot + (supersedes the `efidisk` option). + Usage example (JSON): ```json { - "storage": "local", - "pre_enrolled_keys": "1", - "efitype": "4m" + "efi_storage_pool": "local", + "pre_enrolled_keys": true, + "efi_type": "4m" } ``` + - `storage_pool` - (string) - Name of the Proxmox storage pool to store the EFI disk on. + + - `efitype` - (string) - Specifies the version of the OVMF firmware to be used. Can be `2m` or `4m`. + Defaults to `4m`. + + - `pre_enrolled_keys` - (boolean) - Whether Microsoft Standard Secure Boot keys should be pre-loaded on + the EFI disk. Defaults to `false`. + +- `efidisk` - (string) - This option is deprecated, please use `efi_config` instead. + - `machine` - (string) - Set themachine type. i440fx or q35. ## Example: Cloud-Init enabled Debian diff --git a/docs/builders/iso.mdx b/docs/builders/iso.mdx index 34df23b6..23f8593b 100644 --- a/docs/builders/iso.mdx +++ b/docs/builders/iso.mdx @@ -347,17 +347,29 @@ in the image's Cloud-Init settings for provisioning. - `bios` - (string) - Set the machine bios. This can be set to ovmf or seabios. The default value is seabios. -- `efidisk` - (object) - Set the efidisk storage options. This need to be set if you use ovmf uefi boot +- `efi_config` - (object) - Set the efidisk storage options. This needs to be set if you use ovmf uefi boot + (supersedes the `efidisk` option). + Usage example (JSON): ```json { - "storage": "local", - "pre_enrolled_keys": "1", - "efitype": "4m" + "efi_storage_pool": "local", + "pre_enrolled_keys": true, + "efi_type": "4m" } ``` + - `storage_pool` - (string) - Name of the Proxmox storage pool to store the EFI disk on. + + - `efitype` - (string) - Specifies the version of the OVMF firmware to be used. Can be `2m` or `4m`. + Defaults to `4m`. + + - `pre_enrolled_keys` - (boolean) - Whether Microsoft Standard Secure Boot keys should be pre-loaded on + the EFI disk. Defaults to `false`. + +- `efidisk` - (string) - This option is deprecated, please use `efi_config` instead. + - `machine` - (string) - Set themachine type. i440fx or q35. ## Boot Command