Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / ceph-volume / ceph_volume / util / prepare.py
1 """
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
5 the single-call helper
6 """
7 import os
8 import logging
9 from ceph_volume import process, conf
10 from ceph_volume.util import system, constants
11
12 logger = logging.getLogger(__name__)
13
14
15 def create_key():
16     stdout, stderr, returncode = process.call(['ceph-authtool', '--gen-print-key'])
17     if returncode != 0:
18         raise RuntimeError('Unable to generate a new auth key')
19     return ' '.join(stdout).strip()
20
21
22 def write_keyring(osd_id, secret):
23     # FIXME this only works for cephx, but there will be other types of secrets
24     # later
25     osd_keyring = '/var/lib/ceph/osd/%s-%s/keyring' % (conf.cluster, osd_id)
26     process.run(
27         [
28             'ceph-authtool', osd_keyring,
29             '--create-keyring',
30             '--name', 'osd.%s' % str(osd_id),
31             '--add-key', secret
32         ])
33     system.chown(osd_keyring)
34     # TODO: do the restorecon dance on the osd_keyring path
35
36
37 def create_id(fsid, json_secrets):
38     """
39     :param fsid: The osd fsid to create, always required
40     :param json_secrets: a json-ready object with whatever secrets are wanted
41                          to be passed to the monitor
42     """
43     bootstrap_keyring = '/var/lib/ceph/bootstrap-osd/%s.keyring' % conf.cluster
44     stdout, stderr, returncode = process.call(
45         [
46             'ceph',
47             '--cluster', conf.cluster,
48             '--name', 'client.bootstrap-osd',
49             '--keyring', bootstrap_keyring,
50             '-i', '-',
51             'osd', 'new', fsid
52         ],
53         stdin=json_secrets
54     )
55     if returncode != 0:
56         raise RuntimeError('Unable to create a new OSD id')
57     return ' '.join(stdout).strip()
58
59
60 def mount_tmpfs(path):
61     process.run([
62         'mount',
63         '-t',
64         'tmpfs', 'tmpfs',
65         path
66     ])
67
68
69 def create_osd_path(osd_id, tmpfs=False):
70     path = '/var/lib/ceph/osd/%s-%s' % (conf.cluster, osd_id)
71     system.mkdir_p('/var/lib/ceph/osd/%s-%s' % (conf.cluster, osd_id))
72     if tmpfs:
73         mount_tmpfs(path)
74
75
76 def format_device(device):
77     # only supports xfs
78     command = ['mkfs', '-t', 'xfs']
79
80     # get the mkfs options if any for xfs,
81     # fallback to the default options defined in constants.mkfs
82     flags = conf.ceph.get_list(
83         'osd',
84         'osd_mkfs_options_xfs',
85         default=constants.mkfs.get('xfs'),
86         split=' ',
87     )
88
89     # always force
90     if '-f' not in flags:
91         flags.insert(0, '-f')
92
93     command.extend(flags)
94     command.append(device)
95     process.run(command)
96
97
98 def mount_osd(device, osd_id):
99     destination = '/var/lib/ceph/osd/%s-%s' % (conf.cluster, osd_id)
100     command = ['mount', '-t', 'xfs', '-o']
101     flags = conf.ceph.get_list(
102         'osd',
103         'osd_mount_options_xfs',
104         default=constants.mount.get('xfs'),
105         split=' ',
106     )
107     command.append(flags)
108     command.append(device)
109     command.append(destination)
110     process.run(command)
111
112
113 def _link_device(device, device_type, osd_id):
114     """
115     Allow linking any device type in an OSD directory. ``device`` must the be
116     source, with an absolute path and ``device_type`` will be the destination
117     name, like 'journal', or 'block'
118     """
119     device_path = '/var/lib/ceph/osd/%s-%s/%s' % (
120         conf.cluster,
121         osd_id,
122         device_type
123     )
124     command = ['ln', '-s', device, device_path]
125     system.chown(device)
126
127     process.run(command)
128
129
130 def link_journal(journal_device, osd_id):
131     _link_device(journal_device, 'journal', osd_id)
132
133
134 def link_block(block_device, osd_id):
135     _link_device(block_device, 'block', osd_id)
136
137
138 def link_wal(wal_device, osd_id):
139     _link_device(wal_device, 'block.wal', osd_id)
140
141
142 def link_db(db_device, osd_id):
143     _link_device(db_device, 'block.db', osd_id)
144
145
146 def get_monmap(osd_id):
147     """
148     Before creating the OSD files, a monmap needs to be retrieved so that it
149     can be used to tell the monitor(s) about the new OSD. A call will look like::
150
151         ceph --cluster ceph --name client.bootstrap-osd \
152              --keyring /var/lib/ceph/bootstrap-osd/ceph.keyring \
153              mon getmap -o /var/lib/ceph/osd/ceph-0/activate.monmap
154     """
155     path = '/var/lib/ceph/osd/%s-%s/' % (conf.cluster, osd_id)
156     bootstrap_keyring = '/var/lib/ceph/bootstrap-osd/%s.keyring' % conf.cluster
157     monmap_destination = os.path.join(path, 'activate.monmap')
158
159     process.run([
160         'ceph',
161         '--cluster', conf.cluster,
162         '--name', 'client.bootstrap-osd',
163         '--keyring', bootstrap_keyring,
164         'mon', 'getmap', '-o', monmap_destination
165     ])
166
167
168 def osd_mkfs_bluestore(osd_id, fsid, keyring=None, wal=False, db=False):
169     """
170     Create the files for the OSD to function. A normal call will look like:
171
172           ceph-osd --cluster ceph --mkfs --mkkey -i 0 \
173                    --monmap /var/lib/ceph/osd/ceph-0/activate.monmap \
174                    --osd-data /var/lib/ceph/osd/ceph-0 \
175                    --osd-uuid 8d208665-89ae-4733-8888-5d3bfbeeec6c \
176                    --keyring /var/lib/ceph/osd/ceph-0/keyring \
177                    --setuser ceph --setgroup ceph
178
179     In some cases it is required to use the keyring, when it is passed in as
180     a keywork argument it is used as part of the ceph-osd command
181     """
182     path = '/var/lib/ceph/osd/%s-%s/' % (conf.cluster, osd_id)
183     monmap = os.path.join(path, 'activate.monmap')
184
185     system.chown(path)
186
187     base_command = [
188         'ceph-osd',
189         '--cluster', conf.cluster,
190         # undocumented flag, sets the `type` file to contain 'bluestore'
191         '--osd-objectstore', 'bluestore',
192         '--mkfs',
193         '-i', osd_id,
194         '--monmap', monmap,
195     ]
196
197     supplementary_command = [
198         '--osd-data', path,
199         '--osd-uuid', fsid,
200         '--setuser', 'ceph',
201         '--setgroup', 'ceph'
202     ]
203
204     if keyring is not None:
205         base_command.extend(['--key', keyring])
206
207     if wal:
208         base_command.extend(
209             ['--bluestore-block-wal-path', wal]
210         )
211         system.chown(wal)
212
213     if db:
214         base_command.extend(
215             ['--bluestore-block-db-path', db]
216         )
217         system.chown(db)
218
219     command = base_command + supplementary_command
220
221     process.run(command, obfuscate='--key')
222
223
224 def osd_mkfs_filestore(osd_id, fsid):
225     """
226     Create the files for the OSD to function. A normal call will look like:
227
228           ceph-osd --cluster ceph --mkfs --mkkey -i 0 \
229                    --monmap /var/lib/ceph/osd/ceph-0/activate.monmap \
230                    --osd-data /var/lib/ceph/osd/ceph-0 \
231                    --osd-journal /var/lib/ceph/osd/ceph-0/journal \
232                    --osd-uuid 8d208665-89ae-4733-8888-5d3bfbeeec6c \
233                    --keyring /var/lib/ceph/osd/ceph-0/keyring \
234                    --setuser ceph --setgroup ceph
235
236     """
237     path = '/var/lib/ceph/osd/%s-%s/' % (conf.cluster, osd_id)
238     monmap = os.path.join(path, 'activate.monmap')
239     journal = os.path.join(path, 'journal')
240
241     system.chown(journal)
242     system.chown(path)
243
244     process.run([
245         'ceph-osd',
246         '--cluster', conf.cluster,
247         # undocumented flag, sets the `type` file to contain 'filestore'
248         '--osd-objectstore', 'filestore',
249         '--mkfs',
250         '-i', osd_id,
251         '--monmap', monmap,
252         '--osd-data', path,
253         '--osd-journal', journal,
254         '--osd-uuid', fsid,
255         '--setuser', 'ceph',
256         '--setgroup', 'ceph'
257     ])