Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[3.0.1-rc1] Feature: KMGT disk size #929

Merged
merged 6 commits into from
Feb 5, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions proxmox/converters.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package proxmox

import (
"strconv"
)

const (
kibibyte int64 = 1
mebibyte int64 = 1024
gibibyte int64 = 1048576
tebibyte int64 = 1073741824
)

func convert_KibibytesToString(kibibytes int64) string {
if kibibytes%tebibyte == 0 {
return strconv.FormatInt(kibibytes/tebibyte, 10) + "T"
}
if kibibytes%gibibyte == 0 {
return strconv.FormatInt(kibibytes/gibibyte, 10) + "G"
}
if kibibytes%mebibyte == 0 {
return strconv.FormatInt(kibibytes/mebibyte, 10) + "M"
}
return strconv.FormatInt(kibibytes, 10) + "K"
}

// Relies on the input being validated
func convert_SizeStringToKibibytes_Unsafe(size string) int {
if len(size) > 1 {
switch size[len(size)-1:] {
case "T":
return parseSize_Unsafe(size, tebibyte)
case "G":
return parseSize_Unsafe(size, gibibyte)
case "M":
return parseSize_Unsafe(size, mebibyte)
case "K":
return parseSize_Unsafe(size, kibibyte)
}
}
tmpSize, _ := strconv.ParseInt(size, 10, 0)
return int(tmpSize * gibibyte)
}

// Relies on the input being validated
func parseSize_Unsafe(size string, multiplier int64) int {
tmpSize, _ := strconv.ParseInt(size[:len(size)-1], 10, 0)
return int(tmpSize * multiplier)
}
106 changes: 59 additions & 47 deletions proxmox/resource_vm_qemu.go
Original file line number Diff line number Diff line change
Expand Up @@ -2121,7 +2121,7 @@

for _, setConf := range devicesSet.List() {
devicesSet.Remove(setConf)
setConfMap := setConf.(map[string]interface{})

Check failure on line 2124 in proxmox/resource_vm_qemu.go

View workflow job for this annotation

GitHub Actions / audit

config.Disk.SizeInKibibytes undefined (type *"github.com/Telmate/proxmox-api-go/proxmox".QemuIdeDisk has no field or method SizeInKibibytes)
deviceID := setConfMap[idKey].(int)
setConfMap = adaptDeviceToConf(setConfMap, activeDevicesMap[deviceID])
devicesSet.Add(setConfMap)
Expand All @@ -2141,7 +2141,7 @@

logger, _ := CreateSubLogger("initConnInfo")

var err error

Check failure on line 2144 in proxmox/resource_vm_qemu.go

View workflow job for this annotation

GitHub Actions / audit

config.Passthrough.SizeInKibibytes undefined (type *"github.com/Telmate/proxmox-api-go/proxmox".QemuIdePassthrough has no field or method SizeInKibibytes)
var lasterr error
var interfaces []pxapi.AgentNetworkInterface
var diags diag.Diagnostics
Expand Down Expand Up @@ -2185,7 +2185,7 @@
log.Printf("[DEBUG][initConnInfo] retries will end at %s", guestAgentWaitEnd)
logger.Debug().Int("vmid", vmr.VmId()).Msgf("retrying for at most %v minutes before giving up", guestAgentTimeout)
logger.Debug().Int("vmid", vmr.VmId()).Msgf("retries will end at %s", guestAgentWaitEnd)

Check failure on line 2188 in proxmox/resource_vm_qemu.go

View workflow job for this annotation

GitHub Actions / audit

config.Disk.SizeInKibibytes undefined (type *"github.com/Telmate/proxmox-api-go/proxmox".QemuSataDisk has no field or method SizeInKibibytes)
for time.Now().Before(guestAgentWaitEnd) {
interfaces, err = client.GetVmAgentNetworkInterfaces(vmr)
lasterr = err
Expand All @@ -2205,7 +2205,7 @@
// "not running" means either not installed or not started yet.
// any other error should not happen here
return diag.FromErr(err)
}

Check failure on line 2208 in proxmox/resource_vm_qemu.go

View workflow job for this annotation

GitHub Actions / audit

config.Disk.SizeInKibibytes undefined (type *"github.com/Telmate/proxmox-api-go/proxmox".QemuSataDisk has no field or method SizeInKibibytes)
// wait before next try
time.Sleep(time.Duration(d.Get("additional_wait").(int)) * time.Second)
}
Expand Down Expand Up @@ -2276,7 +2276,7 @@
if sshHost == "" {
sshHost = ipMatch[1]
}
ipconfig0 := net.ParseIP(strings.Split(ipMatch[1], ":")[0])

