示例#1
0
    def __init__(self, driver, name, pool=None, snapshot=None,
                 read_only=False):
        client, ioctx = driver._connect_to_rados(pool)
        try:
            self.volume = tpool.Proxy(rbd.Image(ioctx, name,
                                                snapshot=snapshot,
                                                read_only=read_only))
        except rbd.ImageNotFound:
            with excutils.save_and_reraise_exception():
                LOG.debug("rbd image %s does not exist", name)
                driver._disconnect_from_rados(client, ioctx)
        except rbd.Error:
            with excutils.save_and_reraise_exception():
                LOG.exception(_("error opening rbd image %s"), name)
                driver._disconnect_from_rados(client, ioctx)

        self.driver = driver
        self.client = client
        self.ioctx = ioctx
示例#2
0
    def _main(self):
        """
        """

        starttime = time.time()
        offset = self.offset
        with rados.Rados(conffile='/etc/ceph/ceph.conf') as cluster:
            with cluster.open_ioctx(self.pool) as ioctx:
                rbd_inst = rbd.RBD()
                with rbd.Image(ioctx, self.image) as image:
                    data = '1' * self.block
                    for i in range(self.filesize / self.block):
                        image.write(data, offset)
                        offset = offset + self.block

        endtime = time.time()
        print "time: ", (endtime - starttime)
        print "speed = %sKB/s " % (self.filesize /
                                   (endtime - starttime) / 1024)
示例#3
0
def rbd_clone(dbg, cluster, parent_pool, parent, snapshot, clone_pool, clone):
    log.debug("%s: xcpng.librbd.rbd_utils.rbd_clone: Cluster ID: %s Parent Pool: %s Parent: %s Snapshot: %s Clone Pool: %s Clone: %s"
              % (dbg, cluster.get_fsid(), parent_pool, parent, snapshot, clone_pool, clone))
    p_ioctx = cluster.open_ioctx(parent_pool)
    p_image = rbd.Image(p_ioctx, parent)
    c_ioctx = cluster.open_ioctx(clone_pool)
    rbd_inst = rbd.RBD()

    try:
        if not p_image.is_protected_snap(snapshot):
            p_image.protect_snap(snapshot)
        rbd_inst.clone(p_ioctx, parent, snapshot, c_ioctx, clone)
    except Exception as e:
        log.error("%s: xcpng.librbd.rbd_utils.rbd_clone: Failed to make a clone: Cluster ID: %s Parent Pool: %s Parent: %s Snapshot: %s Clone Pool: %s Clone: %s"
              % (dbg, cluster.get_fsid(), parent_pool, parent, snapshot, clone_pool, clone))
        raise Exception(e)
    finally:
        p_ioctx.close()
        c_ioctx.close()
示例#4
0
    def _delete_image(self,
                      target_pool,
                      image_name,
                      snapshot_name=None,
                      context=None):
        """
        Delete RBD image and snapshot.

        :param image_name Image's name
        :param snapshot_name Image snapshot's name

        :raises NotFound if image does not exist;
                InUseByStore if image is in use or snapshot unprotect failed
        """
        with rados.Rados(conffile=self.conf_file, rados_id=self.user) as conn:
            with conn.open_ioctx(target_pool) as ioctx:
                try:
                    # First remove snapshot.
                    if snapshot_name is not None:
                        with rbd.Image(ioctx, image_name) as image:
                            try:
                                image.unprotect_snap(snapshot_name)
                            except rbd.ImageBusy:
                                log_msg = _("snapshot %(image)s@%(snap)s "
                                            "could not be unprotected because "
                                            "it is in use")
                                LOG.debug(log_msg % {
                                    'image': image_name,
                                    'snap': snapshot_name
                                })
                                raise exceptions.InUseByStore()
                            image.remove_snap(snapshot_name)

                    # Then delete image.
                    rbd.RBD().remove(ioctx, image_name)
                except rbd.ImageNotFound:
                    raise exceptions.NotFound(
                        message=_("RBD image %s does not exist") % image_name)
                except rbd.ImageBusy:
                    log_msg = _("image %s could not be removed "
                                "because it is in use")
                    LOG.debug(log_msg % image_name)
                    raise exceptions.InUseByStore()
