def fetch_image_into_cache(self, image_id): ctx = context.RequestContext(is_admin=True, show_deleted=True) image_meta = registry.get_image_metadata(self.options, ctx, image_id) with self.cache.open(image_meta, "wb") as cache_file: chunks = get_from_backend(image_meta["location"], expected_size=image_meta["size"], options=self.options) for chunk in chunks: cache_file.write(chunk)
def get_image_meta_or_404(self, request, image_id): """ Grabs the image metadata for an image with a supplied identifier or raises an HTTPNotFound (404) response :param request: The WSGI/Webob Request object :param image_id: The opaque image identifier :raises HTTPNotFound if image does not exist """ context = request.context try: return registry.get_image_metadata(context, image_id) except exception.NotFound: msg = _("Image with identifier %s not found") % image_id LOG.debug(msg) raise webob.exc.HTTPNotFound(msg, request=request, content_type='text/plain') except exception.Forbidden: msg = _("Forbidden image access") LOG.debug(msg) raise webob.exc.HTTPForbidden(msg, request=request, content_type='text/plain')
def process_response(self, resp): """ We intercept the response coming back from the main images Resource, caching image files to the cache """ if not self.get_status_code(resp) == httplib.OK: return resp request = resp.request if request.method != "GET": return resp match = get_images_re.match(request.path) if match is None: return resp image_id = match.group(2) if not self.cache.hit(image_id): # Make sure we're not already prefetching or caching the image # that just generated the miss if self.cache.is_image_currently_prefetching(image_id): logger.debug(_("Image '%s' is already being prefetched," " not tee'ing into the cache"), image_id) return resp if self.cache.is_image_currently_being_written(image_id): logger.debug(_("Image '%s' is already being cached," " not tee'ing into the cache"), image_id) return resp logger.debug(_("Tee'ing image '%s' into cache"), image_id) # TODO(jaypipes): This is so incredibly wasteful, but because # the image cache needs the image's name, we have to do this. # In the next iteration, remove the image cache's need for # any attribute other than the id... image_meta = registry.get_image_metadata(request.context, image_id) resp.app_iter = self.get_from_store_tee_into_cache(image_meta, resp.app_iter) return resp
def fetch_image_into_cache(self, image_id): ctx = context.RequestContext(is_admin=True, show_deleted=True) image_meta = registry.get_image_metadata( self.options, ctx, image_id) with self.cache.open(image_meta, "wb") as cache_file: chunks = get_from_backend(image_meta['location'], expected_size=image_meta['size'], options=self.options) for chunk in chunks: cache_file.write(chunk)
def _process_v1_request(self, request, image_id, image_iterator): image_meta = registry.get_image_metadata(request.context, image_id) self._verify_metadata(image_meta) response = webob.Response(request=request) raw_response = { 'image_iterator': image_iterator, 'image_meta': image_meta, } return self.serializer.show(response, raw_response)
def _process_v1_request(self, request, image_id, image_iterator): image_meta = registry.get_image_metadata(request.context, image_id) # Don't display location if 'location' in image_meta: del image_meta['location'] self._verify_metadata(image_meta) response = webob.Response(request=request) raw_response = { 'image_iterator': image_iterator, 'image_meta': image_meta, } return self.serializer.show(response, raw_response)
def _process_v1_request(self, request, image_id, image_iterator): image_meta = registry.get_image_metadata(request.context, image_id) if not image_meta['size']: # override image size metadata with the actual cached # file size, see LP Bug #900959 image_meta['size'] = self.cache.get_image_size(image_id) response = webob.Response(request=request) raw_response = { 'image_iterator': image_iterator, 'image_meta': image_meta, } return self.serializer.show(response, raw_response)
def process_request(self, request): """ For requests for an image file, we check the local image cache. If present, we return the image file, appending the image metadata in headers. If not present, we pass the request on to the next application in the pipeline. """ if request.method != "GET": return None match = get_images_re.match(request.path) if not match: return None image_id = match.group(2) if self.cache.hit(image_id): logger.debug(_("Cache hit for image '%s'"), image_id) image_iterator = self.get_from_cache(image_id) context = request.context try: image_meta = registry.get_image_metadata(context, image_id) response = webob.Response() return self.serializer.show(response, {"image_iterator": image_iterator, "image_meta": image_meta}) except exception.NotFound: msg = _( "Image cache contained image file for image '%s', " "however the registry did not contain metadata for " "that image!" % image_id ) logger.error(msg) return None # Make sure we're not already prefetching or caching the image # that just generated the miss if self.cache.is_image_currently_prefetching(image_id): logger.debug(_("Image '%s' is already being prefetched," " not tee'ing into the cache"), image_id) return None elif self.cache.is_image_currently_being_written(image_id): logger.debug(_("Image '%s' is already being cached," " not tee'ing into the cache"), image_id) return None # NOTE(sirp): If we're about to download and cache an # image which is currently in the prefetch queue, just # delete the queue items since we're caching it anyway if self.cache.is_image_queued_for_prefetch(image_id): self.cache.delete_queued_prefetch_image(image_id) return None
def queue_image(self, image_id): ctx = context.RequestContext(is_admin=True, show_deleted=True) try: image_meta = registry.get_image_metadata(ctx, image_id) if image_meta['status'] != 'active': logger.warn(_("Image '%s' is not active. Not queueing."), image_id) return False except exception.NotFound: logger.warn(_("No metadata found for image '%s'"), image_id) return False logger.debug(_("Queueing image '%s'"), image_id) self.cache.queue_image(image_id) return True
def fetch_image_into_cache(self, image_id): ctx = context.RequestContext(is_admin=True, show_deleted=True) try: image_meta = registry.get_image_metadata(ctx, image_id) if image_meta['status'] != 'active': LOG.warn(_("Image '%s' is not active. Not caching."), image_id) return False except exception.NotFound: LOG.warn(_("No metadata found for image '%s'"), image_id) return False image_data, image_size = get_from_backend(ctx, image_meta['location']) LOG.debug(_("Caching image '%s'"), image_id) self.cache.cache_image_iter(image_id, image_data) return True
def process_request(self, request): """ For requests for an image file, we check the local image cache. If present, we return the image file, appending the image metadata in headers. If not present, we pass the request on to the next application in the pipeline. """ if request.method != 'GET': return None match = get_images_re.match(request.path) if not match: return None image_id = match.group(2) # /images/detail is unfortunately supported, so here we # cut out those requests and anything with a query # parameter... # See LP Bug #879136 if '?' in image_id or image_id == 'detail': return None if self.cache.is_cached(image_id): logger.debug(_("Cache hit for image '%s'"), image_id) image_iterator = self.get_from_cache(image_id) context = request.context try: image_meta = registry.get_image_metadata(context, image_id) if not image_meta['size']: # override image size metadata with the actual cached # file size, see LP Bug #900959 image_meta['size'] = self.cache.get_image_size(image_id) response = webob.Response(request=request) return self.serializer.show(response, { 'image_iterator': image_iterator, 'image_meta': image_meta }) except exception.NotFound: msg = _("Image cache contained image file for image '%s', " "however the registry did not contain metadata for " "that image!" % image_id) logger.error(msg) return None
def process_request(self, request): """ For requests for an image file, we check the local image cache. If present, we return the image file, appending the image metadata in headers. If not present, we pass the request on to the next application in the pipeline. """ if request.method != 'GET': return None match = get_images_re.match(request.path) if not match: return None image_id = match.group(2) # /images/detail is unfortunately supported, so here we # cut out those requests and anything with a query # parameter... # See LP Bug #879136 if '?' in image_id or image_id == 'detail': return None if self.cache.is_cached(image_id): logger.debug(_("Cache hit for image '%s'"), image_id) image_iterator = self.get_from_cache(image_id) context = request.context try: image_meta = registry.get_image_metadata(context, image_id) if not image_meta['size']: # override image size metadata with the actual cached # file size, see LP Bug #900959 image_meta['size'] = self.cache.get_image_size(image_id) response = webob.Response(request=request) return self.serializer.show(response, { 'image_iterator': image_iterator, 'image_meta': image_meta}) except exception.NotFound: msg = _("Image cache contained image file for image '%s', " "however the registry did not contain metadata for " "that image!" % image_id) logger.error(msg) return None
def fetch_image_into_cache(self, image_id): ctx = context.RequestContext(is_admin=True, show_deleted=True) try: image_meta = registry.get_image_metadata(ctx, image_id) if image_meta['status'] != 'active': LOG.warn(_("Image '%s' is not active. Not caching."), image_id) return False except exception.NotFound: LOG.warn(_("No metadata found for image '%s'"), image_id) return False image_data, image_size = get_from_backend(image_meta['location']) LOG.debug(_("Caching image '%s'"), image_id) self.cache.cache_image_iter(image_id, image_data) return True
def _process_v1_request(self, request, image_id, image_iterator): image_meta = registry.get_image_metadata(request.context, image_id) # NOTE: admins can see image metadata in the v1 API, but shouldn't # be able to download the actual image data. if image_meta['deleted']: raise exception.NotFound() if not image_meta['size']: # override image size metadata with the actual cached # file size, see LP Bug #900959 image_meta['size'] = self.cache.get_image_size(image_id) response = webob.Response(request=request) raw_response = { 'image_iterator': image_iterator, 'image_meta': image_meta, } return self.serializer.show(response, raw_response)
def get_image_meta_or_404(self, request, id): """ Grabs the image metadata for an image with a supplied identifier or raises an HTTPNotFound (404) response :param request: The WSGI/Webob Request object :param id: The opaque image identifier :raises HTTPNotFound if image does not exist """ context = request.context try: return registry.get_image_metadata(self.options, context, id) except exception.NotFound: msg = "Image with identifier %s not found" % id logger.debug(msg) raise webob.exc.HTTPNotFound(msg, request=request, content_type="text/plain") except exception.NotAuthorized: msg = "Unauthorized image access" logger.debug(msg) raise webob.exc.HTTPForbidden(msg, request=request, content_type="text/plain")
def get_image_meta_or_404(self, request, image_id): """ Grabs the image metadata for an image with a supplied identifier or raises an HTTPNotFound (404) response :param request: The WSGI/Webob Request object :param image_id: The opaque image identifier :raises HTTPNotFound if image does not exist """ context = request.context try: return registry.get_image_metadata(context, image_id) except exception.NotFound: msg = _("Image with identifier %s not found") % image_id LOG.debug(msg) raise webob.exc.HTTPNotFound( msg, request=request, content_type='text/plain') except exception.Forbidden: msg = _("Forbidden image access") LOG.debug(msg) raise webob.exc.HTTPForbidden(msg, request=request, content_type='text/plain')