]> git.proxmox.com Git - ceph.git/blob - ceph/src/ceph-volume/ceph_volume/devices/lvm/common.py
update ceph source to reef 18.2.0
[ceph.git] / ceph / src / ceph-volume / ceph_volume / devices / lvm / common.py
1 from ceph_volume.util import arg_validators, disk
2 from ceph_volume import process, conf
3 from ceph_volume import terminal
4 from ceph_volume.devices.lvm.zap import Zap
5 import argparse
6
7 def rollback_osd(args, osd_id=None):
8 """
9 When the process of creating or preparing fails, the OSD needs to be
10 destroyed so that the ID can be reused. This prevents from leaving the ID
11 around as "used" on the monitor, which can cause confusion if expecting
12 sequential OSD IDs.
13
14 The usage of `destroy-new` allows this to be done without requiring the
15 admin keyring (otherwise needed for destroy and purge commands)
16 """
17 if not osd_id:
18 # it means that it wasn't generated, so there is nothing to rollback here
19 return
20
21 # once here, this is an error condition that needs to be rolled back
22 terminal.error('Was unable to complete a new OSD, will rollback changes')
23 osd_name = 'osd.%s'
24 bootstrap_keyring = '/var/lib/ceph/bootstrap-osd/%s.keyring' % conf.cluster
25 cmd = [
26 'ceph',
27 '--cluster', conf.cluster,
28 '--name', 'client.bootstrap-osd',
29 '--keyring', bootstrap_keyring,
30 'osd', 'purge-new', osd_name % osd_id,
31 '--yes-i-really-mean-it',
32 ]
33
34 process.run(cmd)
35 Zap(['--destroy', '--osd-id', osd_id]).main()
36
37
38 common_args = {
39 '--data': {
40 'help': 'OSD data path. A physical device or logical volume',
41 'required': True,
42 'type': arg_validators.ValidDataDevice(as_string=True),
43 #'default':,
44 #'type':,
45 },
46 '--data-size': {
47 'help': 'Size of data LV in case a device was passed in --data',
48 'default': '0',
49 'type': disk.Size.parse
50 },
51 '--data-slots': {
52 'help': ('Intended number of slots on data device. The new OSD gets one'
53 'of those slots or 1/nth of the available capacity'),
54 'type': int,
55 'default': 1,
56 },
57 '--osd-id': {
58 'help': 'Reuse an existing OSD id',
59 'default': None,
60 'type': arg_validators.valid_osd_id,
61 },
62 '--osd-fsid': {
63 'help': 'Reuse an existing OSD fsid',
64 'default': None,
65 },
66 '--cluster-fsid': {
67 'help': 'Specify the cluster fsid, useful when no ceph.conf is available',
68 'default': None,
69 },
70 '--crush-device-class': {
71 'dest': 'crush_device_class',
72 'help': 'Crush device class to assign this OSD to',
73 'default': "",
74 },
75 '--dmcrypt': {
76 'action': 'store_true',
77 'help': 'Enable device encryption via dm-crypt',
78 },
79 '--no-systemd': {
80 'dest': 'no_systemd',
81 'action': 'store_true',
82 'help': 'Skip creating and enabling systemd units and starting OSD services when activating',
83 },
84 }
85
86 bluestore_args = {
87 '--bluestore': {
88 'action': 'store_true',
89 'help': 'Use the bluestore objectstore',
90 },
91 '--block.db': {
92 'dest': 'block_db',
93 'help': 'Path to bluestore block.db logical volume or device',
94 'type': arg_validators.ValidDevice(as_string=True),
95 },
96 '--block.db-size': {
97 'dest': 'block_db_size',
98 'help': 'Size of block.db LV in case device was passed in --block.db',
99 'default': '0',
100 'type': disk.Size.parse
101 },
102 '--block.db-slots': {
103 'dest': 'block_db_slots',
104 'help': ('Intended number of slots on db device. The new OSD gets one'
105 'of those slots or 1/nth of the available capacity'),
106 'type': int,
107 'default': 1,
108 },
109 '--block.wal': {
110 'dest': 'block_wal',
111 'help': 'Path to bluestore block.wal logical volume or device',
112 'type': arg_validators.ValidDevice(as_string=True),
113 },
114 '--block.wal-size': {
115 'dest': 'block_wal_size',
116 'help': 'Size of block.wal LV in case device was passed in --block.wal',
117 'default': '0',
118 'type': disk.Size.parse
119 },
120 '--block.wal-slots': {
121 'dest': 'block_wal_slots',
122 'help': ('Intended number of slots on wal device. The new OSD gets one'
123 'of those slots or 1/nth of the available capacity'),
124 'type': int,
125 'default': 1,
126 },
127 }
128
129
130 def get_default_args():
131 defaults = {}
132 def format_name(name):
133 return name.strip('-').replace('-', '_').replace('.', '_')
134 for argset in (common_args, bluestore_args):
135 defaults.update({format_name(name): val.get('default', None) for name, val in argset.items()})
136 return defaults
137
138
139 def common_parser(prog, description):
140 """
141 Both prepare and create share the same parser, those are defined here to
142 avoid duplication
143 """
144 parser = argparse.ArgumentParser(
145 prog=prog,
146 formatter_class=argparse.RawDescriptionHelpFormatter,
147 description=description,
148 )
149
150 bluestore_group = parser.add_argument_group('bluestore')
151
152 for name, kwargs in common_args.items():
153 parser.add_argument(name, **kwargs)
154
155 for name, kwargs in bluestore_args.items():
156 bluestore_group.add_argument(name, **kwargs)
157
158 # Do not parse args, so that consumers can do something before the args get
159 # parsed triggering argparse behavior
160 return parser
161
162
163 create_parser = common_parser # noqa
164 prepare_parser = common_parser # noqa