]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
ceph-volume: allow `lvm zap` to zap many devices at once
authorAndrew Schoen <aschoen@redhat.com>
Tue, 21 Aug 2018 18:07:55 +0000 (14:07 -0400)
committerAlfredo Deza <adeza@redhat.com>
Fri, 24 Aug 2018 14:18:04 +0000 (10:18 -0400)
Supports passing many devices, partitions or lvs to
ceph-volume lvm zap.

Signed-off-by: Andrew Schoen <aschoen@redhat.com>
src/ceph-volume/ceph_volume/devices/lvm/zap.py
src/ceph-volume/ceph_volume/tests/devices/test_zap.py

index 128470720923c313eb078410da7f8da5cad86f33..90c5447c0e1e8959d5c27e21ef2a4777eac8da67 100644 (file)
@@ -61,56 +61,56 @@ class Zap(object):
 
     @decorators.needs_root
     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
-            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)
-
+        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)
-
-        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" % path)
+            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)
@@ -119,7 +119,7 @@ class Zap(object):
 
     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.
@@ -139,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.
 
@@ -160,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',
index b768c6e901c97864d1a25b440b19b7655190c737..493c74c509c733be891712414f5a1f95cb30e20a 100644 (file)
@@ -7,7 +7,7 @@ class TestZap(object):
     def test_main_spits_help_with_no_arguments(self, capsys):
         lvm.zap.Zap([]).main()
         stdout, stderr = capsys.readouterr()
-        assert 'Zaps the given logical volume, raw device or partition' in stdout
+        assert 'Zaps the given logical volume(s), raw device(s) or partition(s)' in stdout
 
     def test_main_shows_full_help(self, capsys):
         with pytest.raises(SystemExit):