:param argument: The command-line value that will need to be split to
retrieve the actual lv
"""
+ #TODO is this efficient?
try:
vg_name, lv_name = argument.split('/')
except (ValueError, AttributeError):
return None
return api.get_lv(lv_name=lv_name, vg_name=vg_name)
- def setup_device(self, device_type, device_name, tags):
+ def setup_device(self, device_type, device_name, tags, size):
"""
Check if ``device`` is an lv, if so, set the tags, making sure to
update the tags with the lv_uuid and lv_path which the incoming tags
tags['ceph.%s_uuid' % device_type] = uuid
tags['ceph.%s_device' % device_type] = path
lv.set_tags(tags)
+ elif disk.is_device(device_name):
+ # We got a disk, create an lv
+ lv_type = "osd-{}".format(device_type)
+ uuid = system.generate_uuid()
+ tags['ceph.{}_uuid'.format(device_type)] = uuid
+ kwargs = {
+ 'device': device_name,
+ 'tags': tags,
+ }
+ if size != 0:
+ kwargs['size'] = disk.Size.parse(size)
+ lv = api.create_lv(
+ lv_type,
+ uuid,
+ **kwargs)
+ path = lv.lv_path
+ tags['ceph.{}_device'.format(device_type)] = path
+ lv.set_tags(tags)
else:
# otherwise assume this is a regular disk partition
uuid = self.get_ptuuid(device_name)
tags['ceph.%s_device' % device_type] = path
return path, uuid, tags
- def prepare_device(self, arg, device_type, cluster_fsid, osd_fsid):
+ def prepare_data_device(self, device_type, osd_uuid):
"""
Check if ``arg`` is a device or partition to create an LV out of it
with a distinct volume group name, assigning LV tags on it and
:param arg: The value of ``--data`` when parsing args
:param device_type: Usually, either ``data`` or ``block`` (filestore vs. bluestore)
- :param cluster_fsid: The cluster fsid/uuid
- :param osd_fsid: The OSD fsid/uuid
+ :param osd_uuid: The OSD uuid
"""
- if disk.is_partition(arg) or disk.is_device(arg):
+ device = self.args.data
+ if disk.is_partition(device) or disk.is_device(device):
# we must create a vg, and then a single lv
- vg = api.create_vg(arg)
- lv_name = "osd-%s-%s" % (device_type, osd_fsid)
+ lv_name_prefix = "osd-{}".format(device_type)
+ kwargs = {'device': device,
+ 'tags': {'ceph.type': device_type},
+ }
+ logger.debug('data device size: {}'.format(self.args.data_size))
+ if self.args.data_size != 0:
+ kwargs['size'] = disk.Size.parse(self.args.data_size)
return api.create_lv(
- lv_name,
- vg.name, # the volume group
- tags={'ceph.type': device_type})
+ lv_name_prefix,
+ osd_uuid,
+ **kwargs)
else:
error = [
- 'Cannot use device (%s).' % arg,
+ 'Cannot use device ({}).'.format(device),
'A vg/lv path or an existing device is needed']
raise RuntimeError(' '.join(error))
- raise RuntimeError('no data logical volume found with: %s' % arg)
+ raise RuntimeError('no data logical volume found with: {}'.format(device))
def safe_prepare(self, args=None):
"""
"""
if args is not None:
self.args = args
+ if api.is_ceph_device(self.get_lv(self.args.data)):
+ logger.info("device {} is already used".format(self.args.data))
+ raise RuntimeError("skipping {}, it is already prepared".format(self.args.data))
try:
self.prepare()
except Exception:
'ceph.crush_device_class': crush_device_class,
}
if self.args.filestore:
+ #TODO: allow auto creation of journal on passed device, only works
+ # when physical device is passed, not LV
if not self.args.journal:
raise RuntimeError('--journal is required when using --filestore')
data_lv = self.get_lv(self.args.data)
if not data_lv:
- data_lv = self.prepare_device(self.args.data, 'data', cluster_fsid, osd_fsid)
+ data_lv = self.prepare_data_device('data', osd_fsid)
tags['ceph.data_device'] = data_lv.lv_path
tags['ceph.data_uuid'] = data_lv.lv_uuid
tags['ceph.vdo'] = api.is_vdo(data_lv.lv_path)
journal_device, journal_uuid, tags = self.setup_device(
- 'journal', self.args.journal, tags
- )
+ 'journal', self.args.journal, tags, self.args.journal_size)
tags['ceph.type'] = 'data'
data_lv.set_tags(tags)
elif self.args.bluestore:
block_lv = self.get_lv(self.args.data)
if not block_lv:
- block_lv = self.prepare_device(self.args.data, 'block', cluster_fsid, osd_fsid)
+ block_lv = self.prepare_data_device('block', osd_fsid)
tags['ceph.block_device'] = block_lv.lv_path
tags['ceph.block_uuid'] = block_lv.lv_uuid
tags['ceph.encrypted'] = encrypted
tags['ceph.vdo'] = api.is_vdo(block_lv.lv_path)
- wal_device, wal_uuid, tags = self.setup_device('wal', self.args.block_wal, tags)
- db_device, db_uuid, tags = self.setup_device('db', self.args.block_db, tags)
+ wal_device, wal_uuid, tags = self.setup_device(
+ 'wal', self.args.block_wal, tags, self.args.block_wal_size)
+ db_device, db_uuid, tags = self.setup_device(
+ 'db', self.args.block_db, tags, self.args.block_db_size)
tags['ceph.type'] = 'block'
block_lv.set_tags(tags)
ceph-volume lvm prepare --data {vg/lv}
- Existing block device, that will be made a group and logical volume:
+ Existing block device (a logical volume will be created):
ceph-volume lvm prepare --data /path/to/device
- Optionally, can consume db and wal partitions or logical volumes:
+ Optionally, can consume db and wal devices, partitions or logical
+ volumes. A device will get a logical volume, partitions and existing
+ logical volumes will be used as is:
- ceph-volume lvm prepare --data {vg/lv} --block.wal {partition} --block.db {vg/lv}
+ ceph-volume lvm prepare --data {vg/lv} --block.wal {partition} --block.db {/path/to/device}
""")
parser = prepare_parser(
prog='ceph-volume lvm prepare',
# cause both to be True
if not self.args.bluestore and not self.args.filestore:
self.args.bluestore = True
- self.safe_prepare(self.args)
+ self.safe_prepare()