]>
git.proxmox.com Git - ceph.git/blob - ceph/src/ceph-volume/ceph_volume/devices/raw/prepare.py
1 from __future__
import print_function
5 from textwrap
import dedent
6 from ceph_volume
.util
import prepare
as prepare_utils
7 from ceph_volume
.util
import encryption
as encryption_utils
8 from ceph_volume
.util
import disk
9 from ceph_volume
.util
import system
10 from ceph_volume
import decorators
, terminal
11 from ceph_volume
.devices
.lvm
.common
import rollback_osd
12 from .common
import create_parser
14 logger
= logging
.getLogger(__name__
)
16 def prepare_dmcrypt(key
, device
, device_type
, fsid
):
18 Helper for devices that are encrypted. The operations needed for
19 block, db, wal, devices are all the same
23 kname
= disk
.lsblk(device
)['KNAME']
24 mapping
= 'ceph-{}-{}-{}-dmcrypt'.format(fsid
, kname
, device_type
)
26 encryption_utils
.luks_format(
30 encryption_utils
.luks_open(
36 return '/dev/mapper/{}'.format(mapping
)
38 def prepare_bluestore(block
, wal
, db
, secrets
, osd_id
, fsid
, tmpfs
):
40 :param block: The name of the logical volume for the bluestore data
41 :param wal: a regular/plain disk or logical volume, to be used for block.wal
42 :param db: a regular/plain disk or logical volume, to be used for block.db
43 :param secrets: A dict with the secrets needed to create the osd (e.g. cephx)
44 :param id_: The OSD id
45 :param fsid: The OSD fsid, also known as the OSD UUID
47 cephx_secret
= secrets
.get('cephx_secret', prepare_utils
.create_key())
49 if secrets
.get('dmcrypt_key'):
50 key
= secrets
['dmcrypt_key']
51 block
= prepare_dmcrypt(key
, block
, 'block', fsid
)
52 wal
= prepare_dmcrypt(key
, wal
, 'wal', fsid
)
53 db
= prepare_dmcrypt(key
, db
, 'db', fsid
)
55 # create the directory
56 prepare_utils
.create_osd_path(osd_id
, tmpfs
=tmpfs
)
58 prepare_utils
.link_block(block
, osd_id
)
59 # get the latest monmap
60 prepare_utils
.get_monmap(osd_id
)
61 # write the OSD keyring if it doesn't exist already
62 prepare_utils
.write_keyring(osd_id
, cephx_secret
)
63 # prepare the osd filesystem
64 prepare_utils
.osd_mkfs_bluestore(
72 class Prepare(object):
74 help = 'Format a raw device and associate it with a (BlueStore) OSD'
76 def __init__(self
, argv
):
80 def safe_prepare(self
, args
=None):
82 An intermediate step between `main()` and `prepare()` so that we can
83 capture the `self.osd_id` in case we need to rollback
85 :param args: Injected args, usually from `raw create` which compounds
86 both `prepare` and `create`
93 logger
.exception('raw prepare was unable to complete')
94 logger
.info('will rollback OSD ID creation')
95 rollback_osd(self
.args
, self
.osd_id
)
97 dmcrypt_log
= 'dmcrypt' if args
.dmcrypt
else 'clear'
98 terminal
.success("ceph-volume raw {} prepare successful for: {}".format(dmcrypt_log
, self
.args
.data
))
101 @decorators.needs_root
103 secrets
= {'cephx_secret': prepare_utils
.create_key()}
104 encrypted
= 1 if self
.args
.dmcrypt
else 0
105 cephx_lockbox_secret
= '' if not encrypted
else prepare_utils
.create_key()
108 secrets
['dmcrypt_key'] = os
.getenv('CEPH_VOLUME_DMCRYPT_SECRET')
109 secrets
['cephx_lockbox_secret'] = cephx_lockbox_secret
# dummy value to make `ceph osd new` not complaining
111 osd_fsid
= system
.generate_uuid()
112 crush_device_class
= self
.args
.crush_device_class
113 if crush_device_class
:
114 secrets
['crush_device_class'] = crush_device_class
115 tmpfs
= not self
.args
.no_tmpfs
118 if self
.args
.block_wal
:
119 wal
= self
.args
.block_wal
120 if self
.args
.block_db
:
121 db
= self
.args
.block_db
123 # reuse a given ID if it exists, otherwise create a new ID
124 self
.osd_id
= prepare_utils
.create_id(
125 osd_fsid
, json
.dumps(secrets
))
138 sub_command_help
= dedent("""
139 Prepare an OSD by assigning an ID and FSID, registering them with the
140 cluster with an ID and FSID, formatting the volume.
142 Once the OSD is ready, an ad-hoc systemd unit will be enabled so that
143 it can later get activated and the OSD daemon can get started.
145 ceph-volume raw prepare --bluestore --data {device}
147 DB and WAL devices are supported.
149 ceph-volume raw prepare --bluestore --data {device} --block.db {device} --block.wal {device}
152 parser
= create_parser(
153 prog
='ceph-volume raw prepare',
154 description
=sub_command_help
,
157 print(sub_command_help
)
159 self
.args
= parser
.parse_args(self
.argv
)
160 if not self
.args
.bluestore
:
161 terminal
.error('must specify --bluestore (currently the only supported backend)')
163 if self
.args
.dmcrypt
and not os
.getenv('CEPH_VOLUME_DMCRYPT_SECRET'):
164 terminal
.error('encryption was requested (--dmcrypt) but environment variable ' \
165 'CEPH_VOLUME_DMCRYPT_SECRET is not set, you must set ' \
166 'this variable to provide a dmcrypt secret.')
169 self
.safe_prepare(self
.args
)