]>
git.proxmox.com Git - ceph.git/blob - ceph/src/ceph-volume/ceph_volume/util/prepare.py
2 These utilities for prepare provide all the pieces needed to prepare a device
3 but also a compounded ("single call") helper to do them in order. Some plugins
4 may want to change some part of the process, while others might want to consume
10 from ceph_volume
import process
, conf
11 from ceph_volume
.util
import system
, constants
13 logger
= logging
.getLogger(__name__
)
17 stdout
, stderr
, returncode
= process
.call(
18 ['ceph-authtool', '--gen-print-key'],
21 raise RuntimeError('Unable to generate a new auth key')
22 return ' '.join(stdout
).strip()
25 def write_keyring(osd_id
, secret
, keyring_name
='keyring', name
=None):
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
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
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
)
42 'ceph-authtool', osd_keyring
,
47 system
.chown(osd_keyring
)
50 def create_id(fsid
, json_secrets
, osd_id
=None):
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
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
58 bootstrap_keyring
= '/var/lib/ceph/bootstrap-osd/%s.keyring' % conf
.cluster
61 '--cluster', conf
.cluster
,
62 '--name', 'client.bootstrap-osd',
63 '--keyring', bootstrap_keyring
,
69 stdout
, stderr
, returncode
= process
.call(
75 raise RuntimeError('Unable to create a new OSD id')
76 return ' '.join(stdout
).strip()
81 Checks to see if an osd ID exists or not. Returns True
82 if it does exist, False if it doesn't.
84 :param osd_id: The osd ID to check
88 bootstrap_keyring
= '/var/lib/ceph/bootstrap-osd/%s.keyring' % conf
.cluster
89 stdout
, stderr
, returncode
= process
.call(
92 '--cluster', conf
.cluster
,
93 '--name', 'client.bootstrap-osd',
94 '--keyring', bootstrap_keyring
,
102 raise RuntimeError('Unable check if OSD id exists: %s' % osd_id
)
104 output
= json
.loads(''.join(stdout
).strip())
105 osds
= output
['nodes']
106 return any([str(osd
['id']) == str(osd_id
) for osd
in osds
])
109 def mount_tmpfs(path
):
118 def create_osd_path(osd_id
, tmpfs
=False):
119 path
= '/var/lib/ceph/osd/%s-%s' % (conf
.cluster
, osd_id
)
120 system
.mkdir_p('/var/lib/ceph/osd/%s-%s' % (conf
.cluster
, osd_id
))
125 def format_device(device
):
127 command
= ['mkfs', '-t', 'xfs']
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(
133 'osd_mkfs_options_xfs',
134 default
=constants
.mkfs
.get('xfs'),
139 if '-f' not in flags
:
140 flags
.insert(0, '-f')
142 command
.extend(flags
)
143 command
.append(device
)
147 def _normalize_mount_flags(flags
, extras
=None):
149 Mount flag options have to be a single string, separated by a comma. If the
150 flags are separated by spaces, or with commas and spaces in ceph.conf, the
151 mount options will be passed incorrectly.
153 This will help when parsing ceph.conf values return something like::
161 :param flags: A list of flags, or a single string of mount flags
162 :param extras: Extra set of mount flags, useful when custom devices like VDO need
163 ad-hoc mount configurations
165 # Instead of using set(), we append to this new list here, because set()
166 # will create an arbitrary order on the items that is made worst when
167 # testing with tools like tox that includes a randomizer seed. By
168 # controlling the order, it is easier to correctly assert the expectation
170 if isinstance(flags
, list):
174 # ensure that spaces and commas are removed so that they can join
175 # correctly, remove duplicates
177 if f
and f
not in unique_flags
:
178 unique_flags
.append(f
.strip().strip(','))
179 return ','.join(unique_flags
)
181 # split them, clean them, and join them back again
182 flags
= flags
.strip().split(' ')
186 # remove possible duplicates
188 if f
and f
not in unique_flags
:
189 unique_flags
.append(f
.strip().strip(','))
190 flags
= ','.join(unique_flags
)
191 # Before returning, split them again, since strings can be mashed up
192 # together, preventing removal of duplicate entries
193 return ','.join(set(flags
.split(',')))
196 def mount_osd(device
, osd_id
, **kw
):
198 is_vdo
= kw
.get('is_vdo', '0')
201 destination
= '/var/lib/ceph/osd/%s-%s' % (conf
.cluster
, osd_id
)
202 command
= ['mount', '-t', 'xfs', '-o']
203 flags
= conf
.ceph
.get_list(
205 'osd_mount_options_xfs',
206 default
=constants
.mount
.get('xfs'),
210 _normalize_mount_flags(flags
, extras
=extras
)
212 command
.append(device
)
213 command
.append(destination
)
217 def _link_device(device
, device_type
, osd_id
):
219 Allow linking any device type in an OSD directory. ``device`` must the be
220 source, with an absolute path and ``device_type`` will be the destination
221 name, like 'journal', or 'block'
223 device_path
= '/var/lib/ceph/osd/%s-%s/%s' % (
228 command
= ['ln', '-s', device
, device_path
]
234 def link_journal(journal_device
, osd_id
):
235 _link_device(journal_device
, 'journal', osd_id
)
238 def link_block(block_device
, osd_id
):
239 _link_device(block_device
, 'block', osd_id
)
242 def link_wal(wal_device
, osd_id
):
243 _link_device(wal_device
, 'block.wal', osd_id
)
246 def link_db(db_device
, osd_id
):
247 _link_device(db_device
, 'block.db', osd_id
)
250 def get_monmap(osd_id
):
252 Before creating the OSD files, a monmap needs to be retrieved so that it
253 can be used to tell the monitor(s) about the new OSD. A call will look like::
255 ceph --cluster ceph --name client.bootstrap-osd \
256 --keyring /var/lib/ceph/bootstrap-osd/ceph.keyring \
257 mon getmap -o /var/lib/ceph/osd/ceph-0/activate.monmap
259 path
= '/var/lib/ceph/osd/%s-%s/' % (conf
.cluster
, osd_id
)
260 bootstrap_keyring
= '/var/lib/ceph/bootstrap-osd/%s.keyring' % conf
.cluster
261 monmap_destination
= os
.path
.join(path
, 'activate.monmap')
265 '--cluster', conf
.cluster
,
266 '--name', 'client.bootstrap-osd',
267 '--keyring', bootstrap_keyring
,
268 'mon', 'getmap', '-o', monmap_destination
272 def osd_mkfs_bluestore(osd_id
, fsid
, keyring
=None, wal
=False, db
=False):
274 Create the files for the OSD to function. A normal call will look like:
276 ceph-osd --cluster ceph --mkfs --mkkey -i 0 \
277 --monmap /var/lib/ceph/osd/ceph-0/activate.monmap \
278 --osd-data /var/lib/ceph/osd/ceph-0 \
279 --osd-uuid 8d208665-89ae-4733-8888-5d3bfbeeec6c \
280 --keyring /var/lib/ceph/osd/ceph-0/keyring \
281 --setuser ceph --setgroup ceph
283 In some cases it is required to use the keyring, when it is passed in as
284 a keywork argument it is used as part of the ceph-osd command
286 path
= '/var/lib/ceph/osd/%s-%s/' % (conf
.cluster
, osd_id
)
287 monmap
= os
.path
.join(path
, 'activate.monmap')
293 '--cluster', conf
.cluster
,
294 # undocumented flag, sets the `type` file to contain 'bluestore'
295 '--osd-objectstore', 'bluestore',
301 supplementary_command
= [
308 if keyring
is not None:
309 base_command
.extend(['--keyfile', '-'])
313 ['--bluestore-block-wal-path', wal
]
319 ['--bluestore-block-db-path', db
]
323 command
= base_command
+ supplementary_command
325 _
, _
, returncode
= process
.call(command
, stdin
=keyring
, show_command
=True)
327 raise RuntimeError('Command failed with exit code %s: %s' % (returncode
, ' '.join(command
)))
330 def osd_mkfs_filestore(osd_id
, fsid
):
332 Create the files for the OSD to function. A normal call will look like:
334 ceph-osd --cluster ceph --mkfs --mkkey -i 0 \
335 --monmap /var/lib/ceph/osd/ceph-0/activate.monmap \
336 --osd-data /var/lib/ceph/osd/ceph-0 \
337 --osd-journal /var/lib/ceph/osd/ceph-0/journal \
338 --osd-uuid 8d208665-89ae-4733-8888-5d3bfbeeec6c \
339 --keyring /var/lib/ceph/osd/ceph-0/keyring \
340 --setuser ceph --setgroup ceph
343 path
= '/var/lib/ceph/osd/%s-%s/' % (conf
.cluster
, osd_id
)
344 monmap
= os
.path
.join(path
, 'activate.monmap')
345 journal
= os
.path
.join(path
, 'journal')
347 system
.chown(journal
)
352 '--cluster', conf
.cluster
,
353 # undocumented flag, sets the `type` file to contain 'filestore'
354 '--osd-objectstore', 'filestore',
359 '--osd-journal', journal
,