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`).
- `ovmf` - OVMF (UEFI).
- `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.
- `enabled` - (Optional) Whether to enable the CDROM drive (defaults
to `false`).
@ -361,7 +363,8 @@ output "ubuntu_vm_public_key" {
- `device` - (Optional) The device (defaults to `socket`).
- `/dev/*` - A host serial device.
- `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.
- `lsi53c810` - LSI Logic 53C810.
- `virtio-scsi-pci` - VirtIO SCSI.

View File

@ -33,6 +33,10 @@ type CustomAudioDevice struct {
// CustomAudioDevices handles QEMU audio device parameters.
type CustomAudioDevices []CustomAudioDevice
type CustomBoot struct {
Order *[]string `json:"order,omitempty" url:"order,omitempty,semicolon"`
}
// CustomCloudInitConfig handles QEMU cloud-init parameters.
type CustomCloudInitConfig struct {
Files *CustomCloudInitFiles `json:"cicustom,omitempty" url:"cicustom,omitempty"`
@ -236,8 +240,7 @@ type VirtualEnvironmentVMCreateRequestBody struct {
BackupFile *string `json:"archive,omitempty" url:"archive,omitempty"`
BandwidthLimit *int `json:"bwlimit,omitempty" url:"bwlimit,omitempty"`
BIOS *string `json:"bios,omitempty" url:"bios,omitempty"`
BootDisk *string `json:"bootdisk,omitempty" url:"bootdisk,omitempty"`
BootOrder *string `json:"boot,omitempty" url:"boot,omitempty"`
Boot *CustomBoot `json:"boot,omitempty" url:"boot,omitempty"`
CDROM *string `json:"cdrom,omitempty" url:"cdrom,omitempty"`
CloudInitConfig *CustomCloudInitConfig `json:"cloudinit,omitempty" url:"cloudinit,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
}
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.
func (r CustomCloudInitConfig) EncodeValues(_ string, v *url.Values) error {
if r.Files != nil {
@ -1299,6 +1310,31 @@ func (r *CustomAudioDevice) UnmarshalJSON(b []byte) error {
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.
func (r *CustomCloudInitFiles) UnmarshalJSON(b []byte) error {
var s string

View File

@ -112,6 +112,7 @@ const (
mkResourceVirtualEnvironmentVMRebootAfterCreation = "reboot"
mkResourceVirtualEnvironmentVMOnBoot = "on_boot"
mkResourceVirtualEnvironmentVMBootOrder = "boot_order"
mkResourceVirtualEnvironmentVMACPI = "acpi"
mkResourceVirtualEnvironmentVMAgent = "agent"
mkResourceVirtualEnvironmentVMAgentEnabled = "enabled"
@ -242,6 +243,15 @@ func VM() *schema.Resource {
Optional: true,
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: {
Type: schema.TypeBool,
Description: "Whether to enable ACPI",
@ -1915,15 +1925,33 @@ func vmCreateCustom(ctx context.Context, d *schema.ResourceData, m interface{})
var memorySharedObject *proxmox.CustomSharedMemory
bootDisk := "scsi0"
bootOrder := "c"
var bootOrderConverted []string
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))
for fi, flag := range cpuFlags {
cpuFlagsConverted[fi] = flag.(string)
}
@ -1959,10 +1987,11 @@ func vmCreateCustom(ctx context.Context, d *schema.ResourceData, m interface{})
TrimClonedDisks: &agentTrim,
Type: &agentType,
},
AudioDevices: audioDevices,
BIOS: &bios,
BootDisk: &bootDisk,
BootOrder: &bootOrder,
AudioDevices: audioDevices,
BIOS: &bios,
Boot: &proxmox.CustomBoot{
Order: &bootOrderConverted,
},
CloudInitConfig: initializationConfig,
CPUCores: &cpuCores,
CPUEmulation: &proxmox.CustomCPUEmulation{
@ -4036,6 +4065,19 @@ func vmUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.D
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.
if d.HasChange(mkResourceVirtualEnvironmentVMCDROM) {
cdromBlock, err := getSchemaBlock(

View File

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