0
0
mirror of https://github.com/bpg/terraform-provider-proxmox.git synced 2025-08-22 19:38:35 +00:00

feat(vm): add support for boot_order argument for VM (#219)

* feat(vm): add support for 'boot_order and boot_disk flags for VM

* refactoring (1)

* refactor to use only boot_order argument

---------

Co-authored-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com>
This commit is contained in:
Henri Williams 2023-04-07 20:35:38 +01:00 committed by GitHub
parent 2fa922930f
commit f9e263ad5e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 95 additions and 12 deletions

View File

@ -120,6 +120,8 @@ output "ubuntu_vm_public_key" {
- `bios` - (Optional) The BIOS implementation (defaults to `seabios`). - `bios` - (Optional) The BIOS implementation (defaults to `seabios`).
- `ovmf` - OVMF (UEFI). - `ovmf` - OVMF (UEFI).
- `seabios` - SeaBIOS. - `seabios` - SeaBIOS.
- `boot_order` - (Optional) Specify a list of devices to boot from in the order
they appear in the list (defaults to `[]`).
- `cdrom` - (Optional) The CDROM configuration. - `cdrom` - (Optional) The CDROM configuration.
- `enabled` - (Optional) Whether to enable the CDROM drive (defaults - `enabled` - (Optional) Whether to enable the CDROM drive (defaults
to `false`). to `false`).
@ -361,7 +363,8 @@ output "ubuntu_vm_public_key" {
- `device` - (Optional) The device (defaults to `socket`). - `device` - (Optional) The device (defaults to `socket`).
- `/dev/*` - A host serial device. - `/dev/*` - A host serial device.
- `socket` - A unix socket. - `socket` - A unix socket.
- `scsi_hardware` - (Optional) The SCSI hardware type (defaults to `virtio-scsi-pci`). - `scsi_hardware` - (Optional) The SCSI hardware type (defaults
to `virtio-scsi-pci`).
- `lsi` - LSI Logic SAS1068E. - `lsi` - LSI Logic SAS1068E.
- `lsi53c810` - LSI Logic 53C810. - `lsi53c810` - LSI Logic 53C810.
- `virtio-scsi-pci` - VirtIO SCSI. - `virtio-scsi-pci` - VirtIO SCSI.

View File

@ -33,6 +33,10 @@ type CustomAudioDevice struct {
// CustomAudioDevices handles QEMU audio device parameters. // CustomAudioDevices handles QEMU audio device parameters.
type CustomAudioDevices []CustomAudioDevice type CustomAudioDevices []CustomAudioDevice
type CustomBoot struct {
Order *[]string `json:"order,omitempty" url:"order,omitempty,semicolon"`
}
// CustomCloudInitConfig handles QEMU cloud-init parameters. // CustomCloudInitConfig handles QEMU cloud-init parameters.
type CustomCloudInitConfig struct { type CustomCloudInitConfig struct {
Files *CustomCloudInitFiles `json:"cicustom,omitempty" url:"cicustom,omitempty"` Files *CustomCloudInitFiles `json:"cicustom,omitempty" url:"cicustom,omitempty"`
@ -236,8 +240,7 @@ type VirtualEnvironmentVMCreateRequestBody struct {
BackupFile *string `json:"archive,omitempty" url:"archive,omitempty"` BackupFile *string `json:"archive,omitempty" url:"archive,omitempty"`
BandwidthLimit *int `json:"bwlimit,omitempty" url:"bwlimit,omitempty"` BandwidthLimit *int `json:"bwlimit,omitempty" url:"bwlimit,omitempty"`
BIOS *string `json:"bios,omitempty" url:"bios,omitempty"` BIOS *string `json:"bios,omitempty" url:"bios,omitempty"`
BootDisk *string `json:"bootdisk,omitempty" url:"bootdisk,omitempty"` Boot *CustomBoot `json:"boot,omitempty" url:"boot,omitempty"`
BootOrder *string `json:"boot,omitempty" url:"boot,omitempty"`
CDROM *string `json:"cdrom,omitempty" url:"cdrom,omitempty"` CDROM *string `json:"cdrom,omitempty" url:"cdrom,omitempty"`
CloudInitConfig *CustomCloudInitConfig `json:"cloudinit,omitempty" url:"cloudinit,omitempty"` CloudInitConfig *CustomCloudInitConfig `json:"cloudinit,omitempty" url:"cloudinit,omitempty"`
CPUArchitecture *string `json:"arch,omitempty" url:"arch,omitempty"` CPUArchitecture *string `json:"arch,omitempty" url:"arch,omitempty"`
@ -646,6 +649,14 @@ func (r CustomAudioDevices) EncodeValues(key string, v *url.Values) error {
return nil return nil
} }
func (r CustomBoot) EncodeValues(key string, v *url.Values) error {
if r.Order != nil && len(*r.Order) > 0 {
v.Add(key, fmt.Sprintf("order=%s", strings.Join(*r.Order, ";")))
}
return nil
}
// EncodeValues converts a CustomCloudInitConfig struct to multiple URL values. // EncodeValues converts a CustomCloudInitConfig struct to multiple URL values.
func (r CustomCloudInitConfig) EncodeValues(_ string, v *url.Values) error { func (r CustomCloudInitConfig) EncodeValues(_ string, v *url.Values) error {
if r.Files != nil { if r.Files != nil {
@ -1299,6 +1310,31 @@ func (r *CustomAudioDevice) UnmarshalJSON(b []byte) error {
return nil return nil
} }
// UnmarshalJSON converts a CustomBoot string to an object.
func (r *CustomBoot) UnmarshalJSON(b []byte) error {
var s string
err := json.Unmarshal(b, &s)
if err != nil {
return fmt.Errorf("error unmarshalling CustomBoot: %w", err)
}
pairs := strings.Split(s, ",")
for _, p := range pairs {
v := strings.Split(strings.TrimSpace(p), "=")
if len(v) == 2 {
if v[0] == "order" {
v := strings.Split(strings.TrimSpace(v[1]), ";")
r.Order = &v
}
}
}
return nil
}
// UnmarshalJSON converts a CustomCloudInitFiles string to an object. // UnmarshalJSON converts a CustomCloudInitFiles string to an object.
func (r *CustomCloudInitFiles) UnmarshalJSON(b []byte) error { func (r *CustomCloudInitFiles) UnmarshalJSON(b []byte) error {
var s string var s string

View File

@ -112,6 +112,7 @@ const (
mkResourceVirtualEnvironmentVMRebootAfterCreation = "reboot" mkResourceVirtualEnvironmentVMRebootAfterCreation = "reboot"
mkResourceVirtualEnvironmentVMOnBoot = "on_boot" mkResourceVirtualEnvironmentVMOnBoot = "on_boot"
mkResourceVirtualEnvironmentVMBootOrder = "boot_order"
mkResourceVirtualEnvironmentVMACPI = "acpi" mkResourceVirtualEnvironmentVMACPI = "acpi"
mkResourceVirtualEnvironmentVMAgent = "agent" mkResourceVirtualEnvironmentVMAgent = "agent"
mkResourceVirtualEnvironmentVMAgentEnabled = "enabled" mkResourceVirtualEnvironmentVMAgentEnabled = "enabled"
@ -242,6 +243,15 @@ func VM() *schema.Resource {
Optional: true, Optional: true,
Default: dvResourceVirtualEnvironmentVMOnBoot, Default: dvResourceVirtualEnvironmentVMOnBoot,
}, },
mkResourceVirtualEnvironmentVMBootOrder: {
Type: schema.TypeList,
Description: "The guest will attempt to boot from devices in the order they appear here",
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
DefaultFunc: func() (interface{}, error) {
return []interface{}{}, nil
},
},
mkResourceVirtualEnvironmentVMACPI: { mkResourceVirtualEnvironmentVMACPI: {
Type: schema.TypeBool, Type: schema.TypeBool,
Description: "Whether to enable ACPI", Description: "Whether to enable ACPI",
@ -1915,15 +1925,33 @@ func vmCreateCustom(ctx context.Context, d *schema.ResourceData, m interface{})
var memorySharedObject *proxmox.CustomSharedMemory var memorySharedObject *proxmox.CustomSharedMemory
bootDisk := "scsi0" var bootOrderConverted []string
bootOrder := "c"
if cdromEnabled { if cdromEnabled {
bootOrder = "cd" bootOrderConverted = []string{"ide3"}
}
bootOrder := d.Get(mkResourceVirtualEnvironmentVMBootOrder).([]interface{})
//nolint:nestif
if len(bootOrder) == 0 {
if sataDeviceObjects != nil {
bootOrderConverted = append(bootOrderConverted, "sata0")
}
if scsiDeviceObjects != nil {
bootOrderConverted = append(bootOrderConverted, "scsi0")
}
if virtioDeviceObjects != nil {
bootOrderConverted = append(bootOrderConverted, "virtio0")
}
if networkDeviceObjects != nil {
bootOrderConverted = append(bootOrderConverted, "net0")
}
} else {
bootOrderConverted = make([]string, len(bootOrder))
for i, device := range bootOrder {
bootOrderConverted[i] = device.(string)
}
} }
cpuFlagsConverted := make([]string, len(cpuFlags)) cpuFlagsConverted := make([]string, len(cpuFlags))
for fi, flag := range cpuFlags { for fi, flag := range cpuFlags {
cpuFlagsConverted[fi] = flag.(string) cpuFlagsConverted[fi] = flag.(string)
} }
@ -1959,10 +1987,11 @@ func vmCreateCustom(ctx context.Context, d *schema.ResourceData, m interface{})
TrimClonedDisks: &agentTrim, TrimClonedDisks: &agentTrim,
Type: &agentType, Type: &agentType,
}, },
AudioDevices: audioDevices, AudioDevices: audioDevices,
BIOS: &bios, BIOS: &bios,
BootDisk: &bootDisk, Boot: &proxmox.CustomBoot{
BootOrder: &bootOrder, Order: &bootOrderConverted,
},
CloudInitConfig: initializationConfig, CloudInitConfig: initializationConfig,
CPUCores: &cpuCores, CPUCores: &cpuCores,
CPUEmulation: &proxmox.CustomCPUEmulation{ CPUEmulation: &proxmox.CustomCPUEmulation{
@ -4036,6 +4065,19 @@ func vmUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.D
rebootRequired = true rebootRequired = true
} }
// Prepare the new boot configuration.
if d.HasChange(mkResourceVirtualEnvironmentVMBootOrder) {
bootOrder := d.Get(mkResourceVirtualEnvironmentVMBootOrder).([]interface{})
bootOrderConverted := make([]string, len(bootOrder))
for i, device := range bootOrder {
bootOrderConverted[i] = device.(string)
}
updateBody.Boot = &proxmox.CustomBoot{
Order: &bootOrderConverted,
}
rebootRequired = true
}
// Prepare the new CDROM configuration. // Prepare the new CDROM configuration.
if d.HasChange(mkResourceVirtualEnvironmentVMCDROM) { if d.HasChange(mkResourceVirtualEnvironmentVMCDROM) {
cdromBlock, err := getSchemaBlock( cdromBlock, err := getSchemaBlock(

View File

@ -38,6 +38,7 @@ func TestVMSchema(t *testing.T) {
mkResourceVirtualEnvironmentVMAgent, mkResourceVirtualEnvironmentVMAgent,
mkResourceVirtualEnvironmentVMAudioDevice, mkResourceVirtualEnvironmentVMAudioDevice,
mkResourceVirtualEnvironmentVMBIOS, mkResourceVirtualEnvironmentVMBIOS,
mkResourceVirtualEnvironmentVMBootOrder,
mkResourceVirtualEnvironmentVMCDROM, mkResourceVirtualEnvironmentVMCDROM,
mkResourceVirtualEnvironmentVMClone, mkResourceVirtualEnvironmentVMClone,
mkResourceVirtualEnvironmentVMCPU, mkResourceVirtualEnvironmentVMCPU,
@ -73,6 +74,7 @@ func TestVMSchema(t *testing.T) {
mkResourceVirtualEnvironmentVMAgent: schema.TypeList, mkResourceVirtualEnvironmentVMAgent: schema.TypeList,
mkResourceVirtualEnvironmentVMAudioDevice: schema.TypeList, mkResourceVirtualEnvironmentVMAudioDevice: schema.TypeList,
mkResourceVirtualEnvironmentVMBIOS: schema.TypeString, mkResourceVirtualEnvironmentVMBIOS: schema.TypeString,
mkResourceVirtualEnvironmentVMBootOrder: schema.TypeList,
mkResourceVirtualEnvironmentVMCDROM: schema.TypeList, mkResourceVirtualEnvironmentVMCDROM: schema.TypeList,
mkResourceVirtualEnvironmentVMCPU: schema.TypeList, mkResourceVirtualEnvironmentVMCPU: schema.TypeList,
mkResourceVirtualEnvironmentVMDescription: schema.TypeString, mkResourceVirtualEnvironmentVMDescription: schema.TypeString,