예제 #1
0
파일: utils.py 프로젝트: xglhjk6/glance
 def add_to_backend(self,
                    conf,
                    image_id,
                    data,
                    size,
                    scheme=None,
                    context=None,
                    verifier=None):
     store_max_size = 7
     current_store_size = 2
     for location in self.data.keys():
         if image_id in location:
             raise exception.Duplicate()
     if not size:
         # 'data' is a string wrapped in a LimitingReader|CooperativeReader
         # pipeline, so peek under the hood of those objects to get at the
         # string itself.
         size = len(data.data.fd)
     if (current_store_size + size) > store_max_size:
         raise exception.StorageFull()
     if context.user == USER2:
         raise exception.Forbidden()
     if context.user == USER3:
         raise exception.StorageWriteDenied()
     self.data[image_id] = (data, size)
     checksum = 'Z'
     return (image_id, size, checksum, self.store_metadata)
예제 #2
0
    def add(self, image_id, image_file, image_size):
        """
        Stores an image file with supplied identifier to the backend
        storage system and returns a tuple containing information
        about the stored image.

        :param image_id: The opaque image identifier
        :param image_file: The image data to write, as a file-like object
        :param image_size: The size of the image data to write, in bytes

        :retval tuple of URL in backing store, bytes written, checksum
                and a dictionary with storage system specific information
        :raises `glance.common.exception.Duplicate` if the image already
                existed

        :note By default, the backend writes the image data to a file
              `/<DATADIR>/<ID>`, where <DATADIR> is the value of
              the filesystem_store_datadir configuration option and <ID>
              is the supplied image ID.
        """
        datadir = self._find_best_datadir(image_size)
        filepath = os.path.join(datadir, str(image_id))

        if os.path.exists(filepath):
            raise exception.Duplicate(
                _("Image file %s already exists!") % filepath)

        checksum = hashlib.md5()
        bytes_written = 0
        try:
            with open(filepath, 'wb') as f:
                for buf in utils.chunkreadable(image_file,
                                               ChunkedFile.CHUNKSIZE):
                    bytes_written += len(buf)
                    checksum.update(buf)
                    f.write(buf)
        except IOError as e:
            if e.errno != errno.EACCES:
                self._delete_partial(filepath, image_id)
            exceptions = {
                errno.EFBIG: exception.StorageFull(),
                errno.ENOSPC: exception.StorageFull(),
                errno.EACCES: exception.StorageWriteDenied()
            }
            raise exceptions.get(e.errno, e)
        except Exception:
            with excutils.save_and_reraise_exception():
                self._delete_partial(filepath, image_id)

        checksum_hex = checksum.hexdigest()
        metadata = self._get_metadata()

        LOG.debug(
            _("Wrote %(bytes_written)d bytes to %(filepath)s with "
              "checksum %(checksum_hex)s"), {
                  'bytes_written': bytes_written,
                  'filepath': filepath,
                  'checksum_hex': checksum_hex
              })
        return ('file://%s' % filepath, bytes_written, checksum_hex, metadata)
예제 #3
0
    def add(self, image_id, image_file, image_size):
        """
        Stores an image file with supplied identifier to the backend
        storage system and returns an `glance.store.ImageAddResult` object
        containing information about the stored image.

        :param image_id: The opaque image identifier
        :param image_file: The image data to write, as a file-like object
        :param image_size: The size of the image data to write, in bytes

        :retval `glance.store.ImageAddResult` object
        :raises `glance.common.exception.Duplicate` if the image already
                existed

        :note By default, the backend writes the image data to a file
              `/<DATADIR>/<ID>`, where <DATADIR> is the value of
              the filesystem_store_datadir configuration option and <ID>
              is the supplied image ID.
        """

        filepath = os.path.join(self.datadir, str(image_id))

        if os.path.exists(filepath):
            raise exception.Duplicate(
                _("Image file %s already exists!") % filepath)

        checksum = hashlib.md5()
        bytes_written = 0
        try:
            with open(filepath, 'wb') as f:
                for buf in utils.chunkreadable(image_file,
                                               ChunkedFile.CHUNKSIZE):
                    bytes_written += len(buf)
                    checksum.update(buf)
                    f.write(buf)
        except IOError as e:
            if e.errno in [errno.EFBIG, errno.ENOSPC]:
                try:
                    os.unlink(filepath)
                except Exception:
                    msg = _('Unable to remove partial image data for image %s')
                    LOG.error(msg % image_id)
                raise exception.StorageFull()
            elif e.errno == errno.EACCES:
                raise exception.StorageWriteDenied()
            else:
                raise

        checksum_hex = checksum.hexdigest()

        LOG.debug(
            _("Wrote %(bytes_written)d bytes to %(filepath)s with "
              "checksum %(checksum_hex)s") % locals())
        return ('file://%s' % filepath, bytes_written, checksum_hex)
예제 #4
0
 def add_to_backend(self, context, scheme, image_id, data, size):
     store_max_size = 7
     current_store_size = 2
     for location in self.data.keys():
         if image_id in location:
             raise exception.Duplicate()
     if size and (current_store_size + size) > store_max_size:
         raise exception.StorageFull()
     if context.user == USER2:
         raise exception.Forbidden()
     if context.user == USER3:
         raise exception.StorageWriteDenied()
     self.data[image_id] = (data, size or len(data))
     checksum = 'Z'
     return (image_id, size, checksum)
예제 #5
0
 def data_iterator():
     self.notifier.log = []
     yield 'abcde'
     raise exception.StorageWriteDenied('The Very Model')