示例#5
0
 def __iter__(self):
     try:
         with rados.Rados(conffile=self.conf_file,
                          rados_id=self.user) as conn:
             with conn.open_ioctx(self.pool) as ioctx:
                 with rbd.Image(ioctx, self.name,
                                snapshot=self.snapshot) as image:
                     img_info = image.stat()
                     size = img_info['size']
                     bytes_left = size
                     while bytes_left > 0:
                         length = min(self.chunk_size, bytes_left)
                         data = image.read(size - bytes_left, length)
                         bytes_left -= len(data)
                         yield data
                     raise StopIteration()
     except rbd.ImageNotFound:
         raise exceptions.NotFound(
             _('RBD image %s does not exist') % self.name)
示例#6
0
文件: task.py 项目: zqlzhang511/ceph
    def queue_flatten(self, image_spec):
        image_spec = self.extract_image_spec(image_spec)

        authorize_request(self.module, image_spec[0], image_spec[1])
        self.log.info("queue_flatten: {}".format(image_spec))

        refs = {
            TASK_REF_ACTION: TASK_REF_ACTION_FLATTEN,
            TASK_REF_POOL_NAME: image_spec[0],
            TASK_REF_POOL_NAMESPACE: image_spec[1],
            TASK_REF_IMAGE_NAME: image_spec[2]
        }

        with self.open_ioctx(image_spec) as ioctx:
            try:
                with rbd.Image(ioctx, image_spec[2]) as image:
                    refs[TASK_REF_IMAGE_ID] = image.id()

                    try:
                        parent_image_id = image.parent_id()
                    except rbd.ImageNotFound:
                        parent_image_id = None

            except rbd.ImageNotFound:
                pass

            task = self.find_task(refs)
            if task:
                return 0, task.to_json(), ''

            if TASK_REF_IMAGE_ID not in refs:
                raise rbd.ImageNotFound("Image {} does not exist".format(
                    self.format_image_spec(image_spec)),
                                        errno=errno.ENOENT)
            if not parent_image_id:
                raise rbd.ImageNotFound(
                    "Image {} does not have a parent".format(
                        self.format_image_spec(image_spec)),
                    errno=errno.ENOENT)

            return 0, self.add_task(
                ioctx, "Flattening image {}".format(
                    self.format_image_spec(image_spec)), refs), ""
示例#7
0
 def _get_meta_data_tcmu(self):
     """
     query the rbd to get the features and size of the rbd
     :return:
     """
     self.logger.debug("Refreshing image metadata")
     with rados.Rados(conffile=settings.config.cephconf,
                      name=settings.config.cluster_client_name) as cluster:
         with cluster.open_ioctx(self.pool) as ioctx:
             try:
                 with rbd.Image(ioctx, self.image) as rbd_image:
                     self.exists = True
                     self.size = rbd_image.size()
                     self.size_h = human_size(self.size)
                     self.features = rbd_image.features()
                     self.feature_list = self._get_features()
                     self._parse_snapshots(list(rbd_image.list_snaps()))
             except rbd.ImageNotFound:
                 self.exists = False
