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

fix(vm): re-use ide, sata, and scsi cloud-init storage (#1083) (#1141)

* fix(vm): add failing acceptance test for cloud-init over scsi interface (#1083)

Signed-off-by: Michael Franzl <michael@franzl.name>

* fix(vm): re-use ide, sata, and scsi initialization storage (#1083)

Signed-off-by: Michael Franzl <michael@franzl.name>

* fix linter error

Signed-off-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com>

---------

Signed-off-by: Michael Franzl <michael@franzl.name>
Signed-off-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com>
Co-authored-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com>
This commit is contained in:
Michael Franzl 2024-03-26 02:23:10 +01:00 committed by GitHub
parent e5ef91e72d
commit d41463de79
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 182 additions and 16 deletions

View File

@ -103,6 +103,90 @@ func TestAccResourceVM(t *testing.T) {
}
}
func TestAccResourceVMInitialization(t *testing.T) {
providerConfig := getProviderConfig(t)
tests := []struct {
name string
step []resource.TestStep
}{
{"initialization works with cloud-init config provided over SCSI interface", []resource.TestStep{{
Config: providerConfig + `
resource "proxmox_virtual_environment_file" "cloud_config" {
content_type = "snippets"
datastore_id = "local"
node_name = "pve"
source_raw {
data = <<EOF
#cloud-config
runcmd:
- apt update
- apt install -y qemu-guest-agent
- systemctl enable qemu-guest-agent
- systemctl start qemu-guest-agent
EOF
file_name = "cloud-config.yaml"
}
}
resource "proxmox_virtual_environment_vm" "test_vm_network1" {
node_name = "pve"
started = true
agent {
enabled = true
}
cpu {
cores = 2
}
memory {
dedicated = 2048
}
disk {
datastore_id = "local-lvm"
file_id = proxmox_virtual_environment_download_file.ubuntu_cloud_image.id
interface = "virtio0"
iothread = true
discard = "on"
size = 20
}
initialization {
interface = "scsi1"
ip_config {
ipv4 {
address = "dhcp"
}
}
user_data_file_id = proxmox_virtual_environment_file.cloud_config.id
}
network_device {
bridge = "vmbr0"
}
}
resource "proxmox_virtual_environment_download_file" "ubuntu_cloud_image" {
content_type = "iso"
datastore_id = "local"
node_name = "pve"
url = "https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img"
overwrite_unmanaged = true
}`,
}}},
}
accProviders := testAccMuxProviders(context.Background(), t)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: accProviders,
Steps: tt.step,
})
})
}
}
func TestAccResourceVMNetwork(t *testing.T) {
providerConfig := getProviderConfig(t)

View File

@ -1412,33 +1412,115 @@ func vmCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.D
// Check for an existing CloudInit IDE drive. If no such drive is found, return the specified `defaultValue`.
func findExistingCloudInitDrive(vmConfig *vms.GetResponseData, vmID int, defaultValue string) string {
devices := []*vms.CustomStorageDevice{
vmConfig.IDEDevice0, vmConfig.IDEDevice1, vmConfig.IDEDevice2, vmConfig.IDEDevice3,
ideDevices := []*vms.CustomStorageDevice{
vmConfig.IDEDevice0,
vmConfig.IDEDevice1,
vmConfig.IDEDevice2,
vmConfig.IDEDevice3,
}
for i, device := range devices {
for i, device := range ideDevices {
if device != nil && device.Enabled && device.IsCloudInitDrive(vmID) {
return fmt.Sprintf("ide%d", i)
}
}
sataDevices := []*vms.CustomStorageDevice{
vmConfig.SATADevice0,
vmConfig.SATADevice1,
vmConfig.SATADevice2,
vmConfig.SATADevice3,
vmConfig.SATADevice4,
vmConfig.SATADevice5,
}
for i, device := range sataDevices {
if device != nil && device.Enabled && device.IsCloudInitDrive(vmID) {
return fmt.Sprintf("sata%d", i)
}
}
scsiDevices := []*vms.CustomStorageDevice{
vmConfig.SCSIDevice0,
vmConfig.SCSIDevice1,
vmConfig.SCSIDevice2,
vmConfig.SCSIDevice3,
vmConfig.SCSIDevice4,
vmConfig.SCSIDevice5,
vmConfig.SCSIDevice6,
vmConfig.SCSIDevice7,
vmConfig.SCSIDevice8,
vmConfig.SCSIDevice9,
vmConfig.SCSIDevice10,
vmConfig.SCSIDevice11,
vmConfig.SCSIDevice12,
vmConfig.SCSIDevice13,
}
for i, device := range scsiDevices {
if device != nil && device.Enabled && device.IsCloudInitDrive(vmID) {
return fmt.Sprintf("scsi%d", i)
}
}
return defaultValue
}
// Return a pointer to the IDE device configuration based on its name. The device name is assumed to be a
// valid IDE interface name.
func getIdeDevice(vmConfig *vms.GetResponseData, deviceName string) *vms.CustomStorageDevice {
ideDevice := vmConfig.IDEDevice3
// Return a pointer to the storage device configuration based on a name. The device name is assumed to be a
// valid ide, sata, or scsi interface name.
func getStorageDevice(vmConfig *vms.GetResponseData, deviceName string) *vms.CustomStorageDevice {
switch deviceName {
case "ide0":
ideDevice = vmConfig.IDEDevice0
return vmConfig.IDEDevice0
case "ide1":
ideDevice = vmConfig.IDEDevice1
return vmConfig.IDEDevice1
case "ide2":
ideDevice = vmConfig.IDEDevice2
}
return vmConfig.IDEDevice2
case "ide3":
return vmConfig.IDEDevice3
return ideDevice
case "sata0":
return vmConfig.SATADevice0
case "sata1":
return vmConfig.SATADevice1
case "sata2":
return vmConfig.SATADevice2
case "sata3":
return vmConfig.SATADevice3
case "sata4":
return vmConfig.SATADevice4
case "sata5":
return vmConfig.SATADevice5
case "scsi0":
return vmConfig.SCSIDevice0
case "scsi1":
return vmConfig.SCSIDevice1
case "scsi2":
return vmConfig.SCSIDevice2
case "scsi3":
return vmConfig.SCSIDevice3
case "scsi4":
return vmConfig.SCSIDevice4
case "scsi5":
return vmConfig.SCSIDevice5
case "scsi6":
return vmConfig.SCSIDevice6
case "scsi7":
return vmConfig.SCSIDevice7
case "scsi8":
return vmConfig.SCSIDevice8
case "scsi9":
return vmConfig.SCSIDevice9
case "scsi10":
return vmConfig.SCSIDevice10
case "scsi11":
return vmConfig.SCSIDevice11
case "scsi12":
return vmConfig.SCSIDevice12
case "scsi13":
return vmConfig.SCSIDevice13
default:
return nil
}
}
// Delete IDE interfaces that can then be used for CloudInit. The first interface will always
@ -3289,7 +3371,7 @@ func vmReadCustom(
currentInterface = currentBlock[mkCDROMInterface].(string)
}
cdromIDEDevice := getIdeDevice(vmConfig, currentInterface)
cdromIDEDevice := getStorageDevice(vmConfig, currentInterface)
if cdromIDEDevice != nil {
cdrom := make([]interface{}, 1)
@ -3611,7 +3693,7 @@ func vmReadCustom(
initializationInterface := findExistingCloudInitDrive(vmConfig, vmID, "")
if initializationInterface != "" {
initializationDevice := getIdeDevice(vmConfig, initializationInterface)
initializationDevice := getStorageDevice(vmConfig, initializationInterface)
fileVolumeParts := strings.Split(initializationDevice.FileVolume, ":")
initialization[mkInitializationInterface] = initializationInterface
@ -4801,7 +4883,7 @@ func vmUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.D
stoppedBeforeUpdate = true
fileVolume = fmt.Sprintf("%s:cloudinit", initializationDatastoreID)
} else {
ideDevice := getIdeDevice(vmConfig, existingInterface)
ideDevice := getStorageDevice(vmConfig, existingInterface)
fileVolume = ideDevice.FileVolume
}