]>
git.proxmox.com Git - ceph.git/blob - ceph/src/ceph-volume/ceph_volume/devices/lvm/prepare.py
1 from __future__
import print_function
4 from textwrap
import dedent
5 from ceph_volume
.util
import prepare
as prepare_utils
6 from ceph_volume
.util
import system
7 from ceph_volume
import conf
, decorators
9 from .common
import prepare_parser
12 def canonical_device_path(device
):
14 Ensure that a device is canonical (full path) and that it exists so that
15 it can be used throughout the prepare/activate process
17 # FIXME: this is obviously super naive
18 inferred
= os
.path
.join('/dev', device
)
19 if os
.path
.exists(os
.path
.abspath(device
)):
21 elif os
.path
.exists(inferred
):
23 raise RuntimeError('Selected device does not exist: %s' % device
)
26 def prepare_filestore(device
, journal
, secrets
, id_
=None, fsid
=None):
28 :param device: The name of the volume group or lvm to work with
29 :param journal: similar to device but can also be a regular/plain disk
30 :param secrets: A dict with the secrets needed to create the osd (e.g. cephx)
31 :param id_: The OSD id
32 :param fsid: The OSD fsid, also known as the OSD UUID
34 cephx_secret
= secrets
.get('cephx_secret', prepare_utils
.create_key())
35 json_secrets
= json
.dumps(secrets
)
37 # allow re-using an existing fsid, in case prepare failed
38 fsid
= fsid
or system
.generate_uuid()
39 # allow re-using an id, in case a prepare failed
40 osd_id
= id_
or prepare_utils
.create_id(fsid
, json_secrets
)
41 # create the directory
42 prepare_utils
.create_path(osd_id
)
44 prepare_utils
.format_device(device
)
45 # mount the data device
46 prepare_utils
.mount_osd(device
, osd_id
)
48 prepare_utils
.link_journal(journal
, osd_id
)
49 # get the latest monmap
50 prepare_utils
.get_monmap(osd_id
)
51 # prepare the osd filesystem
52 prepare_utils
.osd_mkfs(osd_id
, fsid
)
53 # write the OSD keyring if it doesn't exist already
54 prepare_utils
.write_keyring(osd_id
, cephx_secret
)
57 def prepare_bluestore():
58 raise NotImplemented()
61 class Prepare(object):
63 help = 'Format an LVM device and associate it with an OSD'
65 def __init__(self
, argv
):
68 @decorators.needs_root
69 def prepare(self
, args
):
70 # FIXME we don't allow re-using a keyring, we always generate one for the
71 # OSD, this needs to be fixed. This could either be a file (!) or a string
72 # (!!) or some flags that we would need to compound into a dict so that we
73 # can convert to JSON (!!!)
74 secrets
= {'cephx_secret': prepare_utils
.create_key()}
76 cluster_fsid
= conf
.ceph
.get('global', 'fsid')
77 fsid
= args
.osd_fsid
or system
.generate_uuid()
78 #osd_id = args.osd_id or prepare_utils.create_id(fsid)
79 # allow re-using an id, in case a prepare failed
80 osd_id
= args
.osd_id
or prepare_utils
.create_id(fsid
, json
.dumps(secrets
))
81 journal_name
= "journal_%s" % fsid
82 osd_name
= "osd_%s" % fsid
85 data_vg
= api
.get_vg(vg_name
=args
.data
)
86 data_lv
= api
.get_lv(lv_name
=args
.data
)
87 journal_vg
= api
.get_vg(vg_name
=args
.journal
)
88 journal_lv
= api
.get_lv(lv_name
=args
.journal
)
90 # it is possible to pass a device as a journal that is not
91 # an actual logical volume (or group)
94 raise RuntimeError('--journal is required when not using a vg for OSD data')
95 # collocated: carve out the journal from the data vg
97 journal_lv
= api
.create_lv(
100 size
=args
.journal_size
,
104 cluster_fsid
=cluster_fsid
107 # if a volume group was defined for the journal create that first
109 journal_lv
= api
.create_lv(
112 size
=args
.journal_size
,
116 cluster_fsid
=cluster_fsid
119 journal_device
= journal_lv
.lv_path
120 # The journal is probably a device, not in LVM
122 journal_device
= canonical_device_path(args
.journal
)
123 # At this point we must have a journal_lv or a journal device
124 # now create the osd from the group if that was found
126 # XXX make sure that a there aren't more OSDs than physical
127 # devices from this volume group
128 data_lv
= api
.create_lv(
134 journal_device
=journal_device
,
135 cluster_fsid
=cluster_fsid
137 # we must have either an existing data_lv or a newly created, so lets make
138 # sure that the tags are correct
140 raise RuntimeError('no data logical volume found with: %s' % args
.data
)
143 'ceph.osd_fsid': fsid
,
144 'ceph.osd_id': osd_id
,
145 'ceph.cluster_fsid': cluster_fsid
,
146 'ceph.journal_device': journal_device
,
147 'ceph.data_device': data_lv
.lv_path
,
158 prepare_bluestore(args
)
161 sub_command_help
= dedent("""
162 Prepare an OSD by assigning an ID and FSID, registering them with the
163 cluster with an ID and FSID, formatting and mounting the volume, and
164 finally by adding all the metadata to the logical volumes using LVM
165 tags, so that it can later be discovered.
167 Once the OSD is ready, an ad-hoc systemd unit will be enabled so that
168 it can later get activated and the OSD daemon can get started.
170 Most basic Usage looks like (journal will be collocated from the same volume group):
172 ceph-volume lvm prepare --data {volume group name}
175 Example calls for supported scenarios:
177 Dedicated volume group for Journal(s)
178 -------------------------------------
180 Existing logical volume (lv) or device:
182 ceph-volume lvm prepare --data {logical volume} --journal /path/to/{lv}|{device}
186 ceph-volume lvm prepare --data {data volume group} --journal {journal volume group}
188 Collocated (same group) for data and journal
189 --------------------------------------------
191 ceph-volume lvm prepare --data {volume group}
194 parser
= prepare_parser(
195 prog
='ceph-volume lvm prepare',
196 description
=sub_command_help
,
198 if len(self
.argv
) == 0:
199 print(sub_command_help
)
201 args
= parser
.parse_args(self
.argv
)