示例#8
0
    def open_r(self) -> None:
        self._read_executor = JobExecutor(name='IO-Read', workers=self._simultaneous_reads, blocking_submit=False)

        re_match = re.match('^([^/]+)/([^@]+)(?:@(.+))?$', self.parsed_url.path)
        if not re_match:
            raise UsageError('URL {} is invalid . Need {}:<pool>/<imagename> or {}:<pool>/<imagename>@<snapshotname>.'.format(
                self.url, self.name, self.name))
        self._pool_name, self._image_name, self._snapshot_name = re_match.groups()

        # try opening it and quit if that's not possible.
        try:
            ioctx = self._cluster.open_ioctx(self._pool_name)
        except rados.ObjectNotFound:
            raise FileNotFoundError('Ceph pool {} not found.'.format(self._pool_name)) from None

        try:
            rbd.Image(ioctx, self._image_name, self._snapshot_name, read_only=True)
        except rbd.ImageNotFound:
            raise FileNotFoundError('RBD image or snapshot {} not found.'.format(self.url)) from None
示例#9
0
文件: rbd_ls.py 项目: zhunzhong/ceph
    def _get(self):
        self.log.debug("rbd.list")
        names = self.rbd.list(self.ioctx)
        result = []
        for name in names:
            i = rbd.Image(self.ioctx, name)
            stat = i.stat()
            stat['name'] = name

            try:
                parent_info = i.parent_info()
                parent = "{}@{}".format(parent_info[0], parent_info[1])
                if parent_info[0] != self.pool:
                    parent = "{}/{}".format(parent_info[0], parent)
                stat['parent'] = parent
            except rbd.ImageNotFound:
                pass
            result.append(stat)
        return result
示例#10
0
    def add(self, image_id, image_file, image_size):
        """
        Stores an image file with supplied identifier to the backend
        storage system and returns an `glance.store.ImageAddResult` object
        containing information about the stored image.

        :param image_id: The opaque image identifier
        :param image_file: The image data to write, as a file-like object
        :param image_size: The size of the image data to write, in bytes

        :retval `glance.store.ImageAddResult` object
        :raises `glance.common.exception.Duplicate` if the image already
                existed
        """
        checksum = hashlib.md5()
        image_name = str(image_id)
        with rados.Rados(conffile=self.conf_file, rados_id=self.user) as conn:
            fsid = None
            if hasattr(conn, 'get_fsid'):
                fsid = conn.get_fsid()
            with conn.open_ioctx(self.pool) as ioctx:
                order = int(math.log(self.chunk_size, 2))
                LOG.debug('creating image %s with order %d', image_name, order)
                try:
                    location = self._create_image(fsid, ioctx, image_name,
                                                  image_size, order)
                except rbd.ImageExists:
                    raise exception.Duplicate(
                        _('RBD image %s already exists') % image_id)
                with rbd.Image(ioctx, image_name) as image:
                    bytes_left = image_size
                    while bytes_left > 0:
                        length = min(self.chunk_size, bytes_left)
                        data = image_file.read(length)
                        image.write(data, image_size - bytes_left)
                        bytes_left -= length
                        checksum.update(data)
                    if location.snapshot:
                        image.create_snap(location.snapshot)
                        image.protect_snap(location.snapshot)

        return (location.get_uri(), image_size, checksum.hexdigest())
示例#11
0
def revert_snapshot(pool, volume_name, snap_name):
    # try:
    #     cluster.connect()
    #     ioctx = cluster.open_ioctx(pool)
    #     try:
    #         image = rbd.Image(ioctx, volume_name)
    #         image.rollback_to_snap(snap_name)
    #         print("The rbd snapshot rollback successful")
    #     #except rados.Error:
    #     except rbd.ImageNotFound:
    #         print("The rbd snapshot ImageNotFound")
    #     finally:
    #         ioctx.close()
    # finally:
    #     cluster.shutdown()
    with cluster.connect() as connect:
        with cluster.open_ioctx(pool) as ioctx:
            image = rbd.Image(ioctx, volume_name)
            image.rollback_to_snap(snap_name)
            print("The rbd snapshot rollback successful")
