4 from textwrap
import dedent
6 from ceph_volume
import decorators
, terminal
, process
7 from ceph_volume
.api
import lvm
as api
8 from ceph_volume
.util
import system
, encryption
, disk
10 logger
= logging
.getLogger(__name__
)
11 mlogger
= terminal
.MultiLogger(__name__
)
16 Removes the filesystem from an lv or partition.
27 Clears all data from the given path. Path should be
28 an absolute path to an lv or partition.
30 10M of data is written to the path to make sure that
31 there is no trace left of any previous Filesystem.
36 'of={path}'.format(path
=path
),
44 help = 'Removes all data and filesystems from a logical volume or partition.'
46 def __init__(self
, argv
):
49 @decorators.needs_root
52 lv
= api
.get_lv_from_argument(device
)
54 # we are zapping a logical volume
57 # we are zapping a partition
58 #TODO: ensure device is a partition
61 mlogger
.info("Zapping: %s", path
)
63 # check if there was a pv created with the
65 pv
= api
.get_pv(pv_name
=device
)
68 lv
= api
.get_lv(vg_name
=vg_name
)
73 osd_path
= "/var/lib/ceph/osd/{}-{}".format(lv
.tags
['ceph.cluster_name'], lv
.tags
['ceph.osd_id'])
74 dmcrypt_uuid
= lv
.lv_uuid
75 dmcrypt
= lv
.encrypted
76 if system
.path_is_mounted(osd_path
):
77 mlogger
.info("Unmounting %s", osd_path
)
78 system
.unmount(osd_path
)
80 # we're most likely dealing with a partition here, check to
81 # see if it was encrypted
82 partuuid
= disk
.get_partuuid(device
)
83 if encryption
.status("/dev/mapper/{}".format(partuuid
)):
84 dmcrypt_uuid
= partuuid
87 if dmcrypt
and dmcrypt_uuid
:
88 dmcrypt_path
= "/dev/mapper/{}".format(dmcrypt_uuid
)
89 mlogger
.info("Closing encrypted path %s", dmcrypt_path
)
90 encryption
.dmcrypt_close(dmcrypt_path
)
92 if args
.destroy
and pv
:
93 logger
.info("Found a physical volume created from %s, will destroy all it's vgs and lvs", device
)
95 mlogger
.info("Destroying volume group %s because --destroy was given", vg_name
)
96 api
.remove_vg(vg_name
)
97 mlogger
.info("Destroying physical volume %s because --destroy was given", device
)
99 elif args
.destroy
and not pv
:
100 mlogger
.info("Skipping --destroy because no associated physical volumes are found for %s", device
)
106 # remove all lvm metadata
109 terminal
.success("Zapping successful for: %s" % path
)
112 sub_command_help
= dedent("""
113 Zaps the given logical volume, raw device or partition for reuse by ceph-volume.
114 If given a path to a logical volume it must be in the format of vg/lv. Any
115 filesystems present on the given device, vg/lv, or partition will be removed and
116 all data will be purged.
118 If the logical volume, raw device or partition is being used for any ceph related
119 mount points they will be unmounted.
121 However, the lv or partition will be kept intact.
123 Example calls for supported scenarios:
125 Zapping a logical volume:
127 ceph-volume lvm zap {vg name/lv name}
131 ceph-volume lvm zap /dev/sdc1
133 If the --destroy flag is given and you are zapping a raw device or partition
134 then all vgs and lvs that exist on that raw device or partition will be destroyed.
136 This is especially useful if a raw device or partition was used by ceph-volume lvm create
137 or ceph-volume lvm prepare commands previously and now you want to reuse that device.
141 ceph-volume lvm zap /dev/sda --destroy
143 If the --destroy flag is given and you are zapping an lv then the lv is still
144 kept intact for reuse.
147 parser
= argparse
.ArgumentParser(
148 prog
='ceph-volume lvm zap',
149 formatter_class
=argparse
.RawDescriptionHelpFormatter
,
150 description
=sub_command_help
,
157 help='Path to an lv (as vg/lv), partition (as /dev/sda1) or device (as /dev/sda)'
163 help='Destroy all volume groups and logical volumes if you are zapping a raw device or partition',
165 if len(self
.argv
) == 0:
166 print(sub_command_help
)
168 args
= parser
.parse_args(self
.argv
)