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
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
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
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)
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)
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))
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)
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
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)
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
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:
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)