def format_physical_drive(self, pd): """ :param pd: :return: """ # DG JSON type is inconsistent disk_group = self.dash_is_none(pd['DG']) if isinstance(disk_group, str): disk_group = int(disk_group) return { 'size': Size(pd['Size'], force_iec_values=True).bytes, 'status': self.drive_status_map.get(pd['State'], 'UNKNOWN'), 'type': pd['Med'], 'extra': { 'address': pd['EID:Slt'], 'drive_id': pd['DID'], 'model': pd['Model'], 'disk_group': disk_group, 'interface': pd['Intf'], 'self_encrypted_drive': pd['SED'] != 'N', 'spun': pd['Sp'], 'sector_size': Size(pd['SeSz'].lower()).bytes, 'vendor_state': pd['State'], 'spare_type': self.hotspare_map.get(pd['State'], None) } }
def create_logical_drive_on_existing_array(self, adapter, adapter_info, level, array, converted_size, percent_string): """ :param adapter: :param adapter_info: :param level: :param array: :param converted_size: :param percent_string: :return: """ # Check to see that the array exists try: array = adapter_info['configuration']['arrays'][array] except (KeyError, IndexError): raise RAIDAbstractionException('The referenced array {}:{} does not exist'.format(adapter, array)) # Check to see if the array has enough free space (or any free space, if size is None) free_space = Size(array['free_space']) if free_space < Size('1MiB'): raise RAIDAbstractionException('The array {}:{} has not free space'.format(adapter, array)) if converted_size: if free_space < converted_size: raise RAIDAbstractionException('Requested size {} exceeds available size {}'.format( converted_size, free_space)) elif percent_string: if percent_string.free: converted_size = Size(percent_string.value * free_space.bytes) else: raise RAIDAbstractionException('only %FREE is supported for RAID abstraction') return self.create(adapter_info, level, drives=None, size=converted_size, array=array)
def create_logical_drive_on_new_array(self, adapter, adapter_info, level, drives, converted_size, percent_string): """ :param adapter: :param adapter_info: :param level: :param drives: :param converted_size: :param percent_string: :return: """ # Creating new array, so we need to check that there is enough space (if specified) # and that the RAID level is valid target_drives = self.get_drives_from_selection(adapter, drives) # this will raise an exception if it's invalid self.raid_minimums(level, len(target_drives)) # Now we have to get the smallest drive (though they all should be the same) if converted_size or percent_string: smallest_drive_size = sorted([x['size'] for x in target_drives])[0] available_size = self.raid_calculator(level, len(target_drives), smallest_drive_size) if converted_size: if available_size < converted_size.bytes: raise RAIDAbstractionException('Requested size of {} exceeds available size of {}'.format( converted_size, Size(available_size))) else: converted_size = Size(percent_string.value * available_size) return self.create(adapter_info, level, drives=target_drives, size=converted_size, array=None)
def set_disk_labels(layout, layout_config): """ Read into configuration and set label to gpt or msdos based on size. If label is present in the configuration and is gpt but not efi, make sure bios boot partition is present. """ # TODO: Trace disk generator and inject this partition_tables = layout_config.get('partition_tables') for partition_table in partition_tables: label = partition_table.get('label') if label: LOG.info('Table: %s is set as %s in configuration' % (partition_table.get('disk', 'undefined'), partition_table['label'])) # 'first' and 'any' are valid disk references in the configuration # 'first' indicates the first unallocated disk # (as sorted by udev (subsystem->sub_id) # 'any' references that first disk encountered # that is large enough to hold the partitions # 'any' is slated for removal in v0.4.0 roadmap if partition_table['disk'] == 'first': disk = layout.unallocated[0] elif partition_table['disk'] == 'any': size = Size(0) for partition in partition_table.get('partitions'): # Percent strings are relative and # cannot be used to calculate total size if '%' not in partition['size']: size += Size(partition['size']) disk = layout.find_device_by_size(size) else: disk = layout.find_device_by_ref(partition_table['disk']) if not sysfs_info.has_efi(): if disk.size.over_2t: LOG.info('%s is over 2.2TiB, using gpt' % disk.devname) label = 'gpt' if not layout_config.get('no_bios_boot_partition'): # TODO: Add config option to disks, # allowing user to specify the boot disk # if disk == the first disk or presumed boot disk if list(layout.disks.keys()).index(disk.devname) == 0: add_bios_boot_partition(partition_table) elif label == 'gpt': add_bios_boot_partition(partition_table) else: LOG.info('%s is under 2.2TiB, using msdos' % disk.devname) label = 'msdos' else: LOG.info('Booting in UEFI mode, using gpt') label = 'gpt' # Only install boot partition on "first" drive # TODO: Allow the user to specifygit if list(layout.disks.keys()).index(disk.devname) == 0: add_efi_boot_partition(partition_table) partition_table['label'] = label
def __init__(self, name, in_byte): self.n = name self.line = Num(0) self.size = Size(0, in_byte) try: self.line = Num(sum(1 for l in open(name))) self.size = Size(os.path.getsize(name), in_byte) except: pass
def __init__(self, name, physical_volumes, pe_size=4194304): self.logical_volumes = list() self.name = name self.physical_volumes = physical_volumes self.pv_raw_size = Size( sum([pv.reference.size.bytes for pv in self.physical_volumes])) self.pe_size = Size(pe_size) self.extents = self.pv_raw_size.bytes / self.pe_size.bytes self.size = Size(self.pe_size.bytes * self.extents)
def create_basic(self, var): """ @type var: debugee.Variable @rtype: drawable.VariableDrawable """ return drawable.VariableDrawable(self.canvas, var, padding=Padding.all(5), size=Size(-1, 20), max_size=Size(150, -1))
def _rescale_layout(self, child): if not self.children: self.size = Size(child.size.w + 2 * self.border, child.size.h + 2 * self.border) else: self.size = Size( self.size.w + (child.size.w + self.spacing) * int(self.orientation), self.size.h + (child.size.h + self.spacing) * int(not self.orientation))
def __init__(self, name, filters, afilters, settings): self.settings = settings self.in_byte = settings['size_in_byte'] self.list_files = [] self.list_folders = [] self.name = name self.len_name = 0 self.count_files = Num(0) self.count_folders = Num(0) self.total_lines = Num(0) self.total_size = Size(0, self.in_byte) self.global_count_files = Num(0) self.global_count_folders = Num(0) self.global_total_lines = Num(0) self.global_total_size = Size(0, self.in_byte) for f in os.listdir(self.name): #apply filters and afilters a = False for fl in filters: if re.match(fl, f): a |= True a |= os.path.isdir(os.path.join(self.name, f)) for af in afilters: if re.match(af, f): a &= False if a == False: continue full_name = os.path.join(self.name, f) if os.path.isdir(full_name): self.list_folders.append( Tree(full_name, filters, afilters, settings)) (n, f, d, l, s) = self.list_folders[-1].total() if f == 0 and d == 0: self.list_folders.pop() continue self.count_folders += Num(1) self.global_total_lines += l self.global_total_size += s self.global_count_files += f self.global_count_folders += d else: self.list_files.append(File(full_name, self.in_byte)) (n, l, s) = self.list_files[-1].get() self.total_lines += l self.count_files += Num(1) self.total_size += s
def test_bsize(): # check failure on incorrect string with pytest.raises(ValueError) as e: Size("hugala buga lugala") assert "does not contain size" in str(e.value) # check failure on malformed units with pytest.raises(ValueError) as e: Size("1 GidB") assert "Unable to identify unit" in str(e.value) # accept int parameter, without units assert Size(0).get() == "0.0 B" # accept parameter with an exponent assert Size("1.048576e+06B").get() == "1.0 MiB" # accept units case insensitive, without space, convert assert Size("1000kilObytes").get("autodec", "%d") == "1" # check conversion from decimal to binary assert Size("1048.576 KB").get("mebibytes", "%0.5f %sb") == "1.00000 MiB" # check string to bytes conversion assert Size("1.2 terabyte").bytes == 1.2e12 # check string without byte prefix gets converted to binary assert Size("5g").get() == "5.0 GiB" assert Size("5gb").get() == "4.7 GiB"
def __init__(self, canvas, **properties): """ @type canvas: drawing.canvas.Canvas """ self.canvas = canvas self._position = self._parse_property(properties, "position", Vector(0, 0), Vector.vectorize) """@type _position: drawing.vector.Vector""" self._margin = self._parse_property(properties, "margin", Margin.all(0)) """@type _margin: drawing.geometry.Margin""" self._padding = self._parse_property(properties, "padding", Padding.all(0)) """@type _padding: drawing.geometry.Padding""" self._request_size = self._parse_property(properties, "size", Size(-1, -1), Size.make_size) """@type _request_size: drawing.size.Size""" self._min_size = self._parse_property(properties, "min_size", Size(0, 0), Size.make_size) """@type _min_size: drawing.size.Size""" self._max_size = self._parse_property(properties, "max_size", Size(999, 999), Size.make_size) """@type _max_size: drawing.size.Size""" self.bg_color = self._parse_property(properties, "bg_color", Drawable.get_default_bg_color(), Color.make_color) """@type bg_color: drawing.drawable.Color""" self.name = self._parse_property(properties, "name", "") """@type name: str""" self.parent = None """@type parent: Drawable""" self.children = [] self._visible = True self.click_handler = ClickHandler(self) self.on_mouse_click = EventBroadcaster() self.on_mouse_enter = EventBroadcaster() self.on_mouse_leave = EventBroadcaster() self.on_mouse_click.subscribe(self.handle_mouse_click) self.on_mouse_enter.subscribe(self.handle_mouse_enter) self.on_mouse_enter.subscribe(self.handle_tooltip_start) self.on_mouse_leave.subscribe(self.handle_mouse_leave) self.on_mouse_leave.subscribe(self.handle_tooltip_end) self.canvas.register_drawable(self) self.cached_rect = None
def __init__(self, canvas, vector): """ @type canvas: drawing.canvas.Canvas @type vector: debugee.Variable """ super(VectorDrawable, self).__init__(canvas, LinearLayoutDirection.Horizontal) VariableContainer.__init__(self, vector) self.range = (0, min(VectorDrawable.MAX_INITIAL_SHOW_COUNT, self.variable.max_size)) saved_range = self.canvas.vector_range_cache.get_range( self.variable.address) if saved_range: self.range = saved_range self.range = (self.range[0], min(self.range[1], self.variable.max_size)) self.variable.start = self.range[0] self.variable.count = self.range[1] self.start_variable = Variable(value=str(self.variable.start), name="start index of {}".format( self.variable.name)) self.start_variable.set_constraint(self._check_count) self.start_variable.on_value_changed.subscribe( lambda *x: self._reload(True)) self.start_variable_draw = VariableDrawable(self.canvas, self.start_variable, size=Size(-1, 20), padding=Padding.all(5)) self.count_variable = Variable(value=str(self.variable.count), name="size of {}".format( self.variable.name)) self.count_variable.set_constraint(self._check_count) self.count_variable.on_value_changed.subscribe( lambda *x: self._reload(True)) self.count_variable_draw = VariableDrawable(self.canvas, self.count_variable, size=Size(-1, 20), padding=Padding.all(5)) self.add_children((self.start_variable_draw, self.count_variable_draw)) self._reload(False)
def __init__(self, canvas, composite, **properties): """ @type canvas: canvas.Canvas @type composite: variable.Variable | debugee.Frame """ super(CompositeLabel, self).__init__(canvas, LinearLayoutDirection.Vertical, **properties) VariableContainer.__init__(self, composite) label = self.get_composite_label() if label: self.label = Label(canvas, self.get_composite_label, FontStyle(italic=True), size=Size(-1, 25), padding=Padding.all(5), margin=Margin(0, 0, 5, 0)) self.add_child(self.label) children = [] for var in self.get_composite_children(): drawable = self.create_composite_value(var) if drawable: children.append(drawable) self.add_children(children)
def __init__(self, devname, level, members, spare_members=None, size=0, file_system=None, mount_point=None, fsck_option=0, pv_name=None): """ Logical representation of a mdadm controlled RAID :param devname: /dev/mdX :param level: 0, 1 :param members: Partition objects that represent member disks :param spare_members: (optional) Partition objects that represent spare disks :param file_system: (optional) A file system object, if that is your intent :param mount_point: (optional) where to mount, needs file system :param pv_name: (optional) Am I a pv? if so, file_system and mount_point are ignored """ self.devname = devname self.level = level self.members = members self.spare_members = spare_members or [] self.file_system = file_system self.mount_point = mount_point self.pv_name = pv_name self.size = Size(0) self.allocated = False self.mdadm = MDADM() self.fsck_option = fsck_option
def populate_logical_drives(self, disk_group, dg_info): """ :param disk_group: :param dg_info: :return: """ lds = [] for vd in dg_info['VD LIST']: dg_id, vd_id = (int(x) for x in vd['DG/VD'].split('/')) if dg_id == disk_group: lds.append({ 'level': int(vd['TYPE'].strip('RAID')), 'size': Size(vd['Size'], force_iec_values=True).bytes, 'status': self.logical_drive_map.get((vd['State']), 'UNKNOWN'), 'extra': { 'disk_group': dg_id, 'access': vd['Access'], 'consistency': vd['Consist'], 'cache': vd['Cache'], 'name': vd['Name'], 'vendor_state': vd['State'] } }) return lds
def __init__(self, type_or_name, size_or_percent, flags=None, file_system=None, mount_point=None, fsck_option=0): """ Constructor: size: a Size compatible value (see Size object documentation).. flags: list() name: the name of the partition, valid only on gpt partition tables """ if isinstance(size_or_percent, PercentString): self.size = None self.percent_string = size_or_percent else: self.size = Size(size_or_percent) self.percent_string = None self.flags = flags or list() self.name = type_or_name self.file_system = file_system self.mount_point = mount_point self.partition_id = None self.devname = None self.allocated = False self.fsck_option = fsck_option
def free_space(self): """ Calculate free space using standard logic """ if not self.partitions: free = self.size - self.partition_start else: free = self.size - self.current_usage if self.type == GPT: free -= Size(GPT_BACKUP_SIZE) else: free -= Size(1) log.debug('Free space: %d' % free.bytes) return free
def init_layout(self): if 'layout' in self.press_configuration: # hacks allow us to easily override these from the library or # command line interface if self.explicit_loop_only is not None: self.press_configuration['layout']['loop_only'] = \ self.explicit_loop_only if self.explicit_use_fibre_channel is not None: self.press_configuration['layout']['use_fibre_channel'] = \ self.explicit_use_fibre_channel self.layout = layout_from_config( self.press_configuration['layout'], parted_path=self.parted_path, partition_start=Size(self.partition_start).bytes, alignment=Size(self.alignment).bytes, pe_size=self.lvm_pe_size)
def resize(self, x, y): direction = self.direction position = Position() position.x = self.x position.y = self.y size = Size() size.width = self.width size.height = self.height side = get_side(direction) if side is not VERTICAL: size.width = x - self.pivot.x if size.width < 0: position.x = x else: position.x = self.pivot.x if side is not HORIZONTAL: size.height = y - self.pivot.y if size.height < 0: position.y = y else: position.y = self.pivot.y self.set_position(position) self.set_size(size)
def _snap_sectors(self, start, end, size, type): if start: if not end: end = start + size.sectors - 1 if (end - start) != (size.sectors - 1): raise PartitionError(709) elif type == 'LOGICAL': try: last = [ p for p in self._disk.partitions() if p.type == 'LOGICAL' ][-1] except IndexError: last = [ p for p in self._disk.partitions() if p.type == 'EXTENDED' ][-1] ls, e, ln = last.geom start = ls + 1 end = start + size.sectors - 1 else: size = Size() last = None for part in self.disk.free_partitions(): if part.size > size: last = part try: start, e, ln = part.geom except AttributeError: raise PartitionError(712) end = start + size.sectors - 1 return (start, end)
def __parse_pd_line(line): line = line.strip() port, box, bay = line.split()[1].split(':') attributes = [ x.strip() for x in line.split('(')[1].strip(')').split(',')[1:] ] disk_type, size, status = attributes[0], attributes[1], attributes[2] # Failed drives will sometimes report size using the string '???' try: size = Size(size).bytes except SizeObjectValError: size = None # setting to none so that arithmetic operations will break # if this is not accounted for spare = 'spare' in attributes[3:] pd_info = { 'port': port, 'box': box, 'bay': bay, 'type': disk_type, 'size': size, 'status': status, 'spare': spare } return pd_info
def start_(self): cw = self.customWidget self.read() if self.status == 'stop': return True cw.dir = self.dir cw.urls = self.urls self.size = Size() cw.setColor('downloading') self.exec_queue.run(lambda : cw.pbar.setMaximum(MAX_PBAR)) self.exec_queue.run(lambda : cw.pbar.setFormat('%p%')) cw.downloader_pausable = True self.update_tools_buttons() if cw.paused: data = cw.pause_data self._filesize_prev = data['filesize'] cw.paused = False cw.pause_lock = False self.update_tools_buttons() torrent.download(self._info, save_path=self.dir, callback=self.callback) if cw.alive: self.exec_queue.run(lambda : cw.setSpeed('')) if cw.pause_lock and cw.pbar.value() < cw.pbar.maximum(): cw.pause_data = {'type': self.type, 'url': self.url, 'filesize': self._filesize_prev} cw.paused = True cw.pause_lock = False self.update_tools_buttons() return True self.title = self.name if not self.single: self.exec_queue.run(lambda : cw.pbar.setMaximum(len(cw.imgs)))
def current_usage(self): used = Size(0) if not self.logical_volumes: return used for volume in self.logical_volumes: used += volume.size return used
def create_logical_drive(self, adapter, level, drives=None, size=None, array=None): """ :param adapter: :type adapter: int :param level: 0, 1, 5, 6, 10, 1+0, 50, 60 :type level: str :param drives: drives should be referenced as 0 based comma separated indexes, ranges, or a combination of both. For example:: 0, 1, 2, 3 or 0-3 or 0, 2, 4-8, 9, 10 When using a range, both the lower and upper bounds are inclusive Another option is to use all or unassigned. `all` requires that all drives on the adapter are not part of the array. `unassigned` will select all drives not currently members of an array or participating as spares :param size: Size can be specified in bytes (int), a string using SI or IEC standards, a percent of total space, or a percent of free space available. If no size is listed, all available space will be used :param array: An index of an existing array we are updating :return: """ # TODO: Add span support # TODO: Add generic cache policy support if not (array is not None or drives is not None): raise RAIDAbstractionException( 'Either drive targets or an array must be specified') adapter_info = self.get_adapter_info(adapter) percent_string = None converted_size = None if size: if isinstance(size, str) and '%' in size: percent_string = PercentString(size) else: converted_size = Size(size) if drives is not None: return self.create_logical_drive_on_new_array( adapter, adapter_info, level, drives, converted_size, percent_string) else: return self.create_logical_drive_on_existing_array( adapter, adapter_info, level, array, converted_size, percent_string)
def __init__(self): self.size = Size() self.InterfaceMechanical = { 'Dimension': self.size.Dimension, 'Mass': self.size.Mass }
def total_free_space(self): """ Returns the total free space size as a Size class instance. """ size = Size() for part in self.free_partitions(): size += part.size return size
def usable_free_space(self): """ Returns the largest free space size as a Size class instance. """ size = Size() for part in self.free_partitions(): if part.size > size: size = part.size return size
def create_pointer(self, var): """ @type var: debugee.Variable @rtype: drawable.PointerDrawable """ return drawable.PointerDrawable(self.canvas, var, padding=Padding.all(5), size=Size(-1, 20))
def __init__(self, canvas, frame, **properties): """ @type canvas: canvas.Canvas @type frame: debugee.Frame """ super(StackFrameDrawable, self).__init__(canvas, frame, **properties) self.label.min_size = Size(100, 25) self.label.on_mouse_click.subscribe(self._handle_label_click)
def __parse_array_line(line): line = line.strip() array_info = { 'letter': line.split()[1], 'type': line.split()[3].strip('(,'), 'free_space': Size(line.split(':')[1].strip().strip(')')).bytes } return array_info