示例#1
0
    def prepare_device(self, arg, device_type, cluster_fsid, osd_fsid):
        """
        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
        ultimately, returning the logical volume object.  Failing to detect
        a device or partition will result in error.

        :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
        """
        if disk.is_partition(arg) or disk.is_device(arg):
            # we must create a vg, and then a single lv
            vg_name = "ceph-%s" % cluster_fsid
            if api.get_vg(vg_name=vg_name):
                # means we already have a group for this, make a different one
                # XXX this could end up being annoying for an operator, maybe?
                vg_name = "ceph-%s" % str(uuid.uuid4())
            api.create_vg(vg_name, arg)
            lv_name = "osd-%s-%s" % (device_type, osd_fsid)
            return api.create_lv(
                lv_name,
                vg_name,  # the volume group
                tags={'ceph.type': device_type})
        else:
            error = [
                'Cannot use device (%s).' % arg,
                'A vg/lv path or an existing device is needed'
            ]
            raise RuntimeError(' '.join(error))

        raise RuntimeError('no data logical volume found with: %s' % arg)
示例#2
0
    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
        ultimately, returning the logical volume object.  Failing to detect
        a device or partition will result in error.

        :param arg: The value of ``--data`` when parsing args
        :param device_type: Usually, either ``data`` or ``block`` (filestore vs. bluestore)
        :param osd_uuid: The OSD uuid
        """
        device = self.args.data
        if disk.is_partition(device) or disk.is_device(device):
            # we must create a vg, and then a single lv
            lv_name_prefix = "osd-{}".format(device_type)
            kwargs = {
                'device': device,
                'tags': {
                    'ceph.type': device_type
                },
                'slots': self.args.data_slots,
            }
            logger.debug('data device size: {}'.format(self.args.data_size))
            if self.args.data_size != 0:
                kwargs['size'] = self.args.data_size
            return api.create_lv(lv_name_prefix, osd_uuid, **kwargs)
        else:
            error = [
                '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: {}'.format(device))
示例#3
0
文件: prepare.py 项目: mkoderer/ceph
    def prepare_device(self, arg, device_type, cluster_fsid, osd_fsid):
        """
        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
        ultimately, returning the logical volume object.  Failing to detect
        a device or partition will result in error.

        :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
        """
        if disk.is_partition(arg) or disk.is_device(arg):
            # we must create a vg, and then a single lv
            vg_name = "ceph-%s" % cluster_fsid
            if api.get_vg(vg_name=vg_name):
                # means we already have a group for this, make a different one
                # XXX this could end up being annoying for an operator, maybe?
                vg_name = "ceph-%s" % str(uuid.uuid4())
            api.create_vg(vg_name, arg)
            lv_name = "osd-%s-%s" % (device_type, osd_fsid)
            return api.create_lv(
                lv_name,
                vg_name,  # the volume group
                tags={'ceph.type': device_type})
        else:
            error = [
                'Cannot use device (%s).' % arg,
                'A vg/lv path or an existing device is needed']
            raise RuntimeError(' '.join(error))

        raise RuntimeError('no data logical volume found with: %s' % arg)
示例#4
0
    def setup_device(self, device_type, device_name, tags, size, slots):
        """
        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
        will not have.

        If the device is not a logical volume, then retrieve the partition UUID
        by querying ``blkid``
        """
        if device_name is None:
            return '', '', tags
        tags['ceph.type'] = device_type
        tags['ceph.vdo'] = api.is_vdo(device_name)

        try:
            vg_name, lv_name = device_name.split('/')
            lv = api.get_first_lv(filters={'lv_name': lv_name,
                                           'vg_name': vg_name})
        except ValueError:
            lv = None

        if lv:
            uuid = lv.lv_uuid
            path = lv.lv_path
            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,
                'slots': slots
            }
            #TODO use get_block_db_size and co here to get configured size in
            #conf file
            if size != 0:
                kwargs['size'] = 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)
            path = device_name
            tags['ceph.%s_uuid' % device_type] = uuid
            tags['ceph.%s_device' % device_type] = path
        return path, uuid, tags
示例#5
0
    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
        will not have.

        If the device is not a logical volume, then retrieve the partition UUID
        by querying ``blkid``
        """
        if device_name is None:
            return '', '', tags
        tags['ceph.type'] = device_type
        tags['ceph.vdo'] = api.is_vdo(device_name)
        lv = self.get_lv(device_name)
        if lv:
            uuid = lv.lv_uuid
            path = lv.lv_path
            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,
                'slots':
                getattr(self.args, 'block_{}_slots'.format(device_type), 1),
            }
            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)
            path = device_name
            tags['ceph.%s_uuid' % device_type] = uuid
            tags['ceph.%s_device' % device_type] = path
        return path, uuid, tags
