]> git.proxmox.com Git - ceph.git/blob - ceph/src/ceph-volume/ceph_volume/devices/lvm/zap.py
update sources to v12.2.3
[ceph.git] / ceph / src / ceph-volume / ceph_volume / devices / lvm / zap.py
1 import argparse
2 import logging
3
4 from textwrap import dedent
5
6 from ceph_volume import decorators, terminal, process
7 from ceph_volume.api import lvm as api
8 from ceph_volume.util import system
9
10 logger = logging.getLogger(__name__)
11 mlogger = terminal.MultiLogger(__name__)
12
13
14 def wipefs(path):
15 """
16 Removes the filesystem from an lv or partition.
17 """
18 process.run([
19 'wipefs',
20 '--all',
21 path
22 ])
23
24
25 def zap_data(path):
26 """
27 Clears all data from the given path. Path should be
28 an absolute path to an lv or partition.
29
30 10M of data is written to the path to make sure that
31 there is no trace left of any previous Filesystem.
32 """
33 process.run([
34 'dd',
35 'if=/dev/zero',
36 'of={path}'.format(path=path),
37 'bs=1M',
38 'count=10',
39 ])
40
41
42 class Zap(object):
43
44 help = 'Removes all data and filesystems from a logical volume or partition.'
45
46 def __init__(self, argv):
47 self.argv = argv
48
49 @decorators.needs_root
50 def zap(self, args):
51 device = args.device
52 lv = api.get_lv_from_argument(device)
53 if lv:
54 # we are zapping a logical volume
55 path = lv.lv_path
56 else:
57 # we are zapping a partition
58 #TODO: ensure device is a partition
59 path = device
60
61 mlogger.info("Zapping: %s", path)
62
63 # check if there was a pv created with the
64 # name of device
65 pv = api.get_pv(pv_name=device)
66 if pv:
67 vg_name = pv.vg_name
68 lv = api.get_lv(vg_name=vg_name)
69
70 if lv:
71 osd_path = "/var/lib/ceph/osd/{}-{}".format(lv.tags['ceph.cluster_name'], lv.tags['ceph.osd_id'])
72 if system.path_is_mounted(osd_path):
73 mlogger.info("Unmounting %s", osd_path)
74 system.unmount(osd_path)
75
76 if args.destroy and pv:
77 logger.info("Found a physical volume created from %s, will destroy all it's vgs and lvs", device)
78 vg_name = pv.vg_name
79 mlogger.info("Destroying volume group %s because --destroy was given", vg_name)
80 api.remove_vg(vg_name)
81 mlogger.info("Destroying physical volume %s because --destroy was given", device)
82 api.remove_pv(device)
83 elif args.destroy and not pv:
84 mlogger.info("Skipping --destroy because no associated physical volumes are found for %s", device)
85
86 wipefs(path)
87 zap_data(path)
88
89 if lv and not pv:
90 # remove all lvm metadata
91 lv.clear_tags()
92
93 terminal.success("Zapping successful for: %s" % path)
94
95 def main(self):
96 sub_command_help = dedent("""
97 Zaps the given logical volume, raw device or partition for reuse by ceph-volume.
98 If given a path to a logical volume it must be in the format of vg/lv. Any
99 filesystems present on the given device, vg/lv, or partition will be removed and
100 all data will be purged.
101
102 If the logical volume, raw device or partition is being used for any ceph related
103 mount points they will be unmounted.
104
105 However, the lv or partition will be kept intact.
106
107 Example calls for supported scenarios:
108
109 Zapping a logical volume:
110
111 ceph-volume lvm zap {vg name/lv name}
112
113 Zapping a partition:
114
115 ceph-volume lvm zap /dev/sdc1
116
117 If the --destroy flag is given and you are zapping a raw device or partition
118 then all vgs and lvs that exist on that raw device or partition will be destroyed.
119
120 This is especially useful if a raw device or partition was used by ceph-volume lvm create
121 or ceph-volume lvm prepare commands previously and now you want to reuse that device.
122
123 For example:
124
125 ceph-volume lvm zap /dev/sda --destroy
126
127 If the --destroy flag is given and you are zapping an lv then the lv is still
128 kept intact for reuse.
129
130 """)
131 parser = argparse.ArgumentParser(
132 prog='ceph-volume lvm zap',
133 formatter_class=argparse.RawDescriptionHelpFormatter,
134 description=sub_command_help,
135 )
136
137 parser.add_argument(
138 'device',
139 metavar='DEVICE',
140 nargs='?',
141 help='Path to an lv (as vg/lv), partition (as /dev/sda1) or device (as /dev/sda)'
142 )
143 parser.add_argument(
144 '--destroy',
145 action='store_true',
146 default=False,
147 help='Destroy all volume groups and logical volumes if you are zapping a raw device or partition',
148 )
149 if len(self.argv) == 0:
150 print(sub_command_help)
151 return
152 args = parser.parse_args(self.argv)
153 self.zap(args)