コード例 #1
0
    def test_upload_data_to_store_not_found_after_upload(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).AndRaise(
                                           exception.NotFound)
        self.mox.StubOutWithMock(upload_utils, "initiate_deletion")
        upload_utils.initiate_deletion(req, location, image_meta['id'],
                                       mox.IsA(bool))
        self.mox.StubOutWithMock(upload_utils, "safe_kill")
        upload_utils.safe_kill(req, image_meta['id'])
        notifier.error('image.upload', mox.IgnoreArg())
        self.mox.ReplayAll()

        self.assertRaises(webob.exc.HTTPPreconditionFailed,
                          upload_utils.upload_data_to_store, req, image_meta,
                          image_data, store, notifier)

        self.mox.VerifyAll()
コード例 #2
0
ファイル: images.py プロジェクト: brk3/glance
    def delete(self, req, id):
        """
        Deletes the image and all its chunks from the Glance

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

        :raises HttpBadRequest if image registry is invalid
        :raises HttpNotFound if image or any chunk is not available
        :raises HttpUnauthorized if image or any chunk is not
                deleteable by the requesting user
        """
        self._enforce(req, "delete_image")

        image = self.get_image_meta_or_404(req, id)
        if image["protected"]:
            msg = _("Image is protected")
            LOG.debug(msg)
            raise HTTPForbidden(explanation=msg, request=req, content_type="text/plain")

        if image["status"] == "pending_delete":
            msg = _("Forbidden to delete a %s image.") % image["status"]
            LOG.debug(msg)
            raise HTTPForbidden(explanation=msg, request=req, content_type="text/plain")
        elif image["status"] == "deleted":
            msg = _("Image %s not found.") % id
            LOG.debug(msg)
            raise HTTPNotFound(explanation=msg, request=req, content_type="text/plain")

        if image["location"] and CONF.delayed_delete:
            status = "pending_delete"
        else:
            status = "deleted"

        try:
            # Delete the image from the registry first, since we rely on it
            # for authorization checks.
            # See https://bugs.launchpad.net/glance/+bug/1065187
            registry.update_image_metadata(req.context, id, {"status": status})
            registry.delete_image_metadata(req.context, id)

            # The image's location field may be None in the case
            # of a saving or queued image, therefore don't ask a backend
            # to delete the image if the backend doesn't yet store it.
            # See https://bugs.launchpad.net/glance/+bug/747799
            if image["location"]:
                upload_utils.initiate_deletion(req, image["location"], id, CONF.delayed_delete)
        except exception.NotFound as e:
            msg = _("Failed to find image to delete: %(e)s") % locals()
            for line in msg.split("\n"):
                LOG.info(line)
            raise HTTPNotFound(explanation=msg, request=req, content_type="text/plain")
        except exception.Forbidden as e:
            msg = _("Forbidden to delete image: %(e)s") % locals()
            for line in msg.split("\n"):
                LOG.info(line)
            raise HTTPForbidden(explanation=msg, request=req, content_type="text/plain")
        else:
            self.notifier.info("image.delete", redact_loc(image))
            return Response(body="", status=200)
コード例 #3
0
ファイル: images.py プロジェクト: jiangyh/glance
    def _activate(self, req, image_id, location, location_metadata=None, from_state=None):
        """
        Sets the image status to `active` and the image's location
        attribute.

        :param req: The WSGI/Webob Request object
        :param image_id: Opaque image identifier
        :param location: Location of where Glance stored this image
        :param location_metadata: a dictionary of storage specific information
        """
        image_meta = {}
        image_meta["location"] = location
        image_meta["status"] = "active"
        if location_metadata:
            image_meta["location_data"] = [{"url": location, "metadata": location_metadata}]

        try:
            s = from_state
            image_meta_data = registry.update_image_metadata(req.context, image_id, image_meta, from_state=s)
            self.notifier.info("image.activate", redact_loc(image_meta_data))
            self.notifier.info("image.update", redact_loc(image_meta_data))
            return image_meta_data
        except exception.Duplicate:
            with excutils.save_and_reraise_exception():
                # Delete image data since it has been supersceded by another
                # upload and re-raise.
                LOG.debug(
                    "duplicate operation - deleting image data for "
                    " %(id)s (location:%(location)s)" % {"id": image_id, "location": image_meta["location"]}
                )
                upload_utils.initiate_deletion(req, image_meta["location"], image_id, CONF.delayed_delete)
        except exception.Invalid as e:
            msg = "Failed to activate image. Got error: %s" % utils.exception_to_str(e)
            LOG.debug(msg)
            raise HTTPBadRequest(explanation=msg, request=req, content_type="text/plain")
