Example #1
0
    def _upload(self, req, image_meta):
        """
        Uploads the payload of the request to a backend store in
        Glance. If the `x-image-meta-store` header is set, Glance
        will attempt to use that scheme; if not, Glance will use the
        scheme set by the flag `default_store` to find the backing store.

        :param req: The WSGI/Webob Request object
        :param image_meta: Mapping of metadata about image

        :raises HTTPConflict if image already exists
        :retval The location where the image was stored
        """

        copy_from = self._copy_from(req)
        if copy_from:
            try:
                image_data, image_size = self._get_from_store(
                    req.context, copy_from)
            except Exception as e:
                upload_utils.safe_kill(req, image_meta['id'], 'queued')
                msg = _("Copy from external source failed: %s") % e
                LOG.debug(msg)
                return
            image_meta['size'] = image_size or image_meta['size']
        else:
            try:
                req.get_content_type(('application/octet-stream', ))
            except exception.InvalidContentType:
                upload_utils.safe_kill(req, image_meta['id'], 'queued')
                msg = _("Content-Type must be application/octet-stream")
                LOG.debug(msg)
                raise HTTPBadRequest(explanation=msg)

            image_data = req.body_file

        scheme = req.headers.get('x-image-meta-store', CONF.default_store)

        store = self.get_store_or_400(req, scheme)

        image_id = image_meta['id']
        LOG.debug(_("Setting image %s to status 'saving'"), image_id)
        registry.update_image_metadata(req.context, image_id,
                                       {'status': 'saving'})

        LOG.debug(
            _("Uploading image data for image %(image_id)s "
              "to %(scheme)s store"), {
                  'image_id': image_id,
                  'scheme': scheme
              })

        self.notifier.info("image.prepare", redact_loc(image_meta))

        image_meta, location, loc_meta = upload_utils.upload_data_to_store(
            req, image_meta, image_data, store, self.notifier)

        self.notifier.info('image.upload', redact_loc(image_meta))

        return location, loc_meta
Example #2
0
    def test_upload_data_to_store(self):
        # 'user_storage_quota' is not set
        def store_add(image_id, data, size, **kwargs):
            # Check if 'data' is instance of 'CooperativeReader' when
            # 'user_storage_quota' is disabled.
            self.assertIsInstance(data, utils.CooperativeReader)
            return location, 10, "checksum", {}

        req = unit_test_utils.get_fake_request()
        with self._get_store_and_notifier(
                ext_update_data={'size': 10},
                exc_class=store_add) as (location, checksum, image_meta,
                                         image_data, store, notifier,
                                         update_data):
            ret = image_meta.update(update_data)
            with patch.object(registry, 'update_image_metadata',
                              return_value=ret) as mock_update_image_metadata:
                actual_meta, location_data = upload_utils.upload_data_to_store(
                    req, image_meta, image_data, store, notifier)

                self.assertEqual(location, location_data['url'])
                self.assertEqual(image_meta.update(update_data), actual_meta)
                mock_update_image_metadata.assert_called_once_with(
                    req.context, image_meta['id'], update_data,
                    from_state='saving')
Example #3
0
    def test_upload_data_to_store(self):
        req = unit_test_utils.get_fake_request()

        location = "file://foo/bar"
        size = 10
        checksum = "checksum"

        image_meta = {'id': unit_test_utils.UUID1,
                      'size': size}
        image_data = "blah"

        notifier = self.mox.CreateMockAnything()
        store = self.mox.CreateMockAnything()
        store.add(
            image_meta['id'],
            mox.IgnoreArg(),
            image_meta['size']).AndReturn((location, size, checksum, {}))

        self.mox.StubOutWithMock(registry, "update_image_metadata")
        update_data = {'checksum': checksum,
                       'size': size}
        registry.update_image_metadata(
            req.context, image_meta['id'],
            update_data).AndReturn(image_meta.update(update_data))
        self.mox.ReplayAll()

        actual_meta, location_data = upload_utils.upload_data_to_store(
            req, image_meta, image_data, store, notifier)

        self.mox.VerifyAll()

        self.assertEqual(location_data['url'], location)
        self.assertEqual(actual_meta, image_meta.update(update_data))
Example #4
0
    def test_upload_data_to_store(self):
        req = unit_test_utils.get_fake_request()

        location = "file://foo/bar"
        size = 10
        checksum = "checksum"

        image_meta = {'id': unit_test_utils.UUID1,
                      'size': size}
        image_data = "blah"

        notifier = self.mox.CreateMockAnything()
        store = self.mox.CreateMockAnything()
        store.add(
            image_meta['id'],
            mox.IgnoreArg(),
            image_meta['size']).AndReturn((location, size, checksum, {}))

        self.mox.StubOutWithMock(registry, "update_image_metadata")
        update_data = {'checksum': checksum,
                       'size': size}
        registry.update_image_metadata(req.context,
                                       image_meta['id'],
                                       update_data
                                       ).AndReturn(
                                           image_meta.update(update_data))
        self.mox.ReplayAll()

        actual_meta, actual_loc, loc_meta = upload_utils.upload_data_to_store(
            req, image_meta, image_data, store, notifier)

        self.mox.VerifyAll()

        self.assertEqual(actual_loc, location)
        self.assertEqual(actual_meta, image_meta.update(update_data))
