mirror of
https://github.com/bpg/terraform-provider-proxmox.git
synced 2025-07-01 11:02:59 +00:00
Initial speed limit support for disk devices
This commit is contained in:
parent
f69339966a
commit
40084fa433
@ -347,6 +347,9 @@ This resource doesn't expose any additional attributes.
|
||||
* `file_format` - (Optional) The file format (defaults to `qcow2`)
|
||||
* `file_id` - (Optional) The file ID for a disk image
|
||||
* `size` - (Optional) The disk size in gigabytes (defaults to `8`)
|
||||
* `speed` - (Optional) The speed limits
|
||||
* `read` - (Optional) The maximum read speed in megabytes per second
|
||||
* `write` - (Optional) The maximum write speed in megabytes per second
|
||||
* `keyboard_layout` - (Optional) The keyboard layout (defaults to `en-us`)
|
||||
* `memory` - (Optional) The memory configuration
|
||||
* `dedicated` - (Optional) The dedicated memory in megabytes (defaults to `512`)
|
||||
|
@ -138,11 +138,13 @@ type CustomStartupOrder struct {
|
||||
|
||||
// CustomStorageDevice handles QEMU SATA device parameters.
|
||||
type CustomStorageDevice struct {
|
||||
AIO *string `json:"aio,omitempty" url:"aio,omitempty"`
|
||||
BackupEnabled *CustomBool `json:"backup,omitempty" url:"backup,omitempty,int"`
|
||||
Enabled bool `json:"-" url:"-"`
|
||||
FileVolume string `json:"file" url:"file"`
|
||||
Media *string `json:"media,omitempty" url:"media,omitempty"`
|
||||
AIO *string `json:"aio,omitempty" url:"aio,omitempty"`
|
||||
BackupEnabled *CustomBool `json:"backup,omitempty" url:"backup,omitempty,int"`
|
||||
Enabled bool `json:"-" url:"-"`
|
||||
FileVolume string `json:"file" url:"file"`
|
||||
MaxReadSpeedMbps *int `json:"mbps_rd,omitempty" url:"mbps_rd,omitempty"`
|
||||
MaxWriteSpeedMbps *int `json:"mbps_wr,omitempty" url:"mbps_wr,omitempty"`
|
||||
Media *string `json:"media,omitempty" url:"media,omitempty"`
|
||||
}
|
||||
|
||||
// CustomStorageDevices handles QEMU SATA device parameters.
|
||||
@ -787,6 +789,14 @@ func (r CustomStorageDevice) EncodeValues(key string, v *url.Values) error {
|
||||
}
|
||||
}
|
||||
|
||||
if r.MaxReadSpeedMbps != nil {
|
||||
values = append(values, fmt.Sprintf("mbps_rd=%d", *r.MaxReadSpeedMbps))
|
||||
}
|
||||
|
||||
if r.MaxWriteSpeedMbps != nil {
|
||||
values = append(values, fmt.Sprintf("mbps_wr=%d", *r.MaxWriteSpeedMbps))
|
||||
}
|
||||
|
||||
if r.Media != nil {
|
||||
values = append(values, fmt.Sprintf("media=%s", *r.Media))
|
||||
}
|
||||
|
@ -32,6 +32,8 @@ const (
|
||||
dvResourceVirtualEnvironmentVMDiskFileFormat = "qcow2"
|
||||
dvResourceVirtualEnvironmentVMDiskFileID = ""
|
||||
dvResourceVirtualEnvironmentVMDiskSize = 8
|
||||
dvResourceVirtualEnvironmentVMDiskSpeedRead = 0
|
||||
dvResourceVirtualEnvironmentVMDiskSpeedWrite = 0
|
||||
dvResourceVirtualEnvironmentVMKeyboardLayout = "en-us"
|
||||
dvResourceVirtualEnvironmentVMMemoryDedicated = 512
|
||||
dvResourceVirtualEnvironmentVMMemoryFloating = 0
|
||||
@ -79,6 +81,9 @@ const (
|
||||
mkResourceVirtualEnvironmentVMDiskFileFormat = "file_format"
|
||||
mkResourceVirtualEnvironmentVMDiskFileID = "file_id"
|
||||
mkResourceVirtualEnvironmentVMDiskSize = "size"
|
||||
mkResourceVirtualEnvironmentVMDiskSpeed = "speed"
|
||||
mkResourceVirtualEnvironmentVMDiskSpeedRead = "read"
|
||||
mkResourceVirtualEnvironmentVMDiskSpeedWrite = "write"
|
||||
mkResourceVirtualEnvironmentVMKeyboardLayout = "keyboard_layout"
|
||||
mkResourceVirtualEnvironmentVMMemory = "memory"
|
||||
mkResourceVirtualEnvironmentVMMemoryDedicated = "dedicated"
|
||||
@ -416,6 +421,40 @@ func resourceVirtualEnvironmentVM() *schema.Resource {
|
||||
Default: dvResourceVirtualEnvironmentVMDiskSize,
|
||||
ValidateFunc: validation.IntBetween(1, 8192),
|
||||
},
|
||||
mkResourceVirtualEnvironmentVMDiskSpeed: {
|
||||
Type: schema.TypeList,
|
||||
Description: "The speed limits",
|
||||
Optional: true,
|
||||
DefaultFunc: func() (interface{}, error) {
|
||||
defaultList := make([]interface{}, 1)
|
||||
defaultMap := make(map[string]interface{})
|
||||
|
||||
defaultMap[mkResourceVirtualEnvironmentVMDiskSpeedRead] = dvResourceVirtualEnvironmentVMDiskSpeedRead
|
||||
defaultMap[mkResourceVirtualEnvironmentVMDiskSpeedWrite] = dvResourceVirtualEnvironmentVMDiskSpeedWrite
|
||||
|
||||
defaultList[0] = defaultMap
|
||||
|
||||
return defaultList, nil
|
||||
},
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
mkResourceVirtualEnvironmentVMDiskSpeedRead: {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Description: "The maximum read speed in megabytes per second",
|
||||
Default: dvResourceVirtualEnvironmentVMDiskSpeedRead,
|
||||
},
|
||||
mkResourceVirtualEnvironmentVMDiskSpeedWrite: {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Description: "The maximum write speed in megabytes per second",
|
||||
Default: dvResourceVirtualEnvironmentVMDiskSpeedRead,
|
||||
},
|
||||
},
|
||||
},
|
||||
MaxItems: 1,
|
||||
MinItems: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
MaxItems: 14,
|
||||
@ -567,11 +606,11 @@ func resourceVirtualEnvironmentVMCreate(d *schema.ResourceData, m interface{}) e
|
||||
return err
|
||||
}
|
||||
|
||||
schema := resourceVirtualEnvironmentVM().Schema
|
||||
resourceSchema := resourceVirtualEnvironmentVM().Schema
|
||||
agent := d.Get(mkResourceVirtualEnvironmentVMAgent).([]interface{})
|
||||
|
||||
if len(agent) == 0 {
|
||||
agentDefault, err := schema[mkResourceVirtualEnvironmentVMAgent].DefaultValue()
|
||||
agentDefault, err := resourceSchema[mkResourceVirtualEnvironmentVMAgent].DefaultValue()
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
@ -588,7 +627,7 @@ func resourceVirtualEnvironmentVMCreate(d *schema.ResourceData, m interface{}) e
|
||||
cdrom := d.Get(mkResourceVirtualEnvironmentVMCDROM).([]interface{})
|
||||
|
||||
if len(cdrom) == 0 {
|
||||
cdromDefault, err := schema[mkResourceVirtualEnvironmentVMCDROM].DefaultValue()
|
||||
cdromDefault, err := resourceSchema[mkResourceVirtualEnvironmentVMCDROM].DefaultValue()
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
@ -703,7 +742,7 @@ func resourceVirtualEnvironmentVMCreate(d *schema.ResourceData, m interface{}) e
|
||||
cpu := d.Get(mkResourceVirtualEnvironmentVMCPU).([]interface{})
|
||||
|
||||
if len(cpu) == 0 {
|
||||
cpuDefault, err := schema[mkResourceVirtualEnvironmentVMCPU].DefaultValue()
|
||||
cpuDefault, err := resourceSchema[mkResourceVirtualEnvironmentVMCPU].DefaultValue()
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
@ -721,6 +760,10 @@ func resourceVirtualEnvironmentVMCreate(d *schema.ResourceData, m interface{}) e
|
||||
disk := d.Get(mkResourceVirtualEnvironmentVMDisk).([]interface{})
|
||||
scsiDevices := make(proxmox.CustomStorageDevices, len(disk))
|
||||
|
||||
diskSchemaElem := resourceSchema[mkResourceVirtualEnvironmentVMDisk].Elem
|
||||
diskSchemaResource := diskSchemaElem.(*schema.Resource)
|
||||
diskSpeedResource := diskSchemaResource.Schema[mkResourceVirtualEnvironmentVMDiskSpeed]
|
||||
|
||||
for i, d := range disk {
|
||||
block := d.(map[string]interface{})
|
||||
|
||||
@ -728,11 +771,34 @@ func resourceVirtualEnvironmentVMCreate(d *schema.ResourceData, m interface{}) e
|
||||
enabled, _ := block[mkResourceVirtualEnvironmentVMDiskEnabled].(bool)
|
||||
fileID, _ := block[mkResourceVirtualEnvironmentVMDiskFileID].(string)
|
||||
size, _ := block[mkResourceVirtualEnvironmentVMDiskSize].(int)
|
||||
speed := block[mkResourceVirtualEnvironmentVMDiskSpeed].([]interface{})
|
||||
|
||||
if len(speed) == 0 {
|
||||
diskSpeedDefault, err := diskSpeedResource.DefaultValue()
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
speed = diskSpeedDefault.([]interface{})
|
||||
}
|
||||
|
||||
speedBlock := speed[0].(map[string]interface{})
|
||||
speedLimitRead := speedBlock[mkResourceVirtualEnvironmentVMDiskSpeedRead].(int)
|
||||
speedLimitWrite := speedBlock[mkResourceVirtualEnvironmentVMDiskSpeedWrite].(int)
|
||||
|
||||
diskDevice := proxmox.CustomStorageDevice{
|
||||
Enabled: enabled,
|
||||
}
|
||||
|
||||
if speedLimitRead > 0 {
|
||||
diskDevice.MaxReadSpeedMbps = &speedLimitRead
|
||||
}
|
||||
|
||||
if speedLimitWrite > 0 {
|
||||
diskDevice.MaxWriteSpeedMbps = &speedLimitWrite
|
||||
}
|
||||
|
||||
if fileID != "" {
|
||||
diskDevice.Enabled = false
|
||||
} else {
|
||||
@ -746,7 +812,7 @@ func resourceVirtualEnvironmentVMCreate(d *schema.ResourceData, m interface{}) e
|
||||
memory := d.Get(mkResourceVirtualEnvironmentVMMemory).([]interface{})
|
||||
|
||||
if len(memory) == 0 {
|
||||
memoryDefault, err := schema[mkResourceVirtualEnvironmentVMMemory].DefaultValue()
|
||||
memoryDefault, err := resourceSchema[mkResourceVirtualEnvironmentVMMemory].DefaultValue()
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
@ -842,6 +908,7 @@ func resourceVirtualEnvironmentVMCreate(d *schema.ResourceData, m interface{}) e
|
||||
}
|
||||
|
||||
scsiHardware := "virtio-scsi-pci"
|
||||
startOnBoot := proxmox.CustomBool(true)
|
||||
tabletDeviceEnabled := proxmox.CustomBool(true)
|
||||
|
||||
body := &proxmox.VirtualEnvironmentVMCreateRequestBody{
|
||||
@ -865,6 +932,7 @@ func resourceVirtualEnvironmentVMCreate(d *schema.ResourceData, m interface{}) e
|
||||
SCSIHardware: &scsiHardware,
|
||||
SerialDevices: []string{"socket"},
|
||||
SharedMemory: memorySharedObject,
|
||||
StartOnBoot: &startOnBoot,
|
||||
TabletDeviceEnabled: &tabletDeviceEnabled,
|
||||
VMID: &vmID,
|
||||
}
|
||||
@ -926,22 +994,54 @@ func resourceVirtualEnvironmentVMCreateImportedDisks(d *schema.ResourceData, m i
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieve some information about the disk schema.
|
||||
resourceSchema := resourceVirtualEnvironmentVM().Schema
|
||||
diskSchemaElem := resourceSchema[mkResourceVirtualEnvironmentVMDisk].Elem
|
||||
diskSchemaResource := diskSchemaElem.(*schema.Resource)
|
||||
diskSpeedResource := diskSchemaResource.Schema[mkResourceVirtualEnvironmentVMDiskSpeed]
|
||||
|
||||
// Generate the commands required to import the specified disks.
|
||||
importedDiskCount := 0
|
||||
|
||||
for i, d := range disk {
|
||||
block := d.(map[string]interface{})
|
||||
|
||||
datastoreID, _ := block[mkResourceVirtualEnvironmentVMDiskDatastoreID].(string)
|
||||
enabled, _ := block[mkResourceVirtualEnvironmentVMDiskEnabled].(bool)
|
||||
fileFormat, _ := block[mkResourceVirtualEnvironmentVMDiskFileFormat].(string)
|
||||
fileID, _ := block[mkResourceVirtualEnvironmentVMDiskFileID].(string)
|
||||
size, _ := block[mkResourceVirtualEnvironmentVMDiskSize].(int)
|
||||
|
||||
if !enabled || fileID == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
datastoreID, _ := block[mkResourceVirtualEnvironmentVMDiskDatastoreID].(string)
|
||||
fileFormat, _ := block[mkResourceVirtualEnvironmentVMDiskFileFormat].(string)
|
||||
size, _ := block[mkResourceVirtualEnvironmentVMDiskSize].(int)
|
||||
speed := block[mkResourceVirtualEnvironmentVMDiskSpeed].([]interface{})
|
||||
|
||||
if len(speed) == 0 {
|
||||
diskSpeedDefault, err := diskSpeedResource.DefaultValue()
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
speed = diskSpeedDefault.([]interface{})
|
||||
}
|
||||
|
||||
speedBlock := speed[0].(map[string]interface{})
|
||||
speedLimitRead := speedBlock[mkResourceVirtualEnvironmentVMDiskSpeedRead].(int)
|
||||
speedLimitWrite := speedBlock[mkResourceVirtualEnvironmentVMDiskSpeedWrite].(int)
|
||||
|
||||
diskOptions := ""
|
||||
|
||||
if speedLimitRead > 0 {
|
||||
diskOptions += fmt.Sprintf(",mbps_rd=%d", speedLimitRead)
|
||||
}
|
||||
|
||||
if speedLimitWrite > 0 {
|
||||
diskOptions += fmt.Sprintf(",mbps_wr=%d", speedLimitWrite)
|
||||
}
|
||||
|
||||
fileIDParts := strings.Split(fileID, ":")
|
||||
filePath := fmt.Sprintf("/var/lib/vz/template/%s", fileIDParts[1])
|
||||
filePathTmp := fmt.Sprintf("/tmp/vm-%d-disk-%d.%s", vmID, diskCount+importedDiskCount, fileFormat)
|
||||
@ -951,7 +1051,7 @@ func resourceVirtualEnvironmentVMCreateImportedDisks(d *schema.ResourceData, m i
|
||||
fmt.Sprintf("cp %s %s", filePath, filePathTmp),
|
||||
fmt.Sprintf("qemu-img resize %s %dG", filePathTmp, size),
|
||||
fmt.Sprintf("qm importdisk %d %s %s -format qcow2", vmID, filePathTmp, datastoreID),
|
||||
fmt.Sprintf("qm set %d --scsi%d %s:vm-%d-disk-%d", vmID, i, datastoreID, vmID, diskCount+importedDiskCount),
|
||||
fmt.Sprintf("qm set %d -scsi%d %s:vm-%d-disk-%d%s", vmID, i, datastoreID, vmID, diskCount+importedDiskCount, diskOptions),
|
||||
fmt.Sprintf("rm -f %s", filePathTmp),
|
||||
)
|
||||
|
||||
|
@ -247,6 +247,21 @@ func TestResourceVirtualEnvironmentVMSchema(t *testing.T) {
|
||||
schema.TypeInt,
|
||||
})
|
||||
|
||||
diskSpeedSchema := testNestedSchemaExistence(t, diskSchema, mkResourceVirtualEnvironmentVMDiskSpeed)
|
||||
|
||||
testOptionalArguments(t, diskSpeedSchema, []string{
|
||||
mkResourceVirtualEnvironmentVMDiskSpeedRead,
|
||||
mkResourceVirtualEnvironmentVMDiskSpeedWrite,
|
||||
})
|
||||
|
||||
testSchemaValueTypes(t, diskSpeedSchema, []string{
|
||||
mkResourceVirtualEnvironmentVMDiskSpeedRead,
|
||||
mkResourceVirtualEnvironmentVMDiskSpeedWrite,
|
||||
}, []schema.ValueType{
|
||||
schema.TypeInt,
|
||||
schema.TypeInt,
|
||||
})
|
||||
|
||||
memorySchema := testNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMMemory)
|
||||
|
||||
testOptionalArguments(t, memorySchema, []string{
|
||||
|
Loading…
Reference in New Issue
Block a user