コード例 #4
0
ファイル: test_upload_utils.py プロジェクト: pekowski/glance
    def test_initiate_delete(self):
        req = unit_test_utils.get_fake_request()
        location = "file://foo/bar"
        id = unit_test_utils.UUID1

        self.mox.StubOutWithMock(glance.store, "safe_delete_from_backend")
        glance.store.safe_delete_from_backend(location, req.context, id)
        self.mox.ReplayAll()

        upload_utils.initiate_deletion(req, location, id)

        self.mox.VerifyAll()
コード例 #5
0
    def test_initiate_delete(self):
        req = unit_test_utils.get_fake_request()
        location = "file://foo/bar"
        id = unit_test_utils.UUID1

        self.mox.StubOutWithMock(glance.store, "safe_delete_from_backend")
        glance.store.safe_delete_from_backend(location, req.context, id)
        self.mox.ReplayAll()

        upload_utils.initiate_deletion(req, location, id)

        self.mox.VerifyAll()
コード例 #6
0
    def _activate(self,
                  req,
                  image_id,
                  location,
                  location_metadata=None,
                  from_state=None):
        """
        Sets the image status to `active` and the image's location
        attribute.

        :param req: The WSGI/Webob Request object
        :param image_id: Opaque image identifier
        :param location: Location of where Glance stored this image
        :param location_metadata: a dictionary of storage specific information
        """
        image_meta = {}
        image_meta['location'] = location
        image_meta['status'] = 'active'
        if location_metadata:
            image_meta['location_data'] = [{
                'url': location,
                'metadata': location_metadata
            }]

        try:
            s = from_state
            image_meta_data = registry.update_image_metadata(req.context,
                                                             image_id,
                                                             image_meta,
                                                             from_state=s)
            self.notifier.info("image.activate", redact_loc(image_meta_data))
            self.notifier.info("image.update", redact_loc(image_meta_data))
            return image_meta_data
        except exception.Duplicate:
            # Delete image data since it has been supersceded by another
            # upload.
            LOG.debug(
                _("duplicate operation - deleting image data for %(id)s "
                  "(location:%(location)s)") % {
                      'id': image_id,
                      'location': image_meta['location']
                  })
            upload_utils.initiate_deletion(req, image_meta['location'],
                                           image_id, CONF.delayed_delete)
            # Then propagate the exception.
            raise
        except exception.Invalid as e:
            msg = _("Failed to activate image. Got error: %(e)s") % {'e': e}
            LOG.debug(msg)
            raise HTTPBadRequest(explanation=msg,
                                 request=req,
                                 content_type="text/plain")
コード例 #7
0
ファイル: test_upload_utils.py プロジェクト: jdurgin/glance
    def test_initiate_delete(self):
        req = unit_test_utils.get_fake_request()
        location = {
            "url": "file://foo/bar",
            "metadata": {},
            "status": "active"
        }
        id = unit_test_utils.UUID1

        with patch.object(store_utils,
                          "safe_delete_from_backend") as mock_store_utils:
            upload_utils.initiate_deletion(req, location, id)
            mock_store_utils.assert_called_once_with(req.context, id, location)
