Example #1
0
    def get(self, location):
        """
        Takes a `tank.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 `tank.store.location.Location` object, supplied
                        from tank.store.location.get_location_from_uri()
        :raises `tank.exception.NotFound` if image does not exist
        """
        loc = location.store_location
        chase_conn = self._make_chase_connection(auth_url=loc.chase_auth_url,
                                                 user=loc.user,
                                                 key=loc.key)

        try:
            (resp_headers,
             resp_body) = chase_conn.get_object(container=loc.container,
                                                obj=loc.obj,
                                                resp_chunk_size=self.CHUNKSIZE)
        except chase_client.ClientException, e:
            if e.http_status == httplib.NOT_FOUND:
                uri = location.get_store_uri()
                raise exception.NotFound(
                    _("Chase could not find image at "
                      "uri %(uri)s") % locals())
            else:
                raise
Example #2
0
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 ``tank.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
Example #3
0
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 ``tank.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
Example #4
0
    def get(self, location):
        """
        Takes a `tank.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 `tank.store.location.Location` object, supplied
                        from tank.store.location.get_location_from_uri()
        :raises `tank.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)
Example #5
0
 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)
Example #6
0
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
        query = session.query(models.ImageMember).\
                        options(joinedload(models.ImageMember.image)).\
                        filter_by(image_id=image_id).\
                        filter_by(member=member)

        if not can_show_deleted(context):
            query = query.filter_by(deleted=False)

        return query.one()

    except exc.NoResultFound:
        raise exception.NotFound("No membership found for image %s member %s" %
                                 (image_id, member))
Example #7
0
    def delete(self, location):
        """
        Takes a `tank.store.location.Location` object that indicates
        where to find the image file to delete

        :location `tank.store.location.Location` object, supplied
                  from tank.store.location.get_location_from_uri()

        :raises NotFound if image does not exist
        """
        loc = location.store_location

        with rados.Rados(conffile=self.conf_file, rados_id=self.user) as conn:
            with conn.open_ioctx(self.pool) as ioctx:
                try:
                    rbd.RBD().remove(ioctx, str(loc.image))
                except rbd.ImageNotFound:
                    raise exception.NotFound(
                        _('RBD image %s does not exist') % loc.image)
Example #8
0
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:
        query = session.query(models.ImageMember).\
                        options(joinedload(models.ImageMember.image)).\
                        filter_by(id=member_id)

        if not can_show_deleted(context):
            query = query.filter_by(deleted=False)

        member = query.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
Example #9
0
    def delete(self, location):
        """
        Takes a `tank.store.location.Location` object that indicates
        where to find the image file to delete

        :location `tank.store.location.Location` object, supplied
                  from tank.store.location.get_location_from_uri()

        :raises NotFound if image does not exist
        :raises NotAuthorized if cannot delete because of permissions
        """
        loc = location.store_location
        fn = loc.path
        if os.path.exists(fn):
            try:
                logger.debug(_("Deleting image at %(fn)s") % locals())
                os.unlink(fn)
            except OSError:
                raise exception.NotAuthorized(
                    _("You cannot delete file %s") % fn)
        else:
            raise exception.NotFound(_("Image file %s does not exist") % fn)
Example #10
0
def image_get(context, image_id, session=None, force_show_deleted=False):
    """Get an image or raise if it does not exist."""
    session = session or get_session()

    try:
        query = session.query(models.Image).\
                        options(joinedload(models.Image.properties)).\
                        options(joinedload(models.Image.members)).\
                        filter_by(id=image_id)

        # filter out deleted images if context disallows it
        if not force_show_deleted and not can_show_deleted(context):
            query = query.filter_by(deleted=False)

        image = query.one()

    except exc.NoResultFound:
        raise exception.NotFound("No image found with ID %s" % image_id)

    # Make sure they can look at it
    if not context.is_image_visible(image):
        raise exception.NotAuthorized("Image not visible to you")

    return image
Example #11
0
                for segment in chase_conn.get_container(obj_container,
                                                        prefix=obj_prefix)[1]:
                    # TODO(jaypipes): This would be an easy area to parallelize
                    # since we're simply sending off parallelizable requests
                    # to Chase to delete stuff. It's not like we're going to
                    # be hogging up network or file I/O here...
                    chase_conn.delete_object(obj_container, segment['name'])

            else:
                chase_conn.delete_object(loc.container, loc.obj)

        except chase_client.ClientException, e:
            if e.http_status == httplib.NOT_FOUND:
                uri = location.get_store_uri()
                raise exception.NotFound(
                    _("Chase could not find image at "
                      "uri %(uri)s") % locals())
            else:
                raise


class ChunkReader(object):
    def __init__(self, fd, checksum, total):
        self.fd = fd
        self.checksum = checksum
        self.total = total
        self.bytes_read = 0

    def read(self, i):
        left = self.total - self.bytes_read
        if i > left:
Example #12
0
    def _do_request(self, method, url, body, headers):
        """
        Connects to the server and issues a request.  Handles converting
        any returned HTTP error status codes to X7/Tank exceptions
        and closing the server connection. Returns the result data, or
        raises an appropriate exception.

        :param method: HTTP method ("GET", "POST", "PUT", etc...)
        :param url: urlparse.ParsedResult object with URL information
        :param body: string of data to send, or None (default)
        :param headers: mapping of key/value pairs to add as headers

        :note

        If the body param has a read attribute, and method is either
        POST or PUT, this method will automatically conduct a chunked-transfer
        encoding and use the body as a file object, transferring chunks
        of data using the connection's send() method. This allows large
        objects to be transferred efficiently without buffering the entire
        body in memory.
        """
        if url.query:
            path = url.path + "?" + url.query
        else:
            path = url.path

        try:
            connection_type = self.get_connection_type()
            headers = headers or {}

            if 'x-auth-token' not in headers and self.auth_tok:
                headers['x-auth-token'] = self.auth_tok

            c = connection_type(url.hostname, url.port, **self.connect_kwargs)

            # Do a simple request or a chunked request, depending
            # on whether the body param is a file-like object and
            # the method is PUT or POST
            if hasattr(body, 'read') and method.lower() in ('post', 'put'):
                # Chunk it, baby...
                c.putrequest(method, path)

                for header, value in headers.items():
                    c.putheader(header, value)
                c.putheader('Transfer-Encoding', 'chunked')
                c.endheaders()

                chunk = body.read(self.CHUNKSIZE)
                while chunk:
                    c.send('%x\r\n%s\r\n' % (len(chunk), chunk))
                    chunk = body.read(self.CHUNKSIZE)
                c.send('0\r\n\r\n')
            else:
                # Simple request...
                c.request(method, path, body, headers)
            res = c.getresponse()
            status_code = self.get_status_code(res)
            if status_code in self.OK_RESPONSE_CODES:
                return res
            elif status_code in self.REDIRECT_RESPONSE_CODES:
                raise exception.RedirectException(res.getheader('Location'))
            elif status_code == httplib.UNAUTHORIZED:
                raise exception.NotAuthorized(res.read())
            elif status_code == httplib.FORBIDDEN:
                raise exception.NotAuthorized(res.read())
            elif status_code == httplib.NOT_FOUND:
                raise exception.NotFound(res.read())
            elif status_code == httplib.CONFLICT:
                raise exception.Duplicate(res.read())
            elif status_code == httplib.BAD_REQUEST:
                raise exception.Invalid(res.read())
            elif status_code == httplib.MULTIPLE_CHOICES:
                raise exception.MultipleChoices(body=res.read())
            elif status_code == httplib.INTERNAL_SERVER_ERROR:
                raise Exception("Internal Server error: %s" % res.read())
            else:
                raise Exception("Unknown error occurred! %s" % res.read())

        except (socket.error, IOError), e:
            raise exception.ClientConnectionError(e)