From 192fe4e1dd24713f33131583de4ca81b625bad98 Mon Sep 17 00:00:00 2001 From: Alfredo Deza Date: Wed, 23 Aug 2017 13:26:15 -0400 Subject: [PATCH] ceph-volume lvm.prepare enforce usage of vg/lv when preparing lvm devices Signed-off-by: Alfredo Deza --- .../ceph_volume/devices/lvm/prepare.py | 109 +++++++----------- 1 file changed, 41 insertions(+), 68 deletions(-) diff --git a/src/ceph-volume/ceph_volume/devices/lvm/prepare.py b/src/ceph-volume/ceph_volume/devices/lvm/prepare.py index 63030e6b44403..b6e8be870a59b 100644 --- a/src/ceph-volume/ceph_volume/devices/lvm/prepare.py +++ b/src/ceph-volume/ceph_volume/devices/lvm/prepare.py @@ -9,20 +9,6 @@ from . import api from .common import prepare_parser -def canonical_device_path(device): - """ - Ensure that a device is canonical (full path) and that it exists so that - it can be used throughout the prepare/activate process - """ - # FIXME: this is obviously super naive - inferred = os.path.join('/dev', device) - if os.path.exists(os.path.abspath(device)): - return device - elif os.path.exists(inferred): - return inferred - raise RuntimeError('Selected device does not exist: %s' % device) - - def prepare_filestore(device, journal, secrets, id_=None, fsid=None): """ :param device: The name of the volume group or lvm to work with @@ -65,6 +51,19 @@ class Prepare(object): def __init__(self, argv): self.argv = argv + def get_journal_lv(self, argument): + """ + Perform some parsing of the value of ``--journal`` so that the process + can determine correctly if it got a device path or an lv + :param argument: The value of ``--journal``, that will need to be split + to retrieve the actual lv + """ + try: + vg_name, lv_name = argument.split('/') + except (ValueError, AttributeError): + return None + return api.get_lv(lv_name=lv_name, vg_name=vg_name) + @decorators.needs_root def prepare(self, args): # FIXME we don't allow re-using a keyring, we always generate one for the @@ -77,66 +76,40 @@ class Prepare(object): fsid = args.osd_fsid or system.generate_uuid() # allow re-using an id, in case a prepare failed osd_id = args.osd_id or prepare_utils.create_id(fsid, json.dumps(secrets)) - journal_name = "journal_%s" % fsid - osd_name = "osd_%s" % fsid - + vg_name, lv_name = args.data.split('/') if args.filestore: - data_vg = api.get_vg(vg_name=args.data) - data_lv = api.get_lv(lv_name=args.data) - journal_vg = api.get_vg(vg_name=args.journal) - journal_lv = api.get_lv(lv_name=args.journal) - journal_device = None - # it is possible to pass a device as a journal that is not - # an actual logical volume (or group) - if not args.journal: - if data_lv: - raise RuntimeError('--journal is required when not using a vg for OSD data') - # collocated: carve out the journal from the data vg - if data_vg: - journal_lv = api.create_lv( - name=journal_name, - group=data_vg.name, - size=args.journal_size, - osd_fsid=fsid, - osd_id=osd_id, - type='journal', - cluster_fsid=cluster_fsid - ) + data_lv = api.get_lv(lv_name=lv_name, vg_name=vg_name) - # if a volume group was defined for the journal create that first - if journal_vg: - journal_lv = api.create_lv( - name=journal_name, - group=args.journal, - size=args.journal_size, - osd_fsid=fsid, - osd_id=osd_id, - type='journal', - cluster_fsid=cluster_fsid - ) - if journal_lv: - journal_device = journal_lv.lv_path - # The journal is probably a device, not in LVM - elif args.journal: - journal_device = canonical_device_path(args.journal) - # At this point we must have a journal_lv or a journal device - # now create the osd from the group if that was found - if data_vg: - # XXX make sure that a there aren't more OSDs than physical - # devices from this volume group - data_lv = api.create_lv( - name=osd_name, - group=args.data, - osd_fsid=fsid, - osd_id=osd_id, - type='data', - journal_device=journal_device, - cluster_fsid=cluster_fsid - ) # we must have either an existing data_lv or a newly created, so lets make # sure that the tags are correct if not data_lv: raise RuntimeError('no data logical volume found with: %s' % args.data) + + if not args.journal: + raise RuntimeError('--journal is required when using --filestore') + journal_device = None + journal_lv = self.get_journal_lv(args.journal) + + # check if we have an actual path to a device, which is allowed + if not journal_lv: + if os.path.exists(args.journal): + journal_device = args.journal + else: + raise RuntimeError( + '--journal specified an invalid or non-existent device: %s' % args.journal + ) + # Otherwise the journal_device is the path to the lv + else: + journal_device = journal_lv.lv_path + journal_lv.set_tags({ + 'ceph.type': 'journal', + 'ceph.osd_fsid': fsid, + 'ceph.osd_id': osd_id, + 'ceph.cluster_fsid': cluster_fsid, + 'ceph.journal_device': journal_device, + 'ceph.data_device': data_lv.lv_path, + }) + data_lv.set_tags({ 'ceph.type': 'data', 'ceph.osd_fsid': fsid, -- 2.39.5