mirror of
https://github.com/bpg/terraform-provider-proxmox.git
synced 2025-06-30 18:42:58 +00:00
feat: Add hostpci
support (#194)
* feat: Add `hostpci` support * document `machine` argument * fix `rombar` argument name
This commit is contained in:
parent
4fe63fcf61
commit
01d20504a1
@ -198,7 +198,15 @@ output "ubuntu_vm_public_key" {
|
||||
* `read_burstable` - (Optional) The maximum burstable read speed in megabytes per second.
|
||||
* `write` - (Optional) The maximum write speed in megabytes per second.
|
||||
* `write_burstable` - (Optional) The maximum burstable write speed in megabytes per second.
|
||||
* ssd - (Optional) Whether to use an SSD emulation option for this disk (defaults to `false`). Note that SSD emulation is not supported on VirtIO Block drives.
|
||||
* `ssd` - (Optional) Whether to use an SSD emulation option for this disk (defaults to `false`). Note that SSD emulation is not supported on VirtIO Block drives.
|
||||
* `hostpci` - (Optional) A host PCI device mapping (multiple blocks supported).
|
||||
* `device` - (Required) The PCI device name for Proxmox, in form of `hostpciX` where `X` is a sequential number from 0 to 3.
|
||||
* `id` - (Required) The PCI device ID.
|
||||
* `mdev` - (Optional) The mediated device ID to use.
|
||||
* `pcie` - (Optional) Tells Proxmox to use a PCIe or PCI port. Some guests/device combination require PCIe rather than PCI. PCIe is only available for q35 machine types.
|
||||
* `rombar` - (Optional) Makes the firmware ROM visible for the VM (defaults to `true`).
|
||||
* `rom_file` - (Optional) A path to a ROM file for the device to use. This is a relative path under `/usr/share/kvm/`.
|
||||
* `xvga` - (Optional) Marks the PCI(e) device as the primary GPU of the VM. With this enabled the `vga` configuration argument will be ignored.
|
||||
* `initialization` - (Optional) The cloud-init configuration.
|
||||
* `datastore_id` - (Optional) The identifier for the datastore to create the cloud-init disk in (defaults
|
||||
to `local-lvm`).
|
||||
@ -245,6 +253,9 @@ output "ubuntu_vm_public_key" {
|
||||
* `sl` - Slovenian.
|
||||
* `sv` - Swedish.
|
||||
* `tr` - Turkish.
|
||||
* `machine` - (Optional) The VM machine type (defaults to `i440fx`).
|
||||
* `i440fx` - Standard PC (i440FX + PIIX, 1996).
|
||||
* `q35` - Standard PC (Q35 + ICH9, 2009).
|
||||
* `memory` - (Optional) The memory configuration.
|
||||
* `dedicated` - (Optional) The dedicated memory in megabytes (defaults to `512`).
|
||||
* `floating` - (Optional) The floating memory in megabytes (defaults to `0`).
|
||||
|
@ -109,7 +109,7 @@ type CustomNUMADevices []CustomNUMADevice
|
||||
// CustomPCIDevice handles QEMU host PCI device mapping parameters.
|
||||
type CustomPCIDevice struct {
|
||||
DeviceIDs []string `json:"host" url:"host,semicolon"`
|
||||
DevicePath *string `json:"mdev,omitempty" url:"mdev,omitempty"`
|
||||
MDev *string `json:"mdev,omitempty" url:"mdev,omitempty"`
|
||||
PCIExpress *CustomBool `json:"pcie,omitempty" url:"pcie,omitempty,int"`
|
||||
ROMBAR *CustomBool `json:"rombar,omitempty" url:"rombar,omitempty,int"`
|
||||
ROMFile *string `json:"romfile,omitempty" url:"romfile,omitempty"`
|
||||
@ -261,7 +261,7 @@ type VirtualEnvironmentVMCreateRequestBody struct {
|
||||
KVMEnabled *CustomBool `json:"kvm,omitempty" url:"kvm,omitempty,int"`
|
||||
LocalTime *CustomBool `json:"localtime,omitempty" url:"localtime,omitempty,int"`
|
||||
Lock *string `json:"lock,omitempty" url:"lock,omitempty"`
|
||||
MachineType *string `json:"machine,omitempty" url:"machine,omitempty"`
|
||||
Machine *string `json:"machine,omitempty" url:"machine,omitempty"`
|
||||
MigrateDowntime *float64 `json:"migrate_downtime,omitempty" url:"migrate_downtime,omitempty"`
|
||||
MigrateSpeed *int `json:"migrate_speed,omitempty" url:"migrate_speed,omitempty"`
|
||||
Name *string `json:"name,omitempty" url:"name,omitempty"`
|
||||
@ -393,7 +393,7 @@ type VirtualEnvironmentVMGetResponseData struct {
|
||||
KVMEnabled *CustomBool `json:"kvm,omitempty"`
|
||||
LocalTime *CustomBool `json:"localtime,omitempty"`
|
||||
Lock *string `json:"lock,omitempty"`
|
||||
MachineType *string `json:"machine,omitempty"`
|
||||
Machine *string `json:"machine,omitempty"`
|
||||
MigrateDowntime *float64 `json:"migrate_downtime,omitempty"`
|
||||
MigrateSpeed *int `json:"migrate_speed,omitempty"`
|
||||
Name *string `json:"name,omitempty"`
|
||||
@ -409,7 +409,10 @@ type VirtualEnvironmentVMGetResponseData struct {
|
||||
NUMAEnabled *CustomBool `json:"numa,omitempty"`
|
||||
OSType *string `json:"ostype,omitempty"`
|
||||
Overwrite *CustomBool `json:"force,omitempty"`
|
||||
PCIDevices *CustomPCIDevices `json:"hostpci,omitempty"`
|
||||
PCIDevice0 *CustomPCIDevice `json:"hostpci0,omitempty"`
|
||||
PCIDevice1 *CustomPCIDevice `json:"hostpci1,omitempty"`
|
||||
PCIDevice2 *CustomPCIDevice `json:"hostpci2,omitempty"`
|
||||
PCIDevice3 *CustomPCIDevice `json:"hostpci3,omitempty"`
|
||||
PoolID *string `json:"pool,omitempty" url:"pool,omitempty"`
|
||||
Revert *string `json:"revert,omitempty"`
|
||||
SATADevice0 *CustomStorageDevice `json:"sata0,omitempty"`
|
||||
@ -877,8 +880,8 @@ func (r CustomPCIDevice) EncodeValues(key string, v *url.Values) error {
|
||||
fmt.Sprintf("host=%s", strings.Join(r.DeviceIDs, ";")),
|
||||
}
|
||||
|
||||
if r.DevicePath != nil {
|
||||
values = append(values, fmt.Sprintf("mdev=%s", *r.DevicePath))
|
||||
if r.MDev != nil {
|
||||
values = append(values, fmt.Sprintf("mdev=%s", *r.MDev))
|
||||
}
|
||||
|
||||
if r.PCIExpress != nil {
|
||||
@ -1507,6 +1510,46 @@ func (r *CustomNetworkDevice) UnmarshalJSON(b []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON converts a CustomPCIDevice string to an object.
|
||||
func (r *CustomPCIDevice) UnmarshalJSON(b []byte) error {
|
||||
var s string
|
||||
|
||||
err := json.Unmarshal(b, &s)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pairs := strings.Split(s, ",")
|
||||
|
||||
for _, p := range pairs {
|
||||
v := strings.Split(strings.TrimSpace(p), "=")
|
||||
if len(v) == 1 {
|
||||
r.DeviceIDs = strings.Split(v[1], ";")
|
||||
} else if len(v) == 2 {
|
||||
switch v[0] {
|
||||
case "host":
|
||||
r.DeviceIDs = strings.Split(v[1], ";")
|
||||
case "mdev":
|
||||
r.MDev = &v[1]
|
||||
case "pcie":
|
||||
bv := CustomBool(v[1] == "1")
|
||||
r.PCIExpress = &bv
|
||||
case "rombar":
|
||||
bv := CustomBool(v[1] == "1")
|
||||
r.ROMBAR = &bv
|
||||
case "romfile":
|
||||
r.ROMFile = &v[1]
|
||||
case "x-vga":
|
||||
bv := CustomBool(v[1] == "1")
|
||||
r.XVGA = &bv
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON converts a CustomSharedMemory string to an object.
|
||||
func (r *CustomSharedMemory) UnmarshalJSON(b []byte) error {
|
||||
var s string
|
||||
|
@ -16,9 +16,10 @@ import (
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff"
|
||||
|
||||
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
|
||||
|
||||
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -58,6 +59,13 @@ const (
|
||||
dvResourceVirtualEnvironmentVMDiskSpeedReadBurstable = 0
|
||||
dvResourceVirtualEnvironmentVMDiskSpeedWrite = 0
|
||||
dvResourceVirtualEnvironmentVMDiskSpeedWriteBurstable = 0
|
||||
dvResourceVirtualEnvironmentVMHostPCIDevice = ""
|
||||
dvResourceVirtualEnvironmentVMHostPCIDeviceID = ""
|
||||
dvResourceVirtualEnvironmentVMHostPCIDeviceMDev = ""
|
||||
dvResourceVirtualEnvironmentVMHostPCIDevicePCIE = 0
|
||||
dvResourceVirtualEnvironmentVMHostPCIDeviceROMBAR = 1
|
||||
dvResourceVirtualEnvironmentVMHostPCIDeviceROMFile = ""
|
||||
dvResourceVirtualEnvironmentVMHostPCIDeviceXVGA = 0
|
||||
dvResourceVirtualEnvironmentVMInitializationDatastoreID = "local-lvm"
|
||||
dvResourceVirtualEnvironmentVMInitializationDNSDomain = ""
|
||||
dvResourceVirtualEnvironmentVMInitializationDNSServer = ""
|
||||
@ -70,6 +78,7 @@ const (
|
||||
dvResourceVirtualEnvironmentVMInitializationVendorDataFileID = ""
|
||||
dvResourceVirtualEnvironmentVMInitializationType = ""
|
||||
dvResourceVirtualEnvironmentVMKeyboardLayout = "en-us"
|
||||
dvResourceVirtualEnvironmentVMMachineType = ""
|
||||
dvResourceVirtualEnvironmentVMMemoryDedicated = 512
|
||||
dvResourceVirtualEnvironmentVMMemoryFloating = 0
|
||||
dvResourceVirtualEnvironmentVMMemoryShared = 0
|
||||
@ -147,6 +156,14 @@ const (
|
||||
mkResourceVirtualEnvironmentVMDiskSpeedReadBurstable = "read_burstable"
|
||||
mkResourceVirtualEnvironmentVMDiskSpeedWrite = "write"
|
||||
mkResourceVirtualEnvironmentVMDiskSpeedWriteBurstable = "write_burstable"
|
||||
mkResourceVirtualEnvironmentVMHostPCI = "hostpci"
|
||||
mkResourceVirtualEnvironmentVMHostPCIDevice = "device"
|
||||
mkResourceVirtualEnvironmentVMHostPCIDeviceID = "id"
|
||||
mkResourceVirtualEnvironmentVMHostPCIDeviceMDev = "mdev"
|
||||
mkResourceVirtualEnvironmentVMHostPCIDevicePCIE = "pcie"
|
||||
mkResourceVirtualEnvironmentVMHostPCIDeviceROMBAR = "rombar"
|
||||
mkResourceVirtualEnvironmentVMHostPCIDeviceROMFile = "rom_file"
|
||||
mkResourceVirtualEnvironmentVMHostPCIDeviceXVGA = "xvga"
|
||||
mkResourceVirtualEnvironmentVMInitialization = "initialization"
|
||||
mkResourceVirtualEnvironmentVMInitializationDatastoreID = "datastore_id"
|
||||
mkResourceVirtualEnvironmentVMInitializationDNS = "dns"
|
||||
@ -169,6 +186,7 @@ const (
|
||||
mkResourceVirtualEnvironmentVMIPv4Addresses = "ipv4_addresses"
|
||||
mkResourceVirtualEnvironmentVMIPv6Addresses = "ipv6_addresses"
|
||||
mkResourceVirtualEnvironmentVMKeyboardLayout = "keyboard_layout"
|
||||
mkResourceVirtualEnvironmentVMMachine = "machine"
|
||||
mkResourceVirtualEnvironmentVMMACAddresses = "mac_addresses"
|
||||
mkResourceVirtualEnvironmentVMMemory = "memory"
|
||||
mkResourceVirtualEnvironmentVMMemoryDedicated = "dedicated"
|
||||
@ -795,6 +813,64 @@ func resourceVirtualEnvironmentVM() *schema.Resource {
|
||||
Elem: &schema.Schema{Type: schema.TypeString},
|
||||
},
|
||||
},
|
||||
mkResourceVirtualEnvironmentVMHostPCI: {
|
||||
Type: schema.TypeList,
|
||||
Description: "The Host PCI devices mapped to the VM",
|
||||
Optional: true,
|
||||
ForceNew: true,
|
||||
DefaultFunc: func() (interface{}, error) {
|
||||
return []interface{}{
|
||||
map[string]interface{}{
|
||||
mkResourceVirtualEnvironmentVMHostPCIDevice: dvResourceVirtualEnvironmentVMHostPCIDevice,
|
||||
mkResourceVirtualEnvironmentVMHostPCIDeviceID: dvResourceVirtualEnvironmentVMHostPCIDeviceID,
|
||||
mkResourceVirtualEnvironmentVMHostPCIDeviceXVGA: dvResourceVirtualEnvironmentVMHostPCIDeviceXVGA,
|
||||
mkResourceVirtualEnvironmentVMHostPCIDevicePCIE: dvResourceVirtualEnvironmentVMHostPCIDevicePCIE,
|
||||
mkResourceVirtualEnvironmentVMHostPCIDeviceROMBAR: dvResourceVirtualEnvironmentVMHostPCIDeviceROMBAR,
|
||||
mkResourceVirtualEnvironmentVMHostPCIDeviceROMFile: dvResourceVirtualEnvironmentVMHostPCIDeviceROMFile,
|
||||
mkResourceVirtualEnvironmentVMHostPCIDeviceMDev: dvResourceVirtualEnvironmentVMHostPCIDeviceMDev,
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
mkResourceVirtualEnvironmentVMHostPCIDevice: {
|
||||
Type: schema.TypeString,
|
||||
Description: "The PCI device name for Proxmox, in form of 'hostpciX' where X is a sequential number from 0 to 3",
|
||||
Required: true,
|
||||
},
|
||||
mkResourceVirtualEnvironmentVMHostPCIDeviceID: {
|
||||
Type: schema.TypeString,
|
||||
Description: "The PCI ID of the device, for example 0000:00:1f.0 (or 0000:00:1f.0;0000:00:1f.1 for multiple device functions, or 0000:00:1f for all functions)",
|
||||
Required: true,
|
||||
},
|
||||
mkResourceVirtualEnvironmentVMHostPCIDeviceMDev: {
|
||||
Type: schema.TypeString,
|
||||
Description: "The the mediated device to use",
|
||||
Optional: true,
|
||||
},
|
||||
mkResourceVirtualEnvironmentVMHostPCIDevicePCIE: {
|
||||
Type: schema.TypeBool,
|
||||
Description: "Tells Proxmox VE to use a PCIe or PCI port. Some guests/device combination require PCIe rather than PCI. PCIe is only available for q35 machine types.",
|
||||
Optional: true,
|
||||
},
|
||||
mkResourceVirtualEnvironmentVMHostPCIDeviceROMBAR: {
|
||||
Type: schema.TypeBool,
|
||||
Description: "Makes the firmware ROM visible for the guest. Default is true",
|
||||
Optional: true,
|
||||
},
|
||||
mkResourceVirtualEnvironmentVMHostPCIDeviceROMFile: {
|
||||
Type: schema.TypeString,
|
||||
Description: "A path to a ROM file for the device to use. This is a relative path under /usr/share/kvm/",
|
||||
Optional: true,
|
||||
},
|
||||
mkResourceVirtualEnvironmentVMHostPCIDeviceXVGA: {
|
||||
Type: schema.TypeBool,
|
||||
Description: "Marks the PCI(e) device as the primary GPU of the VM. With this enabled the vga configuration argument will be ignored.",
|
||||
Optional: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
mkResourceVirtualEnvironmentVMKeyboardLayout: {
|
||||
Type: schema.TypeString,
|
||||
Description: "The keyboard layout",
|
||||
@ -802,6 +878,12 @@ func resourceVirtualEnvironmentVM() *schema.Resource {
|
||||
Default: dvResourceVirtualEnvironmentVMKeyboardLayout,
|
||||
ValidateDiagFunc: getKeyboardLayoutValidator(),
|
||||
},
|
||||
mkResourceVirtualEnvironmentVMMachine: {
|
||||
Type: schema.TypeString,
|
||||
Description: "The VM machine type, either default i440fx or q35",
|
||||
Optional: true,
|
||||
Default: dvResourceVirtualEnvironmentVMMachineType,
|
||||
},
|
||||
mkResourceVirtualEnvironmentVMMACAddresses: {
|
||||
Type: schema.TypeList,
|
||||
Description: "The MAC addresses for the network interfaces",
|
||||
@ -1273,6 +1355,7 @@ func resourceVirtualEnvironmentVMCreateClone(ctx context.Context, d *schema.Reso
|
||||
cdrom := d.Get(mkResourceVirtualEnvironmentVMCDROM).([]interface{})
|
||||
cpu := d.Get(mkResourceVirtualEnvironmentVMCPU).([]interface{})
|
||||
initialization := d.Get(mkResourceVirtualEnvironmentVMInitialization).([]interface{})
|
||||
hostPCI := d.Get(mkResourceVirtualEnvironmentVMHostPCI).([]interface{})
|
||||
keyboardLayout := d.Get(mkResourceVirtualEnvironmentVMKeyboardLayout).(string)
|
||||
memory := d.Get(mkResourceVirtualEnvironmentVMMemory).([]interface{})
|
||||
networkDevice := d.Get(mkResourceVirtualEnvironmentVMNetworkDevice).([]interface{})
|
||||
@ -1416,6 +1499,13 @@ func resourceVirtualEnvironmentVMCreateClone(ctx context.Context, d *schema.Reso
|
||||
updateBody.CloudInitConfig = initializationConfig
|
||||
}
|
||||
|
||||
if len(hostPCI) > 0 {
|
||||
updateBody.PCIDevices, err = resourceVirtualEnvironmentVMGetHostPCIDeviceObjects(d)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
}
|
||||
|
||||
if len(cdrom) > 0 || len(initialization) > 0 {
|
||||
updateBody.IDEDevices = ideDevices
|
||||
}
|
||||
@ -1702,6 +1792,11 @@ func resourceVirtualEnvironmentVMCreateCustom(ctx context.Context, d *schema.Res
|
||||
cdromCloudInitFileID = fmt.Sprintf("%s:cloudinit", initializationDatastoreID)
|
||||
}
|
||||
|
||||
pciDeviceObjects, err := resourceVirtualEnvironmentVMGetHostPCIDeviceObjects(d)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
keyboardLayout := d.Get(mkResourceVirtualEnvironmentVMKeyboardLayout).(string)
|
||||
memoryBlock, err := getSchemaBlock(resource, d, []string{mkResourceVirtualEnvironmentVMMemory}, 0, true)
|
||||
if err != nil {
|
||||
@ -1712,6 +1807,7 @@ func resourceVirtualEnvironmentVMCreateCustom(ctx context.Context, d *schema.Res
|
||||
memoryFloating := memoryBlock[mkResourceVirtualEnvironmentVMMemoryFloating].(int)
|
||||
memoryShared := memoryBlock[mkResourceVirtualEnvironmentVMMemoryShared].(int)
|
||||
|
||||
machine := d.Get(mkResourceVirtualEnvironmentVMMachine).(string)
|
||||
name := d.Get(mkResourceVirtualEnvironmentVMName).(string)
|
||||
tags := d.Get(mkResourceVirtualEnvironmentVMTags).([]interface{})
|
||||
|
||||
@ -1820,6 +1916,7 @@ func resourceVirtualEnvironmentVMCreateCustom(ctx context.Context, d *schema.Res
|
||||
KeyboardLayout: &keyboardLayout,
|
||||
NetworkDevices: networkDeviceObjects,
|
||||
OSType: &operatingSystemType,
|
||||
PCIDevices: pciDeviceObjects,
|
||||
SCSIHardware: &scsiHardware,
|
||||
SerialDevices: serialDevices,
|
||||
SharedMemory: memorySharedObject,
|
||||
@ -1860,6 +1957,10 @@ func resourceVirtualEnvironmentVMCreateCustom(ctx context.Context, d *schema.Res
|
||||
createBody.Tags = &tagsString
|
||||
}
|
||||
|
||||
if machine != "" {
|
||||
createBody.Machine = &machine
|
||||
}
|
||||
|
||||
if name != "" {
|
||||
createBody.Name = &name
|
||||
}
|
||||
@ -2319,6 +2420,44 @@ func resourceVirtualEnvironmentVMGetDiskDeviceObjects(d *schema.ResourceData, di
|
||||
return diskDeviceObjects, nil
|
||||
}
|
||||
|
||||
func resourceVirtualEnvironmentVMGetHostPCIDeviceObjects(d *schema.ResourceData) (proxmox.CustomPCIDevices, error) {
|
||||
pciDevice := d.Get(mkResourceVirtualEnvironmentVMHostPCI).([]interface{})
|
||||
pciDeviceObjects := make(proxmox.CustomPCIDevices, len(pciDevice))
|
||||
|
||||
for i, pciDeviceEntry := range pciDevice {
|
||||
block := pciDeviceEntry.(map[string]interface{})
|
||||
|
||||
ids, _ := block[mkResourceVirtualEnvironmentVMHostPCIDeviceID].(string)
|
||||
mdev, _ := block[mkResourceVirtualEnvironmentVMHostPCIDeviceMDev].(string)
|
||||
pcie := proxmox.CustomBool(block[mkResourceVirtualEnvironmentVMHostPCIDevicePCIE].(bool))
|
||||
rombar := proxmox.CustomBool(block[mkResourceVirtualEnvironmentVMHostPCIDeviceROMBAR].(bool))
|
||||
romfile, _ := block[mkResourceVirtualEnvironmentVMHostPCIDeviceROMFile].(string)
|
||||
xvga := proxmox.CustomBool(block[mkResourceVirtualEnvironmentVMHostPCIDeviceXVGA].(bool))
|
||||
|
||||
device := proxmox.CustomPCIDevice{
|
||||
DeviceIDs: strings.Split(ids, ";"),
|
||||
PCIExpress: &pcie,
|
||||
ROMBAR: &rombar,
|
||||
XVGA: &xvga,
|
||||
}
|
||||
if ids != "" {
|
||||
device.DeviceIDs = strings.Split(ids, ";")
|
||||
}
|
||||
|
||||
if mdev != "" {
|
||||
device.MDev = &mdev
|
||||
}
|
||||
|
||||
if romfile != "" {
|
||||
device.ROMFile = &romfile
|
||||
}
|
||||
|
||||
pciDeviceObjects[i] = device
|
||||
}
|
||||
|
||||
return pciDeviceObjects, nil
|
||||
}
|
||||
|
||||
func resourceVirtualEnvironmentVMGetNetworkDeviceObjects(d *schema.ResourceData) (proxmox.CustomNetworkDevices, error) {
|
||||
networkDevice := d.Get(mkResourceVirtualEnvironmentVMNetworkDevice).([]interface{})
|
||||
networkDeviceObjects := make(proxmox.CustomNetworkDevices, len(networkDevice))
|
||||
@ -2840,6 +2979,75 @@ func resourceVirtualEnvironmentVMReadCustom(ctx context.Context, d *schema.Resou
|
||||
diags = append(diags, diag.FromErr(err)...)
|
||||
}
|
||||
|
||||
currentPCIList := d.Get(mkResourceVirtualEnvironmentVMHostPCI).([]interface{})
|
||||
pciMap := map[string]interface{}{}
|
||||
var orderedPCIList []interface{}
|
||||
|
||||
pciDevices := getPCIInfo(vmConfig, d)
|
||||
for pi, pp := range pciDevices {
|
||||
if (pp == nil) || (pp.DeviceIDs == nil) {
|
||||
continue
|
||||
}
|
||||
|
||||
pci := map[string]interface{}{}
|
||||
|
||||
pci[mkResourceVirtualEnvironmentVMHostPCIDevice] = pi
|
||||
pci[mkResourceVirtualEnvironmentVMHostPCIDeviceID] = strings.Join(pp.DeviceIDs, ";")
|
||||
|
||||
if pp.MDev != nil {
|
||||
pci[mkResourceVirtualEnvironmentVMHostPCIDeviceMDev] = *pp.MDev
|
||||
} else {
|
||||
pci[mkResourceVirtualEnvironmentVMHostPCIDeviceMDev] = ""
|
||||
}
|
||||
|
||||
if pp.PCIExpress != nil {
|
||||
pci[mkResourceVirtualEnvironmentVMHostPCIDevicePCIE] = *pp.PCIExpress
|
||||
} else {
|
||||
pci[mkResourceVirtualEnvironmentVMHostPCIDevicePCIE] = false
|
||||
}
|
||||
|
||||
if pp.ROMBAR != nil {
|
||||
pci[mkResourceVirtualEnvironmentVMHostPCIDeviceROMBAR] = *pp.ROMBAR
|
||||
} else {
|
||||
pci[mkResourceVirtualEnvironmentVMHostPCIDeviceROMBAR] = false
|
||||
}
|
||||
|
||||
if pp.ROMFile != nil {
|
||||
pci[mkResourceVirtualEnvironmentVMHostPCIDeviceROMFile] = *pp.ROMFile
|
||||
} else {
|
||||
pci[mkResourceVirtualEnvironmentVMHostPCIDeviceROMFile] = ""
|
||||
}
|
||||
|
||||
if pp.XVGA != nil {
|
||||
pci[mkResourceVirtualEnvironmentVMHostPCIDeviceXVGA] = *pp.XVGA
|
||||
} else {
|
||||
pci[mkResourceVirtualEnvironmentVMHostPCIDeviceXVGA] = false
|
||||
}
|
||||
|
||||
pciMap[pi] = pci
|
||||
}
|
||||
|
||||
keyList = []string{}
|
||||
for key := range pciMap {
|
||||
keyList = append(keyList, key)
|
||||
}
|
||||
sort.Strings(keyList)
|
||||
|
||||
for _, k := range keyList {
|
||||
orderedPCIList = append(orderedPCIList, pciMap[k])
|
||||
}
|
||||
|
||||
if len(clone) > 0 {
|
||||
if len(currentPCIList) > 0 {
|
||||
err := d.Set(mkResourceVirtualEnvironmentVMHostPCI, orderedPCIList)
|
||||
diags = append(diags, diag.FromErr(err)...)
|
||||
}
|
||||
} else if len(currentPCIList) > 0 {
|
||||
// todo: reordering of devices by PVE may cause an issue here
|
||||
err := d.Set(mkResourceVirtualEnvironmentVMHostPCI, orderedPCIList)
|
||||
diags = append(diags, diag.FromErr(err)...)
|
||||
}
|
||||
|
||||
// Compare the initialization configuration to the one stored in the state.
|
||||
initialization := map[string]interface{}{}
|
||||
|
||||
@ -3388,6 +3596,17 @@ func resourceVirtualEnvironmentVMReadPrimitiveValues(d *schema.ResourceData, vmC
|
||||
diags = append(diags, diag.FromErr(err)...)
|
||||
}
|
||||
|
||||
currentMachine := d.Get(mkResourceVirtualEnvironmentVMMachine).(string)
|
||||
|
||||
if len(clone) == 0 || currentMachine != dvResourceVirtualEnvironmentVMMachineType {
|
||||
if vmConfig.Machine != nil {
|
||||
err = d.Set(mkResourceVirtualEnvironmentVMMachine, *vmConfig.Machine)
|
||||
} else {
|
||||
err = d.Set(mkResourceVirtualEnvironmentVMMachine, "")
|
||||
}
|
||||
diags = append(diags, diag.FromErr(err)...)
|
||||
}
|
||||
|
||||
currentName := d.Get(mkResourceVirtualEnvironmentVMName).(string)
|
||||
|
||||
if len(clone) == 0 || currentName != dvResourceVirtualEnvironmentVMName {
|
||||
@ -3504,6 +3723,12 @@ func resourceVirtualEnvironmentVMUpdate(ctx context.Context, d *schema.ResourceD
|
||||
rebootRequired = true
|
||||
}
|
||||
|
||||
if d.HasChange(mkResourceVirtualEnvironmentVMMachine) {
|
||||
machine := d.Get(mkResourceVirtualEnvironmentVMMachine).(string)
|
||||
updateBody.Machine = &machine
|
||||
rebootRequired = true
|
||||
}
|
||||
|
||||
name := d.Get(mkResourceVirtualEnvironmentVMName).(string)
|
||||
|
||||
if name == "" {
|
||||
@ -3731,6 +3956,16 @@ func resourceVirtualEnvironmentVMUpdate(ctx context.Context, d *schema.ResourceD
|
||||
rebootRequired = true
|
||||
}
|
||||
|
||||
// Prepare the new hostpci devices configuration.
|
||||
if d.HasChange(mkResourceVirtualEnvironmentVMHostPCI) {
|
||||
updateBody.PCIDevices, err = resourceVirtualEnvironmentVMGetHostPCIDeviceObjects(d)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
rebootRequired = true
|
||||
}
|
||||
|
||||
// Prepare the new memory configuration.
|
||||
if d.HasChange(mkResourceVirtualEnvironmentVMMemory) {
|
||||
memoryBlock, err := getSchemaBlock(resource, d, []string{mkResourceVirtualEnvironmentVMMemory}, 0, true)
|
||||
|
@ -38,7 +38,9 @@ func TestResourceVirtualEnvironmentVMSchema(t *testing.T) {
|
||||
mkResourceVirtualEnvironmentVMDescription,
|
||||
mkResourceVirtualEnvironmentVMDisk,
|
||||
mkResourceVirtualEnvironmentVMInitialization,
|
||||
mkResourceVirtualEnvironmentVMHostPCI,
|
||||
mkResourceVirtualEnvironmentVMKeyboardLayout,
|
||||
mkResourceVirtualEnvironmentVMMachine,
|
||||
mkResourceVirtualEnvironmentVMMemory,
|
||||
mkResourceVirtualEnvironmentVMName,
|
||||
mkResourceVirtualEnvironmentVMNetworkDevice,
|
||||
@ -67,10 +69,12 @@ func TestResourceVirtualEnvironmentVMSchema(t *testing.T) {
|
||||
mkResourceVirtualEnvironmentVMCPU: schema.TypeList,
|
||||
mkResourceVirtualEnvironmentVMDescription: schema.TypeString,
|
||||
mkResourceVirtualEnvironmentVMDisk: schema.TypeList,
|
||||
mkResourceVirtualEnvironmentVMHostPCI: schema.TypeList,
|
||||
mkResourceVirtualEnvironmentVMInitialization: schema.TypeList,
|
||||
mkResourceVirtualEnvironmentVMIPv4Addresses: schema.TypeList,
|
||||
mkResourceVirtualEnvironmentVMIPv6Addresses: schema.TypeList,
|
||||
mkResourceVirtualEnvironmentVMKeyboardLayout: schema.TypeString,
|
||||
mkResourceVirtualEnvironmentVMMachine: schema.TypeString,
|
||||
mkResourceVirtualEnvironmentVMMemory: schema.TypeList,
|
||||
mkResourceVirtualEnvironmentVMName: schema.TypeString,
|
||||
mkResourceVirtualEnvironmentVMNetworkDevice: schema.TypeList,
|
||||
@ -211,6 +215,25 @@ func TestResourceVirtualEnvironmentVMSchema(t *testing.T) {
|
||||
mkResourceVirtualEnvironmentVMInitializationUserAccount: schema.TypeList,
|
||||
})
|
||||
|
||||
hostPCISchema := testNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMHostPCI)
|
||||
|
||||
testOptionalArguments(t, hostPCISchema, []string{
|
||||
mkResourceVirtualEnvironmentVMHostPCIDeviceMDev,
|
||||
mkResourceVirtualEnvironmentVMHostPCIDevicePCIE,
|
||||
mkResourceVirtualEnvironmentVMHostPCIDeviceROMBAR,
|
||||
mkResourceVirtualEnvironmentVMHostPCIDeviceROMFile,
|
||||
mkResourceVirtualEnvironmentVMHostPCIDeviceXVGA,
|
||||
})
|
||||
|
||||
testValueTypes(t, hostPCISchema, map[string]schema.ValueType{
|
||||
mkResourceVirtualEnvironmentVMHostPCIDevice: schema.TypeString,
|
||||
mkResourceVirtualEnvironmentVMHostPCIDeviceMDev: schema.TypeString,
|
||||
mkResourceVirtualEnvironmentVMHostPCIDevicePCIE: schema.TypeBool,
|
||||
mkResourceVirtualEnvironmentVMHostPCIDeviceROMBAR: schema.TypeBool,
|
||||
mkResourceVirtualEnvironmentVMHostPCIDeviceROMFile: schema.TypeString,
|
||||
mkResourceVirtualEnvironmentVMHostPCIDeviceXVGA: schema.TypeBool,
|
||||
})
|
||||
|
||||
initializationDNSSchema := testNestedSchemaExistence(t, initializationSchema, mkResourceVirtualEnvironmentVMInitializationDNS)
|
||||
|
||||
testOptionalArguments(t, initializationDNSSchema, []string{
|
||||
|
@ -18,9 +18,10 @@ import (
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
|
||||
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
|
||||
|
||||
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
||||
)
|
||||
|
||||
func getBIOSValidator() schema.SchemaValidateDiagFunc {
|
||||
@ -519,6 +520,17 @@ func parseDiskSize(size *string) (int, error) {
|
||||
return diskSize, err
|
||||
}
|
||||
|
||||
func getPCIInfo(vm *proxmox.VirtualEnvironmentVMGetResponseData, d *schema.ResourceData) map[string]*proxmox.CustomPCIDevice {
|
||||
pciDevices := map[string]*proxmox.CustomPCIDevice{}
|
||||
|
||||
pciDevices["hostpci0"] = vm.PCIDevice0
|
||||
pciDevices["hostpci1"] = vm.PCIDevice1
|
||||
pciDevices["hostpci2"] = vm.PCIDevice2
|
||||
pciDevices["hostpci3"] = vm.PCIDevice3
|
||||
|
||||
return pciDevices
|
||||
}
|
||||
|
||||
func getCloudInitTypeValidator() schema.SchemaValidateDiagFunc {
|
||||
return validation.ToDiagFunc(validation.StringInSlice([]string{
|
||||
"configdrive2",
|
||||
|
Loading…
Reference in New Issue
Block a user