From 9291ce6ffc3abda341f313f00b2ed10483783c90 Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Wed, 17 Feb 2021 11:27:26 -0500 Subject: [PATCH] Correct output of fromhuman and add size compare Ensures that the bytes_tohuman returns an integer to avoid the hacky workaround of stripping off the B. Adds a verification on the size of a new volume, that it is not larger than the free space of the pool to prevent errors/excessively-large volumes from being created. Closes #120 --- api-daemon/pvcapid/ova.py | 8 ++++---- daemon-common/ceph.py | 13 ++++++++++--- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/api-daemon/pvcapid/ova.py b/api-daemon/pvcapid/ova.py index 90d2e7d9..e56295cb 100755 --- a/api-daemon/pvcapid/ova.py +++ b/api-daemon/pvcapid/ova.py @@ -177,8 +177,8 @@ def upload_ova(pool, name, ova_size): pvc_common.stopZKConnection(zk_conn) # Normalize the OVA size to bytes - ova_size_bytes = int(pvc_ceph.format_bytes_fromhuman(ova_size)[:-1]) - ova_size = pvc_ceph.format_bytes_fromhuman(ova_size) + ova_size_bytes = pvc_ceph.format_bytes_fromhuman(ova_size) + ova_size = '{}B'.format(ova_size_bytes) # Verify that the cluster has enough space to store the OVA volumes (2x OVA size, temporarily, 1x permanently) zk_conn = pvc_common.startZKConnection(config['coordinators']) @@ -274,7 +274,7 @@ def upload_ova(pool, name, ova_size): vm_volume_size = disk.get('capacity') # Normalize the dev size to bytes - dev_size = pvc_ceph.format_bytes_fromhuman(dev_size_raw) + dev_size = '{}B'.format(pvc_ceph.format_bytes_fromhuman(dev_size_raw)) def cleanup_img_maps(): zk_conn = pvc_common.startZKConnection(config['coordinators']) @@ -368,7 +368,7 @@ def upload_ova(pool, name, ova_size): vm_volume_size = disk.get('capacity') # The function always return XXXXB, so strip off the B and convert to an integer - vm_volume_size_bytes = int(pvc_ceph.format_bytes_fromhuman(vm_volume_size)[:-1]) + vm_volume_size_bytes = pvc_ceph.format_bytes_fromhuman(vm_volume_size) vm_volume_size_gb = math.ceil(vm_volume_size_bytes / 1024 / 1024 / 1024) query = "INSERT INTO ova_volume (ova, pool, volume_name, volume_format, disk_id, disk_size_gb) VALUES (%s, %s, %s, %s, %s, %s);" diff --git a/daemon-common/ceph.py b/daemon-common/ceph.py index a2352204..ba452ac6 100644 --- a/daemon-common/ceph.py +++ b/daemon-common/ceph.py @@ -122,7 +122,7 @@ def format_bytes_fromhuman(datahuman): dataunit = 'B' datasize = int(datahuman) databytes = datasize * byte_unit_matrix[dataunit] - return '{}B'.format(databytes) + return databytes # Format ops sizes to/from human-readable units @@ -475,7 +475,14 @@ def getVolumeInformation(zk_conn, pool, volume): def add_volume(zk_conn, pool, name, size): - # 1. Create the volume + # 1. Verify the size of the volume + pool_information = getPoolInformation(zk_conn, pool) + + size_bytes = format_bytes_fromhuman(size) + if size_bytes >= int(pool_information['stats']['free_bytes']): + return False, 'ERROR: Requested volume size is greater than the available free space in the pool' + + # 2. Create the volume retcode, stdout, stderr = common.run_os_command('rbd create --size {} --image-feature layering,exclusive-lock {}/{}'.format(size, pool, name)) if retcode: return False, 'ERROR: Failed to create RBD volume "{}": {}'.format(name, stderr) @@ -545,7 +552,7 @@ def resize_volume(zk_conn, pool, name, size): target_lv_conn = libvirt.open(dest_lv) target_vm_conn = target_lv_conn.lookupByName(vm_info['name']) if target_vm_conn: - target_vm_conn.blockResize(volume_id, int(format_bytes_fromhuman(size)[:-1]), libvirt.VIR_DOMAIN_BLOCK_RESIZE_BYTES) + target_vm_conn.blockResize(volume_id, format_bytes_fromhuman(size), libvirt.VIR_DOMAIN_BLOCK_RESIZE_BYTES) target_lv_conn.close() except Exception: pass