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 def unmount_lv(self
, lv
):
50 if lv
.tags
.get('ceph.cluster_name') and lv
.tags
.get('ceph.osd_id'):
51 lv_path
= "/var/lib/ceph/osd/{}-{}".format(lv
.tags
['ceph.cluster_name'], lv
.tags
['ceph.osd_id'])
54 dmcrypt_uuid
= lv
.lv_uuid
55 dmcrypt
= lv
.encrypted
56 if system
.path_is_mounted(lv_path
):
57 mlogger
.info("Unmounting %s", lv_path
)
58 system
.unmount(lv_path
)
59 if dmcrypt
and dmcrypt_uuid
:
60 self
.dmcrypt_close(dmcrypt_uuid
)
62 @decorators.needs_root
64 for device
in args
.devices
:
65 if disk
.is_mapper_device(device
):
66 terminal
.error("Refusing to zap the mapper device: {}".format(device
))
68 lv
= api
.get_lv_from_argument(device
)
70 # we are zapping a logical volume
74 # we are zapping a partition
75 #TODO: ensure device is a partition
77 # check to if it is encrypted to close
78 partuuid
= disk
.get_partuuid(device
)
79 if encryption
.status("/dev/mapper/{}".format(partuuid
)):
80 dmcrypt_uuid
= partuuid
81 self
.dmcrypt_close(dmcrypt_uuid
)
83 mlogger
.info("Zapping: %s", path
)
85 # check if there was a pv created with the
88 pvs
.filter(pv_name
=device
)
89 vgs
= set([pv
.vg_name
for pv
in pvs
])
94 lv
= api
.get_lv(vg_name
=vg_name
, lv_uuid
=pv
.lv_uuid
)
101 mlogger
.info("Destroying volume group %s because --destroy was given", vg_name
)
102 api
.remove_vg(vg_name
)
104 mlogger
.info("Destroying physical volume %s because --destroy was given", device
)
105 api
.remove_pv(device
)
113 lvs
.filter(vg_name
=lv
.vg_name
)
115 mlogger
.info('Only 1 LV left in VG, will proceed to destroy volume group %s', lv
.vg_name
)
116 api
.remove_vg(lv
.vg_name
)
118 mlogger
.info('More than 1 LV left in VG, will proceed to destroy LV only')
119 mlogger
.info('Removing LV because --destroy was given: %s', lv
)
122 # just remove all lvm metadata, leaving the LV around
125 terminal
.success("Zapping successful for: %s" % ", ".join(args
.devices
))
127 def dmcrypt_close(self
, dmcrypt_uuid
):
128 dmcrypt_path
= "/dev/mapper/{}".format(dmcrypt_uuid
)
129 mlogger
.info("Closing encrypted path %s", dmcrypt_path
)
130 encryption
.dmcrypt_close(dmcrypt_path
)
133 sub_command_help
= dedent("""
134 Zaps the given logical volume(s), raw device(s) or partition(s) for reuse by ceph-volume.
135 If given a path to a logical volume it must be in the format of vg/lv. Any
136 filesystems present on the given device, vg/lv, or partition will be removed and
137 all data will be purged.
139 If the logical volume, raw device or partition is being used for any ceph related
140 mount points they will be unmounted.
142 However, the lv or partition will be kept intact.
144 Example calls for supported scenarios:
146 Zapping a logical volume:
148 ceph-volume lvm zap {vg name/lv name}
152 ceph-volume lvm zap /dev/sdc1
154 Zapping many raw devices:
156 ceph-volume lvm zap /dev/sda /dev/sdb /db/sdc
158 If the --destroy flag is given and you are zapping a raw device or partition
159 then all vgs and lvs that exist on that raw device or partition will be destroyed.
161 This is especially useful if a raw device or partition was used by ceph-volume lvm create
162 or ceph-volume lvm prepare commands previously and now you want to reuse that device.
166 ceph-volume lvm zap /dev/sda --destroy
168 If the --destroy flag is given and you are zapping an lv then the lv is still
169 kept intact for reuse.
172 parser
= argparse
.ArgumentParser(
173 prog
='ceph-volume lvm zap',
174 formatter_class
=argparse
.RawDescriptionHelpFormatter
,
175 description
=sub_command_help
,
183 help='Path to one or many lv (as vg/lv), partition (as /dev/sda1) or device (as /dev/sda)'
189 help='Destroy all volume groups and logical volumes if you are zapping a raw device or partition',
191 if len(self
.argv
) == 0:
192 print(sub_command_help
)
194 args
= parser
.parse_args(self
.argv
)