示例#12
0
 def backup(self, disk_id):
     for pool in pools:
         ioctx = cluster.open_ioctx(pool)
         rbd_obj = rbd.RBD()
         pool_rbd = rbd_obj.list(ioctx)
         for obj in pool_rbd:
             if disk_id in obj:
                 ins_img = rbd.Image(ioctx, obj)
                 now = dt.now()
                 tstmp = now.strftime("%a-%Y-%b-%d-%H_%M_%S")
                 snap_name = instance_name + '_' + 'snap-' + tstmp
                 try:
                     ins_img.create_snap(snap_name)
                     print("Successfully created the disk " + obj +
                           " snapshot " + snap_name + " for the instance " +
                           instance_name + ".")
                 except:
                     print("Error occured while creating the disk " + obj +
                           " snapshot " + snap_name + " for the instance " +
                           instance_name + ".")
示例#13
0
def loopRados(ioctx):
    for object in ioctx.list_objects():
        if object.key[:7] == "rbd_id.":
            myrbd = rbd.Image(ioctx, name=object.key[7:])
            fields = {"name": myrbd.get_name(), "id": myrbd.id()}
            if args.force:
                for myfield in antifield.keys():
                    print("Forcing {} entry for {}".format(
                        myfield, fields['name']))
                    appendOmap(fields, myfield)
            else:
                with rados.ReadOpCtx() as read_op:
                    for myfield in antifield.keys():
                        iter, ret = ioctx.get_omap_vals_by_keys(
                            read_op,
                            tuple([
                                "{}_{}".format(myfield, fields[myfield]),
                            ]))
                        ioctx.operate_read_op(read_op, "rbd_directory")
                        checkIter(iter, fields, myfield)
示例#14
0
文件: rbd.py 项目: yuyonglucky/glance
    def add(self, image_id, image_file, image_size):
        """
        Stores an image file with supplied identifier to the backend
        storage system and returns a tuple containing information
        about the stored image.

        :param image_id: The opaque image identifier
        :param image_file: The image data to write, as a file-like object
        :param image_size: The size of the image data to write, in bytes

        :retval tuple of URL in backing store, bytes written, checksum
                and a dictionary with storage system specific information
        :raises `glance.common.exception.Duplicate` if the image already
                existed
        """
        checksum = hashlib.md5()
        image_name = str(image_id)
        with rados.Rados(conffile=self.conf_file, rados_id=self.user) as conn:
            fsid = None
            if hasattr(conn, 'get_fsid'):
                fsid = conn.get_fsid()
            with conn.open_ioctx(self.pool) as ioctx:
                order = int(math.log(self.chunk_size, 2))
                LOG.debug('creating image %s with order %d', image_name, order)
                try:
                    location = self._create_image(fsid, ioctx, image_name,
                                                  image_size, order)
                except rbd.ImageExists:
                    raise exception.Duplicate(
                        _('RBD image %s already exists') % image_id)
                with rbd.Image(ioctx, image_name) as image:
                    offset = 0
                    chunks = utils.chunkreadable(image_file, self.chunk_size)
                    for chunk in chunks:
                        offset += image.write(chunk, offset)
                        checksum.update(chunk)
                    if location.snapshot:
                        image.create_snap(location.snapshot)
                        image.protect_snap(location.snapshot)

        return (location.get_uri(), image_size, checksum.hexdigest(), {})
示例#15
0
 def create_snapshot(self, pool_id, namespace, image_id):
     try:
         with self.module.rados.open_ioctx2(int(pool_id)) as ioctx:
             ioctx.set_namespace(namespace)
             with rbd.Image(ioctx, image_id=image_id) as image:
                 mode = image.mirror_image_get_mode()
                 if mode != rbd.RBD_MIRROR_IMAGE_MODE_SNAPSHOT:
                     return
                 info = image.mirror_image_get_info()
                 if info['state'] != rbd.RBD_MIRROR_IMAGE_ENABLED or \
                    not info['primary']:
                     return
                 snap_id = image.mirror_image_create_snapshot()
                 self.log.debug(
                     "create_snapshot: {}/{}/{}: snap_id={}".format(
                         ioctx.get_pool_name(), namespace, image.get_name(),
                         snap_id))
     except Exception as e:
         self.log.error(
             "exception when creating snapshot for {}/{}/{}: {}".format(
                 pool_id, namespace, image_id, e))
