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 start/shutdown order configuration (#445)

This commit is contained in:
Pavel Boldyrev 2023-07-29 22:55:12 -04:00 committed by GitHub
parent cfe3d96576
commit b045746a94
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 149 additions and 3 deletions

View File

@ -26,6 +26,12 @@ resource "proxmox_virtual_environment_vm" "ubuntu_vm" {
enabled = true
}
startup {
order = "3"
up_delay = "60"
down_delay = "60"
}
disk {
datastore_id = "local-lvm"
file_id = proxmox_virtual_environment_file.ubuntu_cloud_image.id
@ -410,6 +416,13 @@ output "ubuntu_vm_public_key" {
- `pvscsi` - VMware Paravirtual SCSI.
- `started` - (Optional) Whether to start the virtual machine (defaults
to `true`).
- `startup` - (Optional) Defines startup and shutdown behavior of the VM.
- `order` - (Required) A non-negative number defining the general startup
order.
- `up` - (Optional) A non-negative number defining the delay in seconds
before the next VM is started.
- `down` - (Optional) A non-negative number defining the delay in seconds
before the next VM is shut down.
- `tablet_device` - (Optional) Whether to enable the USB tablet device (defaults
to `true`).
- `tags` - (Optional) A list of tags of the VM. This is only meta information (

View File

@ -13,6 +13,12 @@ resource "proxmox_virtual_environment_vm" "example_template" {
numa = true
}
startup {
order = "3"
up_delay = "60"
down_delay = "60"
}
efi_disk {
datastore_id = local.datastore_id
file_format = "raw"

View File

@ -104,6 +104,9 @@ const (
dvResourceVirtualEnvironmentVMPoolID = ""
dvResourceVirtualEnvironmentVMSerialDeviceDevice = "socket"
dvResourceVirtualEnvironmentVMStarted = true
dvResourceVirtualEnvironmentVMStartupOrder = -1
dvResourceVirtualEnvironmentVMStartupUpDelay = -1
dvResourceVirtualEnvironmentVMStartupDownDelay = -1
dvResourceVirtualEnvironmentVMTabletDevice = true
dvResourceVirtualEnvironmentVMTemplate = false
dvResourceVirtualEnvironmentVMTimeoutClone = 1800
@ -232,6 +235,10 @@ const (
mkResourceVirtualEnvironmentVMSerialDevice = "serial_device"
mkResourceVirtualEnvironmentVMSerialDeviceDevice = "device"
mkResourceVirtualEnvironmentVMStarted = "started"
mkResourceVirtualEnvironmentVMStartup = "startup"
mkResourceVirtualEnvironmentVMStartupOrder = "order"
mkResourceVirtualEnvironmentVMStartupUpDelay = "up_delay"
mkResourceVirtualEnvironmentVMStartupDownDelay = "down_delay"
mkResourceVirtualEnvironmentVMTabletDevice = "tablet_device"
mkResourceVirtualEnvironmentVMTags = "tags"
mkResourceVirtualEnvironmentVMTemplate = "template"
@ -1214,6 +1221,47 @@ func VM() *schema.Resource {
return d.Get(mkResourceVirtualEnvironmentVMTemplate).(bool)
},
},
mkResourceVirtualEnvironmentVMStartup: {
Type: schema.TypeList,
Description: "Defines startup and shutdown behavior of the VM",
Optional: true,
DefaultFunc: func() (interface{}, error) {
return []interface{}{
map[string]interface{}{
mkResourceVirtualEnvironmentVMStartupOrder: dvResourceVirtualEnvironmentVMStartupOrder,
mkResourceVirtualEnvironmentVMVGAMemory: dvResourceVirtualEnvironmentVMVGAMemory,
mkResourceVirtualEnvironmentVMVGAType: dvResourceVirtualEnvironmentVMVGAType,
},
}, nil
},
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
mkResourceVirtualEnvironmentVMStartupOrder: {
Type: schema.TypeInt,
Description: "A non-negative number defining the general startup order",
Optional: true,
Default: dvResourceVirtualEnvironmentVMStartupOrder,
},
mkResourceVirtualEnvironmentVMStartupUpDelay: {
Type: schema.TypeInt,
Description: "A non-negative number defining the delay in seconds before the next VM is started",
Optional: true,
Default: dvResourceVirtualEnvironmentVMStartupUpDelay,
ValidateDiagFunc: validation.ToDiagFunc(validation.IntAtLeast(0)),
},
mkResourceVirtualEnvironmentVMStartupDownDelay: {
Type: schema.TypeInt,
Description: "A non-negative number defining the delay in seconds before the next VM is shut down",
Optional: true,
Default: dvResourceVirtualEnvironmentVMStartupDownDelay,
ValidateDiagFunc: validation.ToDiagFunc(validation.IntAtLeast(0)),
},
},
},
MaxItems: 1,
MinItems: 0,
},
mkResourceVirtualEnvironmentVMTabletDevice: {
Type: schema.TypeBool,
Description: "Whether to enable the USB tablet device",
@ -1778,6 +1826,8 @@ func vmCreateClone(ctx context.Context, d *schema.ResourceData, m interface{}) d
updateBody.StartOnBoot = &onBoot
updateBody.StartupOrder = vmGetStartupOrder(d)
//nolint:gosimple
if tabletDevice != dvResourceVirtualEnvironmentVMTabletDevice {
updateBody.TabletDeviceEnabled = &tabletDevice
@ -2148,6 +2198,8 @@ func vmCreateCustom(ctx context.Context, d *schema.ResourceData, m interface{})
serialDevices := vmGetSerialDeviceList(d)
startupOrder := vmGetStartupOrder(d)
onBoot := types.CustomBool(d.Get(mkResourceVirtualEnvironmentVMOnBoot).(bool))
tabletDevice := types.CustomBool(d.Get(mkResourceVirtualEnvironmentVMTabletDevice).(bool))
template := types.CustomBool(d.Get(mkResourceVirtualEnvironmentVMTemplate).(bool))
@ -2268,6 +2320,7 @@ func vmCreateCustom(ctx context.Context, d *schema.ResourceData, m interface{})
SerialDevices: serialDevices,
SharedMemory: memorySharedObject,
StartOnBoot: &onBoot,
StartupOrder: startupOrder,
TabletDeviceEnabled: &tabletDevice,
Template: &template,
VGADevice: vgaDevice,
@ -3009,6 +3062,33 @@ func vmGetSerialDeviceList(d *schema.ResourceData) vms.CustomSerialDevices {
return list
}
func vmGetStartupOrder(d *schema.ResourceData) *vms.CustomStartupOrder {
startup := d.Get(mkResourceVirtualEnvironmentVMStartup).([]interface{})
if len(startup) > 0 {
startupBlock := startup[0].(map[string]interface{})
startupOrder := startupBlock[mkResourceVirtualEnvironmentVMStartupOrder].(int)
startupUpDelay := startupBlock[mkResourceVirtualEnvironmentVMStartupUpDelay].(int)
startupDownDelay := startupBlock[mkResourceVirtualEnvironmentVMStartupDownDelay].(int)
order := vms.CustomStartupOrder{}
if startupUpDelay >= 0 {
order.Up = &startupUpDelay
}
if startupDownDelay >= 0 {
order.Down = &startupDownDelay
}
if startupOrder >= 0 {
order.Order = &startupOrder
return &order
}
}
return nil
}
func vmGetTagsString(d *schema.ResourceData) string {
tags := d.Get(mkResourceVirtualEnvironmentVMTags).([]interface{})
var sanitizedTags []string
@ -4064,6 +4144,53 @@ func vmReadCustom(
diags = append(diags, diag.FromErr(err)...)
}
// Compare the startup order to the one stored in the state.
startup := map[string]interface{}{}
//nolint:nestif
if vmConfig.StartupOrder != nil {
if vmConfig.StartupOrder.Order != nil {
startup[mkResourceVirtualEnvironmentVMStartupOrder] = *vmConfig.StartupOrder.Order
} else {
startup[mkResourceVirtualEnvironmentVMStartupOrder] = dvResourceVirtualEnvironmentVMStartupOrder
}
if vmConfig.StartupOrder.Up != nil {
startup[mkResourceVirtualEnvironmentVMStartupUpDelay] = *vmConfig.StartupOrder.Up
} else {
startup[mkResourceVirtualEnvironmentVMStartupUpDelay] = dvResourceVirtualEnvironmentVMStartupUpDelay
}
if vmConfig.StartupOrder.Down != nil {
startup[mkResourceVirtualEnvironmentVMStartupDownDelay] = *vmConfig.StartupOrder.Down
} else {
startup[mkResourceVirtualEnvironmentVMStartupDownDelay] = dvResourceVirtualEnvironmentVMStartupDownDelay
}
} else {
startup[mkResourceVirtualEnvironmentVMStartupOrder] = dvResourceVirtualEnvironmentVMStartupOrder
startup[mkResourceVirtualEnvironmentVMStartupUpDelay] = dvResourceVirtualEnvironmentVMStartupUpDelay
startup[mkResourceVirtualEnvironmentVMStartupDownDelay] = dvResourceVirtualEnvironmentVMStartupDownDelay
}
currentStartup := d.Get(mkResourceVirtualEnvironmentVMStartup).([]interface{})
//nolint:gocritic
if len(clone) > 0 {
if len(currentStartup) > 0 {
err := d.Set(mkResourceVirtualEnvironmentVMStartup, []interface{}{startup})
diags = append(diags, diag.FromErr(err)...)
}
} else if len(currentStartup) > 0 ||
startup[mkResourceVirtualEnvironmentVMStartupOrder] != mkResourceVirtualEnvironmentVMStartupOrder ||
startup[mkResourceVirtualEnvironmentVMStartupUpDelay] != dvResourceVirtualEnvironmentVMStartupUpDelay ||
startup[mkResourceVirtualEnvironmentVMStartupDownDelay] != dvResourceVirtualEnvironmentVMStartupDownDelay {
err := d.Set(mkResourceVirtualEnvironmentVMStartup, []interface{}{startup})
diags = append(diags, diag.FromErr(err)...)
} else {
err := d.Set(mkResourceVirtualEnvironmentVMStartup, []interface{}{})
diags = append(diags, diag.FromErr(err)...)
}
// Compare the VGA configuration to the one stored in the state.
vga := map[string]interface{}{}