def _list_vsphere_volumes(self): """ Lists vsphere volumes in configured datastore only. :return: """ datastore = self._find_datastore() vms = datastore.vm logging.debug('Found {} VMs'.format(len(vms))) searchResults = self._find_virtual_disks() content = self._si.RetrieveContent() virtualDiskManager = content.virtualDiskManager vol_list = {} for result in searchResults: for file in result.file: volume_path = result.folderPath + file.path disk_uuid = virtualDiskManager.QueryVirtualDiskUuid( name=volume_path, datacenter=self._dc) disk_uuid = self._normalize_uuid(disk_uuid) str_dataset_id = file.path str_dataset_id = str_dataset_id[:-5] # logging.debug(str_dataset_id) dataset_id = uuid.UUID(str_dataset_id) # logging.debug(dataset_id) volume = BlockDeviceVolume(size=int( KiB(file.capacityKb).to_Byte().value), dataset_id=dataset_id, blockdevice_id=unicode(disk_uuid)) vsphere_volume = VsphereBlockDeviceVolume( blockDeviceVolume=volume, path=volume_path) for vm in vms: if isinstance(vm, vim.VirtualMachine) and \ hasattr(vm.config, 'hardware'): devices = vm.config.hardware.device for device in devices: if hasattr(device.backing, 'diskMode'): device_disk_uuid = device.backing.uuid device_disk_uuid = self._normalize_uuid( device_disk_uuid) if device_disk_uuid == disk_uuid: volume = volume.set( 'attached_to', unicode(vm.config.instanceUuid)) vsphere_volume.blockDeviceVolume = volume vsphere_volume.vm = vm vsphere_volume.uuid = vm.config.instanceUuid vsphere_volume.device = device break vol_list[unicode(disk_uuid)] = vsphere_volume logging.debug("Found {} vSphere volumes: {}".format( len(vol_list), '.'.join(vol_list.keys()))) return vol_list
def vmax_round_allocation(in_bytes): """ Returns a size in bytes that is on a clean cylinder boundary. :param in_bytes: input size in bytes :return: """ if in_bytes < int(GiB(1).to_Byte().value): in_bytes = int(GiB(1).to_Byte().value) boundary = int(KiB(1920).to_Byte().value) remainder = in_bytes % boundary if remainder == 0: round_up = in_bytes else: round_up = in_bytes + boundary - remainder return round_up
def _blockdevicevolume_from_scaleio_volume(scaleio_volume, attached_to=None): """ :param scaleiopy.scaleio.ScaleIO_Volume scaleio_volume: a ScaleIO Volume :returns: ``BlockDeviceVolume``` """ # TODO only put one mapping per volume, however # ScaleIO can multi-map, should attached_to # consider being a list? # Return a ``BlockDeviceVolume`` return BlockDeviceVolume( blockdevice_id=unicode(scaleio_volume.id), size=int(KiB(scaleio_volume.size_kb).to_Byte().value), attached_to=attached_to, dataset_id=UUID(bytes=(str(str(scaleio_volume.name)[1:23]) + '==').replace('_', '/').decode('base64')))
def test_parsenum_all_sizes(self, expr, size): """ Send standard size expressions to ``parse_num`` in many sizes, we expect to get correct size results. :param expr str: A string representing the size expression :param size int: A string representing the volume size """ if expr is "KB": expected_size = int(KiB(size).to_Byte()) elif expr is "MB": expected_size = int(MiB(size).to_Byte()) elif expr is "GB": expected_size = int(GiB(size).to_Byte()) elif expr is "TB": expected_size = int(TiB(size).to_Byte()) else: expected_size = int(Byte(size).to_Byte()) return self.assertEqual(expected_size, int(parse_num(str(size) + expr).to_Byte()))
def parse_num(expression): """ Parse a string of a dataset size 10g, 100kib etc into a usable integer. If user doesn't submit a correct size, give back the default size. :param expression: the dataset expression to parse. """ if not expression: return DEFAULT_SIZE if type(expression) is unicode: expression = str(expression) def _match(exp, search=re.compile( r'^(\d+){1}([KMGTkmgt][IiBb]){0,1}([Bb]){0,1}').search): return bool(search(exp)) if _match(expression): unit = expression.translate(None, "1234567890.") num = int(expression.replace(unit, "")) unit = unit.lower() if unit == 'tb' or unit == 't' or unit == 'tib': return TiB(num) elif unit == 'gb' or unit == 'g' or unit == 'gib': return GiB(num) elif unit == 'mb' or unit == 'm' or unit == 'mib': return MiB(num) elif unit == 'kb' or unit == 'k' or unit == 'kib': return KiB(num) elif unit == '': return Byte(num) else: return DEFAULT_SIZE else: return DEFAULT_SIZE
def unused_memory() -> 'BitMath': f_meminfo.read() # to update meminfo pseudo-file f_meminfo.seek(0) return KiB(sum(_unused_memory())).best_prefix()
def parse_k8s_memory_value(memory_value): """Parse and convert Kubernetes specific memory value :param memory_value: memory value from Kubernetes manifest :type memory_value: str :raises NotImplementedError: raised if value postfix is unknown :return: parsed memory value :rtype: int """ # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ # https://medium.com/@betz.mark/understanding-resource-limits-in-kubernetes-memory-6b41e9a955f9 _K8S_MEMORY_SUFFIXES_FIXED = ['E', 'P', 'T', 'G', 'M', 'K'] _K8S_MEMORY_SUFFIXES_POWER = ['Ei', 'Pi', 'Ti', 'Gi', 'Mi', 'Ki'] if type(memory_value) is str: # exponential notation e.g. 3e2 = 300 if 'e' in memory_value: memory_value = float(memory_value) # check if power-of-two notation is used # it is important to check power-of-two first as fixed-point comparison would also match elif [ e for e in _K8S_MEMORY_SUFFIXES_POWER if (e in memory_value) ]: if 'Ki' in memory_value: memory_value = memory_value.strip('Ki') memory_value = KiB(float(memory_value)).to_MB().value elif 'Mi' in memory_value: memory_value = memory_value.strip('Mi') memory_value = MiB(float(memory_value)).to_MB().value elif 'Gi' in memory_value: memory_value = memory_value.strip('Gi') memory_value = GiB(float(memory_value)).to_MB().value elif 'Ti' in memory_value: memory_value = memory_value.strip('Ti') memory_value = TiB(float(memory_value)).to_MB().value elif 'Pi' in memory_value: memory_value = memory_value.strip('Ki') memory_value = PiB(float(memory_value)).to_MB().value elif 'Ei' in memory_value: memory_value = memory_value.strip('Ei') memory_value = EiB(float(memory_value)).to_MB().value else: raise NotImplementedError( 'Memory value unit of {} not implemented'.format( memory_value)) # check if fixed-point integer notation is used elif [ e for e in _K8S_MEMORY_SUFFIXES_FIXED if (e in memory_value) ]: if 'M' in memory_value: memory_value = memory_value.strip('M') elif 'K' in memory_value: memory_value = memory_value.strip('K') memory_value = kB(float(memory_value)).to_MB().value elif 'G' in memory_value: memory_value = memory_value.strip('G') memory_value = GB(float(memory_value)).to_MB().value elif 'T' in memory_value: memory_value = memory_value.strip('T') memory_value = TB(float(memory_value)).to_MB().value elif 'P' in memory_value: memory_value = memory_value.strip('P') memory_value = PB(float(memory_value)).to_MB().value elif 'E' in memory_value: memory_value = memory_value.strip('E') memory_value = EB(float(memory_value)).to_MB().value else: raise NotImplementedError( 'Memory value unit of {} not implemented'.format( memory_value)) # direct definition in bytes - convert to MB else: memory_value = memory_value / float('1e+6') return int(memory_value)