0
0
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:
Pavel Boldyrev 2022-12-28 22:14:48 -05:00 committed by GitHub
parent 4fe63fcf61
commit 01d20504a1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 333 additions and 9 deletions

View File

@ -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`).

View File

@ -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

View File

@ -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)

View File

@ -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{

View File

@ -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",