示例#16
0
 def remove_snap(self, image_name: str, snap: str):
     '''
     删除一个rbd image快照
     :param snap: 快照名称
     :param image_name: rbd image名称
     :return:
         True    # success
     :raises: RadosError
     '''
     cluster = self.get_cluster()
     try:
         with cluster.open_ioctx(self.pool_name) as ioctx:
             with rbd.Image(ioctx=ioctx, name=image_name) as image:
                 if image.is_protected_snap(snap):  # protected snap check
                     image.unprotect_snap(snap)
                 image.remove_snap(snap)
     except rbd.ObjectNotFound as e:
         return True
     except Exception as e:
         raise RadosError(f'remove_snap error:{str(e)}')
     return True
示例#17
0
文件: rbd.py 项目: pipul/glance
    def get_size(self, location):
        """
        Takes a `glance.store.location.Location` object that indicates
        where to find the image file, and returns the size

        :param location `glance.store.location.Location` object, supplied
                        from glance.store.location.get_location_from_uri()
        :raises `glance.exception.NotFound` if image does not exist
        """
        loc = location.store_location
        with rados.Rados(conffile=self.conf_file, rados_id=self.user) as conn:
            with conn.open_ioctx(self.pool) as ioctx:
                try:
                    with rbd.Image(ioctx, loc.image,
                                   snapshot=loc.snapshot) as image:
                        img_info = image.stat()
                        return img_info['size']
                except rbd.ImageNotFound:
                    msg = _('RBD image %s does not exist') % loc.get_uri()
                    LOG.debug(msg)
                    raise exception.NotFound(msg)
示例#18
0
文件: task.py 项目: zqlzhang511/ceph
    def queue_remove(self, image_spec):
        image_spec = self.extract_image_spec(image_spec)

        authorize_request(self.module, image_spec[0], image_spec[1])
        self.log.info("queue_remove: {}".format(image_spec))

        refs = {
            TASK_REF_ACTION: TASK_REF_ACTION_REMOVE,
            TASK_REF_POOL_NAME: image_spec[0],
            TASK_REF_POOL_NAMESPACE: image_spec[1],
            TASK_REF_IMAGE_NAME: image_spec[2]
        }

        with self.open_ioctx(image_spec) as ioctx:
            try:
                with rbd.Image(ioctx, image_spec[2]) as image:
                    refs[TASK_REF_IMAGE_ID] = image.id()
                    snaps = list(image.list_snaps())

            except rbd.ImageNotFound:
                pass

            task = self.find_task(refs)
            if task:
                return 0, task.to_json(), ''

            if TASK_REF_IMAGE_ID not in refs:
                raise rbd.ImageNotFound("Image {} does not exist".format(
                    self.format_image_spec(image_spec)),
                                        errno=errno.ENOENT)
            if snaps:
                raise rbd.ImageBusy("Image {} has snapshots".format(
                    self.format_image_spec(image_spec)),
                                    errno=errno.EBUSY)

            return 0, self.add_task(
                ioctx,
                "Removing image {}".format(self.format_image_spec(image_spec)),
                refs), ''
示例#19
0
    def queue_remove(self, image_spec):
        image_spec = self.extract_image_spec(image_spec)
        self.log.info("queue_remove: {}".format(image_spec))

        refs = {TASK_REF_ACTION: TASK_REF_ACTION_REMOVE,
                TASK_REF_POOL_NAME: image_spec[0],
                TASK_REF_POOL_NAMESPACE: image_spec[1],
                TASK_REF_IMAGE_NAME: image_spec[2]}
        task = self.find_task(refs)
        if task:
            return 0, task.to_json(), ''

        with self.open_ioctx(image_spec) as ioctx:
            with rbd.Image(ioctx, image_spec[2]) as image:
                if list(image.list_snaps()):
                    raise rbd.ImageBusy("Image {} has snapshots".format(
                        self.format_image_spec(image_spec)), errno=errno.EBUSY)

            return 0, self.add_task(ioctx,
                                    "Removing image {}".format(
                                        self.format_image_spec(image_spec)),
                                    refs), ''
