]> git.proxmox.com Git - ceph.git/blame - ceph/src/ceph-volume/ceph_volume/devices/lvm/prepare.py
bump version to 12.2.0-pve1
[ceph.git] / ceph / src / ceph-volume / ceph_volume / devices / lvm / prepare.py
CommitLineData
d2e6a577
FG
1from __future__ import print_function
2import json
3import os
4from textwrap import dedent
5from ceph_volume.util import prepare as prepare_utils
6from ceph_volume.util import system
7from ceph_volume import conf, decorators
8from . import api
9from .common import prepare_parser
10
11
d2e6a577
FG
12def prepare_filestore(device, journal, secrets, id_=None, fsid=None):
13 """
14 :param device: The name of the volume group or lvm to work with
15 :param journal: similar to device but can also be a regular/plain disk
16 :param secrets: A dict with the secrets needed to create the osd (e.g. cephx)
17 :param id_: The OSD id
18 :param fsid: The OSD fsid, also known as the OSD UUID
19 """
20 cephx_secret = secrets.get('cephx_secret', prepare_utils.create_key())
21 json_secrets = json.dumps(secrets)
22
23 # allow re-using an existing fsid, in case prepare failed
24 fsid = fsid or system.generate_uuid()
25 # allow re-using an id, in case a prepare failed
26 osd_id = id_ or prepare_utils.create_id(fsid, json_secrets)
27 # create the directory
28 prepare_utils.create_path(osd_id)
29 # format the device
30 prepare_utils.format_device(device)
31 # mount the data device
32 prepare_utils.mount_osd(device, osd_id)
33 # symlink the journal
34 prepare_utils.link_journal(journal, osd_id)
35 # get the latest monmap
36 prepare_utils.get_monmap(osd_id)
37 # prepare the osd filesystem
38 prepare_utils.osd_mkfs(osd_id, fsid)
39 # write the OSD keyring if it doesn't exist already
40 prepare_utils.write_keyring(osd_id, cephx_secret)
41
42
43def prepare_bluestore():
44 raise NotImplemented()
45
46
47class Prepare(object):
48
49 help = 'Format an LVM device and associate it with an OSD'
50
51 def __init__(self, argv):
52 self.argv = argv
53
b5b8bbf5
FG
54 def get_journal_lv(self, argument):
55 """
56 Perform some parsing of the value of ``--journal`` so that the process
57 can determine correctly if it got a device path or an lv
58 :param argument: The value of ``--journal``, that will need to be split
59 to retrieve the actual lv
60 """
61 try:
62 vg_name, lv_name = argument.split('/')
63 except (ValueError, AttributeError):
64 return None
65 return api.get_lv(lv_name=lv_name, vg_name=vg_name)
66
d2e6a577
FG
67 @decorators.needs_root
68 def prepare(self, args):
69 # FIXME we don't allow re-using a keyring, we always generate one for the
70 # OSD, this needs to be fixed. This could either be a file (!) or a string
71 # (!!) or some flags that we would need to compound into a dict so that we
72 # can convert to JSON (!!!)
73 secrets = {'cephx_secret': prepare_utils.create_key()}
74
75 cluster_fsid = conf.ceph.get('global', 'fsid')
76 fsid = args.osd_fsid or system.generate_uuid()
77 #osd_id = args.osd_id or prepare_utils.create_id(fsid)
78 # allow re-using an id, in case a prepare failed
79 osd_id = args.osd_id or prepare_utils.create_id(fsid, json.dumps(secrets))
b5b8bbf5 80 vg_name, lv_name = args.data.split('/')
d2e6a577 81 if args.filestore:
b5b8bbf5 82 data_lv = api.get_lv(lv_name=lv_name, vg_name=vg_name)
d2e6a577 83
d2e6a577
FG
84 # we must have either an existing data_lv or a newly created, so lets make
85 # sure that the tags are correct
86 if not data_lv:
87 raise RuntimeError('no data logical volume found with: %s' % args.data)
b5b8bbf5
FG
88
89 if not args.journal:
90 raise RuntimeError('--journal is required when using --filestore')
91 journal_device = None
92 journal_lv = self.get_journal_lv(args.journal)
93
94 # check if we have an actual path to a device, which is allowed
95 if not journal_lv:
96 if os.path.exists(args.journal):
97 journal_device = args.journal
98 else:
99 raise RuntimeError(
100 '--journal specified an invalid or non-existent device: %s' % args.journal
101 )
102 # Otherwise the journal_device is the path to the lv
103 else:
104 journal_device = journal_lv.lv_path
105 journal_lv.set_tags({
106 'ceph.type': 'journal',
107 'ceph.osd_fsid': fsid,
108 'ceph.osd_id': osd_id,
109 'ceph.cluster_fsid': cluster_fsid,
110 'ceph.journal_device': journal_device,
111 'ceph.data_device': data_lv.lv_path,
112 })
113
d2e6a577
FG
114 data_lv.set_tags({
115 'ceph.type': 'data',
116 'ceph.osd_fsid': fsid,
117 'ceph.osd_id': osd_id,
118 'ceph.cluster_fsid': cluster_fsid,
119 'ceph.journal_device': journal_device,
120 'ceph.data_device': data_lv.lv_path,
121 })
122
123 prepare_filestore(
124 data_lv.lv_path,
125 journal_device,
126 secrets,
127 id_=osd_id,
128 fsid=fsid,
129 )
130 elif args.bluestore:
131 prepare_bluestore(args)
132
133 def main(self):
134 sub_command_help = dedent("""
135 Prepare an OSD by assigning an ID and FSID, registering them with the
136 cluster with an ID and FSID, formatting and mounting the volume, and
137 finally by adding all the metadata to the logical volumes using LVM
138 tags, so that it can later be discovered.
139
140 Once the OSD is ready, an ad-hoc systemd unit will be enabled so that
141 it can later get activated and the OSD daemon can get started.
142
143 Most basic Usage looks like (journal will be collocated from the same volume group):
144
145 ceph-volume lvm prepare --data {volume group name}
146
147
148 Example calls for supported scenarios:
149
150 Dedicated volume group for Journal(s)
151 -------------------------------------
152
153 Existing logical volume (lv) or device:
154
155 ceph-volume lvm prepare --data {logical volume} --journal /path/to/{lv}|{device}
156
157 Or:
158
159 ceph-volume lvm prepare --data {data volume group} --journal {journal volume group}
160
161 Collocated (same group) for data and journal
162 --------------------------------------------
163
164 ceph-volume lvm prepare --data {volume group}
165
166 """)
167 parser = prepare_parser(
168 prog='ceph-volume lvm prepare',
169 description=sub_command_help,
170 )
171 if len(self.argv) == 0:
172 print(sub_command_help)
173 return
174 args = parser.parse_args(self.argv)
175 self.prepare(args)