def test_multiple_pvs_is_matched_by_tags(self, pvolumes, monkeypatch): FooPVolume = api.PVolume(vg_name="vg1", pv_name='/dev/sdc', pv_uuid="1000", pv_tags="ceph.foo=bar", lv_uuid="0000000") BarPVolume = api.PVolume(vg_name="vg", pv_name='/dev/sda', pv_uuid="0000", pv_tags="ceph.foo=bar") pvolumes.append(FooPVolume) pvolumes.append(BarPVolume) monkeypatch.setattr(api, 'PVolumes', lambda: pvolumes) with pytest.raises(exceptions.MultiplePVsError): api.get_pv(pv_tags={"ceph.foo": "bar"})
def test_single_pv_is_matched_by_uuid(self, pvolumes, monkeypatch): FooPVolume = api.PVolume( pv_name='/dev/vg/foo', pv_uuid='1111', pv_tags="ceph.type=data") pvolumes.append(FooPVolume) monkeypatch.setattr(api, 'PVolumes', lambda: pvolumes) assert api.get_pv(pv_uuid='1111') == FooPVolume
def test_single_pv_is_matched(self, pvolumes, monkeypatch): FooPVolume = api.PVolume(pv_name='/dev/sda', pv_uuid="0000", pv_tags={}) pvolumes.append(FooPVolume) monkeypatch.setattr(api, 'PVolumes', lambda: pvolumes) assert api.get_pv(pv_uuid='0000') == FooPVolume
def test_single_pv_is_matched_by_uuid(self, pvolumes, monkeypatch): FooPVolume = api.PVolume( pv_name='/dev/vg/foo', pv_uuid='1111', pv_tags="ceph.type=data", vg_name="vg") pvolumes.append(FooPVolume) monkeypatch.setattr(api, 'PVolumes', lambda: pvolumes) assert api.get_pv(pv_uuid='1111') == FooPVolume
def test_multiple_pvs_is_matched_by_name(self, pvolumes, monkeypatch): FooPVolume = api.PVolume(vg_name="vg", pv_name='/dev/sda', pv_uuid="0000", pv_tags={}, lv_uuid="0000000") BarPVolume = api.PVolume(vg_name="vg", pv_name='/dev/sda', pv_uuid="0000", pv_tags={}) pvolumes.append(FooPVolume) pvolumes.append(BarPVolume) monkeypatch.setattr(api, 'PVolumes', lambda: pvolumes) assert api.get_pv(pv_name='/dev/sda') == FooPVolume
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 test_vg_name_is_set(self, pvolumes, monkeypatch): FooPVolume = api.PVolume( pv_name='/dev/vg/foo', pv_uuid='1111', pv_tags="ceph.type=data", vg_name="vg") pvolumes.append(FooPVolume) monkeypatch.setattr(api, 'PVolumes', lambda: pvolumes) pv = api.get_pv(pv_name="/dev/vg/foo") assert pv.vg_name == "vg"
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 get_lvm_osd_info(final): pv = api.get_pv(pv_name=final['osd_partition']) if not pv: return lv = api.get_lv(vg_name=pv.vg_name) if lv: final['osd_data_block'] = lv.tags.get('ceph.block_device', '') final['osd_data_wal'] = lv.tags.get('ceph.wal_device', '') final['osd_data_db'] = lv.tags.get('ceph.db_device', '') final['osd_data_osd'] = lv.tags.get('ceph.data_device', '') final['osd_data_id'] = lv.tags.get('ceph.osd_id', '')
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 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): 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 test_nothing_is_passed_in(self): # so we return a None assert api.get_pv() is None
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)
def test_single_pv_is_matched(self, pvolumes, monkeypatch): FooPVolume = api.PVolume(vg_name="vg", pv_name='/dev/sda', pv_uuid="0000", pv_tags={}) pvolumes.append(FooPVolume) monkeypatch.setattr(api, 'PVolumes', lambda: pvolumes) assert api.get_pv(pv_uuid='0000') == FooPVolume