示例#20
0
文件: iscsi.py 项目: benlu36/ceph-1
    def _validate_image(pool, image, backstore, required_rbd_features,
                        supported_rbd_features):
        try:
            ioctx = mgr.rados.open_ioctx(pool)
            try:
                with rbd.Image(ioctx, image) as img:
                    if img.features(
                    ) & required_rbd_features != required_rbd_features:
                        raise DashboardException(
                            msg='Image {} cannot be exported using {} '
                            'backstore because required features are '
                            'missing (required features are '
                            '{})'.format(
                                image, backstore,
                                format_bitmask(required_rbd_features)),
                            code='image_missing_required_features',
                            component='iscsi')
                    if img.features() & supported_rbd_features != img.features(
                    ):
                        raise DashboardException(
                            msg='Image {} cannot be exported using {} '
                            'backstore because it contains unsupported '
                            'features (supported features are '
                            '{})'.format(
                                image, backstore,
                                format_bitmask(supported_rbd_features)),
                            code='image_contains_unsupported_features',
                            component='iscsi')

            except rbd.ImageNotFound:
                raise DashboardException(
                    msg='Image {} does not exist'.format(image),
                    code='image_does_not_exist',
                    component='iscsi')
        except rados.ObjectNotFound:
            raise DashboardException(msg='Pool {} does not exist'.format(pool),
                                     code='pool_does_not_exist',
                                     component='iscsi')
示例#21
0
    def _rbd_list(self, pool_name):
        ioctx = mgr.rados.open_ioctx(pool_name)
        self.rbd = rbd.RBD()
        names = self.rbd.list(ioctx)
        result = []
        for name in names:
            i = rbd.Image(ioctx, name)
            stat = i.stat()
            stat['name'] = name
            features = i.features()
            stat['features'] = features
            stat['features_name'] = self._format_bitmask(features)

            try:
                parent_info = i.parent_info()
                parent = "{}@{}".format(parent_info[0], parent_info[1])
                if parent_info[0] != pool_name:
                    parent = "{}/{}".format(parent_info[0], parent)
                stat['parent'] = parent
            except rbd.ImageNotFound:
                pass
            result.append(stat)
        return result
示例#22
0
def create_rbd():

    # Get the cluster info and open cluster
    cluster = rados.Rados(conffile='/etc/ceph/ceph.conf')
    cluster.connect()

    # Open the data pool
    ioctx = cluster.open_ioctx(pool_name)

    # Get the RBD management instance and create RBD.
    rbd_inst = rbd.RBD()
    rbd_inst.create(ioctx, rbd_name, rbd_size)
    image = rbd.Image(ioctx, rbd_name)

    # Write date to rbd image eg. foofoofoo...
    data = 'foo' * 200
    # write data with offset. write(data, offset)
    image.write(data, 0)

    # Close the image, context and cluster
    image.close()
    ioctx.close()
    cluster.shutdown()
示例#23
0
    def _get_disk_meta(self, cluster_ioctx, disk_meta):
        """
        Use the provided cluster context to take an rbd image name from the
        queue and extract size and feature code. The resulting data is then
        stored in a shared dict accessible by all scan threads
        :param cluster_ioctx: cluster io context object
        :param disk_meta: dict of rbd images, holding metadata
        :return: None
        """

        while True:

            time.sleep(Disks.scan_interval)

            try:
                rbd_name = self.scan_queue.get(block=False)
            except Queue.Empty:
                break
            else:
                pool, image = rbd_name.split('/')
                disk_meta[rbd_name] = {}
                with cluster_ioctx.open_ioctx(pool) as ioctx:
                    try:
                        with rbd.Image(ioctx, image) as rbd_image:
                            size = rbd_image.size()
                            features = rbd_image.features()
                            snapshots = list(rbd_image.list_snaps())

                            self.scan_mutex.acquire()
                            disk_meta[rbd_name] = {
                                "size": size,
                                "features": features,
                                "snapshots": snapshots
                            }
                            self.scan_mutex.release()
                    except rbd.ImageNotFound:
                        pass