Example #5
0
    def test_upload_data_to_store(self):
        # 'user_storage_quota' is not set
        def store_add(image_id, data, size, **kwargs):
            # Check if 'data' is instance of 'CooperativeReader' when
            # 'user_storage_quota' is disabled.
            self.assertIsInstance(data, utils.CooperativeReader)
            return location, 10, "checksum", {}

        req = unit_test_utils.get_fake_request()
        with self._get_store_and_notifier(
                ext_update_data={'size': 10},
                exc_class=store_add) as (location, checksum, image_meta,
                                         image_data, store, notifier,
                                         update_data):
            ret = image_meta.update(update_data)
            with patch.object(registry,
                              'update_image_metadata',
                              return_value=ret) as mock_update_image_metadata:
                actual_meta, location_data = upload_utils.upload_data_to_store(
                    req, image_meta, image_data, store, notifier)

                self.assertEqual(location, location_data['url'])
                self.assertEqual(image_meta.update(update_data), actual_meta)
                mock_update_image_metadata.assert_called_once_with(
                    req.context,
                    image_meta['id'],
                    update_data,
                    from_state='saving')
Example #6
0
    def _upload(self, req, image_meta):
        """
        Uploads the payload of the request to a backend store in
        Glance. If the `x-image-meta-store` header is set, Glance
        will attempt to use that scheme; if not, Glance will use the
        scheme set by the flag `default_store` to find the backing store.

        :param req: The WSGI/Webob Request object
        :param image_meta: Mapping of metadata about image

        :raises HTTPConflict if image already exists
        :retval The location where the image was stored
        """

        copy_from = self._copy_from(req)
        if copy_from:
            try:
                image_data, image_size = self._get_from_store(req.context,
                                                              copy_from)
            except Exception as e:
                upload_utils.safe_kill(req, image_meta['id'])
                msg = _("Copy from external source failed: %s") % e
                LOG.debug(msg)
                return
            image_meta['size'] = image_size or image_meta['size']
        else:
            try:
                req.get_content_type('application/octet-stream')
            except exception.InvalidContentType:
                upload_utils.safe_kill(req, image_meta['id'])
                msg = _("Content-Type must be application/octet-stream")
                LOG.debug(msg)
                raise HTTPBadRequest(explanation=msg)

            image_data = req.body_file

        scheme = req.headers.get('x-image-meta-store', CONF.default_store)

        store = self.get_store_or_400(req, scheme)

        image_id = image_meta['id']
        LOG.debug(_("Setting image %s to status 'saving'"), image_id)
        registry.update_image_metadata(req.context, image_id,
                                       {'status': 'saving'})

        LOG.debug(_("Uploading image data for image %(image_id)s "
                    "to %(scheme)s store"), locals())

        self.notifier.info("image.prepare", redact_loc(image_meta))

        image_meta, location = upload_utils.upload_data_to_store(req,
                                                                 image_meta,
                                                                 image_data,
                                                                 store,
                                                                 self.notifier)

        self.notifier.info('image.upload', redact_loc(image_meta))

        return location
Example #7
0
    def _upload(self, req, image_meta):
        """
        Uploads the payload of the request to a backend store in
        Glance. If the `x-image-meta-store` header is set, Glance
        will attempt to use that scheme; if not, Glance will use the
        scheme set by the flag `default_store` to find the backing store.

        :param req: The WSGI/Webob Request object
        :param image_meta: Mapping of metadata about image

        :raises HTTPConflict if image already exists
        :retval The location where the image was stored
        """

        scheme = req.headers.get("x-image-meta-store", CONF.glance_store.default_store)

        store = self.get_store_or_400(req, scheme)

        copy_from = self._copy_from(req)
        if copy_from:
            try:
                image_data, image_size = self._get_from_store(req.context, copy_from, dest=store)
            except Exception:
                upload_utils.safe_kill(req, image_meta["id"], "queued")
                msg = _LE("Copy from external source '%(scheme)s' failed for " "image: %(image)s") % {
                    "scheme": scheme,
                    "image": image_meta["id"],
                }
                LOG.exception(msg)
                return
            image_meta["size"] = image_size or image_meta["size"]
        else:
            try:
                req.get_content_type(("application/octet-stream",))
            except exception.InvalidContentType:
                upload_utils.safe_kill(req, image_meta["id"], "queued")
                msg = "Content-Type must be application/octet-stream"
                LOG.debug(msg)
                raise HTTPBadRequest(explanation=msg)

            image_data = req.body_file

        image_id = image_meta["id"]
        LOG.debug("Setting image %s to status 'saving'", image_id)
        registry.update_image_metadata(req.context, image_id, {"status": "saving"})

        LOG.debug(
            "Uploading image data for image %(image_id)s " "to %(scheme)s store",
            {"image_id": image_id, "scheme": scheme},
        )

        self.notifier.info("image.prepare", redact_loc(image_meta))

        image_meta, location_data = upload_utils.upload_data_to_store(req, image_meta, image_data, store, self.notifier)

        self.notifier.info("image.upload", redact_loc(image_meta))

        return location_data
    def test_upload_data_to_store(self):
        req = unit_test_utils.get_fake_request()
        with self._get_store_and_notifier(
            ext_update_data={'size': 10}) as (location, checksum, image_meta,
                                              image_data, store, notifier,
                                              update_data):
            ret = image_meta.update(update_data)
            with patch.object(registry, 'update_image_metadata',
                              return_value=ret) as mock_update_image_metadata:
                actual_meta, location_data = upload_utils.upload_data_to_store(
                    req, image_meta, image_data, store, notifier)

                self.assertEqual(location, location_data['url'])
                self.assertEqual(image_meta.update(update_data), actual_meta)
                mock_update_image_metadata.assert_called_once_with(
                    req.context, image_meta['id'], update_data,
                    from_state='saving')