コード例 #8
0
    def test_initiate_delete(self):
        req = unit_test_utils.get_fake_request()
        location = {"url": "file://foo/bar",
                    "metadata": {},
                    "status": "active"}
        id = unit_test_utils.UUID1

        with patch.object(store_utils,
                          "safe_delete_from_backend") as mock_store_utils:
            upload_utils.initiate_deletion(req, location, id)
            mock_store_utils.assert_called_once_with(req.context,
                                                     id,
                                                     location)
コード例 #9
0
    def test_initiate_delete(self):
        req = unit_test_utils.get_fake_request()
        location = {"url": "file://foo/bar",
                    "metadata": {},
                    "status": "active"}
        id = unit_test_utils.UUID1

        self.mox.StubOutWithMock(store_utils, "safe_delete_from_backend")
        store_utils.safe_delete_from_backend(req.context, id, location)
        self.mox.ReplayAll()

        upload_utils.initiate_deletion(req, location, id)

        self.mox.VerifyAll()
コード例 #10
0
    def test_initiate_delete(self):
        req = unit_test_utils.get_fake_request()
        location = {
            "url": "file://foo/bar",
            "metadata": {},
            "status": "active"
        }
        id = unit_test_utils.UUID1

        self.mox.StubOutWithMock(store_utils, "safe_delete_from_backend")
        store_utils.safe_delete_from_backend(req.context, id, location)
        self.mox.ReplayAll()

        upload_utils.initiate_deletion(req, location, id)

        self.mox.VerifyAll()
コード例 #11
0
    def test_initiate_delete_with_delayed_delete(self):
        self.config(delayed_delete=True)
        req = unit_test_utils.get_fake_request()
        location = {"url": "file://foo/bar",
                    "metadata": {},
                    "status": "active"}
        id = unit_test_utils.UUID1

        self.mox.StubOutWithMock(store_utils,
                                 "schedule_delayed_delete_from_backend")
        ret = store_utils.schedule_delayed_delete_from_backend(req.context, id,
                                                               location)
        ret.AndReturn(True)
        self.mox.ReplayAll()

        upload_utils.initiate_deletion(req, location, id)

        self.mox.VerifyAll()
コード例 #12
0
ファイル: images.py プロジェクト: rajeshpillai/glance
    def _activate(self, req, image_id, location, location_metadata=None,
                  from_state=None):
        """
        Sets the image status to `active` and the image's location
        attribute.

        :param req: The WSGI/Webob Request object
        :param image_id: Opaque image identifier
        :param location: Location of where Glance stored this image
        :param location_metadata: a dictionary of storage specific information
        """
        image_meta = {}
        image_meta['location'] = location
        image_meta['status'] = 'active'
        if location_metadata:
            image_meta['location_data'] = [{'url': location,
                                            'metadata': location_metadata}]

        try:
            s = from_state
            image_meta_data = registry.update_image_metadata(req.context,
                                                             image_id,
                                                             image_meta,
                                                             from_state=s)
            self.notifier.info("image.activate", redact_loc(image_meta_data))
            self.notifier.info("image.update", redact_loc(image_meta_data))
            return image_meta_data
        except exception.Duplicate:
            # Delete image data since it has been supersceded by another
            # upload.
            LOG.debug("duplicate operation - deleting image data for %s "
                      "(location:%s)" %
                      (image_id, image_meta['location']))
            upload_utils.initiate_deletion(req, image_meta['location'],
                                           image_id, CONF.delayed_delete)
            # Then propagate the exception.
            raise
        except exception.Invalid as e:
            msg = _("Failed to activate image. Got error: %(e)s") % {'e': e}
            LOG.debug(msg)
            raise HTTPBadRequest(explanation=msg,
                                 request=req,
                                 content_type="text/plain")
