Ejemplo n.º 1
0
    def detail(self, req):
        """
        Returns detailed information for all available images

        :param req: The WSGI/Webob Request object
        :retval The response body is a mapping of the following form::

            {'images': [
                {'id': <ID>,
                 'name': <NAME>,
                 'size': <SIZE>,
                 'disk_format': <DISK_FORMAT>,
                 'container_format': <CONTAINER_FORMAT>,
                 'checksum': <CHECKSUM>,
                 'min_disk': <MIN_DISK>,
                 'min_ram': <MIN_RAM>,
                 'store': <STORE>,
                 'status': <STATUS>,
                 'created_at': <TIMESTAMP>,
                 'updated_at': <TIMESTAMP>,
                 'deleted_at': <TIMESTAMP>|<NONE>,
                 'properties': {'distro': 'Ubuntu 10.04 LTS', ...}}, ...
            ]}
        """
        if req.method == 'HEAD':
            msg = (_("This operation is currently not permitted on "
                     "Glance images details."))
            raise HTTPMethodNotAllowed(explanation=msg,
                                       headers={'Allow': 'GET'},
                                       body_template='${explanation}')
        self._enforce(req, 'get_images')
        params = self._get_query_params(req)
        try:
            images = registry.get_images_detail(req.context, **params)
            # Strip out the Location attribute. Temporary fix for
            # LP Bug #755916. This information is still coming back
            # from the registry, since the API server still needs access
            # to it, however we do not return this potential security
            # information to the API end user...
            for image in images:
                redact_loc(image, copy_dict=False)
                self._enforce_read_protected_props(image, req)
        except exception.Invalid as e:
            raise HTTPBadRequest(explanation="%s" % e)
        return dict(images=images)
Ejemplo n.º 2
0
    def detail(self, req):
        """
        Returns detailed information for all available images

        :param req: The WSGI/Webob Request object
        :retval The response body is a mapping of the following form::

            {'images': [
                {'id': <ID>,
                 'name': <NAME>,
                 'size': <SIZE>,
                 'disk_format': <DISK_FORMAT>,
                 'container_format': <CONTAINER_FORMAT>,
                 'checksum': <CHECKSUM>,
                 'min_disk': <MIN_DISK>,
                 'min_ram': <MIN_RAM>,
                 'store': <STORE>,
                 'status': <STATUS>,
                 'created_at': <TIMESTAMP>,
                 'updated_at': <TIMESTAMP>,
                 'deleted_at': <TIMESTAMP>|<NONE>,
                 'properties': {'distro': 'Ubuntu 10.04 LTS', ...}}, ...
            ]}
        """
        if req.method == 'HEAD':
            msg = (_("This operation is currently not permitted on "
                     "Glance images details."))
            raise HTTPMethodNotAllowed(explanation=msg,
                                       headers={'Allow': 'GET'},
                                       body_template='${explanation}')
        self._enforce(req, 'get_images')
        params = self._get_query_params(req)
        try:
            images = registry.get_images_detail(req.context, **params)
            # Strip out the Location attribute. Temporary fix for
            # LP Bug #755916. This information is still coming back
            # from the registry, since the API server still needs access
            # to it, however we do not return this potential security
            # information to the API end user...
            for image in images:
                redact_loc(image, copy_dict=False)
                self._enforce_read_protected_props(image, req)
        except exception.Invalid as e:
            raise HTTPBadRequest(explanation="%s" % e)
        return dict(images=images)
Ejemplo n.º 3
0
    def detail(self, req):
        """
        Returns detailed information for all public, available images

        :param req: The WSGI/Webob Request object
        :retval The response body is a mapping of the following form::

            {'images': [
                {'id': <ID>,
                 'name': <NAME>,
                 'size': <SIZE>,
                 'disk_format': <DISK_FORMAT>,
                 'container_format': <CONTAINER_FORMAT>,
                 'checksum': <CHECKSUM>,
                 'min_disk': <MIN_DISK>,
                 'min_ram': <MIN_RAM>,
                 'store': <STORE>,
                 'status': <STATUS>,
                 'created_at': <TIMESTAMP>,
                 'updated_at': <TIMESTAMP>,
                 'deleted_at': <TIMESTAMP>|<NONE>,
                 'properties': {'distro': 'Ubuntu 10.04 LTS', ...}}, ...
            ]}
        """
        self._enforce(req, 'get_images')
        params = self._get_query_params(req)
        try:
            images = registry.get_images_detail(req.context, **params)
            # Strip out the Location attribute. Temporary fix for
            # LP Bug #755916. This information is still coming back
            # from the registry, since the API server still needs access
            # to it, however we do not return this potential security
            # information to the API end user...
            for image in images:
                del image['location']
        except exception.Invalid as e:
            raise HTTPBadRequest(explanation="%s" % e)
        return dict(images=images)
Ejemplo n.º 4
0
    def detail(self, req):
        """
        Returns detailed information for all public, available images

        :param req: The WSGI/Webob Request object
        :retval The response body is a mapping of the following form::

            {'images': [
                {'id': <ID>,
                 'name': <NAME>,
                 'size': <SIZE>,
                 'disk_format': <DISK_FORMAT>,
                 'container_format': <CONTAINER_FORMAT>,
                 'checksum': <CHECKSUM>,
                 'min_disk': <MIN_DISK>,
                 'min_ram': <MIN_RAM>,
                 'store': <STORE>,
                 'status': <STATUS>,
                 'created_at': <TIMESTAMP>,
                 'updated_at': <TIMESTAMP>,
                 'deleted_at': <TIMESTAMP>|<NONE>,
                 'properties': {'distro': 'Ubuntu 10.04 LTS', ...}}, ...
            ]}
        """
        self._enforce(req, 'get_images')
        params = self._get_query_params(req)
        try:
            images = registry.get_images_detail(req.context, **params)
            # Strip out the Location attribute. Temporary fix for
            # LP Bug #755916. This information is still coming back
            # from the registry, since the API server still needs access
            # to it, however we do not return this potential security
            # information to the API end user...
            for image in images:
                del image['location']
        except exception.Invalid as e:
            raise HTTPBadRequest(explanation="%s" % e)
        return dict(images=images)
