diff --git a/docs/resources/virtual_environment_vm.md b/docs/resources/virtual_environment_vm.md index 55f7a857..a3538ee8 100644 --- a/docs/resources/virtual_environment_vm.md +++ b/docs/resources/virtual_environment_vm.md @@ -408,6 +408,15 @@ output "ubuntu_vm_public_key" { - `floating` - (Optional) The floating memory in megabytes (defaults to `0`). - `shared` - (Optional) The shared memory in megabytes (defaults to `0`). + - `hugepages` - (Optional) Enable/disable hugepages memory (defaults to disable). + - `2` - 2MB hugepages. + - `1024` - 1GB hugepages. + - `any` - Any hugepages. + - `keep_hugepages` - (Optional) Keep hugepages memory after the VM is stopped (defaults + to `false`). + + Settings `hugepages` and `keep_hugepages` are only allowed for `root@pam` authenticated user. + And required `cpu.numa` to be enabled. - `migrate` - (Optional) Migrate the VM on node change instead of re-creating it (defaults to `false`). - `name` - (Optional) The virtual machine name. diff --git a/example/resource_virtual_environment_vm.tf b/example/resource_virtual_environment_vm.tf index f4cb61ee..e58911bb 100644 --- a/example/resource_virtual_environment_vm.tf +++ b/example/resource_virtual_environment_vm.tf @@ -128,6 +128,7 @@ resource "proxmox_virtual_environment_vm" "example" { memory { dedicated = 768 + # hugepages = "2" } connection { diff --git a/proxmox/nodes/vms/vms_types.go b/proxmox/nodes/vms/vms_types.go index 0a74f87a..89e8a507 100644 --- a/proxmox/nodes/vms/vms_types.go +++ b/proxmox/nodes/vms/vms_types.go @@ -249,6 +249,7 @@ type CreateRequestBody struct { Hotplug types.CustomCommaSeparatedList `json:"hotplug,omitempty" url:"hotplug,omitempty,comma"` Hugepages *string `json:"hugepages,omitempty" url:"hugepages,omitempty"` IDEDevices CustomStorageDevices `json:"ide,omitempty" url:",omitempty"` + KeepHugepages *types.CustomBool `json:"keephugepages,omitempty" url:"keephugepages,omitempty,int"` KeyboardLayout *string `json:"keyboard,omitempty" url:"keyboard,omitempty"` KVMArguments *string `json:"args,omitempty" url:"args,omitempty,space"` KVMEnabled *types.CustomBool `json:"kvm,omitempty" url:"kvm,omitempty,int"` @@ -412,6 +413,7 @@ type GetResponseData struct { IPConfig29 *CustomCloudInitIPConfig `json:"ipconfig29,omitempty"` IPConfig30 *CustomCloudInitIPConfig `json:"ipconfig30,omitempty"` IPConfig31 *CustomCloudInitIPConfig `json:"ipconfig31,omitempty"` + KeepHugepages *types.CustomBool `json:"keephugepages,omitempty"` KeyboardLayout *string `json:"keyboard,omitempty"` KVMArguments *string `json:"args,omitempty"` KVMEnabled *types.CustomBool `json:"kvm,omitempty"` diff --git a/proxmoxtf/resource/vm/vm.go b/proxmoxtf/resource/vm/vm.go index 9c749c83..f5a3567a 100644 --- a/proxmoxtf/resource/vm/vm.go +++ b/proxmoxtf/resource/vm/vm.go @@ -93,6 +93,8 @@ const ( dvMemoryDedicated = 512 dvMemoryFloating = 0 dvMemoryShared = 0 + dvMemoryHugepages = "" + dvMemoryKeepHugepages = false dvMigrate = false dvName = "" @@ -210,15 +212,17 @@ const ( mkInitializationNetworkDataFileID = "network_data_file_id" mkInitializationMetaDataFileID = "meta_data_file_id" - mkKeyboardLayout = "keyboard_layout" - mkKVMArguments = "kvm_arguments" - mkMachine = "machine" - mkMemory = "memory" - mkMemoryDedicated = "dedicated" - mkMemoryFloating = "floating" - mkMemoryShared = "shared" - mkMigrate = "migrate" - mkName = "name" + mkKeyboardLayout = "keyboard_layout" + mkKVMArguments = "kvm_arguments" + mkMachine = "machine" + mkMemory = "memory" + mkMemoryDedicated = "dedicated" + mkMemoryFloating = "floating" + mkMemoryShared = "shared" + mkMemoryHugepages = "hugepages" + mkMemoryKeepHugepages = "keep_hugepages" + mkMigrate = "migrate" + mkName = "name" mkNodeName = "node_name" mkOperatingSystem = "operating_system" @@ -991,9 +995,11 @@ func VM() *schema.Resource { DefaultFunc: func() (interface{}, error) { return []interface{}{ map[string]interface{}{ - mkMemoryDedicated: dvMemoryDedicated, - mkMemoryFloating: dvMemoryFloating, - mkMemoryShared: dvMemoryShared, + mkMemoryDedicated: dvMemoryDedicated, + mkMemoryFloating: dvMemoryFloating, + mkMemoryShared: dvMemoryShared, + mkMemoryHugepages: dvMemoryHugepages, + mkMemoryKeepHugepages: dvMemoryKeepHugepages, }, }, nil }, @@ -1026,6 +1032,25 @@ func VM() *schema.Resource { validation.IntBetween(0, 268435456), ), }, + mkMemoryHugepages: { + Type: schema.TypeString, + Description: "Enable/disable hugepages memory", + Optional: true, + Default: dvMemoryHugepages, + RequiredWith: []string{"cpu.0.numa"}, + ValidateDiagFunc: validation.ToDiagFunc(validation.StringInSlice([]string{ + "1024", + "2", + "any", + }, true)), + }, + mkMemoryKeepHugepages: { + Type: schema.TypeBool, + Description: "Hugepages will not be deleted after VM shutdown and can be used for subsequent starts", + Optional: true, + Default: dvMemoryKeepHugepages, + RequiredWith: []string{"cpu.0.numa", "memory.0.hugepages"}, + }, }, }, MaxItems: 1, @@ -1962,6 +1987,8 @@ func vmCreateClone(ctx context.Context, d *schema.ResourceData, m interface{}) d memoryDedicated := memoryBlock[mkMemoryDedicated].(int) memoryFloating := memoryBlock[mkMemoryFloating].(int) memoryShared := memoryBlock[mkMemoryShared].(int) + hugepages := memoryBlock[mkMemoryHugepages].(string) + keepHugepages := types.CustomBool(memoryBlock[mkMemoryKeepHugepages].(bool)) updateBody.DedicatedMemory = &memoryDedicated updateBody.FloatingMemory = &memoryFloating @@ -1974,6 +2001,14 @@ func vmCreateClone(ctx context.Context, d *schema.ResourceData, m interface{}) d Size: memoryShared, } } + + if hugepages != "" { + updateBody.Hugepages = &hugepages + } + + if keepHugepages { + updateBody.KeepHugepages = &keepHugepages + } } networkDevice := d.Get(network.MkNetworkDevice).([]interface{}) @@ -2372,6 +2407,8 @@ func vmCreateCustom(ctx context.Context, d *schema.ResourceData, m interface{}) memoryDedicated := memoryBlock[mkMemoryDedicated].(int) memoryFloating := memoryBlock[mkMemoryFloating].(int) memoryShared := memoryBlock[mkMemoryShared].(int) + memoryHugepages := memoryBlock[mkMemoryHugepages].(string) + memoryKeepHugepages := types.CustomBool(memoryBlock[mkMemoryKeepHugepages].(bool)) machine := d.Get(mkMachine).(string) name := d.Get(mkName).(string) @@ -2584,6 +2621,14 @@ func vmCreateCustom(ctx context.Context, d *schema.ResourceData, m interface{}) createBody.Machine = &machine } + if memoryHugepages != "" { + createBody.Hugepages = &memoryHugepages + } + + if memoryKeepHugepages { + createBody.KeepHugepages = &memoryKeepHugepages + } + if name != "" { createBody.Name = &name } @@ -3957,6 +4002,18 @@ func vmReadCustom( memory[mkMemoryShared] = 0 } + if vmConfig.Hugepages != nil { + memory[mkMemoryHugepages] = *vmConfig.Hugepages + } else { + memory[mkMemoryHugepages] = "" + } + + if vmConfig.KeepHugepages != nil { + memory[mkMemoryKeepHugepages] = *vmConfig.KeepHugepages + } else { + memory[mkMemoryKeepHugepages] = false + } + currentMemory := d.Get(mkMemory).([]interface{}) if len(clone) > 0 { @@ -3967,7 +4024,9 @@ func vmReadCustom( } else if len(currentMemory) > 0 || memory[mkMemoryDedicated] != dvMemoryDedicated || memory[mkMemoryFloating] != dvMemoryFloating || - memory[mkMemoryShared] != dvMemoryShared { + memory[mkMemoryShared] != dvMemoryShared || + memory[mkMemoryHugepages] != dvMemoryHugepages || + memory[mkMemoryKeepHugepages] != dvMemoryKeepHugepages { err := d.Set(mkMemory, []interface{}{memory}) diags = append(diags, diag.FromErr(err)...) } @@ -4762,7 +4821,6 @@ func vmUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.D updateBody.CPUCores = &cpuCores updateBody.CPUSockets = &cpuSockets updateBody.CPUUnits = &cpuUnits - updateBody.CPUAffinity = &cpuAffinity updateBody.NUMAEnabled = &cpuNUMA if cpuAffinity != "" { @@ -4935,6 +4993,8 @@ func vmUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.D memoryDedicated := memoryBlock[mkMemoryDedicated].(int) memoryFloating := memoryBlock[mkMemoryFloating].(int) memoryShared := memoryBlock[mkMemoryShared].(int) + memoryHugepages := memoryBlock[mkMemoryHugepages].(string) + memoryKeepHugepages := types.CustomBool(memoryBlock[mkMemoryKeepHugepages].(bool)) updateBody.DedicatedMemory = &memoryDedicated updateBody.FloatingMemory = &memoryFloating @@ -4948,6 +5008,14 @@ func vmUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.D } } + if memoryHugepages != "" { + updateBody.Hugepages = &memoryHugepages + updateBody.KeepHugepages = &memoryKeepHugepages + } else { + del = append(del, "hugepages") + del = append(del, "keephugepages") + } + rebootRequired = true }