]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/ceph-volume/ceph_volume/devices/lvm/zap.py
update sources to 12.2.8
[ceph.git] / ceph / src / ceph-volume / ceph_volume / devices / lvm / zap.py
index ee5cdf97b6a590726df2f3c16346f44c8355c14a..90c5447c0e1e8959d5c27e21ef2a4777eac8da67 100644 (file)
@@ -46,71 +46,80 @@ class Zap(object):
     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.
@@ -130,6 +139,10 @@ class Zap(object):
 
               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.
 
@@ -151,10 +164,11 @@ class Zap(object):
         )
 
         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',