示例#24
0
文件: rbd.py 项目: jubalh/backy2
    def _read(self, block):
        ioctx = self._cluster.open_ioctx(self.pool_name)
        with rbd.Image(ioctx,
                       self.image_name,
                       self.snapshot_name,
                       read_only=True) as image:
            offset = block.id * self._block_size
            t1 = time.time()
            data = image.read(offset, block.size,
                              rados.LIBRADOS_OP_FLAG_FADVISE_DONTNEED)
            t2 = time.time()

        if not data:
            raise EOFError('EOF reached on source when there should be data.')

        data_checksum = data_hexdigest(self._hash_function, data)
        logger.debug('{} read block {} (checksum {}...) in {:.2f}s'.format(
            threading.current_thread().name,
            block.id,
            data_checksum[:16],
            t2 - t1,
        ))

        return block, data, data_checksum
示例#25
0
    def create_snap(self, image_name: str, snap_name: str, protected: bool = False):
        '''
        为一个rbd image(卷)创建快照

        :param image_name: 要创建快照的rbd卷名称
        :param snap_name: 快照名称
        :param protected: 是否设置快照protect; 默认False(不protect)
        :return:
            True    # success
            raise RadosError # failed

        :raise class: `RadosError`
        '''
        cluster = self.get_cluster()
        try:
            with cluster.open_ioctx(self.pool_name) as ioctx:
                with rbd.Image(ioctx=ioctx, name=image_name) as image:
                    image.create_snap(snap_name)  # Create a snapshot of the image.
                    if protected:
                        image.protect_snap(snap_name)
        except Exception as e:
            raise RadosError(f'create_snap error:{str(e)}')

        return True
示例#26
0
 def _list(ioctx):
     if self._image_name:  # image config
         try:
             with rbd.Image(ioctx, self._image_name) as image:
                 result = image.config_list()
         except rbd.ImageNotFound:
             result = []
     else:  # pool config
         pg_status = list(CephService.get_pool_pg_status(self._pool_name).keys())
         if len(pg_status) == 1 and 'incomplete' in pg_status[0]:
             # If config_list would be called with ioctx if it's a bad pool,
             # the dashboard would stop working, waiting for the response
             # that would not happen.
             #
             # This is only a workaround for https://tracker.ceph.com/issues/43771 which
             # already got rejected as not worth the effort.
             #
             # Are more complete workaround for the dashboard will be implemented with
             # https://tracker.ceph.com/issues/44224
             #
             # @TODO: If #44224 is addressed remove this workaround
             return []
         result = self._rbd.config_list(ioctx)
     return list(result)
示例#27
0
def get_rbd_images(ceph_pool='rbd'):
    """
    Grab a dictionary of rbd images in a pool across all clusters
    """

    all_images = dict()
    for cluster_name, cluster_config in get_ceph_clusters().iteritems():
        all_images[cluster_name] = []
        ceph_config = parse_ceph_config(cluster_config['conffile'])
        ceph_monitors = get_ceph_config_monitors(ceph_config)
        with Rados(**cluster_config) as cluster:
            with cluster.open_ioctx(ceph_pool) as ioctx:
                rbd_inst = rbd.RBD()
                for rbd_image_name in rbd_inst.list(ioctx):
                    with rbd.Image(ioctx, rbd_image_name) as rbd_image:
                        rbd_size = (rbd_image.size() / 1000000000)
                        rbd_data = {
                            'name': rbd_image_name,
                            'size': rbd_size,
                            'monitors': ceph_monitors
                        }
                        all_images[cluster_name].append(rbd_data)

    return all_images