示例#6
0
    def prepare(self, args):
        # FIXME we don't allow re-using a keyring, we always generate one for the
        # OSD, this needs to be fixed. This could either be a file (!) or a string
        # (!!) or some flags that we would need to compound into a dict so that we
        # can convert to JSON (!!!)
        secrets = {'cephx_secret': prepare_utils.create_key()}

        cluster_fsid = conf.ceph.get('global', 'fsid')
        osd_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(
            osd_fsid, json.dumps(secrets))
        if args.filestore:
            if not args.journal:
                raise RuntimeError(
                    '--journal is required when using --filestore')

            data_lv = self.get_lv(args.data)
            if not data_lv:
                raise RuntimeError('no data logical volume found with: %s' %
                                   args.data)

            tags = {
                'ceph.osd_fsid': osd_fsid,
                'ceph.osd_id': osd_id,
                'ceph.cluster_fsid': cluster_fsid,
                'ceph.cluster_name': conf.cluster,
                'ceph.data_device': data_lv.lv_path,
                'ceph.data_uuid': data_lv.lv_uuid,
            }

            journal_device, journal_uuid, tags = self.setup_device(
                'journal', args.journal, tags)

            tags['ceph.type'] = 'data'
            data_lv.set_tags(tags)

            prepare_filestore(
                data_lv.lv_path,
                journal_device,
                secrets,
                id_=osd_id,
                fsid=osd_fsid,
            )
        elif args.bluestore:
            block_lv = self.get_lv(args.data)
            if not block_lv:
                if disk.is_partition(args.data) or disk.is_device(args.data):
                    # we must create a vg, and then a single lv
                    vg_name = "ceph-%s" % cluster_fsid
                    if api.get_vg(vg_name=vg_name):
                        # means we already have a group for this, make a different one
                        # XXX this could end up being annoying for an operator, maybe?
                        vg_name = "ceph-%s" % str(uuid.uuid4())
                    api.create_vg(vg_name, args.data)
                    block_name = "osd-block-%s" % osd_fsid
                    block_lv = api.create_lv(
                        block_name,
                        vg_name,  # the volume group
                        tags={'ceph.type': 'block'})
                else:
                    error = [
                        'Cannot use device (%s) for bluestore. ' % args.data,
                        'A vg/lv path or an existing device is needed'
                    ]
                    raise RuntimeError(' '.join(error))

            tags = {
                'ceph.osd_fsid': osd_fsid,
                'ceph.osd_id': osd_id,
                'ceph.cluster_fsid': cluster_fsid,
                'ceph.cluster_name': conf.cluster,
                'ceph.block_device': block_lv.lv_path,
                'ceph.block_uuid': block_lv.lv_uuid,
            }

            wal_device, wal_uuid, tags = self.setup_device(
                'wal', args.block_wal, tags)
            db_device, db_uuid, tags = self.setup_device(
                'db', args.block_db, tags)

            tags['ceph.type'] = 'block'
            block_lv.set_tags(tags)

            prepare_bluestore(
                block_lv.lv_path,
                wal_device,
                db_device,
                secrets,
                id_=osd_id,
                fsid=osd_fsid,
            )