def test_lvs_not_found(self, monkeypatch, volumes): CephVolume = api.Volume(lv_name='foo', lv_path='/dev/vg/foo', lv_tags="ceph.type=data") volumes.append(CephVolume) splitname = {'LV_NAME': 'data', 'VG_NAME': 'ceph'} monkeypatch.setattr(api, 'dmsetup_splitname', lambda x: splitname) assert api.is_lv('/dev/sda1', lvs=volumes) is False
def test_is_lv(self, monkeypatch, volumes): CephVolume = api.Volume( vg_name='ceph', lv_name='data', lv_path='/dev/vg/foo', lv_tags="ceph.type=data" ) volumes.append(CephVolume) splitname = {'LV_NAME': 'data', 'VG_NAME': 'ceph'} monkeypatch.setattr(api, 'dmsetup_splitname', lambda x: splitname) assert api.is_lv('/dev/sda1', lvs=volumes) is True
def test_is_not_an_lv(self, monkeypatch): monkeypatch.setattr(api.process, 'call', lambda x, **kw: ('', '', 0)) monkeypatch.setattr(api, 'dmsetup_splitname', lambda x, **kw: {}) assert api.is_lv('/dev/sda1', lvs=[]) is False
def test_is_not_an_lv(self, monkeypatch): monkeypatch.setattr(api, 'dmsetup_splitname', lambda x: {}) assert api.is_lv('/dev/sda1', lvs=[]) is False
def test_is_not_an_lv(self, monkeypatch): monkeypatch.setattr(api, 'dmsetup_splitname', lambda x: {}) assert api.is_lv('/dev/sda1', lvs=[]) is False
def get_devices(_sys_block_path='/sys/block', _dev_path='/dev', _mapper_path='/dev/mapper'): """ Captures all available devices from /sys/block/, including its partitions, along with interesting metadata like sectors, size, vendor, solid/rotational, etc... Returns a dictionary, where keys are the full paths to devices. ..note:: dmapper devices get their path updated to what they link from, if /dev/dm-0 is linked by /dev/mapper/ceph-data, then the latter gets used as the key. ..note:: loop devices, removable media, and logical volumes are never included. """ # Portions of this detection process are inspired by some of the fact # gathering done by Ansible in module_utils/facts/hardware/linux.py. The # processing of metadata and final outcome *is very different* and fully # imcompatible. There are ignored devices, and paths get resolved depending # on dm devices, loop, and removable media device_facts = {} block_devs = get_block_devs(_sys_block_path) dev_devs = get_dev_devs(_dev_path) mapper_devs = get_mapper_devs(_mapper_path) for block in block_devs: sysdir = os.path.join(_sys_block_path, block) metadata = {} # Ensure that the diskname is an absolute path and that it never points # to a /dev/dm-* device diskname = mapper_devs.get(block) or dev_devs.get(block) if not diskname: continue # If the mapper device is a logical volume it gets excluded if is_mapper_device(diskname): if lvm.is_lv(diskname): continue metadata['removable'] = get_file_contents( os.path.join(sysdir, 'removable')) # Is the device read-only ? metadata['ro'] = get_file_contents(os.path.join(sysdir, 'ro')) for key in [ 'vendor', 'model', 'rev', 'sas_address', 'sas_device_handle' ]: metadata[key] = get_file_contents(sysdir + "/device/" + key) for key in ['sectors', 'size']: metadata[key] = get_file_contents(os.path.join(sysdir, key), 0) for key, _file in [('support_discard', '/queue/discard_granularity')]: metadata[key] = get_file_contents(os.path.join(sysdir, _file)) metadata['partitions'] = get_partitions_facts(sysdir) for key in ['rotational', 'nr_requests']: metadata[key] = get_file_contents(sysdir + "/queue/" + key) metadata['scheduler_mode'] = "" scheduler = get_file_contents(sysdir + "/queue/scheduler") if scheduler is not None: m = re.match(r".*?(\[(.*)\])", scheduler) if m: metadata['scheduler_mode'] = m.group(2) if not metadata['sectors']: metadata['sectors'] = 0 size = metadata['sectors'] or metadata['size'] metadata['sectorsize'] = get_file_contents(sysdir + "/queue/logical_block_size") if not metadata['sectorsize']: metadata['sectorsize'] = get_file_contents( sysdir + "/queue/hw_sector_size", 512) metadata['human_readable_size'] = human_readable_size( float(size) * 512) metadata['size'] = float(size) * 512 metadata['path'] = diskname metadata['locked'] = is_locked_raw_device(metadata['path']) device_facts[diskname] = metadata return device_facts
def get_devices(_sys_block_path='/sys/block', _dev_path='/dev', _mapper_path='/dev/mapper'): """ Captures all available devices from /sys/block/, including its partitions, along with interesting metadata like sectors, size, vendor, solid/rotational, etc... Returns a dictionary, where keys are the full paths to devices. ..note:: dmapper devices get their path updated to what they link from, if /dev/dm-0 is linked by /dev/mapper/ceph-data, then the latter gets used as the key. ..note:: loop devices, removable media, and logical volumes are never included. """ # Portions of this detection process are inspired by some of the fact # gathering done by Ansible in module_utils/facts/hardware/linux.py. The # processing of metadata and final outcome *is very different* and fully # imcompatible. There are ignored devices, and paths get resolved depending # on dm devices, loop, and removable media device_facts = {} block_devs = get_block_devs(_sys_block_path) dev_devs = get_dev_devs(_dev_path) mapper_devs = get_mapper_devs(_mapper_path) for block in block_devs: sysdir = os.path.join(_sys_block_path, block) metadata = {} # Ensure that the diskname is an absolute path and that it never points # to a /dev/dm-* device diskname = mapper_devs.get(block) or dev_devs.get(block) if not diskname: continue # If the mapper device is a logical volume it gets excluded if is_mapper_device(diskname): if lvm.is_lv(diskname): continue metadata['removable'] = get_file_contents(os.path.join(sysdir, 'removable')) # Is the device read-only ? metadata['ro'] = get_file_contents(os.path.join(sysdir, 'ro')) for key in ['vendor', 'model', 'rev', 'sas_address', 'sas_device_handle']: metadata[key] = get_file_contents(sysdir + "/device/" + key) for key in ['sectors', 'size']: metadata[key] = get_file_contents(os.path.join(sysdir, key), 0) for key, _file in [('support_discard', '/queue/discard_granularity')]: metadata[key] = get_file_contents(os.path.join(sysdir, _file)) metadata['partitions'] = get_partitions_facts(sysdir) for key in ['rotational', 'nr_requests']: metadata[key] = get_file_contents(sysdir + "/queue/" + key) metadata['scheduler_mode'] = "" scheduler = get_file_contents(sysdir + "/queue/scheduler") if scheduler is not None: m = re.match(r".*?(\[(.*)\])", scheduler) if m: metadata['scheduler_mode'] = m.group(2) if not metadata['sectors']: metadata['sectors'] = 0 size = metadata['sectors'] or metadata['size'] metadata['sectorsize'] = get_file_contents(sysdir + "/queue/logical_block_size") if not metadata['sectorsize']: metadata['sectorsize'] = get_file_contents(sysdir + "/queue/hw_sector_size", 512) metadata['human_readable_size'] = human_readable_size(float(size) * 512) metadata['size'] = float(size) * 512 metadata['path'] = diskname metadata['locked'] = is_locked_raw_device(metadata['path']) for part_name, part_metadata in metadata['partitions'].items(): part_abspath = '/dev/%s' % part_name device_facts[part_abspath] = part_metadata device_facts[diskname] = metadata return device_facts
def get_devices(_sys_block_path='/sys/block'): """ Captures all available block devices as reported by lsblk. Additional interesting metadata like sectors, size, vendor, solid/rotational, etc. is collected from /sys/block/<device> Returns a dictionary, where keys are the full paths to devices. ..note:: loop devices, removable media, and logical volumes are never included. """ device_facts = {} block_devs = get_block_devs_lsblk() for block in block_devs: devname = os.path.basename(block[0]) diskname = block[1] if block[2] != 'disk': continue sysdir = os.path.join(_sys_block_path, devname) metadata = {} # If the mapper device is a logical volume it gets excluded if is_mapper_device(diskname): if lvm.is_lv(diskname): continue # all facts that have no defaults # (<name>, <path relative to _sys_block_path>) facts = [('removable', 'removable'), ('ro', 'ro'), ('vendor', 'device/vendor'), ('model', 'device/model'), ('rev', 'device/rev'), ('sas_address', 'device/sas_address'), ('sas_device_handle', 'device/sas_device_handle'), ('support_discard', 'queue/discard_granularity'), ('rotational', 'queue/rotational'), ('nr_requests', 'queue/nr_requests'), ] for key, file_ in facts: metadata[key] = get_file_contents(os.path.join(sysdir, file_)) metadata['scheduler_mode'] = "" scheduler = get_file_contents(sysdir + "/queue/scheduler") if scheduler is not None: m = re.match(r".*?(\[(.*)\])", scheduler) if m: metadata['scheduler_mode'] = m.group(2) metadata['partitions'] = get_partitions_facts(sysdir) size = get_file_contents(os.path.join(sysdir, 'size'), 0) metadata['sectors'] = get_file_contents(os.path.join(sysdir, 'sectors'), 0) fallback_sectorsize = get_file_contents(sysdir + "/queue/hw_sector_size", 512) metadata['sectorsize'] = get_file_contents(sysdir + "/queue/logical_block_size", fallback_sectorsize) metadata['size'] = float(size) * 512 metadata['human_readable_size'] = human_readable_size(metadata['size']) metadata['path'] = diskname metadata['locked'] = is_locked_raw_device(metadata['path']) device_facts[diskname] = metadata return device_facts