def update(self, req, image_id, changes): self._enforce(req, 'modify_image') context = req.context try: image = self.db_api.image_get(context, image_id) except (exception.NotFound, exception.Forbidden): msg = ("Failed to find image %(image_id)s to update" % locals()) LOG.info(msg) raise webob.exc.HTTPNotFound(explanation=msg) image = self._normalize_properties(dict(image)) updates = self._extract_updates(req, image, changes) tags = None if len(updates) > 0: tags = self._extract_tags(updates) purge_props = 'properties' in updates try: image = self.db_api.image_update(context, image_id, updates, purge_props) except (exception.NotFound, exception.Forbidden): raise webob.exc.HTTPNotFound() image = self._normalize_properties(dict(image)) v2.update_image_read_acl(req, self.store_api, self.db_api, image) if tags is not None: self.db_api.image_tag_set_all(req.context, image_id, tags) image['tags'] = tags else: self._append_tags(req.context, image) self.notifier.info('image.update', image) return image
def delete(self, req, image_id, tenant_id): #TODO(bcwaldon): Refactor these methods so we don't need to explicitly # retrieve a session object here session = self.db_api.get_session() try: image = self.db_api.image_get(req.context, image_id, session=session) except exception.NotFound: raise webob.exc.HTTPNotFound() except exception.Forbidden: # If it's private and doesn't belong to them, don't let on # that it exists raise webob.exc.HTTPNotFound() members = self.db_api.image_member_find(req.context, image_id=image_id, member=tenant_id, session=session) try: member = members[0] except IndexError: raise webob.exc.HTTPNotFound() self.db_api.image_member_delete(req.context, member, session=session) v2.update_image_read_acl(req, self.db_api, image)
def update(self, req, image_id, image): self._enforce(req, 'modify_image') is_public = image.get('is_public') if is_public: self._enforce(req, 'publicize_image') tags = self._extract_tags(image) try: image = self.db_api.image_update(req.context, image_id, image) except (exception.NotFound, exception.Forbidden): msg = ("Failed to find image %(image_id)s to update" % locals()) LOG.info(msg) raise webob.exc.HTTPNotFound(explanation=msg) image = self._normalize_properties(dict(image)) v2.update_image_read_acl(req, self.db_api, image) if tags is not None: self.db_api.image_tag_set_all(req.context, image_id, tags) image['tags'] = tags else: self._append_tags(req.context, image) self.notifier.info('image.update', image) return image
def create(self, req, image_id, access_record): #TODO(bcwaldon): Refactor these methods so we don't need to # explicitly retrieve a session object here session = self.db_api.get_session() try: image = self.db_api.image_get(req.context, image_id, session=session) except exception.NotFound: raise webob.exc.HTTPNotFound() except exception.Forbidden: # If it's private and doesn't belong to them, don't let on # that it exists raise webob.exc.HTTPNotFound() # Image is visible, but authenticated user still may not be able to # share it if not self.db_api.is_image_sharable(req.context, image): msg = _("No permission to share that image") raise webob.exc.HTTPForbidden(msg) access_record['image_id'] = image_id member = self.db_api.image_member_create(req.context, access_record) v2.update_image_read_acl(req, self.db_api, image) return member
def upload(self, req, image_id, data, size): image = self._get_image(req.context, image_id) try: location, size, checksum = self.store_api.add_to_backend( req.context, 'file', image_id, data, size) except exception.Duplicate: raise webob.exc.HTTPConflict() v2.update_image_read_acl(req, self.db_api, image) values = {'location': location, 'size': size, 'checksum': checksum} self.db_api.image_update(req.context, image_id, values)
def create(self, req, image): image["owner"] = req.context.owner image["status"] = "queued" tags = self._extract_tags(image) image = dict(self.db_api.image_create(req.context, image)) if tags is not None: self.db_api.image_tag_set_all(req.context, image["id"], tags) image["tags"] = tags else: image["tags"] = [] v2.update_image_read_acl(req, self.db_api, image) return self._normalize_properties(dict(image))
def create(self, req, image): image.setdefault('owner', req.context.owner) image['status'] = 'queued' tags = self._extract_tags(image) image = dict(self.db_api.image_create(req.context, image)) if tags is not None: self.db_api.image_tag_set_all(req.context, image['id'], tags) image['tags'] = tags else: image['tags'] = [] v2.update_image_read_acl(req, self.db_api, image) return self._normalize_properties(dict(image))
def update(self, req, image_id, image): tags = self._extract_tags(image) try: image = self.db_api.image_update(req.context, image_id, image) except (exception.NotFound, exception.Forbidden): raise webob.exc.HTTPNotFound() image = self._normalize_properties(dict(image)) v2.update_image_read_acl(req, self.db_api, image) if tags is not None: self.db_api.image_tag_set_all(req.context, image_id, tags) image["tags"] = tags else: self._append_tags(req.context, image) return image
def create(self, req, image): self._enforce(req, 'add_image') is_public = image.get('is_public') if is_public: self._enforce(req, 'publicize_image') image['owner'] = req.context.owner image['status'] = 'queued' tags = self._extract_tags(image) image = dict(self.db_api.image_create(req.context, image)) if tags is not None: self.db_api.image_tag_set_all(req.context, image['id'], tags) image['tags'] = tags else: image['tags'] = [] v2.update_image_read_acl(req, self.db_api, image) return self._normalize_properties(dict(image))
def update(self, req, image_id, image): self._enforce(req, 'modify_image') is_public = image.get('is_public') if is_public: self._enforce(req, 'publicize_image') tags = self._extract_tags(image) try: image = self.db_api.image_update(req.context, image_id, image) except (exception.NotFound, exception.Forbidden): raise webob.exc.HTTPNotFound() image = self._normalize_properties(dict(image)) v2.update_image_read_acl(req, self.db_api, image) if tags is not None: self.db_api.image_tag_set_all(req.context, image_id, tags) image['tags'] = tags else: self._append_tags(req.context, image) return image
except exception.StorageWriteDenied, e: msg = _("Insufficient permissions on image storage media: %s") % e LOG.error(msg) raise webob.exc.HTTPServiceUnavailable(explanation=msg, request=req) except webob.exc.HTTPError, e: LOG.error("Failed to upload image data due to HTTP error") raise except Exception, e: LOG.exception("Failed to upload image data due to internal error") raise else: v2.update_image_read_acl(req, self.store_api, self.db_api, image) values = {'location': location, 'size': size, 'checksum': checksum} self.db_api.image_update(req.context, image_id, values) updated_image = self._get_image(req.context, image_id) self.notifier.info('image.upload', updated_image) def download(self, req, image_id): self._enforce(req, 'download_image') ctx = req.context image = self._get_image(ctx, image_id) location = image['location'] if location: image_data, image_size = self.store_api.get_from_backend(ctx, location) #NOTE(bcwaldon): This is done to match the behavior of the v1 API. # The store should always return a size that matches what we have
except exception.StorageWriteDenied, e: msg = _("Insufficient permissions on image storage media: %s") % e LOG.error(msg) raise webob.exc.HTTPServiceUnavailable(explanation=msg, request=req) except webob.exc.HTTPError, e: LOG.error("Failed to upload image data due to HTTP error") raise except Exception, e: LOG.exception("Failed to upload image data due to internal error") raise else: v2.update_image_read_acl(req, self.store_api, self.db_api, image) values = {'location': location, 'size': size, 'checksum': checksum} self.db_api.image_update(req.context, image_id, values) updated_image = self._get_image(req.context, image_id) self.notifier.info('image.upload', updated_image) def download(self, req, image_id): self._enforce(req, 'download_image') ctx = req.context image = self._get_image(ctx, image_id) location = image['location'] if location: image_data, image_size = self.store_api.get_from_backend( ctx, location) #NOTE(bcwaldon): This is done to match the behavior of the v1 API. # The store should always return a size that matches what we have