コード例 #13
0
    def test_initiate_delete_with_delayed_delete(self):
        self.config(delayed_delete=True)
        req = unit_test_utils.get_fake_request()
        location = {
            "url": "file://foo/bar",
            "metadata": {},
            "status": "active"
        }
        id = unit_test_utils.UUID1

        self.mox.StubOutWithMock(store_utils,
                                 "schedule_delayed_delete_from_backend")
        ret = store_utils.schedule_delayed_delete_from_backend(
            req.context, id, location)
        ret.AndReturn(True)
        self.mox.ReplayAll()

        upload_utils.initiate_deletion(req, location, id)

        self.mox.VerifyAll()
コード例 #14
0
    def test_upload_data_to_store_not_found_after_upload(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
                                       ).AndRaise(exception.NotFound)
        self.mox.StubOutWithMock(upload_utils, "initiate_deletion")
        upload_utils.initiate_deletion(req, {'url': location,
                                             'status': 'active',
                                             'metadata': {}}, image_meta['id'])
        self.mox.StubOutWithMock(upload_utils, "safe_kill")
        upload_utils.safe_kill(req, image_meta['id'])
        notifier.error('image.upload', mox.IgnoreArg())
        self.mox.ReplayAll()

        self.assertRaises(webob.exc.HTTPPreconditionFailed,
                          upload_utils.upload_data_to_store,
                          req, image_meta, image_data, store, notifier)

        self.mox.VerifyAll()
コード例 #15
0
    def _activate(self, req, image_id, location_data, from_state=None):
        """
        Sets the image status to `active` and the image's location
        attribute.

        :param req: The WSGI/Webob Request object
        :param image_id: Opaque image identifier
        :param location_data: Location of where Glance stored this image
        """
        image_meta = {}
        image_meta['location'] = location_data['url']
        image_meta['status'] = 'active'
        image_meta['location_data'] = [location_data]

        try:
            s = from_state
            image_meta_data = registry.update_image_metadata(req.context,
                                                             image_id,
                                                             image_meta,
                                                             from_state=s)
            self.notifier.info("image.activate", redact_loc(image_meta_data))
            self.notifier.info("image.update", redact_loc(image_meta_data))
            return image_meta_data
        except exception.Duplicate:
            with excutils.save_and_reraise_exception():
                # Delete image data since it has been supersceded by another
                # upload and re-raise.
                LOG.debug("duplicate operation - deleting image data for "
                          " %(id)s (location:%(location)s)" %
                          {'id': image_id, 'location': image_meta['location']})
                upload_utils.initiate_deletion(req, image_meta['location'],
                                               image_id, CONF.delayed_delete)
        except exception.Invalid as e:
            msg = ("Failed to activate image. Got error: %s" %
                   utils.exception_to_str(e))
            LOG.debug(msg)
            raise HTTPBadRequest(explanation=msg,
                                 request=req,
                                 content_type="text/plain")
コード例 #16
0
    def delete(self, req, id):
        """
        Deletes the image and all its chunks from the Glance

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

        :raises HttpBadRequest if image registry is invalid
        :raises HttpNotFound if image or any chunk is not available
        :raises HttpUnauthorized if image or any chunk is not
                deleteable by the requesting user
        """
        self._enforce(req, 'delete_image')

        image = self.get_image_meta_or_404(req, id)
        if image['protected']:
            msg = _("Image is protected")
            LOG.debug(msg)
            raise HTTPForbidden(explanation=msg,
                                request=req,
                                content_type="text/plain")

        if image['status'] == 'pending_delete':
            msg = (_("Forbidden to delete a %s image.") % image['status'])
            LOG.debug(msg)
            raise HTTPForbidden(explanation=msg, request=req,
                                content_type="text/plain")
        elif image['status'] == 'deleted':
            msg = _("Image %s not found.") % id
            LOG.debug(msg)
            raise HTTPNotFound(explanation=msg, request=req,
                               content_type="text/plain")

        if image['location'] and CONF.delayed_delete:
            status = 'pending_delete'
        else:
            status = 'deleted'

        try:
            # Delete the image from the registry first, since we rely on it
            # for authorization checks.
            # See https://bugs.launchpad.net/glance/+bug/1065187
            image = registry.update_image_metadata(req.context, id,
                                                   {'status': status})
            registry.delete_image_metadata(req.context, id)

            # The image's location field may be None in the case
            # of a saving or queued image, therefore don't ask a backend
            # to delete the image if the backend doesn't yet store it.
            # See https://bugs.launchpad.net/glance/+bug/747799
            if image['location']:
                upload_utils.initiate_deletion(req, image['location'], id,
                                               CONF.delayed_delete)
        except exception.NotFound as e:
            msg = _("Failed to find image to delete: %(e)s") % {'e': e}
            for line in msg.split('\n'):
                LOG.info(line)
            raise HTTPNotFound(explanation=msg,
                               request=req,
                               content_type="text/plain")
        except exception.Forbidden as e:
            msg = _("Forbidden to delete image: %(e)s") % {'e': e}
            for line in msg.split('\n'):
                LOG.info(line)
            raise HTTPForbidden(explanation=msg,
                                request=req,
                                content_type="text/plain")
        else:
            self.notifier.info('image.delete', redact_loc(image))
            return Response(body='', status=200)
