Esempio n. 1
0
    def _reserve(self, req, image_meta):
        """
        Adds the image metadata to the registry and assigns
        an image identifier if one is not supplied in the request
        headers. Sets the image's status to `queued`.

        :param req: The WSGI/Webob Request object
        :param id: The opaque image identifier
        :param image_meta: The image metadata

        :raises HTTPConflict if image already exists
        :raises HTTPBadRequest if image metadata is not valid
        """
        location = self._external_source(image_meta, req)
        scheme = image_meta.get("store")
        if scheme and scheme not in store.get_known_schemes():
            msg = "Required store %s is invalid" % scheme
            LOG.debug(msg)
            raise HTTPBadRequest(explanation=msg, content_type="text/plain")

        image_meta["status"] = "active" if image_meta.get("size") == 0 else "queued"

        if location:
            try:
                backend = store.get_store_from_location(location)
            except store.BadStoreUri:
                msg = "Invalid location %s" % location
                LOG.debug(msg)
                raise HTTPBadRequest(explanation=msg, request=req, content_type="text/plain")
            # check the store exists before we hit the registry, but we
            # don't actually care what it is at this point
            self.get_store_or_400(req, backend)

            # retrieve the image size from remote store (if not provided)
            image_meta["size"] = self._get_size(req.context, image_meta, location)
        else:
            # Ensure that the size attribute is set to zero for directly
            # uploadable images (if not provided). The size will be set
            # to a non-zero value during upload
            image_meta["size"] = image_meta.get("size", 0)

        try:
            image_meta = registry.add_image_metadata(req.context, image_meta)
            self.notifier.info("image.create", redact_loc(image_meta))
            return image_meta
        except exception.Duplicate:
            msg = "An image with identifier %s already exists" % image_meta["id"]
            LOG.debug(msg)
            raise HTTPConflict(explanation=msg, request=req, content_type="text/plain")
        except exception.Invalid as e:
            msg = _("Failed to reserve image. Got error: %s") % utils.exception_to_str(e)
            for line in msg.split("\n"):
                LOG.debug(line)
            raise HTTPBadRequest(explanation=msg, request=req, content_type="text/plain")
        except exception.Forbidden:
            msg = "Forbidden to reserve image."
            LOG.debug(msg)
            raise HTTPForbidden(explanation=msg, request=req, content_type="text/plain")
Esempio n. 2
0
 def _validate_source(source, req):
     """
     External sources (as specified via the location or copy-from headers)
     are supported only over non-local store types, i.e. S3, Swift, HTTP.
     Note the absence of file:// for security reasons, see LP bug #942118.
     If the above constraint is violated, we reject with 400 "Bad Request".
     """
     if source:
         pieces = urlparse.urlparse(source)
         schemes = [scheme for scheme in store.get_known_schemes() if scheme != "file"]
         for scheme in schemes:
             if pieces.scheme == scheme:
                 return source
         msg = "External sourcing not supported for store %s" % source
         LOG.debug(msg)
         raise HTTPBadRequest(explanation=msg, request=req, content_type="text/plain")
Esempio n. 3
0
def validate_external_location(uri):
    """
    Validate if URI of external location are supported.

    Only over non-local store types are OK, i.e. S3, Swift,
    HTTP. Note the absence of 'file://' for security reasons,
    see LP bug #942118, 1400966, 'swift+config://' is also
    absent for security reasons, see LP bug #1334196.

    :param uri: The URI of external image location.
    :return: Whether given URI of external image location are OK.
    """

    # TODO(zhiyan): This function could be moved to glance_store.
    # TODO(gm): Use a whitelist of allowed schemes
    scheme = urlparse.urlparse(uri).scheme
    return scheme in store_api.get_known_schemes() and scheme not in RESTRICTED_URI_SCHEMAS
Esempio n. 4
0
def validate_external_location(uri):
    """
    Validate if URI of external location are supported.

    Only over non-local store types are OK, i.e. S3, Swift,
    HTTP. Note the absence of 'file://' for security reasons,
    see LP bug #942118, 1400966, 'swift+config://' is also
    absent for security reasons, see LP bug #1334196.

    :param uri: The URI of external image location.
    :return: Whether given URI of external image location are OK.
    """

    # TODO(zhiyan): This function could be moved to glance_store.
    # TODO(gm): Use a whitelist of allowed schemes
    scheme = urlparse.urlparse(uri).scheme
    return (scheme in store_api.get_known_schemes()
            and scheme not in RESTRICTED_URI_SCHEMAS)
Esempio n. 5
0
def validate_external_location(uri):
    """
    Validate if URI of external location are supported.

    Only over non-local store types are OK, i.e. S3, Swift,
    HTTP. Note the absence of 'file://' for security reasons,
    see LP bug #942118, 1400966, 'swift+config://' is also
    absent for security reasons, see LP bug #1334196.

    :param uri: The URI of external image location.
    :return: Whether given URI of external image location are OK.
    """

    # TODO(zhiyan): This function could be moved to glance_store.

    pieces = urlparse.urlparse(uri)
    valid_schemes = [scheme for scheme in store_api.get_known_schemes()
                     if scheme != 'file' and scheme != 'swift+config']
    return pieces.scheme in valid_schemes
Esempio n. 6
0
def validate_external_location(uri):
    """
    Validate if URI of external location are supported.

    Only over non-local store types are OK, i.e. S3, Swift,
    HTTP. Note the absence of 'file://' for security reasons,
    see LP bug #942118, 1400966, 'swift+config://' is also
    absent for security reasons, see LP bug #1334196.

    :param uri: The URI of external image location.
    :return: Whether given URI of external image location are OK.
    """

    # TODO(zhiyan): This function could be moved to glance_store.

    pieces = urlparse.urlparse(uri)
    valid_schemes = [
        scheme for scheme in store_api.get_known_schemes()
        if scheme != 'file' and scheme != 'swift+config'
    ]
    return pieces.scheme in valid_schemes