Exemplo n.º 1
0
    def create_report(self, lvs):
        """
        Create a report for LVM dev(s) passed. Returns '{}' to denote failure.
        """

        report = {}

        pvs = api.get_pvs()

        for lv in lvs:
            if not api.is_ceph_device(lv):
                continue

            osd_id = lv.tags['ceph.osd_id']
            report.setdefault(osd_id, [])
            lv_report = lv.as_dict()

            lv_report['devices'] = [
                pv.name for pv in pvs if pv.lv_uuid == lv.lv_uuid
            ] if pvs else []
            report[osd_id].append(lv_report)

            phys_devs = self.create_report_non_lv_device(lv)
            if phys_devs:
                report[osd_id].append(phys_devs)

        return report
Exemplo n.º 2
0
    def safe_prepare(self, args=None):
        """
        An intermediate step between `main()` and `prepare()` so that we can
        capture the `self.osd_id` in case we need to rollback

        :param args: Injected args, usually from `lvm create` which compounds
                     both `prepare` and `create`
        """
        if args is not None:
            self.args = args

        try:
            vgname, lvname = self.args.data.split('/')
            lv = api.get_single_lv(filters={
                'lv_name': lvname,
                'vg_name': vgname
            })
        except ValueError:
            lv = None

        if api.is_ceph_device(lv):
            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:
            logger.exception('lvm prepare was unable to complete')
            logger.info('will rollback OSD ID creation')
            rollback_osd(self.args, self.osd_id)
            raise
        terminal.success("ceph-volume lvm prepare successful for: %s" %
                         self.args.data)
Exemplo n.º 3
0
    def _parse(self):
        lv = None
        if not self.sys_api:
            # if no device was found check if we are a partition
            partname = self.path.split('/')[-1]
            for device, info in sys_info.devices.items():
                part = info['partitions'].get(partname, {})
                if part:
                    self.sys_api = part
                    break

        if self.lvs:
            for _lv in self.lvs:
                # if the path is not absolute, we have 'vg/lv', let's use LV name
                # to get the LV.
                if self.path[0] == '/':
                    if _lv.lv_path == self.path:
                        lv = _lv
                        break
                else:
                    vgname, lvname = self.path.split('/')
                    if _lv.lv_name == lvname and _lv.vg_name == vgname:
                        lv = _lv
                        break
        else:
            if self.path[0] == '/':
                lv = lvm.get_single_lv(filters={'lv_path': self.path})
            else:
                vgname, lvname = self.path.split('/')
                lv = lvm.get_single_lv(filters={
                    'lv_name': lvname,
                    'vg_name': vgname
                })

        if lv:
            self.lv_api = lv
            self.lvs = [lv]
            self.path = lv.lv_path
            self.vg_name = lv.vg_name
            self.lv_name = lv.name
            self.ceph_device = lvm.is_ceph_device(lv)
        else:
            if self.lsblk_all:
                for dev in self.lsblk_all:
                    if dev['NAME'] == os.path.basename(self.path):
                        break
            else:
                dev = disk.lsblk(self.path)
            self.disk_api = dev
            device_type = dev.get('TYPE', '')
            # always check is this is an lvm member
            valid_types = ['part', 'disk']
            if allow_loop_devices():
                valid_types.append('loop')
            if device_type in valid_types:
                self._set_lvm_membership()
            self.ceph_device = disk.has_bluestore_label(self.path)

        self.ceph_disk = CephDiskDevice(self)
Exemplo n.º 4
0
    def _parse(self):
        if not sys_info.devices:
            sys_info.devices = disk.get_devices()
        self.sys_api = sys_info.devices.get(self.abspath, {})
        if not self.sys_api:
            # if no device was found check if we are a partition
            partname = self.abspath.split('/')[-1]
            for device, info in sys_info.devices.items():
                part = info['partitions'].get(partname, {})
                if part:
                    self.sys_api = part
                    break

        # if the path is not absolute, we have 'vg/lv', let's use LV name
        # to get the LV.
        if self.path[0] == '/':
            lv = lvm.get_single_lv(filters={'lv_path': self.path})
        else:
            vgname, lvname = self.path.split('/')
            lv = lvm.get_single_lv(filters={'lv_name': lvname,
                                            'vg_name': vgname})
        if lv:
            self.lv_api = lv
            self.lvs = [lv]
            self.abspath = lv.lv_path
            self.vg_name = lv.vg_name
            self.lv_name = lv.name
            self.ceph_device = lvm.is_ceph_device(lv)
        else:
            dev = disk.lsblk(self.path)
            self.blkid_api = disk.blkid(self.path)
            self.disk_api = dev
            device_type = dev.get('TYPE', '')
            # always check is this is an lvm member
            if device_type in ['part', 'disk']:
                self._set_lvm_membership()
            out, err, rc = process.call([
                'ceph-bluestore-tool', 'show-label',
                '--dev', self.path], verbose_on_failure=False)
            if rc:
                self.ceph_device = True

        self.ceph_disk = CephDiskDevice(self)
Exemplo n.º 5
0
    def create_report(self, lvs, full_report=True, arg_is_vg=False):
        """
        Create a report for LVM dev(s) passed. Returns '{}' to denote failure.
        """
        if not lvs:
            return {}

        def create_report_for_nonlv_device():
            # bluestore will not have a journal, filestore will not have
            # a block/wal/db, so we must skip if not present
            if dev_type == 'data':
                return

            device_uuid = lv.tags.get('ceph.%s_uuid' % dev_type)
            pv = api.get_first_pv(filters={'vg_name': lv.vg_name})
            if device_uuid and pv:
                report[osd_id].append({'tags': {'PARTUUID': device_uuid},
                                       'type': dev_type,
                                       'path': pv.pv_name})

        report = {}

        lvs = [lvs] if isinstance(lvs, api.Volume) else lvs
        for lv in lvs:
            if not api.is_ceph_device(lv):
                continue

            osd_id = lv.tags['ceph.osd_id']
            report.setdefault(osd_id, [])
            lv_report = lv.as_dict()

            dev_type = lv.tags.get('ceph.type', None)
            if dev_type != 'journal' or (dev_type == 'journal' and
               full_report):
                pvs = api.get_pvs(filters={'lv_uuid': lv.lv_uuid})
                lv_report['devices'] = [pv.name for pv in pvs] if pvs else []
                report[osd_id].append(lv_report)

            if arg_is_vg or dev_type in ['journal', 'wal']:
                create_report_for_nonlv_device()

        return report
Exemplo n.º 6
0
 def test_is_not_ceph_device(self, dev):
     assert not api.is_ceph_device(dev)
Exemplo n.º 7
0
 def test_is_ceph_device(self):
     lv_tags = "ceph.type=data,ceph.osd_id=0"
     osd = api.Volume(lv_name='osd/volume', lv_tags=lv_tags)
     assert api.is_ceph_device(osd)