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)
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)
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()