0
0
mirror of https://github.com/bpg/terraform-provider-proxmox.git synced 2025-06-30 10:33:46 +00:00

feat(vm): add support for initialization.upgrade attribute (#1203)

Signed-off-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com>
This commit is contained in:
Pavel Boldyrev 2024-04-10 19:43:39 -04:00 committed by GitHub
parent 8515be686c
commit 59972dc1b5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 65 additions and 10 deletions

View File

@ -372,6 +372,7 @@ output "ubuntu_vm_public_key" {
all vendor data passed to the VM via cloud-init. all vendor data passed to the VM via cloud-init.
- `meta_data_file_id` - (Optional) The identifier for a file containing - `meta_data_file_id` - (Optional) The identifier for a file containing
all meta data passed to the VM via cloud-init. all meta data passed to the VM via cloud-init.
- `upgrade` - (Optional) Whether to do an automatic package upgrade after the first boot (defaults to `true`).
- `keyboard_layout` - (Optional) The keyboard layout (defaults to `en-us`). - `keyboard_layout` - (Optional) The keyboard layout (defaults to `en-us`).
- `da` - Danish. - `da` - Danish.
- `de` - German. - `de` - German.

View File

@ -183,7 +183,7 @@ func TestAccResourceVMInitialization(t *testing.T) {
name string name string
step []resource.TestStep step []resource.TestStep
}{ }{
{"initialization works with cloud-init config provided over SCSI interface", []resource.TestStep{{ {"custom cloud-init: use SCSI interface", []resource.TestStep{{
Config: te.renderConfig(` Config: te.renderConfig(`
resource "proxmox_virtual_environment_file" "cloud_config" { resource "proxmox_virtual_environment_file" "cloud_config" {
content_type = "snippets" content_type = "snippets"
@ -202,7 +202,7 @@ EOF
} }
} }
resource "proxmox_virtual_environment_vm" "test_vm_network1" { resource "proxmox_virtual_environment_vm" "test_vm_cloudinit1" {
node_name = "{{.NodeName}}" node_name = "{{.NodeName}}"
started = true started = true
agent { agent {
@ -246,6 +246,37 @@ EOF
overwrite_unmanaged = true overwrite_unmanaged = true
}`), }`),
}}}, }}},
{"native cloud-init: upgrade packages by default", []resource.TestStep{{
Config: te.renderConfig(`
resource "proxmox_virtual_environment_vm" "test_vm_cloudinit2" {
node_name = "{{.NodeName}}"
started = false
initialization {
}
}`),
Check: resource.ComposeTestCheckFunc(
testResourceAttributes("proxmox_virtual_environment_vm.test_vm_cloudinit2", map[string]string{
"initialization.0.upgrade": "true",
}),
),
}}},
{"native cloud-init: do not upgrade packages", []resource.TestStep{
{
Config: te.renderConfig(`
resource "proxmox_virtual_environment_vm" "test_vm_cloudinit3" {
node_name = "{{.NodeName}}"
started = false
initialization {
upgrade = false
}
}`),
Check: resource.ComposeTestCheckFunc(
testResourceAttributes("proxmox_virtual_environment_vm.test_vm_cloudinit3", map[string]string{
"initialization.0.upgrade": "false",
}),
),
},
}},
} }
for _, tt := range tests { for _, tt := range tests {

View File

@ -49,6 +49,7 @@ type CustomCloudInitConfig struct {
SearchDomain *string `json:"searchdomain,omitempty" url:"searchdomain,omitempty"` SearchDomain *string `json:"searchdomain,omitempty" url:"searchdomain,omitempty"`
SSHKeys *CustomCloudInitSSHKeys `json:"sshkeys,omitempty" url:"sshkeys,omitempty"` SSHKeys *CustomCloudInitSSHKeys `json:"sshkeys,omitempty" url:"sshkeys,omitempty"`
Type *string `json:"citype,omitempty" url:"citype,omitempty"` Type *string `json:"citype,omitempty" url:"citype,omitempty"`
Upgrade *types.CustomBool `json:"ciupgrade,omitempty" url:"ciupgrade,omitempty,int"`
Username *string `json:"ciuser,omitempty" url:"ciuser,omitempty"` Username *string `json:"ciuser,omitempty" url:"ciuser,omitempty"`
} }
@ -360,6 +361,7 @@ type GetResponseData struct {
CloudInitSSHKeys *CustomCloudInitSSHKeys `json:"sshkeys,omitempty"` CloudInitSSHKeys *CustomCloudInitSSHKeys `json:"sshkeys,omitempty"`
CloudInitType *string `json:"citype,omitempty"` CloudInitType *string `json:"citype,omitempty"`
CloudInitUsername *string `json:"ciuser,omitempty"` CloudInitUsername *string `json:"ciuser,omitempty"`
CloudInitUpgrade *types.CustomBool `json:"ciupgrade,omitempty"`
CPUArchitecture *string `json:"arch,omitempty"` CPUArchitecture *string `json:"arch,omitempty"`
CPUCores *int `json:"cores,omitempty"` CPUCores *int `json:"cores,omitempty"`
CPUEmulation *CustomCPUEmulation `json:"cpu,omitempty"` CPUEmulation *CustomCPUEmulation `json:"cpu,omitempty"`
@ -800,6 +802,14 @@ func (r CustomCloudInitConfig) EncodeValues(_ string, v *url.Values) error {
v.Add("citype", *r.Type) v.Add("citype", *r.Type)
} }
if r.Upgrade != nil {
if *r.Upgrade {
v.Add("ciupgrade", "1")
} else {
v.Add("ciupgrade", "0")
}
}
if r.Username != nil { if r.Username != nil {
v.Add("ciuser", *r.Username) v.Add("ciuser", *r.Username)
} }

View File

@ -17,10 +17,11 @@ import (
"strings" "strings"
"time" "time"
"golang.org/x/exp/maps"
"github.com/bpg/terraform-provider-proxmox/proxmoxtf/resource/vm/disk" "github.com/bpg/terraform-provider-proxmox/proxmoxtf/resource/vm/disk"
"github.com/bpg/terraform-provider-proxmox/proxmoxtf/resource/vm/network" "github.com/bpg/terraform-provider-proxmox/proxmoxtf/resource/vm/network"
"github.com/bpg/terraform-provider-proxmox/utils" "github.com/bpg/terraform-provider-proxmox/utils"
"golang.org/x/exp/maps"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
"github.com/google/uuid" "github.com/google/uuid"
@ -222,6 +223,7 @@ const (
mkInitializationVendorDataFileID = "vendor_data_file_id" mkInitializationVendorDataFileID = "vendor_data_file_id"
mkInitializationNetworkDataFileID = "network_data_file_id" mkInitializationNetworkDataFileID = "network_data_file_id"
mkInitializationMetaDataFileID = "meta_data_file_id" mkInitializationMetaDataFileID = "meta_data_file_id"
mkInitializationUpgrade = "upgrade"
mkKeyboardLayout = "keyboard_layout" mkKeyboardLayout = "keyboard_layout"
mkKVMArguments = "kvm_arguments" mkKVMArguments = "kvm_arguments"
@ -896,6 +898,13 @@ func VM() *schema.Resource {
Default: dvInitializationType, Default: dvInitializationType,
ValidateDiagFunc: CloudInitTypeValidator(), ValidateDiagFunc: CloudInitTypeValidator(),
}, },
mkInitializationUpgrade: {
Type: schema.TypeBool,
Description: "Whether to upgrade the cloud-init configuration",
Optional: true,
ForceNew: true,
Default: true,
},
}, },
}, },
MaxItems: 1, MaxItems: 1,
@ -2899,18 +2908,15 @@ func vmGetCloudInitConfig(d *schema.ResourceData) *vms.CustomCloudInitConfig {
} }
password := initializationUserAccountBlock[mkInitializationUserAccountPassword].(string) password := initializationUserAccountBlock[mkInitializationUserAccountPassword].(string)
if password != "" { if password != "" {
initializationConfig.Password = &password initializationConfig.Password = &password
} }
username := initializationUserAccountBlock[mkInitializationUserAccountUsername].(string) username := initializationUserAccountBlock[mkInitializationUserAccountUsername].(string)
initializationConfig.Username = &username initializationConfig.Username = &username
} }
initializationUserDataFileID := initializationBlock[mkInitializationUserDataFileID].(string) initializationUserDataFileID := initializationBlock[mkInitializationUserDataFileID].(string)
if initializationUserDataFileID != "" { if initializationUserDataFileID != "" {
initializationConfig.Files = &vms.CustomCloudInitFiles{ initializationConfig.Files = &vms.CustomCloudInitFiles{
UserVolume: &initializationUserDataFileID, UserVolume: &initializationUserDataFileID,
@ -2918,7 +2924,6 @@ func vmGetCloudInitConfig(d *schema.ResourceData) *vms.CustomCloudInitConfig {
} }
initializationVendorDataFileID := initializationBlock[mkInitializationVendorDataFileID].(string) initializationVendorDataFileID := initializationBlock[mkInitializationVendorDataFileID].(string)
if initializationVendorDataFileID != "" { if initializationVendorDataFileID != "" {
if initializationConfig.Files == nil { if initializationConfig.Files == nil {
initializationConfig.Files = &vms.CustomCloudInitFiles{} initializationConfig.Files = &vms.CustomCloudInitFiles{}
@ -2928,7 +2933,6 @@ func vmGetCloudInitConfig(d *schema.ResourceData) *vms.CustomCloudInitConfig {
} }
initializationNetworkDataFileID := initializationBlock[mkInitializationNetworkDataFileID].(string) initializationNetworkDataFileID := initializationBlock[mkInitializationNetworkDataFileID].(string)
if initializationNetworkDataFileID != "" { if initializationNetworkDataFileID != "" {
if initializationConfig.Files == nil { if initializationConfig.Files == nil {
initializationConfig.Files = &vms.CustomCloudInitFiles{} initializationConfig.Files = &vms.CustomCloudInitFiles{}
@ -2938,7 +2942,6 @@ func vmGetCloudInitConfig(d *schema.ResourceData) *vms.CustomCloudInitConfig {
} }
initializationMetaDataFileID := initializationBlock[mkInitializationMetaDataFileID].(string) initializationMetaDataFileID := initializationBlock[mkInitializationMetaDataFileID].(string)
if initializationMetaDataFileID != "" { if initializationMetaDataFileID != "" {
if initializationConfig.Files == nil { if initializationConfig.Files == nil {
initializationConfig.Files = &vms.CustomCloudInitFiles{} initializationConfig.Files = &vms.CustomCloudInitFiles{}
@ -2948,11 +2951,15 @@ func vmGetCloudInitConfig(d *schema.ResourceData) *vms.CustomCloudInitConfig {
} }
initializationType := initializationBlock[mkInitializationType].(string) initializationType := initializationBlock[mkInitializationType].(string)
if initializationType != "" { if initializationType != "" {
initializationConfig.Type = &initializationType initializationConfig.Type = &initializationType
} }
if initializationBlock[mkInitializationUpgrade] != nil {
v := types.CustomBool(initializationBlock[mkInitializationUpgrade].(bool))
initializationConfig.Upgrade = &v
}
return initializationConfig return initializationConfig
} }
@ -4115,6 +4122,12 @@ func vmReadCustom(
initialization[mkInitializationType] = "" initialization[mkInitializationType] = ""
} }
if vmConfig.CloudInitUpgrade != nil {
initialization[mkInitializationUpgrade] = *vmConfig.CloudInitUpgrade
} else {
initialization[mkInitializationUpgrade] = false
}
currentInitialization := d.Get(mkInitialization).([]interface{}) currentInitialization := d.Get(mkInitialization).([]interface{})
//nolint:gocritic //nolint:gocritic