def _query(self, location, method, depth=0): if depth > MAX_REDIRECTS: msg = ("The HTTP URL exceeded %(max_redirects)s maximum " "redirects.", { 'max_redirects': MAX_REDIRECTS }) LOG.debug(msg) raise exception.MaxRedirectsExceeded(redirects=MAX_REDIRECTS) loc = location.store_location cookie = self._build_vim_cookie_header( self._session.vim.client.options.transport.cookiejar) headers = {'Cookie': cookie} try: conn = self._get_http_conn(method, loc, headers) resp = conn.getresponse() except Exception: with excutils.save_and_reraise_exception(): LOG.exception(_LE('Failed to access image %(image)s content.'), {'image': location.image_id}) if resp.status >= 400: if resp.status == httplib.UNAUTHORIZED: self._create_session() raise exception.NotAuthenticated() if resp.status == httplib.NOT_FOUND: msg = 'VMware datastore could not find image at URI.' LOG.debug(msg) raise exception.NotFound(msg) reason = (_('HTTP request returned a %(status)s status code.') % { 'status': resp.status }) LOG.info(reason) raise exception.BadStoreUri(message=reason) location_header = resp.getheader('location') if location_header: if resp.status not in (301, 302): reason = (_("The HTTP URL %(path)s attempted to redirect " "with an invalid %(status)s status code.") % { 'path': loc.path, 'status': resp.status }) LOG.info(reason) raise exception.BadStoreUri(message=reason) location_class = glance.store.location.Location new_loc = location_class(location.store_name, location.store_location.__class__, uri=location_header, image_id=location.image_id, store_specs=location.store_specs) return self._query(new_loc, method, depth + 1) content_length = int(resp.getheader('content-length', 0)) return (conn, resp, content_length)
def show(self, req, namespace, property_name, filters=None): ns_repo = self.gateway.get_metadef_namespace_repo( req.context, authorization_layer=False) try: namespace_obj = ns_repo.get(namespace) except (exception.Forbidden, exception.NotFound): # NOTE (abhishekk): Returning 404 Not Found as the # namespace is outside of this user's project msg = _("Namespace %s not found") % namespace raise webob.exc.HTTPNotFound(explanation=msg) try: # NOTE(abhishekk): Metadef properties are associated with # namespace, so made provision to pass namespace here # for visibility check api_pol = api_policy.MetadefAPIPolicy(req.context, md_resource=namespace_obj, enforcer=self.policy) api_pol.get_metadef_property() if filters and filters['resource_type']: # Verify that you can fetch resource type details api_pol.get_metadef_resource_type() rs_repo = self.gateway.get_metadef_resource_type_repo( req.context, authorization_layer=False) db_resource_type = rs_repo.get(filters['resource_type'], namespace) prefix = db_resource_type.prefix if prefix and property_name.startswith(prefix): property_name = property_name[len(prefix):] else: msg = (_("Property %(property_name)s does not start " "with the expected resource type association " "prefix of '%(prefix)s'.") % { 'property_name': property_name, 'prefix': prefix }) raise exception.NotFound(msg) prop_repo = self.gateway.get_metadef_property_repo( req.context, authorization_layer=False) db_property = prop_repo.get(namespace, property_name) property = self._to_model(db_property) except exception.Forbidden as e: LOG.debug( "User not permitted to show metadata property '%s' " "within '%s' namespace", property_name, namespace) raise webob.exc.HTTPForbidden(explanation=e.msg) except exception.NotFound as e: raise webob.exc.HTTPNotFound(explanation=e.msg) return property
def test_execute_drop_lock_fails(self, mock_get_task): mock_get_task.return_value = self.task self.wrapper.drop_lock_for_task.side_effect = exception.NotFound() complete = import_flow._CompleteTask(TASK_ID1, TASK_TYPE, self.task_repo, self.wrapper) with mock.patch('glance.async_.flows.api_image_import.LOG') as m_log: complete.execute() m_log.error.assert_called_once_with('Image %(image)s import task ' '%(task)s did not hold the ' 'lock upon completion!', {'image': IMAGE_ID1, 'task': TASK_ID1}) self.task.succeed.assert_called_once_with({'image_id': IMAGE_ID1})
def download(self, req, image_id): image_repo = self.gateway.get_repo(req.context) try: image = image_repo.get(image_id) if not image.locations: reason = _("No image data could be found") raise exception.NotFound(reason) except exception.NotFound as e: raise webob.exc.HTTPNotFound(explanation=unicode(e)) except exception.Forbidden as e: raise webob.exc.HTTPForbidden(explanation=unicode(e)) return image
def save(self, image): image_values = self._format_image_to_db(image) try: new_values = self.db_api.image_update(self.context, image.image_id, image_values, purge_props=True) except (exception.NotFound, exception.Forbidden): msg = _("No image found with ID %s") % image.image_id raise exception.NotFound(msg) self.db_api.image_tag_set_all(self.context, image.image_id, image.tags) image.updated_at = new_values['updated_at']
def _verify_metadata(self, image_meta): """ Sanity check the 'deleted' and 'size' metadata values. """ # 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)
def image_update(self, context, image_id, image_values): LOG.info('Updating image %s with values %s' % (image_id, str(image_values))) try: image = self.images[image_id] LOG.info('Found image %s: %s' % (image_id, str(image))) except KeyError: raise exception.NotFound(image_id=image_id) image.update(image_values) self.images[image_id] = image LOG.info('Image %s updated to %s' % (image_id, str(image))) return image
def get(self, namespace, property_name): try: namespace_entity = self.meta_namespace_repo.get(namespace) db_property_type = self.db_api.metadef_property_get( self.context, namespace, property_name ) except (exception.NotFound, exception.Forbidden): msg = _('Could not find property %s') % property_name raise exception.NotFound(msg) return self._format_metadef_property_from_db( db_property_type, namespace_entity)
def image_tag_delete(context, image_id, value, session=None): """Delete an image tag.""" session = session or get_session() query = session.query(models.ImageTag)\ .filter_by(image_id=image_id)\ .filter_by(value=value)\ .filter_by(deleted=False) try: tag_ref = query.one() except sa_orm.exc.NoResultFound: raise exception.NotFound() tag_ref.delete(session=session)
def remove(self, image): image_values = self._format_image_to_db(image) try: self.db_api.image_update(self.context, image.image_id, image_values, purge_props=True) except (exception.NotFound, exception.Forbidden): msg = _("No image found with ID %s") % image.image_id raise exception.NotFound(msg) # NOTE(markwash): don't update tags? new_values = self.db_api.image_destroy(self.context, image.image_id) image.updated_at = new_values['updated_at']
def _get_file(self, location): store_location = location if isinstance(location, glance.store.location.Location): store_location = location.store_location try: parsed = urlparse.urlparse(store_location.get_uri()) return self.fs.get(parsed.netloc) except gridfs.errors.NoFile: msg = _("Could not find %s image in GridFS") % \ store_location.get_uri() LOG.debug(msg) raise exception.NotFound(msg)
def update(self, req, metadata_object, namespace, object_name): meta_repo = self.gateway.get_metadef_object_repo( req.context, authorization_layer=False) try: ns_repo = self.gateway.get_metadef_namespace_repo( req.context, authorization_layer=False) try: # NOTE(abhishekk): Verifying that namespace is visible # to user namespace_obj = ns_repo.get(namespace) except exception.Forbidden: # NOTE (abhishekk): Returning 404 Not Found as the # namespace is outside of this user's project msg = _("Namespace %s not found") % namespace raise exception.NotFound(msg) # NOTE(abhishekk): Metadef object is created for Metadef namespaces # Here we are just checking if user is authorized to modify metadef # object or not. api_policy.MetadefAPIPolicy( req.context, md_resource=namespace_obj, enforcer=self.policy).modify_metadef_object() metadef_object = meta_repo.get(namespace, object_name) metadef_object._old_name = metadef_object.name metadef_object.name = wsme_utils._get_value(metadata_object.name) metadef_object.description = wsme_utils._get_value( metadata_object.description) metadef_object.required = wsme_utils._get_value( metadata_object.required) metadef_object.properties = wsme_utils._get_value( metadata_object.properties) updated_metadata_obj = meta_repo.save(metadef_object) except exception.Invalid as e: msg = (_("Couldn't update metadata object: %s") % encodeutils.exception_to_unicode(e)) raise webob.exc.HTTPBadRequest(explanation=msg) except exception.Forbidden as e: LOG.debug( "User not permitted to update metadata object '%s' " "within '%s' namespace ", object_name, namespace) raise webob.exc.HTTPForbidden(explanation=e.msg) except exception.NotFound as e: raise webob.exc.HTTPNotFound(explanation=e.msg) except exception.Duplicate as e: raise webob.exc.HTTPConflict(explanation=e.msg) return MetadefObject.to_wsme_model( updated_metadata_obj, get_object_href(namespace, updated_metadata_obj), self.obj_schema_link)
def image_member_find(context, image_id, member, session=None): """Find a membership association between image and member.""" session = session or get_session() try: # Note lack of permissions check; this function is called from # RequestContext.is_image_visible(), so avoid recursive calls return session.query(models.ImageMember).\ options(joinedload(models.ImageMember.image)).\ filter_by(image_id=image_id).\ filter_by(member=member).\ one() except exc.NoResultFound: raise exception.NotFound("No membership found for image %s member %s" % (image_id, member))
def test_revert_drops_lock_missing(self, mock_log): wrapper = import_flow.ImportActionWrapper(self.img_repo, IMAGE_ID1, TASK_ID1) imagelock = import_flow._ImageLock(TASK_ID1, TASK_TYPE, wrapper) with mock.patch.object(wrapper, 'drop_lock_for_task') as mock_drop: mock_drop.side_effect = exception.NotFound() imagelock.revert(None) mock_log.warning.assert_called_once_with( 'Image %(image)s import task ' '%(task)s lost its lock ' 'during execution!', { 'image': IMAGE_ID1, 'task': TASK_ID1 })
def execute(self): """Create temp file into store and return path to it :param image_id: Glance Image ID """ image = self.image_repo.get(self.image_id) # NOTE (abhishekk): If ``all_stores_must_succeed`` is set to True # and copying task fails then we keep data in staging area as it # is so that if second call is made to copy the same image then # no need to copy the data in staging area again. file_path = "%s/%s" % (getattr( CONF, 'os_glance_staging_store').filesystem_store_datadir, self.image_id) if os.path.exists(file_path): return file_path, 0 # At first search image in default_backend default_store = CONF.glance_store.default_backend for loc in image.locations: if loc['metadata'].get('store') == default_store: try: return self._copy_to_staging_store(loc) except store_api.exceptions.NotFound: msg = (_LE("Image not present in default store, searching " "in all glance-api specific available " "stores")) LOG.error(msg) break available_backends = CONF.enabled_backends for loc in image.locations: image_backend = loc['metadata'].get('store') if (image_backend in available_backends.keys() and image_backend != default_store): try: return self._copy_to_staging_store(loc) except store_api.exceptions.NotFound: LOG.error( _LE('Image: %(img_id)s is not present in store ' '%(store)s.'), { 'img_id': self.image_id, 'store': image_backend }) continue raise exception.NotFound( _("Image not found in any configured " "store"))
def get_key(bucket, obj): """ Get a key from a bucket :param bucket: The ``boto.s3.Bucket`` :param obj: Object to get the key for :raises ``glance.exception.NotFound`` if key is not found. """ key = bucket.get_key(obj) if not key or not key.exists(): msg = _("Could not find key %(obj)s in bucket %(bucket)s") % locals() logger.error(msg) raise exception.NotFound(msg) return key
def save(self, image, from_state=None): image_values = self._format_image_to_db(image) if image_values['size'] > CONF.image_size_cap: raise exception.ImageSizeLimitExceeded try: new_values = self.db_api.image_update(self.context, image.image_id, image_values, purge_props=True, from_state=from_state) except (exception.NotFound, exception.Forbidden): msg = _("No image found with ID %s") % image.image_id raise exception.NotFound(msg) self.db_api.image_tag_set_all(self.context, image.image_id, image.tags) image.updated_at = new_values['updated_at']
def get_key(bucket, obj): """ Get a key from a bucket :param bucket: The ``boto.s3.Bucket`` :param obj: Object to get the key for :raises ``glance.exception.NotFound`` if key is not found. """ key = bucket.get_key(obj) if not key or not key.exists(): msg = (_("Could not find key %(obj)s in bucket %(bucket)s") % {'obj': obj, 'bucket': bucket}) LOG.debug(msg) raise exception.NotFound(msg) return key
def get(self, location, connection=None): location = location.store_location if not connection: connection = self.get_connection(location) try: resp_headers, resp_body = connection.get_object( container=location.container, obj=location.obj, resp_chunk_size=self.CHUNKSIZE) except swiftclient.ClientException, e: if e.http_status == httplib.NOT_FOUND: uri = location.get_uri() msg = _("Swift could not find image at URI.") raise exception.NotFound(msg) else: raise
def get_bucket(conn, bucket_id): """ Get a bucket from an s3 connection :param conn: The ``boto.s3.connection.S3Connection`` :param bucket_id: ID of the bucket to fetch :raises ``glance.exception.NotFound`` if bucket is not found. """ bucket = conn.get_bucket(bucket_id) if not bucket: msg = _("Could not find bucket with ID %(bucket_id)s") % locals() logger.error(msg) raise exception.NotFound(msg) return bucket
def image_member_get(context, member_id, session=None): """Get an image member or raise if it does not exist.""" session = session or get_session() try: member = session.query(models.ImageMember).\ options(joinedload(models.ImageMember.image)).\ filter_by(deleted=_deleted(context)).\ filter_by(id=member_id).\ one() except exc.NoResultFound: raise exception.NotFound("No membership found with ID %s" % member_id) # Make sure they can look at it if not context.is_image_visible(member.image): raise exception.NotAuthorized("Image not visible to you") return member
def get_size(self, location): """ Takes a `glance.store.location.Location` object that indicates where to find the image file and returns the image 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 :rtype int """ loc = location.store_location image = SheepdogImage(self.addr, self.port, loc.image, self.chunk_size) if not image.exist(): raise exception.NotFound( _("Sheepdog image %s does not exist") % image.name) return image.get_size()
def delete(self, location): """ Takes a `glance.store.location.Location` object that indicates where to find the image file to delete :location `glance.store.location.Location` object, supplied from glance.store.location.get_location_from_uri() :raises NotFound if image does not exist """ loc = location.store_location image = SheepdogImage(self.addr, self.port, loc.image, self.chunk_size) if not image.exist(): raise exception.NotFound( _("Sheepdog image %s does not exist") % loc.image) image.delete()
def create(self, req, metadata_object, namespace): object_factory = self.gateway.get_metadef_object_factory( req.context, authorization_layer=False) object_repo = self.gateway.get_metadef_object_repo( req.context, authorization_layer=False) try: ns_repo = self.gateway.get_metadef_namespace_repo( req.context, authorization_layer=False) try: # NOTE(abhishekk): Verifying that namespace is visible # to user namespace_obj = ns_repo.get(namespace) except exception.Forbidden: # NOTE (abhishekk): Returning 404 Not Found as the # namespace is outside of this user's project msg = _("Namespace %s not found") % namespace raise exception.NotFound(msg) # NOTE(abhishekk): Metadef object is created for Metadef namespaces # Here we are just checking if user is authorized to create metadef # object or not. api_policy.MetadefAPIPolicy( req.context, md_resource=namespace_obj, enforcer=self.policy).add_metadef_object() new_meta_object = object_factory.new_object( namespace=namespace, **metadata_object.to_dict()) object_repo.add(new_meta_object) except exception.Forbidden as e: LOG.debug( "User not permitted to create metadata object within " "'%s' namespace", namespace) raise webob.exc.HTTPForbidden(explanation=e.msg) except exception.Invalid as e: msg = (_("Couldn't create metadata object: %s") % encodeutils.exception_to_unicode(e)) raise webob.exc.HTTPBadRequest(explanation=msg) except exception.NotFound as e: raise webob.exc.HTTPNotFound(explanation=e.msg) except exception.Duplicate as e: raise webob.exc.HTTPConflict(explanation=e.msg) return MetadefObject.to_wsme_model( new_meta_object, get_object_href(namespace, new_meta_object), self.obj_schema_link)
def delete(self, req, namespace, resource_type): rs_type_repo = self.gateway.get_metadef_resource_type_repo( req.context, authorization_layer=False) ns_repo = self.gateway.get_metadef_namespace_repo( req.context, authorization_layer=False) try: namespace_obj = ns_repo.get(namespace) except (exception.Forbidden, exception.NotFound): # NOTE (abhishekk): Returning 404 Not Found as the # namespace is outside of this user's project msg = _("Namespace %s not found") % namespace raise webob.exc.HTTPNotFound(explanation=msg) try: # NOTE(abhishekk): Metadef resource type is created for Metadef # namespaces. Here we are just checking if user is authorized # to delete metadef resource types or not. api_policy.MetadefAPIPolicy( req.context, md_resource=namespace_obj, enforcer=self.policy).remove_metadef_resource_type_association( ) filters = {} found = False filters['namespace'] = namespace db_resource_type_list = rs_type_repo.list(filters=filters) for db_resource_type in db_resource_type_list: if db_resource_type.name == resource_type: db_resource_type.delete() rs_type_repo.remove(db_resource_type) found = True if not found: raise exception.NotFound() except exception.Forbidden as e: LOG.debug( "User not permitted to delete metadata resource type " "'%s' within '%s' namespace", resource_type, namespace) raise webob.exc.HTTPForbidden(explanation=e.msg) except exception.NotFound: msg = (_("Failed to find resource type %(resourcetype)s to " "delete") % { 'resourcetype': resource_type }) LOG.error(msg) raise webob.exc.HTTPNotFound(explanation=msg)
def get(self, location): """ Takes a `glance.store.location.Location` object that indicates where to find the image file, and returns a tuple of generator (for reading the image file) and image_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 filepath = loc.path if not os.path.exists(filepath): raise exception.NotFound(_("Image file %s not found") % filepath) else: msg = _("Found image at %s. Returning in ChunkedFile.") % filepath logger.debug(msg) return (ChunkedFile(filepath), None)
def get(self, location): """ Takes a `glance.store.location.Location` object that indicates where to find the image file, and returns a generator for reading the image file :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 image = SheepdogImage(self.addr, self.port, loc.image, self.READ_CHUNKSIZE) if not image.exist(): raise exception.NotFound( _("Sheepdog image %s does not exist") % image.name) return (ImageIterator(image), image.get_size())
def image_update(context, image_id, image_values): global DATA try: image = DATA['images'][image_id] except KeyError: raise exception.NotFound(image_id=image_id) properties = image_values.pop('properties', {}) properties = [{ 'name': k, 'value': v, 'deleted': False } for k, v in properties.items()] image['properties'] = properties image['updated_at'] = timeutils.utcnow() image.update(image_values) DATA['images'][image_id] = image return image
def _do_pagination(context, images, marker, limit, show_deleted): start = 0 end = -1 if marker is None: start = 0 else: # Check that the image is accessible image_get(context, marker, force_show_deleted=show_deleted) for i, image in enumerate(images): if image['id'] == marker: start = i + 1 break else: raise exception.NotFound() end = start + limit if limit is not None else None return images[start:end]
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) 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 exception.NotFound( _('RBD image %s does not exist') % self.name)