def scan_device(self, path): device_metadata = {'path': None, 'uuid': None} if not path: return device_metadata if self.is_encrypted: encryption_metadata = encryption.legacy_encrypted(path) device_metadata['path'] = encryption_metadata['device'] device_metadata['uuid'] = disk.get_partuuid( encryption_metadata['device']) return device_metadata # cannot read the symlink if this is tmpfs if os.path.islink(path): device = os.readlink(path) else: device = path lvm_device = lvm.get_lv_from_argument(device) if lvm_device: device_uuid = lvm_device.lv_uuid else: device_uuid = disk.get_partuuid(device) device_metadata['uuid'] = device_uuid device_metadata['path'] = device return device_metadata
def _parse(self): if not sys_info.devices: sys_info.devices = disk.get_devices() self.sys_api = sys_info.devices.get(self.abspath, {}) if not self.sys_api: # if no device was found check if we are a partition partname = self.abspath.split('/')[-1] for device, info in sys_info.devices.items(): part = info['partitions'].get(partname, {}) if part: self.sys_api = part break # start with lvm since it can use an absolute or relative path lv = lvm.get_lv_from_argument(self.path) if lv: self.lv_api = lv self.lvs = [lv] self.abspath = lv.lv_path self.vg_name = lv.vg_name self.lv_name = lv.name else: dev = disk.lsblk(self.path) self.blkid_api = disk.blkid(self.path) self.disk_api = dev device_type = dev.get('TYPE', '') # always check is this is an lvm member if device_type in ['part', 'disk']: self._set_lvm_membership() self.ceph_disk = CephDiskDevice(self)
def zap(self, args): device = args.device lv = api.get_lv_from_argument(device) if lv: # we are zapping a logical volume path = lv.lv_path else: # we are zapping a partition #TODO: ensure device is a partition path = device mlogger.info("Zapping: %s", path) # check if there was a pv created with the # name of device pv = api.get_pv(pv_name=device) if pv: vg_name = pv.vg_name lv = api.get_lv(vg_name=vg_name) dmcrypt = False dmcrypt_uuid = None if lv: osd_path = "/var/lib/ceph/osd/{}-{}".format(lv.tags['ceph.cluster_name'], lv.tags['ceph.osd_id']) dmcrypt_uuid = lv.lv_uuid dmcrypt = lv.encrypted if system.path_is_mounted(osd_path): mlogger.info("Unmounting %s", osd_path) system.unmount(osd_path) else: # we're most likely dealing with a partition here, check to # see if it was encrypted partuuid = disk.get_partuuid(device) if encryption.status("/dev/mapper/{}".format(partuuid)): dmcrypt_uuid = partuuid dmcrypt = True if dmcrypt and dmcrypt_uuid: dmcrypt_path = "/dev/mapper/{}".format(dmcrypt_uuid) mlogger.info("Closing encrypted path %s", dmcrypt_path) encryption.dmcrypt_close(dmcrypt_path) if args.destroy and pv: logger.info("Found a physical volume created from %s, will destroy all it's vgs and lvs", device) vg_name = pv.vg_name mlogger.info("Destroying volume group %s because --destroy was given", vg_name) api.remove_vg(vg_name) mlogger.info("Destroying physical volume %s because --destroy was given", device) api.remove_pv(device) elif args.destroy and not pv: mlogger.info("Skipping --destroy because no associated physical volumes are found for %s", device) wipefs(path) zap_data(path) if lv and not pv: # remove all lvm metadata lv.clear_tags() terminal.success("Zapping successful for: %s" % path)
def _parse(self): if not sys_info.devices: sys_info.devices = disk.get_devices() self.sys_api = sys_info.devices.get(self.abspath, {}) if not self.sys_api: # if no device was found check if we are a partition partname = self.abspath.split('/')[-1] for device, info in sys_info.devices.items(): part = info['partitions'].get(partname, {}) if part: self.sys_api = part break # start with lvm since it can use an absolute or relative path lv = lvm.get_lv_from_argument(self.path) if lv: self.lv_api = lv self.lvs = [lv] self.abspath = lv.lv_path self.vg_name = lv.vg_name self.lv_name = lv.name else: dev = disk.lsblk(self.path) self.blkid_api = disk.blkid(self.path) self.disk_api = dev device_type = dev.get('TYPE', '') # always check is this is an lvm member if device_type in ['part', 'disk']: self._set_lvm_membership() self.ceph_disk = CephDiskDevice(self)
def zap(self, args): for device in args.devices: if disk.is_mapper_device(device): terminal.error( "Refusing to zap the mapper device: {}".format(device)) raise SystemExit(1) lv = api.get_lv_from_argument(device) if lv: # we are zapping a logical volume path = lv.lv_path self.unmount_lv(lv) else: # we are zapping a partition #TODO: ensure device is a partition path = device # check to if it is encrypted to close partuuid = disk.get_partuuid(device) if encryption.status("/dev/mapper/{}".format(partuuid)): dmcrypt_uuid = partuuid self.dmcrypt_close(dmcrypt_uuid) mlogger.info("Zapping: %s", path) # check if there was a pv created with the # name of device pvs = api.PVolumes() pvs.filter(pv_name=device) vgs = set([pv.vg_name for pv in pvs]) for pv in pvs: vg_name = pv.vg_name lv = None if pv.lv_uuid: lv = api.get_lv(vg_name=vg_name, lv_uuid=pv.lv_uuid) if lv: self.unmount_lv(lv) if args.destroy: for vg_name in vgs: mlogger.info( "Destroying volume group %s because --destroy was given", vg_name) api.remove_vg(vg_name) mlogger.info( "Destroying physical volume %s because --destroy was given", device) api.remove_pv(device) wipefs(path) zap_data(path) if lv and not pvs: # remove all lvm metadata lv.clear_tags() terminal.success("Zapping successful for: %s" % ", ".join(args.devices))
def single_report(self, device, lvs=None): """ Generate a report for a single device. This can be either a logical volume in the form of vg/lv or a device with an absolute path like /dev/sda1 or /dev/sda """ if lvs is None: lvs = api.Volumes() report = {} lv = api.get_lv_from_argument(device) # check if there was a pv created with the # name of device pv = api.get_pv(pv_name=device) if pv and not lv: try: lv = api.get_lv(vg_name=pv.vg_name) except MultipleLVsError: lvs.filter(vg_name=pv.vg_name) return self.full_report(lvs=lvs) if lv: try: _id = lv.tags['ceph.osd_id'] except KeyError: logger.warning('device is not part of ceph: %s', device) return report report.setdefault(_id, []) lv_report = lv.as_dict() lv_report['devices'] = self.match_devices(lv.lv_uuid) report[_id].append(lv_report) else: # this has to be a journal/wal/db device (not a logical volume) so try # to find the PARTUUID that should be stored in the OSD logical # volume for device_type in ['journal', 'block', 'wal', 'db']: device_tag_name = 'ceph.%s_device' % device_type device_tag_uuid = 'ceph.%s_uuid' % device_type associated_lv = lvs.get(lv_tags={device_tag_name: device}) if associated_lv: _id = associated_lv.tags['ceph.osd_id'] uuid = associated_lv.tags[device_tag_uuid] report.setdefault(_id, []) report[_id].append( { 'tags': {'PARTUUID': uuid}, 'type': device_type, 'path': device, } ) return report
def single_report(self, device): """ Generate a report for a single device. This can be either a logical volume in the form of vg/lv or a device with an absolute path like /dev/sda1 or /dev/sda """ lvs = api.Volumes() report = {} lv = api.get_lv_from_argument(device) # check if there was a pv created with the # name of device pv = api.get_pv(pv_name=device) if pv and not lv: try: lv = api.get_lv(vg_name=pv.vg_name) except MultipleLVsError: lvs.filter(vg_name=pv.vg_name) return self.full_report(lvs=lvs) if lv: try: _id = lv.tags['ceph.osd_id'] except KeyError: logger.warning('device is not part of ceph: %s', device) return report report.setdefault(_id, []) report[_id].append( lv.as_dict() ) else: # this has to be a journal/wal/db device (not a logical volume) so try # to find the PARTUUID that should be stored in the OSD logical # volume for device_type in ['journal', 'block', 'wal', 'db']: device_tag_name = 'ceph.%s_device' % device_type device_tag_uuid = 'ceph.%s_uuid' % device_type associated_lv = lvs.get(lv_tags={device_tag_name: device}) if associated_lv: _id = associated_lv.tags['ceph.osd_id'] uuid = associated_lv.tags[device_tag_uuid] report.setdefault(_id, []) report[_id].append( { 'tags': {'PARTUUID': uuid}, 'type': device_type, 'path': device, } ) return report
def zap(self, args): device = args.device lv = api.get_lv_from_argument(device) if lv: # we are zapping a logical volume path = lv.lv_path else: # we are zapping a partition #TODO: ensure device is a partition path = device logger.info("Zapping: %s", path) terminal.write("Zapping: %s" % path) if args.destroy and not lv: # check if there was a pv created with the # name of device pv = api.PVolumes().get(pv_name=device) if pv: logger.info( "Found a physical volume created from %s, will destroy all it's vgs and lvs", device) vg_name = pv.vg_name logger.info( "Destroying volume group %s because --destroy was given", vg_name) terminal.write( "Destroying volume group %s because --destroy was given" % vg_name) api.remove_vg(vg_name) logger.info( "Destroying physical volume %s because --destroy was given", device) terminal.write( "Destroying physical volume %s because --destroy was given" % device) api.remove_pv(device) else: logger.info( "Skipping --destroy because no associated physical volumes are found for %s", device) terminal.write( "Skipping --destroy because no associated physical volumes are found for %s" % device) wipefs(path) zap_data(path) if lv: # remove all lvm metadata lv.clear_tags() terminal.success("Zapping successful for: %s" % path)
def zap(self, args): device = args.device lv = api.get_lv_from_argument(device) if lv: # we are zapping a logical volume path = lv.lv_path else: # we are zapping a partition #TODO: ensure device is a partition path = device mlogger.info("Zapping: %s", path) # check if there was a pv created with the # name of device pv = api.get_pv(pv_name=device) if pv: vg_name = pv.vg_name lv = api.get_lv(vg_name=vg_name) if lv: osd_path = "/var/lib/ceph/osd/{}-{}".format( lv.tags['ceph.cluster_name'], lv.tags['ceph.osd_id']) if system.path_is_mounted(osd_path): mlogger.info("Unmounting %s", osd_path) system.unmount(osd_path) if args.destroy and pv: logger.info( "Found a physical volume created from %s, will destroy all it's vgs and lvs", device) vg_name = pv.vg_name mlogger.info( "Destroying volume group %s because --destroy was given", vg_name) api.remove_vg(vg_name) mlogger.info( "Destroying physical volume %s because --destroy was given", device) api.remove_pv(device) elif args.destroy and not pv: mlogger.info( "Skipping --destroy because no associated physical volumes are found for %s", device) wipefs(path) zap_data(path) if lv and not pv: # remove all lvm metadata lv.clear_tags() terminal.success("Zapping successful for: %s" % path)
def zap(self, args): for device in args.devices: if disk.is_mapper_device(device): terminal.error("Refusing to zap the mapper device: {}".format(device)) raise SystemExit(1) lv = api.get_lv_from_argument(device) if lv: # we are zapping a logical volume path = lv.lv_path self.unmount_lv(lv) else: # we are zapping a partition #TODO: ensure device is a partition path = device # check to if it is encrypted to close partuuid = disk.get_partuuid(device) if encryption.status("/dev/mapper/{}".format(partuuid)): dmcrypt_uuid = partuuid self.dmcrypt_close(dmcrypt_uuid) mlogger.info("Zapping: %s", path) # check if there was a pv created with the # name of device pvs = api.PVolumes() pvs.filter(pv_name=device) vgs = set([pv.vg_name for pv in pvs]) for pv in pvs: vg_name = pv.vg_name lv = None if pv.lv_uuid: lv = api.get_lv(vg_name=vg_name, lv_uuid=pv.lv_uuid) if lv: self.unmount_lv(lv) if args.destroy: for vg_name in vgs: mlogger.info("Destroying volume group %s because --destroy was given", vg_name) api.remove_vg(vg_name) if not lv: mlogger.info("Destroying physical volume %s because --destroy was given", device) api.remove_pv(device) wipefs(path) zap_data(path) if lv and not pvs: # remove all lvm metadata lv.clear_tags() terminal.success("Zapping successful for: %s" % ", ".join(args.devices))
def _parse(self): # start with lvm since it can use an absolute or relative path lv = lvm.get_lv_from_argument(self.path) if lv: self.lv_api = lv self.abspath = lv.lv_path else: dev = disk.lsblk(self.path) self.disk_api = dev device_type = dev.get('TYPE', '') # always check is this is an lvm member if device_type in ['part', 'disk']: self._set_lvm_membership() if not sys_info.devices: sys_info.devices = disk.get_devices() self.sys_api = sys_info.devices.get(self.abspath, {})
def _parse(self): # start with lvm since it can use an absolute or relative path lv = lvm.get_lv_from_argument(self.path) if lv: self.lv_api = lv self.abspath = lv.lv_path else: dev = disk.lsblk(self.path) self.disk_api = dev device_type = dev.get('TYPE', '') # always check is this is an lvm member if device_type in ['part', 'disk']: self._set_lvm_membership() if not sys_info.devices: sys_info.devices = disk.get_devices() self.sys_api = sys_info.devices.get(self.abspath, {})
def zap(self, args): device = args.device lv = api.get_lv_from_argument(device) if lv: # we are zapping a logical volume path = lv.lv_path else: # we are zapping a partition #TODO: ensure device is a partition path = device mlogger.info("Zapping: %s", path) # check if there was a pv created with the # name of device pv = api.get_pv(pv_name=device) if pv: vg_name = pv.vg_name lv = api.get_lv(vg_name=vg_name) if lv: osd_path = "/var/lib/ceph/osd/{}-{}".format(lv.tags['ceph.cluster_name'], lv.tags['ceph.osd_id']) if system.path_is_mounted(osd_path): mlogger.info("Unmounting %s", osd_path) system.unmount(osd_path) if args.destroy and pv: logger.info("Found a physical volume created from %s, will destroy all it's vgs and lvs", device) vg_name = pv.vg_name mlogger.info("Destroying volume group %s because --destroy was given", vg_name) api.remove_vg(vg_name) mlogger.info("Destroying physical volume %s because --destroy was given", device) api.remove_pv(device) elif args.destroy and not pv: mlogger.info("Skipping --destroy because no associated physical volumes are found for %s", device) wipefs(path) zap_data(path) if lv and not pv: # remove all lvm metadata lv.clear_tags() terminal.success("Zapping successful for: %s" % path)
def scan_device(self, path): device_metadata = {'path': None, 'uuid': None} if not path: return device_metadata # cannot read the symlink if this is tmpfs if os.path.islink(path): device = os.readlink(path) else: device = path lvm_device = lvm.get_lv_from_argument(device) if lvm_device: device_uuid = lvm_device.lv_uuid else: device_uuid = disk.get_partuuid(device) device_metadata['uuid'] = device_uuid device_metadata['path'] = device return device_metadata
def single_report(self, device): """ Generate a report for a single device. This can be either a logical volume in the form of vg/lv or a device with an absolute path like /dev/sda1 """ lvs = api.Volumes() report = {} lv = api.get_lv_from_argument(device) if lv: try: _id = lv.tags['ceph.osd_id'] except KeyError: logger.warning('device is not part of ceph: %s', device) return report report.setdefault(_id, []) report[_id].append(lv.as_dict()) else: # this has to be a journal/wal/db device (not a logical volume) so try # to find the PARTUUID that should be stored in the OSD logical # volume for device_type in ['journal', 'block', 'wal', 'db']: device_tag_name = 'ceph.%s_device' % device_type device_tag_uuid = 'ceph.%s_uuid' % device_type associated_lv = lvs.get(lv_tags={device_tag_name: device}) if associated_lv: _id = associated_lv.tags['ceph.osd_id'] uuid = associated_lv.tags[device_tag_uuid] report.setdefault(_id, []) report[_id].append({ 'tags': { 'PARTUUID': uuid }, 'type': device_type, 'path': device, }) return report
def zap(self, args): device = args.device lv = api.get_lv_from_argument(device) if lv: # we are zapping a logical volume path = lv.lv_path else: # we are zapping a partition #TODO: ensure device is a partition path = device logger.info("Zapping: %s", path) terminal.write("Zapping: %s" % path) wipefs(path) zap_data(path) if lv: # remove all lvm metadata lv.clear_tags() terminal.success("Zapping successful for: %s" % path)
def single_report(self, device): """ Generate a report for a single device. This can be either a logical volume in the form of vg/lv or a device with an absolute path like /dev/sda1 """ lvs = api.Volumes() report = {} lv = api.get_lv_from_argument(device) if lv: try: _id = lv.tags['ceph.osd_id'] except KeyError: logger.warning('device is not part of ceph: %s', device) return report report.setdefault(_id, []) report[_id].append( lv.as_dict() ) else: # this has to be a journal device (not a logical volume) so try # to find the PARTUUID that should be stored in the OSD logical # volume associated_lv = lvs.get(lv_tags={'ceph.journal_device': device}) if associated_lv: _id = associated_lv.tags['ceph.osd_id'] uuid = associated_lv.tags['ceph.journal_uuid'] report.setdefault(_id, []) report[_id].append( { 'tags': {'PARTUUID': uuid}, 'type': 'journal', 'path': device, } ) return report
def zap(self, args): device = args.device lv = api.get_lv_from_argument(device) if lv: # we are zapping a logical volume path = lv.lv_path else: # we are zapping a partition #TODO: ensure device is a partition path = device logger.info("Zapping: %s", path) terminal.write("Zapping: %s" % path) wipefs(path) zap_data(path) if lv: # remove all lvm metadata lv.clear_tags() terminal.success("Zapping successful for: %s" % path)
def test_too_many_slashes_is_invalid(self, volumes): volumes.append(self.foo_volume) assert api.get_lv_from_argument('path/to/lv') is None
def test_absolute_path_is_lv(self, volumes): volumes.append(self.foo_volume) assert api.get_lv_from_argument('/path/to/lv') == self.foo_volume
def test_absolute_path_is_not_lv(self, volumes): volumes.append(self.foo_volume) assert api.get_lv_from_argument('/path') is None
def test_too_many_slashes_is_invalid(self, volumes): volumes.append(self.foo_volume) assert api.get_lv_from_argument('path/to/lv') is None
def test_absolute_path_is_not_lv(self, volumes): volumes.append(self.foo_volume) assert api.get_lv_from_argument('/path') is None
def test_absolute_path_is_lv(self, volumes): volumes.append(self.foo_volume) assert api.get_lv_from_argument('/path/to/lv') == self.foo_volume
def zap(self, args): device = args.device if disk.is_mapper_device(device): terminal.error( "Refusing to zap the mapper device: {}".format(device)) raise SystemExit(1) lv = api.get_lv_from_argument(device) if lv: # we are zapping a logical volume path = lv.lv_path else: # we are zapping a partition #TODO: ensure device is a partition path = device mlogger.info("Zapping: %s", path) # check if there was a pv created with the # name of device pv = api.get_pv(pv_name=device) if pv: vg_name = pv.vg_name lv = api.get_lv(vg_name=vg_name) dmcrypt = False dmcrypt_uuid = None if lv: if lv.tags.get('ceph.cluster_name') and lv.tags.get('ceph.osd_id'): lv_path = "/var/lib/ceph/osd/{}-{}".format( lv.tags['ceph.cluster_name'], lv.tags['ceph.osd_id']) else: lv_path = lv.path dmcrypt_uuid = lv.lv_uuid dmcrypt = lv.encrypted if system.path_is_mounted(lv_path): mlogger.info("Unmounting %s", lv_path) system.unmount(lv_path) else: # we're most likely dealing with a partition here, check to # see if it was encrypted partuuid = disk.get_partuuid(device) if encryption.status("/dev/mapper/{}".format(partuuid)): dmcrypt_uuid = partuuid dmcrypt = True if dmcrypt and dmcrypt_uuid: dmcrypt_path = "/dev/mapper/{}".format(dmcrypt_uuid) mlogger.info("Closing encrypted path %s", dmcrypt_path) encryption.dmcrypt_close(dmcrypt_path) if args.destroy and pv: logger.info( "Found a physical volume created from %s, will destroy all it's vgs and lvs", device) vg_name = pv.vg_name mlogger.info( "Destroying volume group %s because --destroy was given", vg_name) api.remove_vg(vg_name) mlogger.info( "Destroying physical volume %s because --destroy was given", device) api.remove_pv(device) elif args.destroy and not pv: mlogger.info( "Skipping --destroy because no associated physical volumes are found for %s", device) wipefs(path) zap_data(path) if lv and not pv: # remove all lvm metadata lv.clear_tags() terminal.success("Zapping successful for: %s" % path)