Ejemplo n.º 5
0
def _raw_caching_manager():
    """Spawn a worker process. Function does not block"""
    global g_job_queue, g_image_id, g_done_event, g_delete_lock

    LOG.info(_LI('RAW caching manager starting'))
    # Communication between glance-api and glance-registry is done using REST
    # so we need admin authentication before accessing the registry
    retries = 0
    while True:  # keystone has the bad habit of starting late, retry
        try:
            admin_context = _get_context()
            break
        except Exception as e:
            retries += 1
            err = encodeutils.exception_to_unicode(e)
            duration = _RETRY_COUNT_BEFORE_ERROR * _RETRY_SLEEP_S
            LOG.info(
                _LI("Error getting admin context for %(duration)s s,"
                    " reason: %(reason)s") % {
                        'duration': duration,
                        'reason': err
                    })
            if retries >= _RETRY_COUNT_BEFORE_ERROR:
                LOG.error(
                    _LE("Error getting admin context for %(duration)s s,"
                        " reason: %(reason)s") % {
                            'duration': duration,
                            'reason': err
                        })
                sys.exit()
            time.sleep(_RETRY_SLEEP_S)

    active_images = registry.get_images_detail(admin_context,
                                               filters={
                                                   "is_public": 'None',
                                                   "deleted": "False"
                                               })
    # Cleaning invalid conversions
    _clean_dir_content(CONF.cache_raw_conversion_dir)

    LOG.info(_LI('RAW caching restore previous images'))
    # Restore previous images that were waiting to be cached
    for image_meta in active_images:
        if _is_caching_needed(image_meta):
            try:
                # Delete invalid conversion files
                converted_image = image_meta['id'] + "_raw"
                ceph_cfg_file = CONF.glance_store.rbd_store_ceph_conf
                with rados.Rados(conffile=ceph_cfg_file) as cluster:
                    fsid = cluster.get_fsid()
                    images_pool = CONF.glance_store.rbd_store_pool
                    dest_url = "rbd://%s/%s/%s/%s" % (fsid, images_pool,
                                                      converted_image, "snap")
                _del_rbd_image(dest_url, image_meta['id'])
            except store_exceptions.InUseByStore as e:
                # This is important and should not happen for an uncached
                # img, as we don't really know what to do in this case we
                # should at least make sure that we don't crash the main
                # process and log the message properly
                err = encodeutils.exception_to_unicode(e)
                image_meta_u = {
                    'properties': {
                        'cache_raw_status': 'Error',
                        'cache_raw_error': err
                    }
                }
                _safe_update_image_metadata(admin_context, image_meta['id'],
                                            image_meta_u)
                LOG.error(
                    _LE("Error resuming caching for image:%(id)s"
                        " reason: %(reason)s") % {
                            'id': image_meta['id'],
                            'reason': encodeutils.exception_to_unicode(e)
                        })
                # TODO(oponcea): _log_to_fm(err)
                continue
            try:
                LOG.info(
                    _LI("Found image that is not cached: %s "
                        "enqueuing it for caching") % image_meta['id'])
                create_image_cache(admin_context, image_meta['id'])
            except Exception as e:
                err = encodeutils.exception_to_unicode(e)
                image_meta_u = {
                    'properties': {
                        'cache_raw_status': 'Error',
                        'cache_raw_error': err
                    }
                }
                _safe_update_image_metadata(admin_context, image_meta['id'],
                                            image_meta_u)
                LOG.error(
                    _LE("Error creating RAW cache for image: "
                        "%(img)s, err: %(err)s") % {
                            'img': image_meta['id'],
                            'err': err
                        })
                # TODO(oponcea): _log_to_fm(err)
                continue

    # Start the main loop
    while True:
        LOG.info(_LI("RAW caching waiting for request"))
        try:
            # multiprocessing.Queue.put() uses a background thread to pickle
            # and enqueue object to internal queue; yield from current eventlet
            # to give that thread a chance to run
            image_id = None
            while not image_id:
                eventlet.sleep(0)
                try:
                    image_id = g_job_queue.get(True, 5)
                except Empty:
                    pass
            LOG.info(_LI("RAW caching got job for: %s") % image_id)
        except IOError as e:
            # Remove the exceptions generated by EINTR from logs
            if e.errno != errno.EINTR:
                raise
            continue
        try:
            # Set current caching image
            with g_delete_lock:
                # Do not start a new caching if a delete is in progress.
                # Delete operations are short, this should not take long
                g_image_id.value = str(image_id)
            admin_context = _get_context()

            # Do the caching itself
            _cache_img_to_raw(admin_context, image_id)
        except Exception as e:
            # Execution needs to continue even if conversion
            # errors are encountered
            LOG.error(traceback.format_exc())
            err = encodeutils.exception_to_unicode(e)
            image_meta = {
                'properties': {
                    'cache_raw_status': 'Error',
                    'cache_raw_error': err
                }
            }
            _safe_update_image_metadata(admin_context, image_id, image_meta)
        finally:
            with g_delete_lock:
                # If delete is waiting for caching to complete tell it
                # that it's over.
                g_image_id.value = ""
                # notify_all as same image may be deleted twice
                g_delete_lock.notify_all()