示例#28
0
    def _reader(self, id_):
        """ self._inqueue contains block_ids to be read.
        self._outqueue contains (block_id, data, data_checksum)
        """
        ioctx = self.cluster.open_ioctx(self.pool_name)
        with rbd.Image(ioctx,
                       self.image_name,
                       self.snapshot_name,
                       read_only=True) as image:
            while True:
                entry = self._inqueue.get()
                if entry is None:
                    logger.debug("IO {} finishing.".format(id_))
                    self._outqueue.put(None)  # also let the outqueue end
                    self._inqueue.task_done()
                    break
                block_id, read, metadata = entry
                if not read:
                    self._outqueue.put((block_id, None, None, metadata))
                else:
                    offset = block_id * self.block_size
                    t1 = time.time()
                    self.reader_thread_status[id_] = STATUS_READING
                    data = image.read(offset, self.block_size,
                                      rados.LIBRADOS_OP_FLAG_FADVISE_DONTNEED)
                    self.reader_thread_status[id_] = STATUS_NOTHING
                    t2 = time.time()
                    if not data:
                        raise RuntimeError(
                            'EOF reached on source when there should be data.')

                    data_checksum = self.hash_function(data).hexdigest()

                    self._outqueue.put(
                        (block_id, data, data_checksum, metadata))
                self._inqueue.task_done()
示例#29
0
    def open_r(self) -> None:
        self._read_executor = JobExecutor(name='IO-Read',
                                          workers=self._simultaneous_reads,
                                          blocking_submit=False)

        re_match = re.match('^([^/]+)/(?:([^/]*)/)?([^@]+)(?:@(.+))?$',
                            self.parsed_url.path)
        if not re_match:
            raise UsageError(
                'URL {} is invalid . Need {}:<pool>[/<namespace>]/<imagename>[@<snapshotname>].'
                .format(self.url, self.name))
        self._pool_name, self._namespace_name, self._image_name, self._snapshot_name = re_match.groups(
        )

        # try opening it and quit if that's not possible.
        try:
            ioctx = self._cluster.open_ioctx(self._pool_name)
            if self._namespace_name is not None and len(
                    self._namespace_name) > 0:
                logger.debug(
                    f'Configuring io context to use namespace {self._namespace_name}.'
                )
                ioctx.set_namespace(self._namespace_name)
        except rados.ObjectNotFound:
            raise FileNotFoundError('Ceph pool {} not found.'.format(
                self._pool_name)) from None

        try:
            rbd.Image(ioctx,
                      self._image_name,
                      self._snapshot_name,
                      read_only=True)
        except rbd.ImageNotFound:
            raise FileNotFoundError(
                'RBD image or snapshot {} not found.'.format(
                    self.url)) from None
示例#30
0
    def get_size(self, location, context=None):
        """
        Takes a `glance_store.location.Location` object that indicates
        where to find the image file, and returns the size

        :param location `glance_store.location.Location` object, supplied
                        from glance_store.location.get_location_from_uri()
        :raises `glance_store.exceptions.NotFound` if image does not exist
        """
        loc = location.store_location
        # if there is a pool specific in the location, use it; otherwise
        # we fall back to the default pool specified in the config
        target_pool = loc.pool or self.pool
        with rados.Rados(conffile=self.conf_file, rados_id=self.user) as conn:
            with conn.open_ioctx(target_pool) as ioctx:
                try:
                    with rbd.Image(ioctx, loc.image,
                                   snapshot=loc.snapshot) as image:
                        img_info = image.stat()
                        return img_info['size']
                except rbd.ImageNotFound:
                    msg = _('RBD image %s does not exist') % loc.get_uri()
                    LOG.debug(msg)
                    raise exceptions.NotFound(msg)