Check failure on line 2279 in proxmox/resource_vm_qemu.go

View workflow job for this annotation

GitHub Actions / audit

config.Disk.SizeInKibibytes undefined (type *"github.com/Telmate/proxmox-api-go/proxmox".QemuScsiDisk has no field or method SizeInKibibytes)
interfaces, err = client.GetVmAgentNetworkInterfaces(vmr)
log.Printf("[DEBUG][initConnInfo] ipconfig0 interfaces: %v", interfaces)
logger.Debug().Int("vmid", vmr.VmId()).Msgf("ipconfig0 interfaces %v", interfaces)
Expand All @@ -2298,7 +2298,7 @@
}
}

log.Print("[DEBUG][initConnInfo] found an ip configuration")

Check failure on line 2301 in proxmox/resource_vm_qemu.go

View workflow job for this annotation

GitHub Actions / audit

config.Passthrough.SizeInKibibytes undefined (type *"github.com/Telmate/proxmox-api-go/proxmox".QemuScsiPassthrough has no field or method SizeInKibibytes)
logger.Debug().Int("vmid", vmr.VmId()).Msgf("Found an ip configuration")
// Check if we got a specified port
if strings.Contains(sshHost, ":") {
Expand Down Expand Up @@ -2354,7 +2354,7 @@

func getCloudInitDisk(config *pxapi.QemuStorages) string {
if config != nil && config.Ide != nil && config.Ide.Disk_3 != nil && config.Ide.Disk_3.CloudInit != nil {
return config.Ide.Disk_3.CloudInit.Storage

Check failure on line 2357 in proxmox/resource_vm_qemu.go

View workflow job for this annotation

GitHub Actions / audit

config.Disk.SizeInKibibytes undefined (type *"github.com/Telmate/proxmox-api-go/proxmox".QemuVirtIODisk has no field or method SizeInKibibytes)
}
return ""
}
Expand All @@ -2375,7 +2375,7 @@
sata := mapFromStruct_QemuSataDisks(config.Sata)
scsi := mapFromStruct_QemuScsiDisks(config.Scsi)
virtio := mapFromStruct_QemuVirtIODisks(config.VirtIO)
if ide == nil && sata == nil && scsi == nil && virtio == nil {

Check failure on line 2378 in proxmox/resource_vm_qemu.go

View workflow job for this annotation

GitHub Actions / audit

config.Passthrough.SizeInKibibytes undefined (type *"github.com/Telmate/proxmox-api-go/proxmox".QemuVirtIOPassthrough has no field or method SizeInKibibytes)
return nil
}
return []interface{}{
Expand Down Expand Up @@ -2464,14 +2464,14 @@
"linked_disk_id": mapFromStruct_LinkedCloneId(config.Disk.LinkedDiskId),
"replicate": config.Disk.Replicate,
"serial": string(config.Disk.Serial),
"size": int(config.Disk.Size),
"size": convert_KibibytesToString(int64(config.Disk.SizeInKibibytes)),
"storage": string(config.Disk.Storage),
}
mapFormStruct_QemuDiskBandwidth(mapParams, config.Disk.Bandwidth)
return []interface{}{
map[string]interface{}{
"disk": []interface{}{mapParams},
},

Check failure on line 2474 in proxmox/resource_vm_qemu.go

View workflow job for this annotation

GitHub Actions / audit

unknown field SizeInKibibytes in struct literal of type "github.com/Telmate/proxmox-api-go/proxmox".QemuIdeDisk

Check failure on line 2474 in proxmox/resource_vm_qemu.go

View workflow job for this annotation

GitHub Actions / audit

undefined: pxapi.QemuDiskSize
}
}
if config.Passthrough != nil {
Expand All @@ -2484,7 +2484,7 @@
"file": config.Passthrough.File,
"replicate": config.Passthrough.Replicate,
"serial": string(config.Passthrough.Serial),
"size": int(config.Passthrough.Size),
"size": convert_KibibytesToString(int64(config.Passthrough.SizeInKibibytes)),
}
mapFormStruct_QemuDiskBandwidth(mapParams, config.Passthrough.Bandwidth)
return []interface{}{
Expand Down Expand Up @@ -2528,7 +2528,7 @@
"linked_disk_id": mapFromStruct_LinkedCloneId(config.Disk.LinkedDiskId),
"replicate": config.Disk.Replicate,
"serial": string(config.Disk.Serial),
"size": int(config.Disk.Size),
"size": convert_KibibytesToString(int64(config.Disk.SizeInKibibytes)),
"storage": string(config.Disk.Storage),
}
mapFormStruct_QemuDiskBandwidth(mapParams, config.Disk.Bandwidth)
Expand All @@ -2548,7 +2548,7 @@
"file": config.Passthrough.File,
"replicate": config.Passthrough.Replicate,
"serial": string(config.Passthrough.Serial),
"size": int(config.Passthrough.Size),
"size": convert_KibibytesToString(int64(config.Disk.SizeInKibibytes)),
}
mapFormStruct_QemuDiskBandwidth(mapParams, config.Passthrough.Bandwidth)
return []interface{}{
Expand Down Expand Up @@ -2619,7 +2619,7 @@
"readonly": config.Disk.ReadOnly,
"replicate": config.Disk.Replicate,
"serial": string(config.Disk.Serial),
"size": int(config.Disk.Size),
"size": convert_KibibytesToString(int64(config.Disk.SizeInKibibytes)),
"storage": string(config.Disk.Storage),
}
mapFormStruct_QemuDiskBandwidth(mapParams, config.Disk.Bandwidth)
Expand All @@ -2641,7 +2641,7 @@
"readonly": config.Passthrough.ReadOnly,
"replicate": config.Passthrough.Replicate,
"serial": string(config.Passthrough.Serial),
"size": int(config.Passthrough.Size),
"size": convert_KibibytesToString(int64(config.Passthrough.SizeInKibibytes)),
}
mapFormStruct_QemuDiskBandwidth(mapParams, config.Passthrough.Bandwidth)
return []interface{}{
Expand Down Expand Up @@ -2697,7 +2697,7 @@
"readonly": config.Disk.ReadOnly,
"replicate": config.Disk.Replicate,
"serial": string(config.Disk.Serial),
"size": int(config.Disk.Size),
"size": convert_KibibytesToString(int64(config.Disk.SizeInKibibytes)),
"storage": string(config.Disk.Storage),
}
mapFormStruct_QemuDiskBandwidth(mapParams, config.Disk.Bandwidth)
Expand All @@ -2718,7 +2718,7 @@
"readonly": config.Passthrough.ReadOnly,
"replicate": config.Passthrough.Replicate,
"serial": string(config.Passthrough.Serial),
"size": int(config.Passthrough.Size),
"size": convert_KibibytesToString(int64(config.Passthrough.SizeInKibibytes)),
}
mapFormStruct_QemuDiskBandwidth(mapParams, config.Passthrough.Bandwidth)
return []interface{}{
Expand Down Expand Up @@ -2808,14 +2808,14 @@
if ok && len(tmpDisk) == 1 && tmpDisk[0] != nil {
disk := tmpDisk[0].(map[string]interface{})
ide.Disk = &pxapi.QemuIdeDisk{
Backup: disk["backup"].(bool),
Bandwidth: mapToStruct_QemuDiskBandwidth(disk),
Discard: disk["discard"].(bool),
EmulateSSD: disk["emulatessd"].(bool),
Format: pxapi.QemuDiskFormat(disk["format"].(string)),
Replicate: disk["replicate"].(bool),
Size: uint(disk["size"].(int)),
Storage: disk["storage"].(string),
Backup: disk["backup"].(bool),
Bandwidth: mapToStruct_QemuDiskBandwidth(disk),
Discard: disk["discard"].(bool),
EmulateSSD: disk["emulatessd"].(bool),
Format: pxapi.QemuDiskFormat(disk["format"].(string)),
Replicate: disk["replicate"].(bool),
SizeInKibibytes: pxapi.QemuDiskSize(convert_SizeStringToKibibytes_Unsafe(disk["size"].(string))),
Storage: disk["storage"].(string),
}
if asyncIO, ok := disk["asyncio"].(string); ok {
ide.Disk.AsyncIO = pxapi.QemuDiskAsyncIO(asyncIO)
Expand Down Expand Up @@ -2877,14 +2877,14 @@
if ok && len(tmpDisk) == 1 && tmpDisk[0] != nil {
disk := tmpDisk[0].(map[string]interface{})
sata.Disk = &pxapi.QemuSataDisk{
Backup: disk["backup"].(bool),
Bandwidth: mapToStruct_QemuDiskBandwidth(disk),
Discard: disk["discard"].(bool),
EmulateSSD: disk["emulatessd"].(bool),
Format: pxapi.QemuDiskFormat(disk["format"].(string)),
Replicate: disk["replicate"].(bool),
Size: uint(disk["size"].(int)),
Storage: disk["storage"].(string),
Backup: disk["backup"].(bool),
Bandwidth: mapToStruct_QemuDiskBandwidth(disk),
Discard: disk["discard"].(bool),
EmulateSSD: disk["emulatessd"].(bool),
Format: pxapi.QemuDiskFormat(disk["format"].(string)),
Replicate: disk["replicate"].(bool),
SizeInKibibytes: pxapi.QemuDiskSize(convert_SizeStringToKibibytes_Unsafe(disk["size"].(string))),
Storage: disk["storage"].(string),
}
if asyncIO, ok := disk["asyncio"].(string); ok {
sata.Disk.AsyncIO = pxapi.QemuDiskAsyncIO(asyncIO)
Expand Down Expand Up @@ -2971,16 +2971,16 @@
if ok && len(tmpDisk) == 1 && tmpDisk[0] != nil {
disk := tmpDisk[0].(map[string]interface{})
scsi.Disk = &pxapi.QemuScsiDisk{
Backup: disk["backup"].(bool),
Bandwidth: mapToStruct_QemuDiskBandwidth(disk),
Discard: disk["discard"].(bool),
EmulateSSD: disk["emulatessd"].(bool),
Format: pxapi.QemuDiskFormat(disk["format"].(string)),
IOThread: disk["iothread"].(bool),
ReadOnly: disk["readonly"].(bool),
Replicate: disk["replicate"].(bool),
Size: uint(disk["size"].(int)),
Storage: disk["storage"].(string),
Backup: disk["backup"].(bool),
Bandwidth: mapToStruct_QemuDiskBandwidth(disk),
Discard: disk["discard"].(bool),
EmulateSSD: disk["emulatessd"].(bool),
Format: pxapi.QemuDiskFormat(disk["format"].(string)),
IOThread: disk["iothread"].(bool),
ReadOnly: disk["readonly"].(bool),
Replicate: disk["replicate"].(bool),
SizeInKibibytes: pxapi.QemuDiskSize(convert_SizeStringToKibibytes_Unsafe(disk["size"].(string))),
Storage: disk["storage"].(string),
}
if asyncIO, ok := disk["asyncio"].(string); ok {
scsi.Disk.AsyncIO = pxapi.QemuDiskAsyncIO(asyncIO)
Expand Down Expand Up @@ -3135,15 +3135,15 @@
if ok && len(tmpDisk) == 1 && tmpDisk[0] != nil {
disk := tmpDisk[0].(map[string]interface{})
virtio.Disk = &pxapi.QemuVirtIODisk{
Backup: disk["backup"].(bool),
Bandwidth: mapToStruct_QemuDiskBandwidth(disk),
Discard: disk["discard"].(bool),
Format: pxapi.QemuDiskFormat(disk["format"].(string)),
IOThread: disk["iothread"].(bool),
ReadOnly: disk["readonly"].(bool),
Replicate: disk["replicate"].(bool),
Size: uint(disk["size"].(int)),
Storage: disk["storage"].(string),
Backup: disk["backup"].(bool),
Bandwidth: mapToStruct_QemuDiskBandwidth(disk),
Discard: disk["discard"].(bool),
Format: pxapi.QemuDiskFormat(disk["format"].(string)),
IOThread: disk["iothread"].(bool),
ReadOnly: disk["readonly"].(bool),
Replicate: disk["replicate"].(bool),
SizeInKibibytes: pxapi.QemuDiskSize(convert_SizeStringToKibibytes_Unsafe(disk["size"].(string))),
Storage: disk["storage"].(string),
}
if asyncIO, ok := disk["asyncio"].(string); ok {
virtio.Disk.AsyncIO = pxapi.QemuDiskAsyncIO(asyncIO)
Expand Down Expand Up @@ -3622,9 +3622,21 @@

func schema_DiskSize() *schema.Schema {
return &schema.Schema{
Type: schema.TypeInt,
Required: true,
ValidateDiagFunc: uintValidator(),
Type: schema.TypeString,
Required: true,
ValidateDiagFunc: func(i interface{}, k cty.Path) diag.Diagnostics {
v, ok := i.(string)
if !ok {
return diag.Errorf(errorString, k)
}
if !regexp.MustCompile(`^[123456789]\d*[KMGT]?$`).MatchString(v) {
return diag.Errorf("%s must match the following regex ^[123456789]\\d*[KMGT]?$", k)
}
return nil
},
DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
return convert_SizeStringToKibibytes_Unsafe(old) == convert_SizeStringToKibibytes_Unsafe(new)
},
}
}

Expand Down Expand Up @@ -3668,7 +3680,7 @@

func schema_PassthroughSize() *schema.Schema {
return &schema.Schema{
Type: schema.TypeInt,
Type: schema.TypeString,
Computed: true,
}
}
Loading