]> git.proxmox.com Git - ceph.git/blame - ceph/src/ceph-volume/ceph_volume/util/prepare.py
update sources to v12.2.3
[ceph.git] / ceph / src / ceph-volume / ceph_volume / util / prepare.py
CommitLineData
d2e6a577
FG
1"""
2These utilities for prepare provide all the pieces needed to prepare a device
3but also a compounded ("single call") helper to do them in order. Some plugins
4may want to change some part of the process, while others might want to consume
5the single-call helper
6"""
7import os
8import logging
b32b8144 9import json
d2e6a577
FG
10from ceph_volume import process, conf
11from ceph_volume.util import system, constants
12
13logger = logging.getLogger(__name__)
14
15
16def create_key():
b32b8144
FG
17 stdout, stderr, returncode = process.call(
18 ['ceph-authtool', '--gen-print-key'],
19 show_command=True)
d2e6a577
FG
20 if returncode != 0:
21 raise RuntimeError('Unable to generate a new auth key')
22 return ' '.join(stdout).strip()
23
24
b32b8144
FG
25def write_keyring(osd_id, secret, keyring_name='keyring', name=None):
26 """
27 Create a keyring file with the ``ceph-authtool`` utility. Constructs the
28 path over well-known conventions for the OSD, and allows any other custom
29 ``name`` to be set.
30
31 :param osd_id: The ID for the OSD to be used
32 :param secret: The key to be added as (as a string)
33 :param name: Defaults to 'osd.{ID}' but can be used to add other client
34 names, specifically for 'lockbox' type of keys
35 :param keyring_name: Alternative keyring name, for supporting other
36 types of keys like for lockbox
37 """
38 osd_keyring = '/var/lib/ceph/osd/%s-%s/%s' % (conf.cluster, osd_id, keyring_name)
39 name = name or 'osd.%s' % str(osd_id)
d2e6a577
FG
40 process.run(
41 [
42 'ceph-authtool', osd_keyring,
43 '--create-keyring',
b32b8144 44 '--name', name,
d2e6a577
FG
45 '--add-key', secret
46 ])
47 system.chown(osd_keyring)
d2e6a577
FG
48
49
b32b8144 50def create_id(fsid, json_secrets, osd_id=None):
d2e6a577
FG
51 """
52 :param fsid: The osd fsid to create, always required
53 :param json_secrets: a json-ready object with whatever secrets are wanted
54 to be passed to the monitor
b32b8144
FG
55 :param osd_id: Reuse an existing ID from an OSD that's been destroyed, if the
56 id does not exist in the cluster a new ID will be created
d2e6a577
FG
57 """
58 bootstrap_keyring = '/var/lib/ceph/bootstrap-osd/%s.keyring' % conf.cluster
b32b8144
FG
59 cmd = [
60 'ceph',
61 '--cluster', conf.cluster,
62 '--name', 'client.bootstrap-osd',
63 '--keyring', bootstrap_keyring,
64 '-i', '-',
65 'osd', 'new', fsid
66 ]
67 if check_id(osd_id):
68 cmd.append(osd_id)
69 stdout, stderr, returncode = process.call(
70 cmd,
71 stdin=json_secrets,
72 show_command=True
73 )
74 if returncode != 0:
75 raise RuntimeError('Unable to create a new OSD id')
76 return ' '.join(stdout).strip()
77
78
79def check_id(osd_id):
80 """
81 Checks to see if an osd ID exists or not. Returns True
82 if it does exist, False if it doesn't.
83
84 :param osd_id: The osd ID to check
85 """
86 if osd_id is None:
87 return False
88 bootstrap_keyring = '/var/lib/ceph/bootstrap-osd/%s.keyring' % conf.cluster
d2e6a577
FG
89 stdout, stderr, returncode = process.call(
90 [
91 'ceph',
92 '--cluster', conf.cluster,
93 '--name', 'client.bootstrap-osd',
94 '--keyring', bootstrap_keyring,
b32b8144
FG
95 'osd',
96 'tree',
97 '-f', 'json',
d2e6a577 98 ],
b32b8144 99 show_command=True
d2e6a577
FG
100 )
101 if returncode != 0:
b32b8144
FG
102 raise RuntimeError('Unable check if OSD id exists: %s' % osd_id)
103
104 output = json.loads(''.join(stdout).strip())
105 osds = output['nodes']
106 return any([str(osd['id']) == str(osd_id) for osd in osds])
d2e6a577
FG
107
108
3efd9988
FG
109def mount_tmpfs(path):
110 process.run([
3efd9988
FG
111 'mount',
112 '-t',
113 'tmpfs', 'tmpfs',
114 path
115 ])
116
117
118def create_osd_path(osd_id, tmpfs=False):
119 path = '/var/lib/ceph/osd/%s-%s' % (conf.cluster, osd_id)
d2e6a577 120 system.mkdir_p('/var/lib/ceph/osd/%s-%s' % (conf.cluster, osd_id))
3efd9988
FG
121 if tmpfs:
122 mount_tmpfs(path)
d2e6a577
FG
123
124
125def format_device(device):
126 # only supports xfs
b32b8144 127 command = ['mkfs', '-t', 'xfs']
d2e6a577
FG
128
129 # get the mkfs options if any for xfs,
130 # fallback to the default options defined in constants.mkfs
131 flags = conf.ceph.get_list(
132 'osd',
133 'osd_mkfs_options_xfs',
134 default=constants.mkfs.get('xfs'),
135 split=' ',
136 )
137
138 # always force
139 if '-f' not in flags:
140 flags.insert(0, '-f')
141
142 command.extend(flags)
143 command.append(device)
144 process.run(command)
145
146
147def mount_osd(device, osd_id):
148 destination = '/var/lib/ceph/osd/%s-%s' % (conf.cluster, osd_id)
b32b8144 149 command = ['mount', '-t', 'xfs', '-o']
d2e6a577
FG
150 flags = conf.ceph.get_list(
151 'osd',
152 'osd_mount_options_xfs',
153 default=constants.mount.get('xfs'),
154 split=' ',
155 )
b32b8144 156 command.extend(flags)
d2e6a577
FG
157 command.append(device)
158 command.append(destination)
159 process.run(command)
160
161
3efd9988
FG
162def _link_device(device, device_type, osd_id):
163 """
164 Allow linking any device type in an OSD directory. ``device`` must the be
165 source, with an absolute path and ``device_type`` will be the destination
166 name, like 'journal', or 'block'
167 """
168 device_path = '/var/lib/ceph/osd/%s-%s/%s' % (
d2e6a577 169 conf.cluster,
3efd9988
FG
170 osd_id,
171 device_type
d2e6a577 172 )
b32b8144 173 command = ['ln', '-s', device, device_path]
3efd9988
FG
174 system.chown(device)
175
d2e6a577
FG
176 process.run(command)
177
178
3efd9988
FG
179def link_journal(journal_device, osd_id):
180 _link_device(journal_device, 'journal', osd_id)
181
182
183def link_block(block_device, osd_id):
184 _link_device(block_device, 'block', osd_id)
185
186
187def link_wal(wal_device, osd_id):
188 _link_device(wal_device, 'block.wal', osd_id)
189
190
191def link_db(db_device, osd_id):
192 _link_device(db_device, 'block.db', osd_id)
193
194
d2e6a577
FG
195def get_monmap(osd_id):
196 """
197 Before creating the OSD files, a monmap needs to be retrieved so that it
198 can be used to tell the monitor(s) about the new OSD. A call will look like::
199
200 ceph --cluster ceph --name client.bootstrap-osd \
201 --keyring /var/lib/ceph/bootstrap-osd/ceph.keyring \
202 mon getmap -o /var/lib/ceph/osd/ceph-0/activate.monmap
203 """
204 path = '/var/lib/ceph/osd/%s-%s/' % (conf.cluster, osd_id)
205 bootstrap_keyring = '/var/lib/ceph/bootstrap-osd/%s.keyring' % conf.cluster
206 monmap_destination = os.path.join(path, 'activate.monmap')
207
208 process.run([
d2e6a577
FG
209 'ceph',
210 '--cluster', conf.cluster,
211 '--name', 'client.bootstrap-osd',
212 '--keyring', bootstrap_keyring,
213 'mon', 'getmap', '-o', monmap_destination
214 ])
215
216
3efd9988
FG
217def osd_mkfs_bluestore(osd_id, fsid, keyring=None, wal=False, db=False):
218 """
219 Create the files for the OSD to function. A normal call will look like:
220
221 ceph-osd --cluster ceph --mkfs --mkkey -i 0 \
222 --monmap /var/lib/ceph/osd/ceph-0/activate.monmap \
223 --osd-data /var/lib/ceph/osd/ceph-0 \
224 --osd-uuid 8d208665-89ae-4733-8888-5d3bfbeeec6c \
225 --keyring /var/lib/ceph/osd/ceph-0/keyring \
226 --setuser ceph --setgroup ceph
227
228 In some cases it is required to use the keyring, when it is passed in as
229 a keywork argument it is used as part of the ceph-osd command
230 """
231 path = '/var/lib/ceph/osd/%s-%s/' % (conf.cluster, osd_id)
232 monmap = os.path.join(path, 'activate.monmap')
233
234 system.chown(path)
235
236 base_command = [
3efd9988
FG
237 'ceph-osd',
238 '--cluster', conf.cluster,
239 # undocumented flag, sets the `type` file to contain 'bluestore'
240 '--osd-objectstore', 'bluestore',
241 '--mkfs',
242 '-i', osd_id,
243 '--monmap', monmap,
244 ]
245
246 supplementary_command = [
247 '--osd-data', path,
248 '--osd-uuid', fsid,
249 '--setuser', 'ceph',
250 '--setgroup', 'ceph'
251 ]
252
253 if keyring is not None:
b32b8144 254 base_command.extend(['--keyfile', '-'])
3efd9988
FG
255
256 if wal:
257 base_command.extend(
258 ['--bluestore-block-wal-path', wal]
259 )
260 system.chown(wal)
261
262 if db:
263 base_command.extend(
264 ['--bluestore-block-db-path', db]
265 )
266 system.chown(db)
267
268 command = base_command + supplementary_command
269
b32b8144 270 process.call(command, stdin=keyring, show_command=True)
3efd9988
FG
271
272
273def osd_mkfs_filestore(osd_id, fsid):
d2e6a577
FG
274 """
275 Create the files for the OSD to function. A normal call will look like:
276
277 ceph-osd --cluster ceph --mkfs --mkkey -i 0 \
278 --monmap /var/lib/ceph/osd/ceph-0/activate.monmap \
279 --osd-data /var/lib/ceph/osd/ceph-0 \
280 --osd-journal /var/lib/ceph/osd/ceph-0/journal \
281 --osd-uuid 8d208665-89ae-4733-8888-5d3bfbeeec6c \
282 --keyring /var/lib/ceph/osd/ceph-0/keyring \
283 --setuser ceph --setgroup ceph
284
285 """
286 path = '/var/lib/ceph/osd/%s-%s/' % (conf.cluster, osd_id)
287 monmap = os.path.join(path, 'activate.monmap')
288 journal = os.path.join(path, 'journal')
289
290 system.chown(journal)
291 system.chown(path)
292
293 process.run([
d2e6a577
FG
294 'ceph-osd',
295 '--cluster', conf.cluster,
3efd9988
FG
296 # undocumented flag, sets the `type` file to contain 'filestore'
297 '--osd-objectstore', 'filestore',
d2e6a577
FG
298 '--mkfs',
299 '-i', osd_id,
300 '--monmap', monmap,
301 '--osd-data', path,
302 '--osd-journal', journal,
303 '--osd-uuid', fsid,
304 '--setuser', 'ceph',
305 '--setgroup', 'ceph'
306 ])