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

feat(lxc): add container startup options (#923)

Signed-off-by: Jason Kossis <jkossis@gmail.om>
Co-authored-by: Jason Kossis <jkossis@gmail.om>
This commit is contained in:
Jason Kossis 2024-01-17 20:45:30 -05:00 committed by GitHub
parent 85109cbe3d
commit c9c3067b61
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 140 additions and 0 deletions

View File

@ -59,6 +59,11 @@ resource "proxmox_virtual_environment_container" "ubuntu_container" {
path = "/mnt/volume"
}
startup {
order = "3"
up_delay = "60"
down_delay = "60"
}
}
resource "proxmox_virtual_environment_download_file" "latest_ubuntu_22_jammy_lxc_img" {
@ -194,6 +199,13 @@ output "ubuntu_container_public_key" {
- `unmanaged` - Unmanaged.
- `pool_id` - (Optional) The identifier for a pool to assign the container to.
- `started` - (Optional) Whether to start the container (defaults to `true`).
- `startup` - (Optional) Defines startup and shutdown behavior of the container.
- `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 container is started.
- `down` - (Optional) A non-negative number defining the delay in seconds
before the next container is shut down.
- `start_on_boot` - (Optional) Automatically start container when the host system boots (defaults to `true`).
- `tags` - (Optional) A list of tags the container tags. This is only meta
information (defaults to `[]`). Note: Proxmox always sorts the container tags.

View File

@ -56,6 +56,12 @@ resource "proxmox_virtual_environment_container" "example_template" {
"example",
"terraform",
]
startup {
order = "3"
up_delay = "60"
down_delay = "60"
}
}
resource "proxmox_virtual_environment_container" "example" {

View File

@ -66,6 +66,9 @@ const (
dvResourceVirtualEnvironmentContainerOperatingSystemType = "unmanaged"
dvResourceVirtualEnvironmentContainerPoolID = ""
dvResourceVirtualEnvironmentContainerStarted = true
dvResourceVirtualEnvironmentContainerStartupOrder = -1
dvResourceVirtualEnvironmentContainerStartupUpDelay = -1
dvResourceVirtualEnvironmentContainerStartupDownDelay = -1
dvResourceVirtualEnvironmentContainerStartOnBoot = true
dvResourceVirtualEnvironmentContainerTemplate = false
dvResourceVirtualEnvironmentContainerUnprivileged = false
@ -139,6 +142,10 @@ const (
mkResourceVirtualEnvironmentContainerOperatingSystemType = "type"
mkResourceVirtualEnvironmentContainerPoolID = "pool_id"
mkResourceVirtualEnvironmentContainerStarted = "started"
mkResourceVirtualEnvironmentContainerStartup = "startup"
mkResourceVirtualEnvironmentContainerStartupOrder = "order"
mkResourceVirtualEnvironmentContainerStartupUpDelay = "up_delay"
mkResourceVirtualEnvironmentContainerStartupDownDelay = "down_delay"
mkResourceVirtualEnvironmentContainerStartOnBoot = "start_on_boot"
mkResourceVirtualEnvironmentContainerTags = "tags"
mkResourceVirtualEnvironmentContainerTemplate = "template"
@ -759,6 +766,35 @@ func Container() *schema.Resource {
return d.Get(mkResourceVirtualEnvironmentContainerTemplate).(bool)
},
},
mkResourceVirtualEnvironmentContainerStartup: {
Type: schema.TypeList,
Description: "Defines startup and shutdown behavior of the container",
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
mkResourceVirtualEnvironmentContainerStartupOrder: {
Type: schema.TypeInt,
Description: "A non-negative number defining the general startup order",
Optional: true,
Default: dvResourceVirtualEnvironmentContainerStartupOrder,
},
mkResourceVirtualEnvironmentContainerStartupUpDelay: {
Type: schema.TypeInt,
Description: "A non-negative number defining the delay in seconds before the next container is started",
Optional: true,
Default: dvResourceVirtualEnvironmentContainerStartupUpDelay,
},
mkResourceVirtualEnvironmentContainerStartupDownDelay: {
Type: schema.TypeInt,
Description: "A non-negative number defining the delay in seconds before the next container is shut down",
Optional: true,
Default: dvResourceVirtualEnvironmentContainerStartupDownDelay,
},
},
},
MaxItems: 1,
MinItems: 0,
},
mkResourceVirtualEnvironmentContainerStartOnBoot: {
Type: schema.TypeBool,
Description: "Automatically start container when the host system boots.",
@ -921,6 +957,8 @@ func containerCreateClone(ctx context.Context, d *schema.ResourceData, m interfa
startOnBoot := types.CustomBool(d.Get(mkResourceVirtualEnvironmentContainerStartOnBoot).(bool))
updateBody.StartOnBoot = &startOnBoot
updateBody.StartupBehavior = containerGetStartupBehavior(d)
console := d.Get(mkResourceVirtualEnvironmentContainerConsole).([]interface{})
if len(console) > 0 {
@ -1526,6 +1564,7 @@ func containerCreateCustom(ctx context.Context, d *schema.ResourceData, m interf
poolID := d.Get(mkResourceVirtualEnvironmentContainerPoolID).(string)
started := types.CustomBool(d.Get(mkResourceVirtualEnvironmentContainerStarted).(bool))
startOnBoot := types.CustomBool(d.Get(mkResourceVirtualEnvironmentContainerStartOnBoot).(bool))
startupBehavior := containerGetStartupBehavior(d)
tags := d.Get(mkResourceVirtualEnvironmentContainerTags).([]interface{})
template := types.CustomBool(d.Get(mkResourceVirtualEnvironmentContainerTemplate).(bool))
unprivileged := types.CustomBool(d.Get(mkResourceVirtualEnvironmentContainerUnprivileged).(bool))
@ -1557,6 +1596,7 @@ func containerCreateCustom(ctx context.Context, d *schema.ResourceData, m interf
RootFS: rootFS,
Start: &started,
StartOnBoot: &startOnBoot,
StartupBehavior: startupBehavior,
Swap: &memorySwap,
Template: &template,
TTY: &consoleTTYCount,
@ -1766,6 +1806,34 @@ func containerGetTagsString(d *schema.ResourceData) string {
return strings.Join(sanitizedTags, ";")
}
func containerGetStartupBehavior(d *schema.ResourceData) *containers.CustomStartupBehavior {
startup := d.Get(mkResourceVirtualEnvironmentContainerStartup).([]interface{})
if len(startup) > 0 {
startupBlock := startup[0].(map[string]interface{})
startupOrder := startupBlock[mkResourceVirtualEnvironmentContainerStartupOrder].(int)
startupUpDelay := startupBlock[mkResourceVirtualEnvironmentContainerStartupUpDelay].(int)
startupDownDelay := startupBlock[mkResourceVirtualEnvironmentContainerStartupDownDelay].(int)
order := containers.CustomStartupBehavior{}
if startupUpDelay >= 0 {
order.Up = &startupUpDelay
}
if startupDownDelay >= 0 {
order.Down = &startupDownDelay
}
if startupOrder >= 0 {
order.Order = &startupOrder
}
return &order
}
return nil
}
func containerGetFeatures(resource *schema.Resource, d *schema.ResourceData) (*containers.CustomFeatures, error) {
featuresBlock, err := structure.GetSchemaBlock(
resource,
@ -2317,6 +2385,53 @@ func containerRead(ctx context.Context, d *schema.ResourceData, m interface{}) d
diags = append(diags, diag.FromErr(err)...)
}
// Compare the startup behavior to the one stored in the state.
var startup map[string]interface{}
//nolint:nestif
if containerConfig.StartupBehavior != nil {
startup = map[string]interface{}{}
if containerConfig.StartupBehavior.Order != nil {
startup[mkResourceVirtualEnvironmentContainerStartupOrder] = *containerConfig.StartupBehavior.Order
} else {
startup[mkResourceVirtualEnvironmentContainerStartupOrder] = dvResourceVirtualEnvironmentContainerStartupOrder
}
if containerConfig.StartupBehavior.Up != nil {
startup[mkResourceVirtualEnvironmentContainerStartupUpDelay] = *containerConfig.StartupBehavior.Up
} else {
startup[mkResourceVirtualEnvironmentContainerStartupUpDelay] = dvResourceVirtualEnvironmentContainerStartupUpDelay
}
if containerConfig.StartupBehavior.Down != nil {
startup[mkResourceVirtualEnvironmentContainerStartupDownDelay] = *containerConfig.StartupBehavior.Down
} else {
//nolint:lll
startup[mkResourceVirtualEnvironmentContainerStartupDownDelay] = dvResourceVirtualEnvironmentContainerStartupDownDelay
}
}
currentStartup := d.Get(mkResourceVirtualEnvironmentContainerStartup).([]interface{})
//nolint:gocritic
if len(clone) > 0 {
if len(currentStartup) > 0 {
err := d.Set(mkResourceVirtualEnvironmentContainerStartup, []interface{}{startup})
diags = append(diags, diag.FromErr(err)...)
}
} else if len(startup) == 0 {
err := d.Set(mkResourceVirtualEnvironmentContainerStartup, []interface{}{})
diags = append(diags, diag.FromErr(err)...)
} else if len(currentStartup) > 0 ||
startup[mkResourceVirtualEnvironmentContainerStartupOrder] != mkResourceVirtualEnvironmentContainerStartupOrder ||
startup[mkResourceVirtualEnvironmentContainerStartupUpDelay] != dvResourceVirtualEnvironmentContainerStartupUpDelay ||
//nolint:lll
startup[mkResourceVirtualEnvironmentContainerStartupDownDelay] != dvResourceVirtualEnvironmentContainerStartupDownDelay {
err := d.Set(mkResourceVirtualEnvironmentContainerStartup, []interface{}{startup})
diags = append(diags, diag.FromErr(err)...)
}
// Compare the operating system configuration to the one stored in the state.
operatingSystem := map[string]interface{}{}
@ -2740,6 +2855,13 @@ func containerUpdate(ctx context.Context, d *schema.ResourceData, m interface{})
rebootRequired = true
}
if d.HasChange(mkResourceVirtualEnvironmentContainerStartup) {
updateBody.StartupBehavior = containerGetStartupBehavior(d)
if updateBody.StartupBehavior == nil {
updateBody.Delete = append(updateBody.Delete, "startup")
}
}
// Prepare the new operating system configuration.
if d.HasChange(mkResourceVirtualEnvironmentContainerOperatingSystem) {
operatingSystem, err := structure.GetSchemaBlock(