mirror of
https://github.com/bpg/terraform-provider-proxmox.git
synced 2025-08-22 19:38:35 +00:00
Additional CPU arguments
This commit is contained in:
parent
daa7102a26
commit
a9349cfbd0
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
ENHANCEMENTS:
|
ENHANCEMENTS:
|
||||||
|
|
||||||
resource/virtual_environment_vm: Add `vga` argument
|
resource/virtual_environment_vm: Add `cpu.flags`, `cpu.type` and `vga` arguments
|
||||||
|
|
||||||
## 0.1.0
|
## 0.1.0
|
||||||
|
|
||||||
|
44
README.md
44
README.md
@ -359,8 +359,52 @@ This resource doesn't expose any additional attributes.
|
|||||||
* `user_data_file_id` - (Optional) The ID of a file containing custom user data (conflicts with `user_account`)
|
* `user_data_file_id` - (Optional) The ID of a file containing custom user data (conflicts with `user_account`)
|
||||||
* `cpu` - (Optional) The CPU configuration
|
* `cpu` - (Optional) The CPU configuration
|
||||||
* `cores` - (Optional) The number of CPU cores (defaults to `1`)
|
* `cores` - (Optional) The number of CPU cores (defaults to `1`)
|
||||||
|
* `flags` - (Optional) The CPU flags
|
||||||
|
* `+aes`/`-aes` - Activate AES instruction set for HW acceleration
|
||||||
|
* `+amd-no-ssb`/`-amd-no-ssb` - Notifies guest OS that host is not vulnerable for Spectre on AMD CPUs
|
||||||
|
* `+amd-ssbd`/`-amd-ssbd` - Improves Spectre mitigation performance with AMD CPUs, best used with "virt-ssbd"
|
||||||
|
* `+hv-evmcs`/`-hv-evmcs` - Improve performance for nested virtualization (only supported on Intel CPUs)
|
||||||
|
* `+hv-tlbflush`/`-hv-tlbflush` - Improve performance in overcommitted Windows guests (may lead to guest BSOD on old CPUs)
|
||||||
|
* `+ibpb`/`-ibpb` - Allows improved Spectre mitigation on AMD CPUs
|
||||||
|
* `+md-clear`/`-md-clear` - Required to let the guest OS know if MDS is mitigated correctly
|
||||||
|
* `+pcid`/`-pcid` - Meltdown fix cost reduction on Westmere, Sandy- and Ivy Bridge Intel CPUs
|
||||||
|
* `+pdpe1gb`/`-pdpe1gb` - Allows guest OS to use 1 GB size pages, if host HW supports it
|
||||||
|
* `+spec-ctrl`/`-spec-ctrl` - Allows improved Spectre mitigation with Intel CPUs
|
||||||
|
* `+ssbd`/`-ssbd` - Protection for "Speculative Store Bypass" for Intel models
|
||||||
|
* `+virt-ssbd`/`-virt-ssbd` - Basis for "Speculative Store Bypass" protection for AMD models
|
||||||
* `hotplugged` - (Optional) The number of hotplugged vCPUs (defaults to `0`)
|
* `hotplugged` - (Optional) The number of hotplugged vCPUs (defaults to `0`)
|
||||||
* `sockets` - (Optional) The number of CPU sockets (defaults to `1`)
|
* `sockets` - (Optional) The number of CPU sockets (defaults to `1`)
|
||||||
|
* `type` - (Optional) The emulated CPU type (defaults to `qemu64`)
|
||||||
|
* `486` - Intel 486
|
||||||
|
* `Broadwell`/`Broadwell-IBRS`/`Broadwell-noTSX`/`Broadwell-noTSX-IBRS` - Intel Core Processor (Broadwell, 2014)
|
||||||
|
* `Cascadelake-Server` - Intel Xeon 32xx/42xx/52xx/62xx/82xx/92xx (2019)
|
||||||
|
* `Conroe` - Intel Celeron_4x0 (Conroe/Merom Class Core 2, 2006)
|
||||||
|
* `EPYC`/`EPYC-IBPB` - AMD EPYC Processor (2017)
|
||||||
|
* `Haswell`/`Haswell-IBRS`/`Haswell-noTSX`/`Haswell-noTSX-IBRS` - Intel Core Processor (Haswell, 2013)
|
||||||
|
* `IvyBridge`/`IvyBridge-IBRS` - Intel Xeon E3-12xx v2 (Ivy Bridge, 2012)
|
||||||
|
* `KnightsMill` - Intel Xeon Phi 72xx (2017)
|
||||||
|
* `Nehalem`/`Nehalem-IBRS` - Intel Core i7 9xx (Nehalem Class Core i7, 2008)
|
||||||
|
* `Opteron_G1` - AMD Opteron 240 (Gen 1 Class Opteron, 2004)
|
||||||
|
* `Opteron_G2` - AMD Opteron 22xx (Gen 2 Class Opteron, 2006)
|
||||||
|
* `Opteron_G3` - AMD Opteron 23xx (Gen 3 Class Opteron, 2009)
|
||||||
|
* `Opteron_G4` - AMD Opteron 62xx class CPU (2011)
|
||||||
|
* `Opteron_G5` - AMD Opteron 63xx class CPU (2012)
|
||||||
|
* `Penryn` - Intel Core 2 Duo P9xxx (Penryn Class Core 2, 2007)
|
||||||
|
* `SandyBridge`/`SandyBridge-IBRS` - Intel Xeon E312xx (Sandy Bridge, 2011)
|
||||||
|
* `Skylake-Client`/`Skylake-Client-IBRS` - Intel Core Processor (Skylake, 2015)
|
||||||
|
* `Skylake-Server`/`Skylake-Server-IBRS` - Intel Xeon Processor (Skylake, 2016)
|
||||||
|
* `Westmere`/`Westmere-IBRS` - Intel Westmere E56xx/L56xx/X56xx (Nehalem-C, 2010)
|
||||||
|
* `athlon` - AMD Athlon
|
||||||
|
* `core2duo` - Intel Core 2 Duo
|
||||||
|
* `coreduo` - Intel Core Duo
|
||||||
|
* `host` - Host passthrough
|
||||||
|
* `kvm32`/`kvm64` - Common KVM processor (32 & 64 bit variants)
|
||||||
|
* `max` - Maximum amount of features from host CPU
|
||||||
|
* `pentium` - Intel Pentium (1993)
|
||||||
|
* `pentium2` - Intel Pentium 2 (1997-1999)
|
||||||
|
* `pentium3` - Intel Pentium 3 (1999-2001)
|
||||||
|
* `phenom` - AMD Phenom (2010)
|
||||||
|
* `qemu32`/`qemu64` - QEMU Virtual CPU version 2.5+ (32 & 64 bit variants)
|
||||||
* `description` - (Optional) The description
|
* `description` - (Optional) The description
|
||||||
* `disk` - (Optional) The disk configuration (multiple blocks supported)
|
* `disk` - (Optional) The disk configuration (multiple blocks supported)
|
||||||
* `datastore_id` - (Optional) The ID of the datastore to create the disk in (defaults to `local-lvm`)
|
* `datastore_id` - (Optional) The ID of the datastore to create the disk in (defaults to `local-lvm`)
|
||||||
|
@ -6,6 +6,7 @@ package proxmox
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -55,6 +56,14 @@ type CustomCloudInitIPConfig struct {
|
|||||||
// CustomCloudInitSSHKeys handles QEMU cloud-init SSH keys parameters.
|
// CustomCloudInitSSHKeys handles QEMU cloud-init SSH keys parameters.
|
||||||
type CustomCloudInitSSHKeys []string
|
type CustomCloudInitSSHKeys []string
|
||||||
|
|
||||||
|
// CustomCPUEmulation handles QEMU CPU emulation parameters.
|
||||||
|
type CustomCPUEmulation struct {
|
||||||
|
Flags *[]string `json:"flags,omitempty" url:"flags,omitempty,semicolon"`
|
||||||
|
Hidden *CustomBool `json:"hidden,omitempty" url:"hidden,omitempty,int"`
|
||||||
|
HVVendorID *string `json:"hv-vendor-id,omitempty" url:"hv-vendor-id,omitempty"`
|
||||||
|
Type string `json:"cputype,omitempty" url:"cputype,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
// CustomEFIDisk handles QEMU EFI disk parameters.
|
// CustomEFIDisk handles QEMU EFI disk parameters.
|
||||||
type CustomEFIDisk struct {
|
type CustomEFIDisk struct {
|
||||||
DiskSize *int `json:"size,omitempty" url:"size,omitempty"`
|
DiskSize *int `json:"size,omitempty" url:"size,omitempty"`
|
||||||
@ -202,6 +211,7 @@ type VirtualEnvironmentVMCreateRequestBody struct {
|
|||||||
CloudInitConfig *CustomCloudInitConfig `json:"cloudinit,omitempty" url:"cloudinit,omitempty"`
|
CloudInitConfig *CustomCloudInitConfig `json:"cloudinit,omitempty" url:"cloudinit,omitempty"`
|
||||||
CPUArchitecture *string `json:"arch,omitempty" url:"arch,omitempty"`
|
CPUArchitecture *string `json:"arch,omitempty" url:"arch,omitempty"`
|
||||||
CPUCores *int `json:"cores,omitempty" url:"cores,omitempty"`
|
CPUCores *int `json:"cores,omitempty" url:"cores,omitempty"`
|
||||||
|
CPUEmulation *CustomCPUEmulation `json:"cpu,omitempty" url:"cpu,omitempty"`
|
||||||
CPULimit *int `json:"cpulimit,omitempty" url:"cpulimit,omitempty"`
|
CPULimit *int `json:"cpulimit,omitempty" url:"cpulimit,omitempty"`
|
||||||
CPUSockets *int `json:"sockets,omitempty" url:"sockets,omitempty"`
|
CPUSockets *int `json:"sockets,omitempty" url:"sockets,omitempty"`
|
||||||
CPUUnits *int `json:"cpuunits,omitempty" url:"cpuunits,omitempty"`
|
CPUUnits *int `json:"cpuunits,omitempty" url:"cpuunits,omitempty"`
|
||||||
@ -322,6 +332,7 @@ type VirtualEnvironmentVMGetResponseData struct {
|
|||||||
CloudInitUsername *string `json:"ciuser,omitempty"`
|
CloudInitUsername *string `json:"ciuser,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"`
|
||||||
CPULimit *int `json:"cpulimit,omitempty"`
|
CPULimit *int `json:"cpulimit,omitempty"`
|
||||||
CPUSockets *int `json:"sockets,omitempty"`
|
CPUSockets *int `json:"sockets,omitempty"`
|
||||||
CPUUnits *int `json:"cpuunits,omitempty"`
|
CPUUnits *int `json:"cpuunits,omitempty"`
|
||||||
@ -574,6 +585,33 @@ func (r CustomCloudInitConfig) EncodeValues(key string, v *url.Values) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EncodeValues converts a CustomCPUEmulation struct to a URL vlaue.
|
||||||
|
func (r CustomCPUEmulation) EncodeValues(key string, v *url.Values) error {
|
||||||
|
values := []string{
|
||||||
|
fmt.Sprintf("cputype=%s", r.Type),
|
||||||
|
}
|
||||||
|
|
||||||
|
if r.Flags != nil && len(*r.Flags) > 0 {
|
||||||
|
values = append(values, fmt.Sprintf("flags=%s", strings.Join(*r.Flags, ";")))
|
||||||
|
}
|
||||||
|
|
||||||
|
if r.Hidden != nil {
|
||||||
|
if *r.Hidden {
|
||||||
|
values = append(values, "hidden=1")
|
||||||
|
} else {
|
||||||
|
values = append(values, "hidden=0")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if r.HVVendorID != nil {
|
||||||
|
values = append(values, fmt.Sprintf("hv-vendor-id=%s", *r.HVVendorID))
|
||||||
|
}
|
||||||
|
|
||||||
|
v.Add(key, strings.Join(values, ","))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// EncodeValues converts a CustomEFIDisk struct to a URL vlaue.
|
// EncodeValues converts a CustomEFIDisk struct to a URL vlaue.
|
||||||
func (r CustomEFIDisk) EncodeValues(key string, v *url.Values) error {
|
func (r CustomEFIDisk) EncodeValues(key string, v *url.Values) error {
|
||||||
values := []string{
|
values := []string{
|
||||||
@ -1136,6 +1174,51 @@ func (r *CustomCloudInitSSHKeys) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON converts a CustomCPUEmulation string to an object.
|
||||||
|
func (r *CustomCPUEmulation) UnmarshalJSON(b []byte) error {
|
||||||
|
var s string
|
||||||
|
|
||||||
|
err := json.Unmarshal(b, &s)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if s == "" {
|
||||||
|
return errors.New("Unexpected empty string")
|
||||||
|
}
|
||||||
|
|
||||||
|
pairs := strings.Split(s, ",")
|
||||||
|
|
||||||
|
for _, p := range pairs {
|
||||||
|
v := strings.Split(strings.TrimSpace(p), "=")
|
||||||
|
|
||||||
|
if len(v) == 1 {
|
||||||
|
r.Type = v[0]
|
||||||
|
} else if len(v) == 2 {
|
||||||
|
switch v[0] {
|
||||||
|
case "cputype":
|
||||||
|
r.Type = v[1]
|
||||||
|
case "flags":
|
||||||
|
if v[1] != "" {
|
||||||
|
f := strings.Split(v[1], ";")
|
||||||
|
r.Flags = &f
|
||||||
|
} else {
|
||||||
|
f := []string{}
|
||||||
|
r.Flags = &f
|
||||||
|
}
|
||||||
|
case "hidden":
|
||||||
|
bv := CustomBool(v[1] == "1")
|
||||||
|
r.Hidden = &bv
|
||||||
|
case "hv-vendor-id":
|
||||||
|
r.HVVendorID = &v[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// UnmarshalJSON converts a CustomNetworkDevice string to an object.
|
// UnmarshalJSON converts a CustomNetworkDevice string to an object.
|
||||||
func (r *CustomNetworkDevice) UnmarshalJSON(b []byte) error {
|
func (r *CustomNetworkDevice) UnmarshalJSON(b []byte) error {
|
||||||
var s string
|
var s string
|
||||||
|
@ -28,6 +28,7 @@ const (
|
|||||||
dvResourceVirtualEnvironmentVMCPUCores = 1
|
dvResourceVirtualEnvironmentVMCPUCores = 1
|
||||||
dvResourceVirtualEnvironmentVMCPUHotplugged = 0
|
dvResourceVirtualEnvironmentVMCPUHotplugged = 0
|
||||||
dvResourceVirtualEnvironmentVMCPUSockets = 1
|
dvResourceVirtualEnvironmentVMCPUSockets = 1
|
||||||
|
dvResourceVirtualEnvironmentVMCPUType = "qemu64"
|
||||||
dvResourceVirtualEnvironmentVMDescription = ""
|
dvResourceVirtualEnvironmentVMDescription = ""
|
||||||
dvResourceVirtualEnvironmentVMDiskDatastoreID = "local-lvm"
|
dvResourceVirtualEnvironmentVMDiskDatastoreID = "local-lvm"
|
||||||
dvResourceVirtualEnvironmentVMDiskFileFormat = "qcow2"
|
dvResourceVirtualEnvironmentVMDiskFileFormat = "qcow2"
|
||||||
@ -81,8 +82,10 @@ const (
|
|||||||
mkResourceVirtualEnvironmentVMCloudInitUserDataFileID = "user_data_file_id"
|
mkResourceVirtualEnvironmentVMCloudInitUserDataFileID = "user_data_file_id"
|
||||||
mkResourceVirtualEnvironmentVMCPU = "cpu"
|
mkResourceVirtualEnvironmentVMCPU = "cpu"
|
||||||
mkResourceVirtualEnvironmentVMCPUCores = "cores"
|
mkResourceVirtualEnvironmentVMCPUCores = "cores"
|
||||||
|
mkResourceVirtualEnvironmentVMCPUFlags = "flags"
|
||||||
mkResourceVirtualEnvironmentVMCPUHotplugged = "hotplugged"
|
mkResourceVirtualEnvironmentVMCPUHotplugged = "hotplugged"
|
||||||
mkResourceVirtualEnvironmentVMCPUSockets = "sockets"
|
mkResourceVirtualEnvironmentVMCPUSockets = "sockets"
|
||||||
|
mkResourceVirtualEnvironmentVMCPUType = "type"
|
||||||
mkResourceVirtualEnvironmentVMDescription = "description"
|
mkResourceVirtualEnvironmentVMDescription = "description"
|
||||||
mkResourceVirtualEnvironmentVMDisk = "disk"
|
mkResourceVirtualEnvironmentVMDisk = "disk"
|
||||||
mkResourceVirtualEnvironmentVMDiskDatastoreID = "datastore_id"
|
mkResourceVirtualEnvironmentVMDiskDatastoreID = "datastore_id"
|
||||||
@ -363,8 +366,10 @@ func resourceVirtualEnvironmentVM() *schema.Resource {
|
|||||||
defaultMap := map[string]interface{}{}
|
defaultMap := map[string]interface{}{}
|
||||||
|
|
||||||
defaultMap[mkResourceVirtualEnvironmentVMCPUCores] = dvResourceVirtualEnvironmentVMCPUCores
|
defaultMap[mkResourceVirtualEnvironmentVMCPUCores] = dvResourceVirtualEnvironmentVMCPUCores
|
||||||
|
defaultMap[mkResourceVirtualEnvironmentVMCPUFlags] = []interface{}{}
|
||||||
defaultMap[mkResourceVirtualEnvironmentVMCPUHotplugged] = dvResourceVirtualEnvironmentVMCPUHotplugged
|
defaultMap[mkResourceVirtualEnvironmentVMCPUHotplugged] = dvResourceVirtualEnvironmentVMCPUHotplugged
|
||||||
defaultMap[mkResourceVirtualEnvironmentVMCPUSockets] = dvResourceVirtualEnvironmentVMCPUSockets
|
defaultMap[mkResourceVirtualEnvironmentVMCPUSockets] = dvResourceVirtualEnvironmentVMCPUSockets
|
||||||
|
defaultMap[mkResourceVirtualEnvironmentVMCPUType] = dvResourceVirtualEnvironmentVMCPUType
|
||||||
|
|
||||||
defaultList[0] = defaultMap
|
defaultList[0] = defaultMap
|
||||||
|
|
||||||
@ -379,6 +384,15 @@ func resourceVirtualEnvironmentVM() *schema.Resource {
|
|||||||
Default: dvResourceVirtualEnvironmentVMCPUCores,
|
Default: dvResourceVirtualEnvironmentVMCPUCores,
|
||||||
ValidateFunc: validation.IntBetween(1, 2304),
|
ValidateFunc: validation.IntBetween(1, 2304),
|
||||||
},
|
},
|
||||||
|
mkResourceVirtualEnvironmentVMCPUFlags: {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Description: "The CPU flags",
|
||||||
|
Optional: true,
|
||||||
|
DefaultFunc: func() (interface{}, error) {
|
||||||
|
return []interface{}{}, nil
|
||||||
|
},
|
||||||
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||||||
|
},
|
||||||
mkResourceVirtualEnvironmentVMCPUHotplugged: {
|
mkResourceVirtualEnvironmentVMCPUHotplugged: {
|
||||||
Type: schema.TypeInt,
|
Type: schema.TypeInt,
|
||||||
Description: "The number of hotplugged vCPUs",
|
Description: "The number of hotplugged vCPUs",
|
||||||
@ -393,6 +407,13 @@ func resourceVirtualEnvironmentVM() *schema.Resource {
|
|||||||
Default: dvResourceVirtualEnvironmentVMCPUSockets,
|
Default: dvResourceVirtualEnvironmentVMCPUSockets,
|
||||||
ValidateFunc: validation.IntBetween(1, 16),
|
ValidateFunc: validation.IntBetween(1, 16),
|
||||||
},
|
},
|
||||||
|
mkResourceVirtualEnvironmentVMCPUType: {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Description: "The emulated CPU type",
|
||||||
|
Optional: true,
|
||||||
|
Default: dvResourceVirtualEnvironmentVMCPUType,
|
||||||
|
ValidateFunc: getCPUTypeValidator(),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
MaxItems: 1,
|
MaxItems: 1,
|
||||||
@ -786,8 +807,10 @@ func resourceVirtualEnvironmentVMCreate(d *schema.ResourceData, m interface{}) e
|
|||||||
}
|
}
|
||||||
|
|
||||||
cpuCores := cpuBlock[mkResourceVirtualEnvironmentVMCPUCores].(int)
|
cpuCores := cpuBlock[mkResourceVirtualEnvironmentVMCPUCores].(int)
|
||||||
|
cpuFlags := cpuBlock[mkResourceVirtualEnvironmentVMCPUFlags].([]interface{})
|
||||||
cpuHotplugged := cpuBlock[mkResourceVirtualEnvironmentVMCPUHotplugged].(int)
|
cpuHotplugged := cpuBlock[mkResourceVirtualEnvironmentVMCPUHotplugged].(int)
|
||||||
cpuSockets := cpuBlock[mkResourceVirtualEnvironmentVMCPUSockets].(int)
|
cpuSockets := cpuBlock[mkResourceVirtualEnvironmentVMCPUSockets].(int)
|
||||||
|
cpuType := cpuBlock[mkResourceVirtualEnvironmentVMCPUType].(string)
|
||||||
|
|
||||||
description := d.Get(mkResourceVirtualEnvironmentVMDescription).(string)
|
description := d.Get(mkResourceVirtualEnvironmentVMDescription).(string)
|
||||||
diskDeviceObjects, err := resourceVirtualEnvironmentVMGetDiskDeviceObjects(d, m)
|
diskDeviceObjects, err := resourceVirtualEnvironmentVMGetDiskDeviceObjects(d, m)
|
||||||
@ -847,6 +870,12 @@ func resourceVirtualEnvironmentVMCreate(d *schema.ResourceData, m interface{}) e
|
|||||||
bootOrder = "cd"
|
bootOrder = "cd"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cpuFlagsConverted := make([]string, len(cpuFlags))
|
||||||
|
|
||||||
|
for fi, flag := range cpuFlags {
|
||||||
|
cpuFlagsConverted[fi] = flag.(string)
|
||||||
|
}
|
||||||
|
|
||||||
ideDevice2Media := "cdrom"
|
ideDevice2Media := "cdrom"
|
||||||
ideDevices := proxmox.CustomStorageDevices{
|
ideDevices := proxmox.CustomStorageDevices{
|
||||||
proxmox.CustomStorageDevice{
|
proxmox.CustomStorageDevice{
|
||||||
@ -879,10 +908,14 @@ func resourceVirtualEnvironmentVMCreate(d *schema.ResourceData, m interface{}) e
|
|||||||
TrimClonedDisks: &agentTrim,
|
TrimClonedDisks: &agentTrim,
|
||||||
Type: &agentType,
|
Type: &agentType,
|
||||||
},
|
},
|
||||||
BootDisk: &bootDisk,
|
BootDisk: &bootDisk,
|
||||||
BootOrder: &bootOrder,
|
BootOrder: &bootOrder,
|
||||||
CloudInitConfig: cloudInitConfig,
|
CloudInitConfig: cloudInitConfig,
|
||||||
CPUCores: &cpuCores,
|
CPUCores: &cpuCores,
|
||||||
|
CPUEmulation: &proxmox.CustomCPUEmulation{
|
||||||
|
Flags: &cpuFlagsConverted,
|
||||||
|
Type: cpuType,
|
||||||
|
},
|
||||||
CPUSockets: &cpuSockets,
|
CPUSockets: &cpuSockets,
|
||||||
DedicatedMemory: &memoryDedicated,
|
DedicatedMemory: &memoryDedicated,
|
||||||
FloatingMemory: &memoryFloating,
|
FloatingMemory: &memoryFloating,
|
||||||
@ -1557,12 +1590,33 @@ func resourceVirtualEnvironmentVMRead(d *schema.ResourceData, m interface{}) err
|
|||||||
cpu[mkResourceVirtualEnvironmentVMCPUSockets] = 0
|
cpu[mkResourceVirtualEnvironmentVMCPUSockets] = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if vmConfig.CPUEmulation != nil {
|
||||||
|
if vmConfig.CPUEmulation.Flags != nil {
|
||||||
|
convertedFlags := make([]interface{}, len(*vmConfig.CPUEmulation.Flags))
|
||||||
|
|
||||||
|
for fi, fv := range *vmConfig.CPUEmulation.Flags {
|
||||||
|
convertedFlags[fi] = fv
|
||||||
|
}
|
||||||
|
|
||||||
|
cpu[mkResourceVirtualEnvironmentVMCPUFlags] = convertedFlags
|
||||||
|
} else {
|
||||||
|
cpu[mkResourceVirtualEnvironmentVMCPUFlags] = []interface{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
cpu[mkResourceVirtualEnvironmentVMCPUType] = vmConfig.CPUEmulation.Type
|
||||||
|
} else {
|
||||||
|
cpu[mkResourceVirtualEnvironmentVMCPUFlags] = []interface{}{}
|
||||||
|
cpu[mkResourceVirtualEnvironmentVMCPUType] = ""
|
||||||
|
}
|
||||||
|
|
||||||
currentCPU := d.Get(mkResourceVirtualEnvironmentVMCPU).([]interface{})
|
currentCPU := d.Get(mkResourceVirtualEnvironmentVMCPU).([]interface{})
|
||||||
|
|
||||||
if len(currentCPU) > 0 ||
|
if len(currentCPU) > 0 ||
|
||||||
cpu[mkResourceVirtualEnvironmentVMCPUCores] != dvResourceVirtualEnvironmentVMCPUCores ||
|
cpu[mkResourceVirtualEnvironmentVMCPUCores] != dvResourceVirtualEnvironmentVMCPUCores ||
|
||||||
|
len(cpu[mkResourceVirtualEnvironmentVMCPUFlags].([]interface{})) > 0 ||
|
||||||
cpu[mkResourceVirtualEnvironmentVMCPUHotplugged] != dvResourceVirtualEnvironmentVMCPUHotplugged ||
|
cpu[mkResourceVirtualEnvironmentVMCPUHotplugged] != dvResourceVirtualEnvironmentVMCPUHotplugged ||
|
||||||
cpu[mkResourceVirtualEnvironmentVMCPUSockets] != dvResourceVirtualEnvironmentVMCPUSockets {
|
cpu[mkResourceVirtualEnvironmentVMCPUSockets] != dvResourceVirtualEnvironmentVMCPUSockets ||
|
||||||
|
cpu[mkResourceVirtualEnvironmentVMCPUType] != dvResourceVirtualEnvironmentVMCPUType {
|
||||||
d.Set(mkResourceVirtualEnvironmentVMCPU, []interface{}{cpu})
|
d.Set(mkResourceVirtualEnvironmentVMCPU, []interface{}{cpu})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2040,8 +2094,10 @@ func resourceVirtualEnvironmentVMUpdate(d *schema.ResourceData, m interface{}) e
|
|||||||
}
|
}
|
||||||
|
|
||||||
cpuCores := cpuBlock[mkResourceVirtualEnvironmentVMCPUCores].(int)
|
cpuCores := cpuBlock[mkResourceVirtualEnvironmentVMCPUCores].(int)
|
||||||
|
cpuFlags := cpuBlock[mkResourceVirtualEnvironmentVMCPUFlags].([]interface{})
|
||||||
cpuHotplugged := cpuBlock[mkResourceVirtualEnvironmentVMCPUHotplugged].(int)
|
cpuHotplugged := cpuBlock[mkResourceVirtualEnvironmentVMCPUHotplugged].(int)
|
||||||
cpuSockets := cpuBlock[mkResourceVirtualEnvironmentVMCPUSockets].(int)
|
cpuSockets := cpuBlock[mkResourceVirtualEnvironmentVMCPUSockets].(int)
|
||||||
|
cpuType := cpuBlock[mkResourceVirtualEnvironmentVMCPUType].(string)
|
||||||
|
|
||||||
if cpuCores > 0 {
|
if cpuCores > 0 {
|
||||||
body.CPUCores = &cpuCores
|
body.CPUCores = &cpuCores
|
||||||
@ -2055,6 +2111,17 @@ func resourceVirtualEnvironmentVMUpdate(d *schema.ResourceData, m interface{}) e
|
|||||||
body.CPUSockets = &cpuSockets
|
body.CPUSockets = &cpuSockets
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cpuFlagsConverted := make([]string, len(cpuFlags))
|
||||||
|
|
||||||
|
for fi, flag := range cpuFlags {
|
||||||
|
cpuFlagsConverted[fi] = flag.(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
body.CPUEmulation = &proxmox.CustomCPUEmulation{
|
||||||
|
Flags: &cpuFlagsConverted,
|
||||||
|
Type: cpuType,
|
||||||
|
}
|
||||||
|
|
||||||
rebootRequired = true
|
rebootRequired = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,18 +227,24 @@ func TestResourceVirtualEnvironmentVMSchema(t *testing.T) {
|
|||||||
|
|
||||||
testOptionalArguments(t, cpuSchema, []string{
|
testOptionalArguments(t, cpuSchema, []string{
|
||||||
mkResourceVirtualEnvironmentVMCPUCores,
|
mkResourceVirtualEnvironmentVMCPUCores,
|
||||||
|
mkResourceVirtualEnvironmentVMCPUFlags,
|
||||||
mkResourceVirtualEnvironmentVMCPUHotplugged,
|
mkResourceVirtualEnvironmentVMCPUHotplugged,
|
||||||
mkResourceVirtualEnvironmentVMCPUSockets,
|
mkResourceVirtualEnvironmentVMCPUSockets,
|
||||||
|
mkResourceVirtualEnvironmentVMCPUType,
|
||||||
})
|
})
|
||||||
|
|
||||||
testSchemaValueTypes(t, cpuSchema, []string{
|
testSchemaValueTypes(t, cpuSchema, []string{
|
||||||
mkResourceVirtualEnvironmentVMCPUCores,
|
mkResourceVirtualEnvironmentVMCPUCores,
|
||||||
|
mkResourceVirtualEnvironmentVMCPUFlags,
|
||||||
mkResourceVirtualEnvironmentVMCPUHotplugged,
|
mkResourceVirtualEnvironmentVMCPUHotplugged,
|
||||||
mkResourceVirtualEnvironmentVMCPUSockets,
|
mkResourceVirtualEnvironmentVMCPUSockets,
|
||||||
|
mkResourceVirtualEnvironmentVMCPUType,
|
||||||
}, []schema.ValueType{
|
}, []schema.ValueType{
|
||||||
schema.TypeInt,
|
schema.TypeInt,
|
||||||
|
schema.TypeList,
|
||||||
schema.TypeInt,
|
schema.TypeInt,
|
||||||
schema.TypeInt,
|
schema.TypeInt,
|
||||||
|
schema.TypeString,
|
||||||
})
|
})
|
||||||
|
|
||||||
diskSchema := testNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMDisk)
|
diskSchema := testNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMDisk)
|
||||||
|
@ -22,6 +22,114 @@ func getContentTypeValidator() schema.SchemaValidateFunc {
|
|||||||
}, false)
|
}, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getCPUFlagsValidator() schema.SchemaValidateFunc {
|
||||||
|
return func(i interface{}, k string) (ws []string, es []error) {
|
||||||
|
list, ok := i.([]interface{})
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
es = append(es, fmt.Errorf("expected type of %s to be []interface{}", k))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
validator := validation.StringInSlice([]string{
|
||||||
|
"+aes",
|
||||||
|
"-aes",
|
||||||
|
"+amd-no-ssb",
|
||||||
|
"-amd-no-ssb",
|
||||||
|
"+amd-ssbd",
|
||||||
|
"-amd-ssbd",
|
||||||
|
"+hv-evmcs",
|
||||||
|
"-hv-evmcs",
|
||||||
|
"+hv-tlbflush",
|
||||||
|
"-hv-tlbflush",
|
||||||
|
"+ibpb",
|
||||||
|
"-ibpb",
|
||||||
|
"+md-clear",
|
||||||
|
"-md-clear",
|
||||||
|
"+pcid",
|
||||||
|
"-pcid",
|
||||||
|
"+pdpe1gb",
|
||||||
|
"-pdpe1gb",
|
||||||
|
"+spec-ctrl",
|
||||||
|
"-spec-ctrl",
|
||||||
|
"+ssbd",
|
||||||
|
"-ssbd",
|
||||||
|
"+virt-ssbd",
|
||||||
|
"-virt-ssbd",
|
||||||
|
}, false)
|
||||||
|
|
||||||
|
for li, lv := range list {
|
||||||
|
v, ok := lv.(string)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
es = append(es, fmt.Errorf("expected type of %s[%d] to be string", k, li))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
warns, errs := validator(v, k)
|
||||||
|
|
||||||
|
ws = append(ws, warns...)
|
||||||
|
es = append(es, errs...)
|
||||||
|
|
||||||
|
if len(es) > 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getCPUTypeValidator() schema.SchemaValidateFunc {
|
||||||
|
return validation.StringInSlice([]string{
|
||||||
|
"486",
|
||||||
|
"Broadwell",
|
||||||
|
"Broadwell-IBRS",
|
||||||
|
"Broadwell-noTSX",
|
||||||
|
"Broadwell-noTSX-IBRS",
|
||||||
|
"Cascadelake-Server",
|
||||||
|
"Conroe",
|
||||||
|
"EPYC",
|
||||||
|
"EPYC-IBPB",
|
||||||
|
"Haswell",
|
||||||
|
"Haswell-IBRS",
|
||||||
|
"Haswell-noTSX",
|
||||||
|
"Haswell-noTSX-IBRS",
|
||||||
|
"IvyBridge",
|
||||||
|
"IvyBridge-IBRS",
|
||||||
|
"KnightsMill",
|
||||||
|
"Nehalem",
|
||||||
|
"Nehalem-IBRS",
|
||||||
|
"Opteron_G1",
|
||||||
|
"Opteron_G2",
|
||||||
|
"Opteron_G3",
|
||||||
|
"Opteron_G4",
|
||||||
|
"Opteron_G5",
|
||||||
|
"Penryn",
|
||||||
|
"SandyBridge",
|
||||||
|
"SandyBridge-IBRS",
|
||||||
|
"Skylake-Client",
|
||||||
|
"Skylake-Client-IBRS",
|
||||||
|
"Skylake-Server",
|
||||||
|
"Skylake-Server-IBRS",
|
||||||
|
"Westmere",
|
||||||
|
"Westmere-IBRS",
|
||||||
|
"athlon",
|
||||||
|
"core2duo",
|
||||||
|
"coreduo",
|
||||||
|
"host",
|
||||||
|
"kvm32",
|
||||||
|
"kvm64",
|
||||||
|
"max",
|
||||||
|
"pentium",
|
||||||
|
"pentium2",
|
||||||
|
"pentium3",
|
||||||
|
"phenom",
|
||||||
|
"qemu32",
|
||||||
|
"qemu64",
|
||||||
|
}, false)
|
||||||
|
}
|
||||||
|
|
||||||
func getFileFormatValidator() schema.SchemaValidateFunc {
|
func getFileFormatValidator() schema.SchemaValidateFunc {
|
||||||
return validation.StringInSlice([]string{
|
return validation.StringInSlice([]string{
|
||||||
"qcow2",
|
"qcow2",
|
||||||
|
Loading…
Reference in New Issue
Block a user