def __init__(self, argv):
self.argv = argv
- @decorators.needs_root
- 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)
+ def unmount_lv(self, 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:
- # 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
-
+ lv_path = lv.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)
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)
+ self.dmcrypt_close(dmcrypt_uuid)
- if lv and not pv:
- # remove all lvm metadata
- lv.clear_tags()
-
- terminal.success("Zapping successful for: %s" % path)
+ @decorators.needs_root
+ 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 dmcrypt_close(self, dmcrypt_uuid):
+ dmcrypt_path = "/dev/mapper/{}".format(dmcrypt_uuid)
+ mlogger.info("Closing encrypted path %s", dmcrypt_path)
+ encryption.dmcrypt_close(dmcrypt_path)
def main(self):
sub_command_help = dedent("""
- Zaps the given logical volume, raw device or partition for reuse by ceph-volume.
+ Zaps the given logical volume(s), raw device(s) or partition(s) for reuse by ceph-volume.
If given a path to a logical volume it must be in the format of vg/lv. Any
filesystems present on the given device, vg/lv, or partition will be removed and
all data will be purged.
ceph-volume lvm zap /dev/sdc1
+ Zapping many raw devices:
+
+ ceph-volume lvm zap /dev/sda /dev/sdb /db/sdc
+
If the --destroy flag is given and you are zapping a raw device or partition
then all vgs and lvs that exist on that raw device or partition will be destroyed.
)
parser.add_argument(
- 'device',
- metavar='DEVICE',
- nargs='?',
- help='Path to an lv (as vg/lv), partition (as /dev/sda1) or device (as /dev/sda)'
+ 'devices',
+ metavar='DEVICES',
+ nargs='*',
+ default=[],
+ help='Path to one or many lv (as vg/lv), partition (as /dev/sda1) or device (as /dev/sda)'
)
parser.add_argument(
'--destroy',