Example #9
0
    def test_upload_data_to_store(self):
        req = unit_test_utils.get_fake_request()
        with self._get_store_and_notifier(
            ext_update_data={'size': 10}) as (location, checksum, image_meta,
                                              image_data, store, notifier,
                                              update_data):
            ret = image_meta.update(update_data)
            with patch.object(registry, 'update_image_metadata',
                              return_value=ret) as mock_update_image_metadata:
                actual_meta, location_data = upload_utils.upload_data_to_store(
                    req, image_meta, image_data, store, notifier)

                self.assertEqual(location_data['url'], location)
                self.assertEqual(actual_meta, image_meta.update(update_data))
                mock_update_image_metadata.assert_called_once_with(
                    req.context, image_meta['id'], update_data,
                    from_state='saving')
Example #10
0
    def test_upload_data_to_store_user_storage_quota_enabled(self):
        # Enable user_storage_quota
        self.config(user_storage_quota='100B')

        def store_add(image_id, data, size, **kwargs):
            # Check if 'data' is instance of 'LimitingReader' when
            # 'user_storage_quota' is enabled.
            self.assertIsInstance(data, utils.LimitingReader)
            return location, 10, "checksum", {}

        req = unit_test_utils.get_fake_request()
        with self._get_store_and_notifier(
                ext_update_data={'size': 10},
                exc_class=store_add) as (location, checksum, image_meta,
                                         image_data, store, notifier,
                                         update_data):
            ret = image_meta.update(update_data)
            # mock 'check_quota'
            mock_check_quota = patch('glance.api.common.check_quota',
                                     return_value=100)
            mock_check_quota.start()
            self.addCleanup(mock_check_quota.stop)
            with patch.object(registry,
                              'update_image_metadata',
                              return_value=ret) as mock_update_image_metadata:
                actual_meta, location_data = upload_utils.upload_data_to_store(
                    req, image_meta, image_data, store, notifier)

                self.assertEqual(location, location_data['url'])
                self.assertEqual(image_meta.update(update_data), actual_meta)
                mock_update_image_metadata.assert_called_once_with(
                    req.context,
                    image_meta['id'],
                    update_data,
                    from_state='saving')
                # 'check_quota' is called two times
                check_quota_call_count = (
                    mock_check_quota.target.check_quota.call_count)
                self.assertEqual(2, check_quota_call_count)
Example #11
0
    def test_upload_data_to_store_user_storage_quota_enabled(self):
        # Enable user_storage_quota
        self.config(user_storage_quota='100B')

        def store_add(image_id, data, size, **kwargs):
            # Check if 'data' is instance of 'LimitingReader' when
            # 'user_storage_quota' is enabled.
            self.assertIsInstance(data, utils.LimitingReader)
            return location, 10, "checksum", {}

        req = unit_test_utils.get_fake_request()
        with self._get_store_and_notifier(
                ext_update_data={'size': 10},
                exc_class=store_add) as (location, checksum, image_meta,
                                         image_data, store, notifier,
                                         update_data):
            ret = image_meta.update(update_data)
            # mock 'check_quota'
            mock_check_quota = patch('glance.api.common.check_quota',
                                     return_value=100)
            mock_check_quota.start()
            self.addCleanup(mock_check_quota.stop)
            with patch.object(registry, 'update_image_metadata',
                              return_value=ret) as mock_update_image_metadata:
                actual_meta, location_data = upload_utils.upload_data_to_store(
                    req, image_meta, image_data, store, notifier)

                self.assertEqual(location, location_data['url'])
                self.assertEqual(image_meta.update(update_data), actual_meta)
                mock_update_image_metadata.assert_called_once_with(
                    req.context, image_meta['id'], update_data,
                    from_state='saving')
                # 'check_quota' is called two times
                check_quota_call_count =\
                    mock_check_quota.target.check_quota.call_count
                self.assertEqual(2, check_quota_call_count)