コード例 #17
0
ファイル: images.py プロジェクト: ziziwu/openstack
    def delete(self, req, id):
        """
        Deletes the image and all its chunks from the Glance

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

        :raises HttpBadRequest if image registry is invalid
        :raises HttpNotFound if image or any chunk is not available
        :raises HttpUnauthorized if image or any chunk is not
                deleteable by the requesting user
        """
        self._enforce(req, 'delete_image')

        image = self.get_image_meta_or_404(req, id)
        if image['protected']:
            msg = "Image is protected"
            LOG.debug(msg)
            raise HTTPForbidden(explanation=msg,
                                request=req,
                                content_type="text/plain")

        if image['status'] == 'pending_delete':
            msg = "Forbidden to delete a %s image." % image['status']
            LOG.debug(msg)
            raise HTTPForbidden(explanation=msg, request=req,
                                content_type="text/plain")
        elif image['status'] == 'deleted':
            msg = "Image %s not found." % id
            LOG.debug(msg)
            raise HTTPNotFound(explanation=msg, request=req,
                               content_type="text/plain")

        if image['location'] and CONF.delayed_delete:
            status = 'pending_delete'
        else:
            status = 'deleted'

        ori_status = image['status']

        try:
            # Update the image from the registry first, since we rely on it
            # for authorization checks.
            # See https://bugs.launchpad.net/glance/+bug/1065187
            image = registry.update_image_metadata(req.context, id,
                                                   {'status': status})

            try:
                # The image's location field may be None in the case
                # of a saving or queued image, therefore don't ask a backend
                # to delete the image if the backend doesn't yet store it.
                # See https://bugs.launchpad.net/glance/+bug/747799
                if image['location']:
                    for loc_data in image['location_data']:
                        if loc_data['status'] == 'active':
                            upload_utils.initiate_deletion(req, loc_data, id)
            except Exception:
                with excutils.save_and_reraise_exception():
                    registry.update_image_metadata(req.context, id,
                                                   {'status': ori_status})
            registry.delete_image_metadata(req.context, id)
        except exception.NotFound as e:
            msg = (_("Failed to find image to delete: %s") %
                   utils.exception_to_str(e))
            for line in msg.split('\n'):
                LOG.info(line)
            raise HTTPNotFound(explanation=msg,
                               request=req,
                               content_type="text/plain")
        except exception.Forbidden as e:
            msg = (_("Forbidden to delete image: %s") %
                   utils.exception_to_str(e))
            for line in msg.split('\n'):
                LOG.info(line)
            raise HTTPForbidden(explanation=msg,
                                request=req,
                                content_type="text/plain")
        else:
            self.notifier.info('image.delete', redact_loc(image))
            return Response(body='', status=200)