summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Thode <prometheanfire@gentoo.org>2015-02-08 01:51:57 +0000
committerMatthew Thode <prometheanfire@gentoo.org>2015-02-08 01:51:57 +0000
commit4d2f7c4e3d15c4dd96bf9697666997a75aede7e2 (patch)
tree361598ca90e8cb9b483289a2be1dc7aafca436b9 /app-admin/glance
parentsigning (diff)
downloadgentoo-2-4d2f7c4e3d15c4dd96bf9697666997a75aede7e2.tar.gz
gentoo-2-4d2f7c4e3d15c4dd96bf9697666997a75aede7e2.tar.bz2
gentoo-2-4d2f7c4e3d15c4dd96bf9697666997a75aede7e2.zip
bumping :D
(Portage version: 2.2.14/cvs/Linux x86_64, signed Manifest commit with key 0x33ED3FD25AFC78BA)
Diffstat (limited to 'app-admin/glance')
-rw-r--r--app-admin/glance/ChangeLog12
-rw-r--r--app-admin/glance/files/0001-Prevent-file-swift-config-and-filesystem-schemes.patch119
-rw-r--r--app-admin/glance/files/0001-To-prevent-client-use-v2-patch-api-to-handle-file-an.patch702
-rw-r--r--app-admin/glance/files/glance-CVE-2014-9623.patch542
-rw-r--r--app-admin/glance/glance-2014.2.2.ebuild162
-rw-r--r--app-admin/glance/glance-2014.2.9999.ebuild99
-rw-r--r--app-admin/glance/glance-9999.ebuild139
7 files changed, 215 insertions, 1560 deletions
diff --git a/app-admin/glance/ChangeLog b/app-admin/glance/ChangeLog
index 053b821e95ab..a75e5352ed94 100644
--- a/app-admin/glance/ChangeLog
+++ b/app-admin/glance/ChangeLog
@@ -1,6 +1,16 @@
# ChangeLog for app-admin/glance
# Copyright 1999-2015 Gentoo Foundation; Distributed under the GPL v2
-# $Header: /var/cvsroot/gentoo-x86/app-admin/glance/ChangeLog,v 1.58 2015/01/29 05:39:38 prometheanfire Exp $
+# $Header: /var/cvsroot/gentoo-x86/app-admin/glance/ChangeLog,v 1.59 2015/02/08 01:51:56 prometheanfire Exp $
+
+*glance-2014.2.2 (08 Feb 2015)
+
+ 08 Feb 2015; Matthew Thode <prometheanfire@gentoo.org>
+ +glance-2014.2.2.ebuild,
+ -files/0001-Prevent-file-swift-config-and-filesystem-schemes.patch,
+ -files/0001-To-prevent-client-use-v2-patch-api-to-handle-file-an.patch,
+ -files/glance-CVE-2014-9623.patch, -glance-9999.ebuild,
+ glance-2014.2.9999.ebuild:
+ bumping :D
*glance-2014.2.1-r2 (29 Jan 2015)
diff --git a/app-admin/glance/files/0001-Prevent-file-swift-config-and-filesystem-schemes.patch b/app-admin/glance/files/0001-Prevent-file-swift-config-and-filesystem-schemes.patch
deleted file mode 100644
index 4cb999bd1279..000000000000
--- a/app-admin/glance/files/0001-Prevent-file-swift-config-and-filesystem-schemes.patch
+++ /dev/null
@@ -1,119 +0,0 @@
-From 5191ed1879c5fd5b2694f922bcedec232f461088 Mon Sep 17 00:00:00 2001
-From: Grant Murphy <grant.murphy@hp.com>
-Date: Wed, 7 Jan 2015 16:09:38 -0800
-Subject: [PATCH] Prevent file, swift+config and filesystem schemes
-
-This change ensures that 'file', 'filesystem', and 'swift+config' URI
-schemes are not allowed when setting the location field. A previous
-fix to CVE-2014-9493 attempted to address this issue but did not
-include 'filesystem', a URI scheme allowed by the glance_store.
-
-Without this fix in place it is possible for a client to access any file
-the glance-api server has read permissions for.
-
-Change-Id: I02cd099a8634b9c7e3cf8f172bcbd33f8edcbc83
-Closes-Bug: #1408663
-(cherry picked from commit a2d986b976e9325a272e2d422465165315d19fe6)
----
- glance/common/store_utils.py | 11 ++++++-----
- glance/tests/unit/test_store_location.py | 3 +++
- glance/tests/unit/v1/test_api.py | 32 ++++++++++++--------------------
- 3 files changed, 21 insertions(+), 25 deletions(-)
-
-diff --git a/glance/common/store_utils.py b/glance/common/store_utils.py
-index b7537ce..64cfa87 100644
---- a/glance/common/store_utils.py
-+++ b/glance/common/store_utils.py
-@@ -38,6 +38,8 @@ store_utils_opts = [
- CONF = cfg.CONF
- CONF.register_opts(store_utils_opts)
-
-+RESTRICTED_URI_SCHEMAS = frozenset(['file', 'filesystem', 'swift+config'])
-+
-
- def safe_delete_from_backend(context, image_id, location):
- """
-@@ -136,8 +138,7 @@ def validate_external_location(uri):
- """
-
- # TODO(zhiyan): This function could be moved to glance_store.
--
-- pieces = urlparse.urlparse(uri)
-- valid_schemes = [scheme for scheme in store_api.get_known_schemes()
-- if scheme != 'file' and scheme != 'swift+config']
-- return pieces.scheme in valid_schemes
-+ # TODO(gm): Use a whitelist of allowed schemes
-+ scheme = urlparse.urlparse(uri).scheme
-+ return (scheme in store_api.get_known_schemes() and
-+ scheme not in RESTRICTED_URI_SCHEMAS)
-diff --git a/glance/tests/unit/test_store_location.py b/glance/tests/unit/test_store_location.py
-index c9ee44c..efaecd8 100644
---- a/glance/tests/unit/test_store_location.py
-+++ b/glance/tests/unit/test_store_location.py
-@@ -69,12 +69,15 @@ class TestStoreLocation(base.StoreClearingUnitTest):
-
- loc1 = {'url': 'file:///fake1.img.tar.gz', 'metadata': {}}
- loc2 = {'url': 'swift+config:///xxx', 'metadata': {}}
-+ loc3 = {'url': 'filesystem:///foo.img.tar.gz', 'metadata': {}}
-
- # Test for insert location
- image1 = TestStoreLocation.FakeImageProxy()
- locations = glance.location.StoreLocations(image1, [])
- self.assertRaises(exception.BadStoreUri, locations.insert, 0, loc1)
-+ self.assertRaises(exception.BadStoreUri, locations.insert, 0, loc3)
- self.assertNotIn(loc1, locations)
-+ self.assertNotIn(loc3, locations)
-
- # Test for set_attr of _locations_proxy
- image2 = TestStoreLocation.FakeImageProxy()
-diff --git a/glance/tests/unit/v1/test_api.py b/glance/tests/unit/v1/test_api.py
-index 4ec136d..39e9a44 100644
---- a/glance/tests/unit/v1/test_api.py
-+++ b/glance/tests/unit/v1/test_api.py
-@@ -1071,31 +1071,23 @@ class TestGlanceAPI(base.IsolatedUnitTest):
-
- def test_add_copy_from_with_restricted_sources(self):
- """Tests creates an image from copy-from with restricted sources"""
-- fixture_headers = {'x-image-meta-store': 'file',
-+ header_template = {'x-image-meta-store': 'file',
- 'x-image-meta-disk-format': 'vhd',
-- 'x-glance-api-copy-from': 'file:///etc/passwd',
- 'x-image-meta-container-format': 'ovf',
- 'x-image-meta-name': 'fake image #F'}
-
-- req = webob.Request.blank("/images")
-- req.method = 'POST'
-- for k, v in six.iteritems(fixture_headers):
-- req.headers[k] = v
-- res = req.get_response(self.api)
-- self.assertEqual(400, res.status_int)
-+ schemas = ["file:///etc/passwd",
-+ "swift+config:///xxx",
-+ "filesystem:///etc/passwd"]
-
-- fixture_headers = {'x-image-meta-store': 'file',
-- 'x-image-meta-disk-format': 'vhd',
-- 'x-glance-api-copy-from': 'swift+config://xxx',
-- 'x-image-meta-container-format': 'ovf',
-- 'x-image-meta-name': 'fake image #F'}
--
-- req = webob.Request.blank("/images")
-- req.method = 'POST'
-- for k, v in six.iteritems(fixture_headers):
-- req.headers[k] = v
-- res = req.get_response(self.api)
-- self.assertEqual(400, res.status_int)
-+ for schema in schemas:
-+ req = webob.Request.blank("/images")
-+ req.method = 'POST'
-+ for k, v in six.iteritems(header_template):
-+ req.headers[k] = v
-+ req.headers['x-glance-api-copy-from'] = schema
-+ res = req.get_response(self.api)
-+ self.assertEqual(400, res.status_int)
-
- def test_add_copy_from_upload_image_unauthorized_with_body(self):
- rules = {"upload_image": '!', "modify_image": '@',
---
-2.0.5
-
diff --git a/app-admin/glance/files/0001-To-prevent-client-use-v2-patch-api-to-handle-file-an.patch b/app-admin/glance/files/0001-To-prevent-client-use-v2-patch-api-to-handle-file-an.patch
deleted file mode 100644
index 15b3d9a3a790..000000000000
--- a/app-admin/glance/files/0001-To-prevent-client-use-v2-patch-api-to-handle-file-an.patch
+++ /dev/null
@@ -1,702 +0,0 @@
-From d9a928eac360add67477e29f516af868adfe0d5e Mon Sep 17 00:00:00 2001
-From: Zhi Yan Liu <zhiyanl@cn.ibm.com>
-Date: Mon, 15 Dec 2014 12:29:55 +0800
-Subject: [PATCH] To prevent client use v2 patch api to handle file and swift
- location
-
-The change will be used to restrict client to download and delete any
-file in glance-api server. The same resone and logic as what we did in
-v1:
-https://github.com/openstack/glance/blob/master/glance/api/v1/images.py#L429
-
-Closes-Bug: bug/1400966
-DocImpact
-
-Note: Even this change could fully resolve the problem for Glance, but
-we still need to fix this issue from glance_store perspective
-separatelly due to other projects can use the lib directly.
-
-Conflicts:
- glance/api/v1/images.py
- glance/location.py
- glance/tests/functional/v2/test_images.py
- glance/tests/unit/test_store_location.py
- glance/tests/unit/v1/test_api.py
-
-(cherry-picked from 4afdb017aa1ccef01482f117cb8d0736a6da38ed)
-Signed-off-by: Zhi Yan Liu <zhiyanl@cn.ibm.com>
-Change-Id: I72dbead3cb2dcb87f52658ddb880e26880cc229b
----
- glance/api/v1/images.py | 31 ++---
- glance/common/store_utils.py | 22 ++++
- glance/location.py | 30 +++--
- glance/tests/functional/v1/test_copy_to_file.py | 4 +-
- glance/tests/functional/v2/test_images.py | 158 ++++++++++--------------
- glance/tests/unit/test_store_image.py | 3 +-
- glance/tests/unit/test_store_location.py | 33 ++++-
- glance/tests/unit/utils.py | 9 +-
- glance/tests/unit/v1/test_api.py | 62 +++++++++-
- 9 files changed, 221 insertions(+), 131 deletions(-)
-
-diff --git a/glance/api/v1/images.py b/glance/api/v1/images.py
-index c85b301..746f8cd 100644
---- a/glance/api/v1/images.py
-+++ b/glance/api/v1/images.py
-@@ -23,7 +23,6 @@ import eventlet
- import glance_store as store
- import glance_store.location
- from oslo.config import cfg
--import six.moves.urllib.parse as urlparse
- from webob.exc import HTTPBadRequest
- from webob.exc import HTTPConflict
- from webob.exc import HTTPForbidden
-@@ -40,6 +39,7 @@ from glance.api.v1 import filters
- from glance.api.v1 import upload_utils
- from glance.common import exception
- from glance.common import property_utils
-+from glance.common import store_utils
- from glance.common import utils
- from glance.common import wsgi
- from glance.i18n import _LE
-@@ -415,26 +415,19 @@ class Controller(controller.BaseController):
- @staticmethod
- def _validate_source(source, req):
- """
-- External sources (as specified via the location or copy-from headers)
-- are supported only over non-local store types, i.e. S3, Swift, HTTP.
-- Note the absence of 'file://' for security reasons, see LP bug #942118.
-- 'swift+config://' is also absent for security reasons, see LP bug
-- #1334196.
-- If the above constraint is violated, we reject with 400 "Bad Request".
-+ To validate if external sources (as specified via the location
-+ or copy-from headers) are supported. Otherwise we reject
-+ with 400 "Bad Request".
- """
- if source:
-- pieces = urlparse.urlparse(source)
-- schemes = [scheme for scheme in store.get_known_schemes()
-- if scheme != 'file' and scheme != 'swift+config']
-- for scheme in schemes:
-- if pieces.scheme == scheme:
-- return source
-- msg = ("External sourcing not supported for "
-- "store '%s'" % pieces.scheme)
-- LOG.debug(msg)
-- raise HTTPBadRequest(explanation=msg,
-- request=req,
-- content_type="text/plain")
-+ if store_utils.validate_external_location(source):
-+ return source
-+ else:
-+ msg = _("External source are not supported: '%s'") % source
-+ LOG.debug(msg)
-+ raise HTTPBadRequest(explanation=msg,
-+ request=req,
-+ content_type="text/plain")
-
- @staticmethod
- def _copy_from(req):
-diff --git a/glance/common/store_utils.py b/glance/common/store_utils.py
-index 8f04d39..b7537ce 100644
---- a/glance/common/store_utils.py
-+++ b/glance/common/store_utils.py
-@@ -16,6 +16,7 @@ import sys
-
- import glance_store as store_api
- from oslo.config import cfg
-+import six.moves.urllib.parse as urlparse
-
- from glance.common import utils
- import glance.db as db_api
-@@ -119,3 +120,24 @@ def delete_image_location_from_backend(context, image_id, location):
- # such as uploading process failure then we can't use
- # location status mechanism to support image pending delete.
- safe_delete_from_backend(context, image_id, location)
-+
-+
-+def validate_external_location(uri):
-+ """
-+ Validate if URI of external location are supported.
-+
-+ Only over non-local store types are OK, i.e. S3, Swift,
-+ HTTP. Note the absence of 'file://' for security reasons,
-+ see LP bug #942118, 1400966, 'swift+config://' is also
-+ absent for security reasons, see LP bug #1334196.
-+
-+ :param uri: The URI of external image location.
-+ :return: Whether given URI of external image location are OK.
-+ """
-+
-+ # TODO(zhiyan): This function could be moved to glance_store.
-+
-+ pieces = urlparse.urlparse(uri)
-+ valid_schemes = [scheme for scheme in store_api.get_known_schemes()
-+ if scheme != 'file' and scheme != 'swift+config']
-+ return pieces.scheme in valid_schemes
-diff --git a/glance/location.py b/glance/location.py
-index fcdba0a..f83fa7a 100644
---- a/glance/location.py
-+++ b/glance/location.py
-@@ -66,18 +66,20 @@ class ImageRepoProxy(glance.domain.proxy.Repo):
- return result
-
-
--def _check_location_uri(context, store_api, uri):
-+def _check_location_uri(context, store_api, store_utils, uri):
- """Check if an image location is valid.
-
- :param context: Glance request context
- :param store_api: store API module
-+ :param store_utils: store utils module
- :param uri: location's uri string
- """
-+
- is_ok = True
- try:
-- size = store_api.get_size_from_backend(uri, context=context)
- # NOTE(zhiyan): Some stores return zero when it catch exception
-- is_ok = size > 0
-+ is_ok = (store_utils.validate_external_location(uri) and
-+ store_api.get_size_from_backend(uri, context=context) > 0)
- except (store.UnknownScheme, store.NotFound):
- is_ok = False
- if not is_ok:
-@@ -85,8 +87,8 @@ def _check_location_uri(context, store_api, uri):
- raise exception.BadStoreUri(message=reason)
-
-
--def _check_image_location(context, store_api, location):
-- _check_location_uri(context, store_api, location['url'])
-+def _check_image_location(context, store_api, store_utils, location):
-+ _check_location_uri(context, store_api, store_utils, location['url'])
- store_api.check_location_metadata(location['metadata'])
-
-
-@@ -122,6 +124,7 @@ class ImageFactoryProxy(glance.domain.proxy.ImageFactory):
- def __init__(self, factory, context, store_api, store_utils):
- self.context = context
- self.store_api = store_api
-+ self.store_utils = store_utils
- proxy_kwargs = {'context': context, 'store_api': store_api,
- 'store_utils': store_utils}
- super(ImageFactoryProxy, self).__init__(factory,
-@@ -131,7 +134,10 @@ class ImageFactoryProxy(glance.domain.proxy.ImageFactory):
- def new_image(self, **kwargs):
- locations = kwargs.get('locations', [])
- for loc in locations:
-- _check_image_location(self.context, self.store_api, loc)
-+ _check_image_location(self.context,
-+ self.store_api,
-+ self.store_utils,
-+ loc)
- loc['status'] = 'active'
- if _count_duplicated_locations(locations, loc) > 1:
- raise exception.DuplicateLocation(location=loc['url'])
-@@ -169,7 +175,9 @@ class StoreLocations(collections.MutableSequence):
-
- def insert(self, i, location):
- _check_image_location(self.image_proxy.context,
-- self.image_proxy.store_api, location)
-+ self.image_proxy.store_api,
-+ self.image_proxy.store_utils,
-+ location)
- location['status'] = 'active'
- if _count_duplicated_locations(self.value, location) > 0:
- raise exception.DuplicateLocation(location=location['url'])
-@@ -214,7 +222,9 @@ class StoreLocations(collections.MutableSequence):
-
- def __setitem__(self, i, location):
- _check_image_location(self.image_proxy.context,
-- self.image_proxy.store_api, location)
-+ self.image_proxy.store_api,
-+ self.image_proxy.store_utils,
-+ location)
- location['status'] = 'active'
- self.value.__setitem__(i, location)
- _set_image_size(self.image_proxy.context,
-@@ -303,7 +313,9 @@ def _locations_proxy(target, attr):
- '%s') % ori_value)
- # NOTE(zhiyan): Check locations are all valid.
- for location in value:
-- _check_image_location(self.context, self.store_api,
-+ _check_image_location(self.context,
-+ self.store_api,
-+ self.store_utils,
- location)
- location['status'] = 'active'
- if _count_duplicated_locations(value, location) > 1:
-diff --git a/glance/tests/functional/v1/test_copy_to_file.py b/glance/tests/functional/v1/test_copy_to_file.py
-index 15bb708..b64eac6 100644
---- a/glance/tests/functional/v1/test_copy_to_file.py
-+++ b/glance/tests/functional/v1/test_copy_to_file.py
-@@ -250,7 +250,7 @@ class TestCopyToFile(functional.FunctionalTest):
- response, content = http.request(path, 'POST', headers=headers)
- self.assertEqual(response.status, 400, content)
-
-- expected = 'External sourcing not supported for store \'file\''
-+ expected = 'External source are not supported: \'%s\'' % copy_from
- msg = 'expected "%s" in "%s"' % (expected, content)
- self.assertTrue(expected in content, msg)
-
-@@ -276,7 +276,7 @@ class TestCopyToFile(functional.FunctionalTest):
- response, content = http.request(path, 'POST', headers=headers)
- self.assertEqual(response.status, 400, content)
-
-- expected = 'External sourcing not supported for store \'swift+config\''
-+ expected = 'External source are not supported: \'swift+config://xxx\''
- msg = 'expected "%s" in "%s"' % (expected, content)
- self.assertTrue(expected in content, msg)
-
-diff --git a/glance/tests/functional/v2/test_images.py b/glance/tests/functional/v2/test_images.py
-index 14fe3c7..4c32375 100644
---- a/glance/tests/functional/v2/test_images.py
-+++ b/glance/tests/functional/v2/test_images.py
-@@ -16,7 +16,6 @@
- import BaseHTTPServer
- import os
- import signal
--import tempfile
- import uuid
-
- import requests
-@@ -47,7 +46,7 @@ def get_handler_class(fixture):
- self.end_headers()
- return
-
-- def log_message(*args, **kwargs):
-+ def log_message(self, *args, **kwargs):
- # Override this method to prevent debug output from going
- # to stderr during testing
- return
-@@ -75,6 +74,18 @@ class TestImages(functional.FunctionalTest):
- self.cleanup()
- self.api_server.deployment_flavor = 'noauth'
- self.api_server.data_api = 'glance.db.sqlalchemy.api'
-+ for i in range(3):
-+ ret = http_server("foo_image_id%d" % i, "foo_image%d" % i)
-+ setattr(self, 'http_server%d_pid' % i, ret[0])
-+ setattr(self, 'http_port%d' % i, ret[1])
-+
-+ def tearDown(self):
-+ for i in range(3):
-+ pid = getattr(self, 'http_server%d_pid' % i, None)
-+ if pid:
-+ os.kill(pid, signal.SIGKILL)
-+
-+ super(TestImages, self).tearDown()
-
- def _url(self, path):
- return 'http://127.0.0.1:%d%s' % (self.api_port, path)
-@@ -329,21 +340,15 @@ class TestImages(functional.FunctionalTest):
- self.assertEqual(413, response.status_code, response.text)
-
- # Adding 3 image locations should fail since configured limit is 2
-- for i in range(3):
-- file_path = os.path.join(self.test_dir, 'fake_image_%i' % i)
-- with open(file_path, 'w') as fap:
-- fap.write('glance')
--
- path = self._url('/v2/images/%s' % image_id)
- media_type = 'application/openstack-images-v2.1-json-patch'
- headers = self._headers({'content-type': media_type})
- changes = []
- for i in range(3):
-+ url = ('http://127.0.0.1:%s/foo_image' %
-+ getattr(self, 'http_port%d' % i))
- changes.append({'op': 'add', 'path': '/locations/-',
-- 'value': {'url': 'file://{0}'.format(
-- os.path.join(self.test_dir,
-- 'fake_image_%i' % i)),
-- 'metadata': {}},
-+ 'value': {'url': url, 'metadata': {}},
- })
-
- data = jsonutils.dumps(changes)
-@@ -2176,17 +2181,14 @@ class TestImages(functional.FunctionalTest):
- self.assertNotIn('size', image)
- self.assertNotIn('virtual_size', image)
-
-- file_path = os.path.join(self.test_dir, 'fake_image')
-- with open(file_path, 'w') as fap:
-- fap.write('glance')
--
- # Update locations for the queued image
- path = self._url('/v2/images/%s' % image_id)
- media_type = 'application/openstack-images-v2.1-json-patch'
- headers = self._headers({'content-type': media_type})
-+ url = 'http://127.0.0.1:%s/foo_image' % self.http_port0
- data = jsonutils.dumps([{'op': 'replace', 'path': '/locations',
-- 'value': [{'url': 'file://' + file_path,
-- 'metadata': {}}]}])
-+ 'value': [{'url': url, 'metadata': {}}]
-+ }])
- response = requests.patch(path, headers=headers, data=data)
- self.assertEqual(200, response.status_code, response.text)
-
-@@ -2195,7 +2197,42 @@ class TestImages(functional.FunctionalTest):
- response = requests.get(path, headers=headers)
- self.assertEqual(200, response.status_code)
- image = jsonutils.loads(response.text)
-- self.assertEqual(image['size'], 6)
-+ self.assertEqual(image['size'], 10)
-+
-+ def test_update_locations_with_restricted_sources(self):
-+ self.start_servers(**self.__dict__.copy())
-+ # Create an image
-+ path = self._url('/v2/images')
-+ headers = self._headers({'content-type': 'application/json'})
-+ data = jsonutils.dumps({'name': 'image-1', 'disk_format': 'aki',
-+ 'container_format': 'aki'})
-+ response = requests.post(path, headers=headers, data=data)
-+ self.assertEqual(201, response.status_code)
-+
-+ # Returned image entity should have a generated id and status
-+ image = jsonutils.loads(response.text)
-+ image_id = image['id']
-+ self.assertEqual('queued', image['status'])
-+ self.assertNotIn('size', image)
-+ self.assertNotIn('virtual_size', image)
-+
-+ # Update locations for the queued image
-+ path = self._url('/v2/images/%s' % image_id)
-+ media_type = 'application/openstack-images-v2.1-json-patch'
-+ headers = self._headers({'content-type': media_type})
-+ data = jsonutils.dumps([{'op': 'replace', 'path': '/locations',
-+ 'value': [{'url': 'file:///foo_image',
-+ 'metadata': {}}]
-+ }])
-+ response = requests.patch(path, headers=headers, data=data)
-+ self.assertEqual(400, response.status_code, response.text)
-+
-+ data = jsonutils.dumps([{'op': 'replace', 'path': '/locations',
-+ 'value': [{'url': 'swift+config:///foo_image',
-+ 'metadata': {}}]
-+ }])
-+ response = requests.patch(path, headers=headers, data=data)
-+ self.assertEqual(400, response.status_code, response.text)
-
-
- class TestImagesWithRegistry(TestImages):
-@@ -2421,16 +2458,16 @@ class TestImageLocationSelectionStrategy(functional.FunctionalTest):
- super(TestImageLocationSelectionStrategy, self).setUp()
- self.cleanup()
- self.api_server.deployment_flavor = 'noauth'
-- self.foo_image_file = tempfile.NamedTemporaryFile()
-- self.foo_image_file.write("foo image file")
-- self.foo_image_file.flush()
-- self.addCleanup(self.foo_image_file.close)
-- ret = http_server("foo_image_id", "foo_image")
-- self.http_server_pid, self.http_port = ret
-+ for i in range(3):
-+ ret = http_server("foo_image_id%d" % i, "foo_image%d" % i)
-+ setattr(self, 'http_server%d_pid' % i, ret[0])
-+ setattr(self, 'http_port%d' % i, ret[1])
-
- def tearDown(self):
-- if self.http_server_pid is not None:
-- os.kill(self.http_server_pid, signal.SIGKILL)
-+ for i in range(3):
-+ pid = getattr(self, 'http_server%d_pid' % i, None)
-+ if pid:
-+ os.kill(pid, signal.SIGKILL)
-
- super(TestImageLocationSelectionStrategy, self).tearDown()
-
-@@ -2483,69 +2520,10 @@ class TestImageLocationSelectionStrategy(functional.FunctionalTest):
- path = self._url('/v2/images/%s' % image_id)
- media_type = 'application/openstack-images-v2.1-json-patch'
- headers = self._headers({'content-type': media_type})
-- values = [{'url': 'file://%s' % self.foo_image_file.name,
-- 'metadata': {'idx': '1'}},
-- {'url': 'http://127.0.0.1:%s/foo_image' % self.http_port,
-- 'metadata': {'idx': '0'}}]
-- doc = [{'op': 'replace',
-- 'path': '/locations',
-- 'value': values}]
-- data = jsonutils.dumps(doc)
-- response = requests.patch(path, headers=headers, data=data)
-- self.assertEqual(200, response.status_code)
--
-- # Image locations should be visible
-- path = self._url('/v2/images/%s' % image_id)
-- headers = self._headers({'Content-Type': 'application/json'})
-- response = requests.get(path, headers=headers)
-- self.assertEqual(200, response.status_code)
-- image = jsonutils.loads(response.text)
-- self.assertTrue('locations' in image)
-- self.assertEqual(image['locations'], values)
-- self.assertTrue('direct_url' in image)
-- self.assertEqual(image['direct_url'], values[0]['url'])
--
-- self.stop_servers()
--
-- def test_image_locatons_with_store_type_strategy(self):
-- self.api_server.show_image_direct_url = True
-- self.api_server.show_multiple_locations = True
-- self.image_location_quota = 10
-- self.api_server.location_strategy = 'store_type'
-- preference = "http, swift, filesystem"
-- self.api_server.store_type_location_strategy_preference = preference
-- self.start_servers(**self.__dict__.copy())
--
-- # Create an image
-- path = self._url('/v2/images')
-- headers = self._headers({'content-type': 'application/json'})
-- data = jsonutils.dumps({'name': 'image-1', 'type': 'kernel',
-- 'foo': 'bar', 'disk_format': 'aki',
-- 'container_format': 'aki'})
-- response = requests.post(path, headers=headers, data=data)
-- self.assertEqual(201, response.status_code)
--
-- # Get the image id
-- image = jsonutils.loads(response.text)
-- image_id = image['id']
--
-- # Image locations should not be visible before location is set
-- path = self._url('/v2/images/%s' % image_id)
-- headers = self._headers({'Content-Type': 'application/json'})
-- response = requests.get(path, headers=headers)
-- self.assertEqual(200, response.status_code)
-- image = jsonutils.loads(response.text)
-- self.assertTrue('locations' in image)
-- self.assertTrue(image["locations"] == [])
--
-- # Update image locations via PATCH
-- path = self._url('/v2/images/%s' % image_id)
-- media_type = 'application/openstack-images-v2.1-json-patch'
-- headers = self._headers({'content-type': media_type})
-- values = [{'url': 'file://%s' % self.foo_image_file.name,
-- 'metadata': {'idx': '1'}},
-- {'url': 'http://127.0.0.1:%s/foo_image' % self.http_port,
-- 'metadata': {'idx': '0'}}]
-+ values = [{'url': 'http://127.0.0.1:%s/foo_image' % self.http_port0,
-+ 'metadata': {}},
-+ {'url': 'http://127.0.0.1:%s/foo_image' % self.http_port1,
-+ 'metadata': {}}]
- doc = [{'op': 'replace',
- 'path': '/locations',
- 'value': values}]
-@@ -2553,8 +2531,6 @@ class TestImageLocationSelectionStrategy(functional.FunctionalTest):
- response = requests.patch(path, headers=headers, data=data)
- self.assertEqual(200, response.status_code)
-
-- values.sort(key=lambda loc: int(loc['metadata']['idx']))
--
- # Image locations should be visible
- path = self._url('/v2/images/%s' % image_id)
- headers = self._headers({'Content-Type': 'application/json'})
-diff --git a/glance/tests/unit/test_store_image.py b/glance/tests/unit/test_store_image.py
-index 665f126..8b334ab 100644
---- a/glance/tests/unit/test_store_image.py
-+++ b/glance/tests/unit/test_store_image.py
-@@ -18,6 +18,7 @@ import glance_store
-
- from glance.common import exception
- import glance.location
-+from glance.tests.unit import base as unit_test_base
- from glance.tests.unit import utils as unit_test_utils
- from glance.tests import utils
-
-@@ -759,7 +760,7 @@ class TestStoreImageRepo(utils.BaseTestCase):
- self.assertEqual(acls['read'], [TENANT2])
-
-
--class TestImageFactory(utils.BaseTestCase):
-+class TestImageFactory(unit_test_base.StoreClearingUnitTest):
-
- def setUp(self):
- super(TestImageFactory, self).setUp()
-diff --git a/glance/tests/unit/test_store_location.py b/glance/tests/unit/test_store_location.py
-index 884221b..c9ee44c 100644
---- a/glance/tests/unit/test_store_location.py
-+++ b/glance/tests/unit/test_store_location.py
-@@ -17,6 +17,8 @@ import mock
-
- import glance_store
-
-+from glance.common import exception
-+from glance.common import store_utils
- import glance.location
- from glance.tests.unit import base
-
-@@ -32,11 +34,13 @@ CONF = {'default_store': 'file',
-
- class TestStoreLocation(base.StoreClearingUnitTest):
-
-+ class FakeImageProxy():
-+ size = None
-+ context = None
-+ store_api = mock.Mock()
-+ store_utils = store_utils
-+
- def test_add_location_for_image_without_size(self):
-- class FakeImageProxy():
-- size = None
-- context = None
-- store_api = mock.Mock()
-
- def fake_get_size_from_backend(uri, context=None):
- return 1
-@@ -49,14 +53,31 @@ class TestStoreLocation(base.StoreClearingUnitTest):
- loc2 = {'url': 'file:///fake2.img.tar.gz', 'metadata': {}}
-
- # Test for insert location
-- image1 = FakeImageProxy()
-+ image1 = TestStoreLocation.FakeImageProxy()
- locations = glance.location.StoreLocations(image1, [])
- locations.insert(0, loc2)
- self.assertEqual(image1.size, 1)
-
- # Test for set_attr of _locations_proxy
-- image2 = FakeImageProxy()
-+ image2 = TestStoreLocation.FakeImageProxy()
- locations = glance.location.StoreLocations(image2, [loc1])
- locations[0] = loc2
- self.assertIn(loc2, locations)
- self.assertEqual(image2.size, 1)
-+
-+ def test_add_location_with_restricted_sources(self):
-+
-+ loc1 = {'url': 'file:///fake1.img.tar.gz', 'metadata': {}}
-+ loc2 = {'url': 'swift+config:///xxx', 'metadata': {}}
-+
-+ # Test for insert location
-+ image1 = TestStoreLocation.FakeImageProxy()
-+ locations = glance.location.StoreLocations(image1, [])
-+ self.assertRaises(exception.BadStoreUri, locations.insert, 0, loc1)
-+ self.assertNotIn(loc1, locations)
-+
-+ # Test for set_attr of _locations_proxy
-+ image2 = TestStoreLocation.FakeImageProxy()
-+ locations = glance.location.StoreLocations(image2, [loc1])
-+ self.assertRaises(exception.BadStoreUri, locations.insert, 0, loc2)
-+ self.assertNotIn(loc2, locations)
-diff --git a/glance/tests/unit/utils.py b/glance/tests/unit/utils.py
-index df59160..f7c8d56 100644
---- a/glance/tests/unit/utils.py
-+++ b/glance/tests/unit/utils.py
-@@ -14,12 +14,13 @@
- # under the License.
-
- import urllib
--import urlparse
-
- import glance_store as store
- from oslo.config import cfg
-+import six.moves.urllib.parse as urlparse
-
- from glance.common import exception
-+from glance.common import store_utils
- from glance.common import wsgi
- import glance.context
- import glance.db.simple.api as simple_db
-@@ -135,6 +136,12 @@ class FakeStoreUtils(object):
- else:
- self.safe_delete_from_backend(context, image_id, location)
-
-+ def validate_external_location(self, uri):
-+ if uri and urlparse.urlparse(uri).scheme:
-+ return store_utils.validate_external_location(uri)
-+ else:
-+ return True
-+
-
- class FakeStoreAPI(object):
- def __init__(self, store_metadata=None):
-diff --git a/glance/tests/unit/v1/test_api.py b/glance/tests/unit/v1/test_api.py
-index bd2182e..4ec136d 100644
---- a/glance/tests/unit/v1/test_api.py
-+++ b/glance/tests/unit/v1/test_api.py
-@@ -419,7 +419,7 @@ class TestGlanceAPI(base.IsolatedUnitTest):
-
- res = req.get_response(self.api)
- self.assertEqual(res.status_int, 400)
-- self.assertIn('External sourcing not supported', res.body)
-+ self.assertIn('External source are not supported', res.body)
-
- def test_create_with_location_bad_store_uri(self):
- fixture_headers = {
-@@ -1006,7 +1006,7 @@ class TestGlanceAPI(base.IsolatedUnitTest):
- res = req.get_response(self.api)
- self.assertEqual(res.status_int, 409)
-
-- def test_add_location_with_invalid_location(self):
-+ def test_add_location_with_invalid_location_on_conflict_image_size(self):
- """Tests creates an image from location and conflict image size"""
- fixture_headers = {'x-image-meta-store': 'file',
- 'x-image-meta-disk-format': 'vhd',
-@@ -1023,6 +1023,36 @@ class TestGlanceAPI(base.IsolatedUnitTest):
- res = req.get_response(self.api)
- self.assertEqual(res.status_int, 400)
-
-+ def test_add_location_with_invalid_location_on_restricted_sources(self):
-+ """Tests creates an image from location and restricted sources"""
-+ fixture_headers = {'x-image-meta-store': 'file',
-+ 'x-image-meta-disk-format': 'vhd',
-+ 'x-image-meta-location': 'file:///etc/passwd',
-+ 'x-image-meta-container-format': 'ovf',
-+ 'x-image-meta-name': 'fake image #F'}
-+
-+ req = webob.Request.blank("/images")
-+ req.headers['Content-Type'] = 'application/octet-stream'
-+ req.method = 'POST'
-+ for k, v in fixture_headers.iteritems():
-+ req.headers[k] = v
-+ res = req.get_response(self.api)
-+ self.assertEqual(400, res.status_int)
-+
-+ fixture_headers = {'x-image-meta-store': 'file',
-+ 'x-image-meta-disk-format': 'vhd',
-+ 'x-image-meta-location': 'swift+config://xxx',
-+ 'x-image-meta-container-format': 'ovf',
-+ 'x-image-meta-name': 'fake image #F'}
-+
-+ req = webob.Request.blank("/images")
-+ req.headers['Content-Type'] = 'application/octet-stream'
-+ req.method = 'POST'
-+ for k, v in fixture_headers.iteritems():
-+ req.headers[k] = v
-+ res = req.get_response(self.api)
-+ self.assertEqual(400, res.status_int)
-+
- def test_add_copy_from_with_location(self):
- """Tests creates an image from copy-from and location"""
- fixture_headers = {'x-image-meta-store': 'file',
-@@ -1039,6 +1069,34 @@ class TestGlanceAPI(base.IsolatedUnitTest):
- res = req.get_response(self.api)
- self.assertEqual(res.status_int, 400)
-
-+ def test_add_copy_from_with_restricted_sources(self):
-+ """Tests creates an image from copy-from with restricted sources"""
-+ fixture_headers = {'x-image-meta-store': 'file',
-+ 'x-image-meta-disk-format': 'vhd',
-+ 'x-glance-api-copy-from': 'file:///etc/passwd',
-+ 'x-image-meta-container-format': 'ovf',
-+ 'x-image-meta-name': 'fake image #F'}
-+
-+ req = webob.Request.blank("/images")
-+ req.method = 'POST'
-+ for k, v in six.iteritems(fixture_headers):
-+ req.headers[k] = v
-+ res = req.get_response(self.api)
-+ self.assertEqual(400, res.status_int)
-+
-+ fixture_headers = {'x-image-meta-store': 'file',
-+ 'x-image-meta-disk-format': 'vhd',
-+ 'x-glance-api-copy-from': 'swift+config://xxx',
-+ 'x-image-meta-container-format': 'ovf',
-+ 'x-image-meta-name': 'fake image #F'}
-+
-+ req = webob.Request.blank("/images")
-+ req.method = 'POST'
-+ for k, v in six.iteritems(fixture_headers):
-+ req.headers[k] = v
-+ res = req.get_response(self.api)
-+ self.assertEqual(400, res.status_int)
-+
- def test_add_copy_from_upload_image_unauthorized_with_body(self):
- rules = {"upload_image": '!', "modify_image": '@',
- "add_image": '@'}
---
-2.0.5
-
diff --git a/app-admin/glance/files/glance-CVE-2014-9623.patch b/app-admin/glance/files/glance-CVE-2014-9623.patch
deleted file mode 100644
index a9cc123f9ceb..000000000000
--- a/app-admin/glance/files/glance-CVE-2014-9623.patch
+++ /dev/null
@@ -1,542 +0,0 @@
-From 7d5d8657fd70b20518610b3c6f8e41e16c72fa31 Mon Sep 17 00:00:00 2001
-From: Zhi Yan Liu <zhiyanl@cn.ibm.com>
-Date: Tue, 30 Dec 2014 22:25:50 +0800
-Subject: [PATCH] Cleanup chunks for deleted image that was 'saving'
-
-Currently image data cannot be removed synchronously for an image that
-is in saving state. And when, the upload operation for such an image is
-completed the operator configured quota can be exceeded.
-
-This patch fixes the issue of left over chunks for an image which was
-deleted from saving status. However, by the limitation of the design we
-cannot enforce a global quota check for the image in saving status.
-
-This change introduces a inconsonance between http response codes of
-v1 and v2 APIs. The status codes which we will now see after the upload
-process completes on an image which was deleted mid way are:
-
-v1: 412 Precondition Failed
-v2: 410 Gone
-
-SecurityImpact
-UpgradeImpact
-APIImpact
-
-Closes-Bug: 1383973
-Closes-Bug: 1398830
-Closes-Bug: 1188532
-
-Conflicts:
- glance/api/v1/upload_utils.py
- glance/api/v2/image_data.py
- glance/tests/unit/test_domain_proxy.py
- glance/tests/unit/v1/test_api.py
-
-Change-Id: I47229b366c25367ec1bd48aec684e0880f3dfe60
-Signed-off-by: Zhi Yan Liu <zhiyanl@cn.ibm.com>
-(cherry picked from commit 0dc8fbb3479a53c5bba8475d14f4c7206904c5ea)
----
- glance/api/authorization.py | 4 +-
- glance/api/policy.py | 8 ++--
- glance/api/v1/upload_utils.py | 19 +++++---
- glance/api/v2/image_data.py | 8 +++-
- glance/db/__init__.py | 7 +--
- glance/domain/proxy.py | 4 +-
- glance/location.py | 4 +-
- glance/notifier.py | 4 +-
- glance/quota/__init__.py | 4 +-
- glance/tests/unit/test_domain_proxy.py | 14 +++---
- glance/tests/unit/test_policy.py | 2 +-
- glance/tests/unit/test_quota.py | 17 ++++---
- glance/tests/unit/test_store_image.py | 2 +-
- glance/tests/unit/v1/test_api.py | 57 +++++++++++-------------
- glance/tests/unit/v2/test_image_data_resource.py | 24 +++++-----
- 15 files changed, 98 insertions(+), 80 deletions(-)
-
-diff --git a/glance/api/authorization.py b/glance/api/authorization.py
-index 149ff55..77f7ed3 100644
---- a/glance/api/authorization.py
-+++ b/glance/api/authorization.py
-@@ -158,10 +158,10 @@ class ImageMemberRepoProxy(glance.domain.proxy.Repo):
- raise exception.Forbidden(message
- % self.image.image_id)
-
-- def save(self, image_member):
-+ def save(self, image_member, from_state=None):
- if (self.context.is_admin or
- self.context.owner == image_member.member_id):
-- self.member_repo.save(image_member)
-+ self.member_repo.save(image_member, from_state=from_state)
- else:
- message = _("You cannot update image member %s")
- raise exception.Forbidden(message % image_member.member_id)
-diff --git a/glance/api/policy.py b/glance/api/policy.py
-index 0bc8d56..e395876 100644
---- a/glance/api/policy.py
-+++ b/glance/api/policy.py
-@@ -182,9 +182,9 @@ class ImageRepoProxy(glance.domain.proxy.Repo):
- self.policy.enforce(self.context, 'get_images', {})
- return super(ImageRepoProxy, self).list(*args, **kwargs)
-
-- def save(self, image):
-+ def save(self, image, from_state=None):
- self.policy.enforce(self.context, 'modify_image', {})
-- return super(ImageRepoProxy, self).save(image)
-+ return super(ImageRepoProxy, self).save(image, from_state=from_state)
-
- def add(self, image):
- self.policy.enforce(self.context, 'add_image', {})
-@@ -285,9 +285,9 @@ class ImageMemberRepoProxy(glance.domain.proxy.Repo):
- self.policy.enforce(self.context, 'get_member', {})
- return self.member_repo.get(member_id)
-
-- def save(self, member):
-+ def save(self, member, from_state=None):
- self.policy.enforce(self.context, 'modify_member', {})
-- self.member_repo.save(member)
-+ self.member_repo.save(member, from_state=from_state)
-
- def list(self, *args, **kwargs):
- self.policy.enforce(self.context, 'get_members', {})
-diff --git a/glance/api/v1/upload_utils.py b/glance/api/v1/upload_utils.py
-index 8a190fc..60c3d3d 100644
---- a/glance/api/v1/upload_utils.py
-+++ b/glance/api/v1/upload_utils.py
-@@ -153,12 +153,19 @@ def upload_data_to_store(req, image_meta, image_data, store, notifier):
- update_data = {'checksum': checksum,
- 'size': size}
- try:
-- image_meta = registry.update_image_metadata(req.context,
-- image_id,
-- update_data,
-- from_state='saving')
--
-- except exception.NotFound as e:
-+ try:
-+ state = 'saving'
-+ image_meta = registry.update_image_metadata(req.context,
-+ image_id,
-+ update_data,
-+ from_state=state)
-+ except exception.Duplicate:
-+ image = registry.get_image_metadata(req.context, image_id)
-+ if image['status'] == 'deleted':
-+ raise exception.NotFound()
-+ else:
-+ raise
-+ except exception.NotFound:
- msg = _LI("Image %s could not be found after upload. The image may"
- " have been deleted during the upload.") % image_id
- LOG.info(msg)
-diff --git a/glance/api/v2/image_data.py b/glance/api/v2/image_data.py
-index 430ffc5..cdfa34b 100644
---- a/glance/api/v2/image_data.py
-+++ b/glance/api/v2/image_data.py
-@@ -73,8 +73,8 @@ class ImageDataController(object):
- try:
- image_repo.save(image)
- image.set_data(data, size)
-- image_repo.save(image)
-- except exception.NotFound as e:
-+ image_repo.save(image, from_state='saving')
-+ except (exception.NotFound, exception.Conflict) as e:
- msg = (_("Image %(id)s could not be found after upload."
- "The image may have been deleted during the upload: "
- "%(error)s Cleaning up the chunks uploaded") %
-@@ -152,6 +152,10 @@ class ImageDataController(object):
- raise webob.exc.HTTPServiceUnavailable(explanation=msg,
- request=req)
-
-+ except webob.exc.HTTPGone as e:
-+ with excutils.save_and_reraise_exception():
-+ LOG.error(_LE("Failed to upload image data due to HTTP error"))
-+
- except webob.exc.HTTPError as e:
- with excutils.save_and_reraise_exception():
- LOG.error(_LE("Failed to upload image data due to HTTP error"))
-diff --git a/glance/db/__init__.py b/glance/db/__init__.py
-index 05db7f8..483ba21 100644
---- a/glance/db/__init__.py
-+++ b/glance/db/__init__.py
-@@ -164,7 +164,7 @@ class ImageRepo(object):
- image.created_at = new_values['created_at']
- image.updated_at = new_values['updated_at']
-
-- def save(self, image):
-+ def save(self, image, from_state=None):
- image_values = self._format_image_to_db(image)
- if image_values['size'] > CONF.image_size_cap:
- raise exception.ImageSizeLimitExceeded
-@@ -172,7 +172,8 @@ class ImageRepo(object):
- new_values = self.db_api.image_update(self.context,
- image.image_id,
- image_values,
-- purge_props=True)
-+ purge_props=True,
-+ from_state=from_state)
- except (exception.NotFound, exception.Forbidden):
- msg = _("No image found with ID %s") % image.image_id
- raise exception.NotFound(msg)
-@@ -265,7 +266,7 @@ class ImageMemberRepo(object):
- msg = _("The specified member %s could not be found")
- raise exception.NotFound(msg % image_member.id)
-
-- def save(self, image_member):
-+ def save(self, image_member, from_state=None):
- image_member_values = self._format_image_member_to_db(image_member)
- try:
- new_values = self.db_api.image_member_update(self.context,
-diff --git a/glance/domain/proxy.py b/glance/domain/proxy.py
-index 5a91d34..09c0fb2 100644
---- a/glance/domain/proxy.py
-+++ b/glance/domain/proxy.py
-@@ -94,9 +94,9 @@ class Repo(object):
- result = self.base.add(base_item)
- return self.helper.proxy(result)
-
-- def save(self, item):
-+ def save(self, item, from_state=None):
- base_item = self.helper.unproxy(item)
-- result = self.base.save(base_item)
-+ result = self.base.save(base_item, from_state=from_state)
- return self.helper.proxy(result)
-
- def remove(self, item):
-diff --git a/glance/location.py b/glance/location.py
-index f83fa7a..b49546d 100644
---- a/glance/location.py
-+++ b/glance/location.py
-@@ -60,8 +60,8 @@ class ImageRepoProxy(glance.domain.proxy.Repo):
- self._set_acls(image)
- return result
-
-- def save(self, image):
-- result = super(ImageRepoProxy, self).save(image)
-+ def save(self, image, from_state=None):
-+ result = super(ImageRepoProxy, self).save(image, from_state=from_state)
- self._set_acls(image)
- return result
-
-diff --git a/glance/notifier.py b/glance/notifier.py
-index 5ec0854..21223da 100644
---- a/glance/notifier.py
-+++ b/glance/notifier.py
-@@ -122,8 +122,8 @@ class ImageRepoProxy(glance.domain.proxy.Repo):
- item_proxy_class=ImageProxy,
- item_proxy_kwargs=proxy_kwargs)
-
-- def save(self, image):
-- super(ImageRepoProxy, self).save(image)
-+ def save(self, image, from_state=None):
-+ super(ImageRepoProxy, self).save(image, from_state=from_state)
- self.notifier.info('image.update',
- format_image_notification(image))
-
-diff --git a/glance/quota/__init__.py b/glance/quota/__init__.py
-index 4051992..d628a8c 100644
---- a/glance/quota/__init__.py
-+++ b/glance/quota/__init__.py
-@@ -104,10 +104,10 @@ class ImageRepoProxy(glance.domain.proxy.Repo):
- LOG.debug(six.text_type(exc))
- raise exc
-
-- def save(self, image):
-+ def save(self, image, from_state=None):
- if image.added_new_properties():
- self._enforce_image_property_quota(len(image.extra_properties))
-- return super(ImageRepoProxy, self).save(image)
-+ return super(ImageRepoProxy, self).save(image, from_state=from_state)
-
- def add(self, image):
- self._enforce_image_property_quota(len(image.extra_properties))
-diff --git a/glance/tests/unit/test_domain_proxy.py b/glance/tests/unit/test_domain_proxy.py
-index 1bb6863..2b8f792 100644
---- a/glance/tests/unit/test_domain_proxy.py
-+++ b/glance/tests/unit/test_domain_proxy.py
-@@ -74,7 +74,7 @@ class TestProxyRepoPlain(test_utils.BaseTestCase):
- self._test_method('add', 'snuff', 'enough')
-
- def test_save(self):
-- self._test_method('save', 'snuff', 'enough')
-+ self._test_method('save', 'snuff', 'enough', from_state=None)
-
- def test_remove(self):
- self._test_method('add', None, 'flying')
-@@ -121,14 +121,14 @@ class TestProxyRepoWrapping(test_utils.BaseTestCase):
- self.assertEqual(results[i].args, tuple())
- self.assertEqual(results[i].kwargs, {'a': 1})
-
-- def _test_method_with_proxied_argument(self, name, result):
-+ def _test_method_with_proxied_argument(self, name, result, **kwargs):
- self.fake_repo.result = result
- item = FakeProxy('snoop')
- method = getattr(self.proxy_repo, name)
- proxy_result = method(item)
-
-- self.assertEqual(self.fake_repo.args, ('snoop',))
-- self.assertEqual(self.fake_repo.kwargs, {})
-+ self.assertEqual(('snoop',), self.fake_repo.args)
-+ self.assertEqual(kwargs, self.fake_repo.kwargs)
-
- if result is None:
- self.assertIsNone(proxy_result)
-@@ -145,10 +145,12 @@ class TestProxyRepoWrapping(test_utils.BaseTestCase):
- self._test_method_with_proxied_argument('add', None)
-
- def test_save(self):
-- self._test_method_with_proxied_argument('save', 'dog')
-+ self._test_method_with_proxied_argument('save', 'dog',
-+ from_state=None)
-
- def test_save_with_no_result(self):
-- self._test_method_with_proxied_argument('save', None)
-+ self._test_method_with_proxied_argument('save', None,
-+ from_state=None)
-
- def test_remove(self):
- self._test_method_with_proxied_argument('remove', 'dog')
-diff --git a/glance/tests/unit/test_policy.py b/glance/tests/unit/test_policy.py
-index 5b5e870..44546a0 100644
---- a/glance/tests/unit/test_policy.py
-+++ b/glance/tests/unit/test_policy.py
-@@ -78,7 +78,7 @@ class MemberRepoStub(object):
- def get(self, *args, **kwargs):
- return 'member_repo_get'
-
-- def save(self, image_member):
-+ def save(self, image_member, from_state=None):
- image_member.output = 'member_repo_save'
-
- def list(self, *args, **kwargs):
-diff --git a/glance/tests/unit/test_quota.py b/glance/tests/unit/test_quota.py
-index c12eda2..1c40fb4 100644
---- a/glance/tests/unit/test_quota.py
-+++ b/glance/tests/unit/test_quota.py
-@@ -367,7 +367,8 @@ class TestImagePropertyQuotas(test_utils.BaseTestCase):
- self.image.extra_properties = {'foo': 'bar'}
- self.image_repo_proxy.save(self.image)
-
-- self.image_repo_mock.save.assert_called_once_with(self.base_image)
-+ self.image_repo_mock.save.assert_called_once_with(self.base_image,
-+ from_state=None)
-
- def test_save_image_too_many_image_properties(self):
- self.config(image_property_quota=1)
-@@ -383,7 +384,8 @@ class TestImagePropertyQuotas(test_utils.BaseTestCase):
- self.image.extra_properties = {'foo': 'bar'}
- self.image_repo_proxy.save(self.image)
-
-- self.image_repo_mock.save.assert_called_once_with(self.base_image)
-+ self.image_repo_mock.save.assert_called_once_with(self.base_image,
-+ from_state=None)
-
- def test_add_image_with_image_property(self):
- self.config(image_property_quota=1)
-@@ -422,7 +424,8 @@ class TestImagePropertyQuotas(test_utils.BaseTestCase):
- self.config(image_property_quota=1)
- self.image.extra_properties = {'foo': 'frob', 'spam': 'eggs'}
- self.image_repo_proxy.save(self.image)
-- self.image_repo_mock.save.assert_called_once_with(self.base_image)
-+ self.image_repo_mock.save.assert_called_once_with(self.base_image,
-+ from_state=None)
- self.assertEqual('frob', self.base_image.extra_properties['foo'])
- self.assertEqual('eggs', self.base_image.extra_properties['spam'])
-
-@@ -431,7 +434,8 @@ class TestImagePropertyQuotas(test_utils.BaseTestCase):
- self.config(image_property_quota=1)
- del self.image.extra_properties['foo']
- self.image_repo_proxy.save(self.image)
-- self.image_repo_mock.save.assert_called_once_with(self.base_image)
-+ self.image_repo_mock.save.assert_called_once_with(self.base_image,
-+ from_state=None)
- self.assertNotIn('foo', self.base_image.extra_properties)
- self.assertEqual('ham', self.base_image.extra_properties['spam'])
-
-@@ -447,7 +451,7 @@ class TestImagePropertyQuotas(test_utils.BaseTestCase):
- del self.image.extra_properties['frob']
- del self.image.extra_properties['lorem']
- self.image_repo_proxy.save(self.image)
-- call_args = mock.call(self.base_image)
-+ call_args = mock.call(self.base_image, from_state=None)
- self.assertEqual(call_args, self.image_repo_mock.save.call_args)
- self.assertEqual('bar', self.base_image.extra_properties['foo'])
- self.assertEqual('ham', self.base_image.extra_properties['spam'])
-@@ -466,7 +470,8 @@ class TestImagePropertyQuotas(test_utils.BaseTestCase):
- self.config(image_property_quota=1)
- del self.image.extra_properties['foo']
- self.image_repo_proxy.save(self.image)
-- self.image_repo_mock.save.assert_called_once_with(self.base_image)
-+ self.image_repo_mock.save.assert_called_once_with(self.base_image,
-+ from_state=None)
- self.assertNotIn('foo', self.base_image.extra_properties)
- self.assertEqual('ham', self.base_image.extra_properties['spam'])
- self.assertEqual('baz', self.base_image.extra_properties['frob'])
-diff --git a/glance/tests/unit/test_store_image.py b/glance/tests/unit/test_store_image.py
-index 8b334ab..b656454 100644
---- a/glance/tests/unit/test_store_image.py
-+++ b/glance/tests/unit/test_store_image.py
-@@ -36,7 +36,7 @@ class ImageRepoStub(object):
- def add(self, image):
- return image
-
-- def save(self, image):
-+ def save(self, image, from_state=None):
- return image
-
-
-diff --git a/glance/tests/unit/v1/test_api.py b/glance/tests/unit/v1/test_api.py
-index 39e9a44..7dc0737 100644
---- a/glance/tests/unit/v1/test_api.py
-+++ b/glance/tests/unit/v1/test_api.py
-@@ -39,7 +39,6 @@ from glance.db.sqlalchemy import api as db_api
- from glance.db.sqlalchemy import models as db_models
- from glance.openstack.common import jsonutils
- from glance.openstack.common import timeutils
--
- import glance.registry.client.v1.api as registry
- from glance.tests.unit import base
- import glance.tests.unit.utils as unit_test_utils
-@@ -1735,8 +1734,7 @@ class TestGlanceAPI(base.IsolatedUnitTest):
-
- self.assertEqual(1, mock_store_add_to_backend.call_count)
-
-- def test_delete_during_image_upload(self):
-- req = unit_test_utils.get_fake_request()
-+ def _check_delete_during_image_upload(self, is_admin=False):
-
- fixture_headers = {'x-image-meta-store': 'file',
- 'x-image-meta-disk-format': 'vhd',
-@@ -1744,8 +1742,8 @@ class TestGlanceAPI(base.IsolatedUnitTest):
- 'x-image-meta-name': 'fake image #3',
- 'x-image-meta-property-key1': 'value1'}
-
-- req = webob.Request.blank("/images")
-- req.method = 'POST'
-+ req = unit_test_utils.get_fake_request(path="/images",
-+ is_admin=is_admin)
- for k, v in six.iteritems(fixture_headers):
- req.headers[k] = v
-
-@@ -1770,31 +1768,18 @@ class TestGlanceAPI(base.IsolatedUnitTest):
- mock_initiate_deletion)
-
- orig_update_image_metadata = registry.update_image_metadata
-- ctlr = glance.api.v1.controller.BaseController
-- orig_get_image_meta_or_404 = ctlr.get_image_meta_or_404
--
-- def mock_update_image_metadata(*args, **kwargs):
-
-- if args[2].get('status', None) == 'deleted':
-+ data = "somedata"
-
-- # One shot.
-- def mock_get_image_meta_or_404(*args, **kwargs):
-- ret = orig_get_image_meta_or_404(*args, **kwargs)
-- ret['status'] = 'queued'
-- self.stubs.Set(ctlr, 'get_image_meta_or_404',
-- orig_get_image_meta_or_404)
-- return ret
--
-- self.stubs.Set(ctlr, 'get_image_meta_or_404',
-- mock_get_image_meta_or_404)
-+ def mock_update_image_metadata(*args, **kwargs):
-
-- req = webob.Request.blank("/images/%s" % image_id)
-- req.method = 'PUT'
-- req.headers['Content-Type'] = 'application/octet-stream'
-- req.body = "somedata"
-+ if args[2].get('size', None) == len(data):
-+ path = "/images/%s" % image_id
-+ req = unit_test_utils.get_fake_request(path=path,
-+ method='DELETE',
-+ is_admin=is_admin)
- res = req.get_response(self.api)
-- self.assertEqual(res.status_int, 200)
-- self.assertFalse(res.location)
-+ self.assertEqual(200, res.status_int)
-
- self.stubs.Set(registry, 'update_image_metadata',
- orig_update_image_metadata)
-@@ -1804,20 +1789,30 @@ class TestGlanceAPI(base.IsolatedUnitTest):
- self.stubs.Set(registry, 'update_image_metadata',
- mock_update_image_metadata)
-
-- req = webob.Request.blank("/images/%s" % image_id)
-- req.method = 'DELETE'
-+ req = unit_test_utils.get_fake_request(path="/images/%s" % image_id,
-+ method='PUT')
-+ req.headers['Content-Type'] = 'application/octet-stream'
-+ req.body = data
- res = req.get_response(self.api)
-- self.assertEqual(res.status_int, 200)
-+ self.assertEqual(412, res.status_int)
-+ self.assertFalse(res.location)
-
- self.assertTrue(called['initiate_deletion'])
-
-- req = webob.Request.blank("/images/%s" % image_id)
-- req.method = 'HEAD'
-+ req = unit_test_utils.get_fake_request(path="/images/%s" % image_id,
-+ method='HEAD',
-+ is_admin=True)
- res = req.get_response(self.api)
- self.assertEqual(res.status_int, 200)
- self.assertEqual(res.headers['x-image-meta-deleted'], 'True')
- self.assertEqual(res.headers['x-image-meta-status'], 'deleted')
-
-+ def test_delete_during_image_upload_by_normal_user(self):
-+ self._check_delete_during_image_upload(is_admin=False)
-+
-+ def test_delete_during_image_upload_by_admin(self):
-+ self._check_delete_during_image_upload(is_admin=True)
-+
- def test_disable_purge_props(self):
- """
- Test the special x-glance-registry-purge-props header controls
-diff --git a/glance/tests/unit/v2/test_image_data_resource.py b/glance/tests/unit/v2/test_image_data_resource.py
-index cc8148a..a121e82 100644
---- a/glance/tests/unit/v2/test_image_data_resource.py
-+++ b/glance/tests/unit/v2/test_image_data_resource.py
-@@ -81,7 +81,7 @@ class FakeImageRepo(object):
- else:
- return self.result
-
-- def save(self, image):
-+ def save(self, image, from_state=None):
- self.saved_image = image
-
-
-@@ -184,17 +184,21 @@ class TestImagesController(base.StoreClearingUnitTest):
- request, unit_test_utils.UUID1, 'YYYY', 4)
-
- def test_upload_non_existent_image_during_save_initiates_deletion(self):
-- def fake_save(self):
-+ def fake_save_not_found(self):
- raise exception.NotFound()
-
-- request = unit_test_utils.get_fake_request()
-- image = FakeImage('abcd', locations=['http://example.com/image'])
-- self.image_repo.result = image
-- self.image_repo.save = fake_save
-- image.delete = mock.Mock()
-- self.assertRaises(webob.exc.HTTPGone, self.controller.upload,
-- request, str(uuid.uuid4()), 'ABC', 3)
-- self.assertTrue(image.delete.called)
-+ def fake_save_conflict(self):
-+ raise exception.Conflict()
-+
-+ for fun in [fake_save_not_found, fake_save_conflict]:
-+ request = unit_test_utils.get_fake_request()
-+ image = FakeImage('abcd', locations=['http://example.com/image'])
-+ self.image_repo.result = image
-+ self.image_repo.save = fun
-+ image.delete = mock.Mock()
-+ self.assertRaises(webob.exc.HTTPGone, self.controller.upload,
-+ request, str(uuid.uuid4()), 'ABC', 3)
-+ self.assertTrue(image.delete.called)
-
- def test_upload_non_existent_image_raises_not_found_exception(self):
- def fake_save(self):
---
-2.0.5
-
diff --git a/app-admin/glance/glance-2014.2.2.ebuild b/app-admin/glance/glance-2014.2.2.ebuild
new file mode 100644
index 000000000000..28140ce6e116
--- /dev/null
+++ b/app-admin/glance/glance-2014.2.2.ebuild
@@ -0,0 +1,162 @@
+# Copyright 1999-2015 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-x86/app-admin/glance/glance-2014.2.2.ebuild,v 1.1 2015/02/08 01:51:56 prometheanfire Exp $
+
+EAPI=5
+PYTHON_COMPAT=( python2_7 )
+
+inherit distutils-r1 user
+
+DESCRIPTION="Provides services for discovering, registering, and retrieving
+virtual machine images with Openstack"
+HOMEPAGE="https://launchpad.net/glance"
+SRC_URI="http://launchpad.net/${PN}/juno/${PV}/+download/${P}.tar.gz"
+
+LICENSE="Apache-2.0"
+SLOT="0"
+KEYWORDS="~amd64 ~x86"
+IUSE="doc mysql postgres +sqlite +swift test"
+REQUIRED_USE="|| ( mysql postgres sqlite )"
+
+DEPEND="dev-python/setuptools[${PYTHON_USEDEP}]
+ >=dev-python/pbr-0.8.0[${PYTHON_USEDEP}]
+ <dev-python/pbr-1.0[${PYTHON_USEDEP}]
+ test? (
+ ${RDEPEND}
+ >=dev-python/hacking-0.8.0[${PYTHON_USEDEP}]
+ <dev-python/hacking-0.9[${PYTHON_USEDEP}]
+ >=dev-python/Babel-1.3[${PYTHON_USEDEP}]
+ >=dev-python/coverage-3.6[${PYTHON_USEDEP}]
+ >=dev-python/fixtures-0.3.14[${PYTHON_USEDEP}]
+ >=dev-python/mock-1.0[${PYTHON_USEDEP}]
+ >=dev-python/mox-0.5.3[${PYTHON_USEDEP}]
+ >=dev-python/sphinx-1.1.2[${PYTHON_USEDEP}]
+ !~dev-python/sphinx-1.2.0[${PYTHON_USEDEP}]
+ <dev-python/sphinx-1.3[${PYTHON_USEDEP}]
+ >=dev-python/requests-1.2.1[${PYTHON_USEDEP}]
+ !~dev-python/requests-2.4.0[${PYTHON_USEDEP}]
+ >=dev-python/testrepository-0.0.18[${PYTHON_USEDEP}]
+ >=dev-python/testtools-0.9.34[${PYTHON_USEDEP}]
+ >=dev-python/psutil-1.1.1[${PYTHON_USEDEP}]
+ <dev-python/psutil-2.0.0[${PYTHON_USEDEP}]
+ dev-python/mysql-python[${PYTHON_USEDEP}]
+ dev-python/psycopg[${PYTHON_USEDEP}]
+ ~dev-python/pysendfile-2.0.0[${PYTHON_USEDEP}]
+ dev-python/qpid-python[${PYTHON_USEDEP}]
+ >=dev-python/pyxattr-0.5.0[${PYTHON_USEDEP}]
+ >=dev-python/oslo-sphinx-2.2.0[${PYTHON_USEDEP}]
+ )"
+
+#note to self, wsgiref is a python builtin, no need to package it
+#>=dev-python/wsgiref-0.1.2[${PYTHON_USEDEP}]
+
+RDEPEND="
+ >=dev-python/greenlet-0.3.2[${PYTHON_USEDEP}]
+ sqlite? (
+ >=dev-python/sqlalchemy-0.9.7[sqlite,${PYTHON_USEDEP}]
+ <=dev-python/sqlalchemy-0.9.99[sqlite,${PYTHON_USEDEP}]
+ )
+ mysql? (
+ dev-python/mysql-python
+ >=dev-python/sqlalchemy-0.9.7[${PYTHON_USEDEP}]
+ <=dev-python/sqlalchemy-0.9.99[${PYTHON_USEDEP}]
+ )
+ postgres? (
+ dev-python/psycopg:2
+ >=dev-python/sqlalchemy-0.9.7[${PYTHON_USEDEP}]
+ <=dev-python/sqlalchemy-0.9.99[${PYTHON_USEDEP}]
+ )
+ >=dev-python/anyjson-0.3.3[${PYTHON_USEDEP}]
+ >=dev-python/eventlet-0.15.1[${PYTHON_USEDEP}]
+ <dev-python/eventlet-0.16.0[${PYTHON_USEDEP}]
+ >=dev-python/pastedeploy-1.5.0[${PYTHON_USEDEP}]
+ >=dev-python/routes-1.12.3[${PYTHON_USEDEP}]
+ !~dev-python/routes-2.0[${PYTHON_USEDEP}]
+ >=dev-python/webob-1.2.3[${PYTHON_USEDEP}]
+ >=dev-python/boto-2.32.1[${PYTHON_USEDEP}]
+ >=dev-python/boto-2.35.0[${PYTHON_USEDEP}]
+ ~dev-python/sqlalchemy-migrate-0.9.1[${PYTHON_USEDEP}]
+ >=dev-python/httplib2-0.7.5[${PYTHON_USEDEP}]
+ >=dev-python/kombu-2.5.0[${PYTHON_USEDEP}]
+ >=dev-python/pycrypto-2.6[${PYTHON_USEDEP}]
+ >=dev-python/iso8601-0.1.9[${PYTHON_USEDEP}]
+ dev-python/ordereddict[${PYTHON_USEDEP}]
+ >=dev-python/oslo-config-1.4.0[${PYTHON_USEDEP}]
+ >=dev-python/stevedore-1.0.0[${PYTHON_USEDEP}]
+ >=dev-python/netaddr-0.7.12[${PYTHON_USEDEP}]
+ >=dev-python/keystonemiddleware-1.0.0[${PYTHON_USEDEP}]
+ >=dev-python/WSME-0.6[${PYTHON_USEDEP}]
+ dev-python/posix_ipc[${PYTHON_USEDEP}]
+ swift? (
+ >=dev-python/python-swiftclient-2.2.0[${PYTHON_USEDEP}]
+ )
+ >=dev-python/oslo-vmware-0.6.0[${PYTHON_USEDEP}]
+ <dev-python/oslo-vmware-0.9.0[${PYTHON_USEDEP}]
+ dev-python/paste[${PYTHON_USEDEP}]
+ >=dev-python/jsonschema-2.0.0[${PYTHON_USEDEP}]
+ <dev-python/jsonschema-3.0.0[${PYTHON_USEDEP}]
+ >=dev-python/python-cinderclient-1.1.0[${PYTHON_USEDEP}]
+ >=dev-python/python-keystoneclient-0.10.0[${PYTHON_USEDEP}]
+ >=dev-python/pyopenssl-0.11[${PYTHON_USEDEP}]
+ >=dev-python/six-1.7.0[${PYTHON_USEDEP}]
+ >=dev-python/oslo-db-1.0.0[${PYTHON_USEDEP}]
+ <dev-python/oslo-db-1.1.0[${PYTHON_USEDEP}]
+ >=dev-python/oslo-i18n-1.0.0[${PYTHON_USEDEP}]
+ >=dev-python/oslo-messaging-1.4.0[${PYTHON_USEDEP}]
+ !~dev-python/oslo-messaging-1.5.0[${PYTHON_USEDEP}]
+ <dev-python/oslo-messaging-1.6.0[${PYTHON_USEDEP}]
+ >=dev-python/retrying-1.2.2[${PYTHON_USEDEP}]
+ !~dev-python/retrying-1.3.0[${PYTHON_USEDEP}]
+ >=dev-python/osprofiler-0.3.0[${PYTHON_USEDEP}]
+ >=dev-python/glance_store-0.1.1[${PYTHON_USEDEP}]"
+
+PATCHES=(
+ "${FILESDIR}/${PN}-2013.2-sphinx_mapping.patch"
+)
+
+pkg_setup() {
+ enewgroup glance
+ enewuser glance -1 -1 /var/lib/glance glance
+}
+
+python_compile_all() {
+ use doc && "${PYTHON}" setup.py build_sphinx
+}
+
+python_test() {
+ # https://bugs.launchpad.net/glance/+bug/1251105
+ # https://bugs.launchpad.net/glance/+bug/1242501
+ nosetests glance/ || die "tests failed under python2.7"
+}
+
+python_install() {
+ distutils-r1_python_install
+
+ for svc in api registry scrubber; do
+ newinitd "${FILESDIR}/glance.initd" glance-${svc}
+ done
+
+ diropts -m 0750 -o glance -g glance
+ dodir /var/log/glance /var/lib/glance/images /var/lib/glance/scrubber
+ keepdir /etc/glance
+ keepdir /var/log/glance
+ keepdir /var/lib/glance/images
+ keepdir /var/lib/glance/scrubber
+
+ insinto /etc/glance
+ insopts -m 0640 -o glance -g glance
+ doins "etc/glance-api-paste.ini"
+ doins "etc/glance-api.conf"
+ doins "etc/glance-cache.conf"
+ doins "etc/glance-registry-paste.ini"
+ doins "etc/glance-registry.conf"
+ doins "etc/glance-scrubber.conf"
+ doins "etc/logging.cnf.sample"
+ doins "etc/policy.json"
+ doins "etc/schema-image.json"
+}
+
+python_install_all() {
+ use doc && local HTML_DOCS=( doc/build/html/. )
+ distutils-r1_python_install_all
+}
diff --git a/app-admin/glance/glance-2014.2.9999.ebuild b/app-admin/glance/glance-2014.2.9999.ebuild
index b25c6fbbec11..7ba4ef5cab3b 100644
--- a/app-admin/glance/glance-2014.2.9999.ebuild
+++ b/app-admin/glance/glance-2014.2.9999.ebuild
@@ -1,6 +1,6 @@
-# Copyright 1999-2014 Gentoo Foundation
+# Copyright 1999-2015 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-# $Header: /var/cvsroot/gentoo-x86/app-admin/glance/glance-2014.2.9999.ebuild,v 1.5 2014/12/09 01:20:13 prometheanfire Exp $
+# $Header: /var/cvsroot/gentoo-x86/app-admin/glance/glance-2014.2.9999.ebuild,v 1.6 2015/02/08 01:51:56 prometheanfire Exp $
EAPI=5
PYTHON_COMPAT=( python2_7 )
@@ -22,28 +22,31 @@ REQUIRED_USE="|| ( mysql postgres sqlite )"
DEPEND="dev-python/setuptools[${PYTHON_USEDEP}]
>=dev-python/pbr-0.8.0[${PYTHON_USEDEP}]
<dev-python/pbr-1.0[${PYTHON_USEDEP}]
- test? ( >=dev-python/hacking-0.8.0[${PYTHON_USEDEP}]
- <dev-python/hacking-0.9[${PYTHON_USEDEP}]
- >=dev-python/Babel-1.3[${PYTHON_USEDEP}]
- >=dev-python/coverage-3.6[${PYTHON_USEDEP}]
- >=dev-python/fixtures-0.3.14[${PYTHON_USEDEP}]
- >=dev-python/mock-1.0[${PYTHON_USEDEP}]
- >=dev-python/mox-0.5.3[${PYTHON_USEDEP}]
- >=dev-python/sphinx-1.1.2[${PYTHON_USEDEP}]
- !~dev-python/sphinx-1.2.0[${PYTHON_USEDEP}]
- <dev-python/sphinx-1.3[${PYTHON_USEDEP}]
- >=dev-python/requests-1.2.1[${PYTHON_USEDEP}]
- !~dev-python/requests-2.4.0[${PYTHON_USEDEP}]
- >=dev-python/testrepository-0.0.18[${PYTHON_USEDEP}]
- >=dev-python/testtools-0.9.34[${PYTHON_USEDEP}]
- >=dev-python/psutil-1.1.1[${PYTHON_USEDEP}]
- <dev-python/psutil-2.0.0[${PYTHON_USEDEP}]
- dev-python/mysql-python[${PYTHON_USEDEP}]
- dev-python/psycopg[${PYTHON_USEDEP}]
- ~dev-python/pysendfile-2.0.0[${PYTHON_USEDEP}]
- dev-python/qpid-python[${PYTHON_USEDEP}]
- >=dev-python/pyxattr-0.5.0[${PYTHON_USEDEP}]
- >=dev-python/oslo-sphinx-2.2.0[${PYTHON_USEDEP}] )"
+ test? (
+ ${RDEPEND}
+ >=dev-python/hacking-0.8.0[${PYTHON_USEDEP}]
+ <dev-python/hacking-0.9[${PYTHON_USEDEP}]
+ >=dev-python/Babel-1.3[${PYTHON_USEDEP}]
+ >=dev-python/coverage-3.6[${PYTHON_USEDEP}]
+ >=dev-python/fixtures-0.3.14[${PYTHON_USEDEP}]
+ >=dev-python/mock-1.0[${PYTHON_USEDEP}]
+ >=dev-python/mox-0.5.3[${PYTHON_USEDEP}]
+ >=dev-python/sphinx-1.1.2[${PYTHON_USEDEP}]
+ !~dev-python/sphinx-1.2.0[${PYTHON_USEDEP}]
+ <dev-python/sphinx-1.3[${PYTHON_USEDEP}]
+ >=dev-python/requests-1.2.1[${PYTHON_USEDEP}]
+ !~dev-python/requests-2.4.0[${PYTHON_USEDEP}]
+ >=dev-python/testrepository-0.0.18[${PYTHON_USEDEP}]
+ >=dev-python/testtools-0.9.34[${PYTHON_USEDEP}]
+ >=dev-python/psutil-1.1.1[${PYTHON_USEDEP}]
+ <dev-python/psutil-2.0.0[${PYTHON_USEDEP}]
+ dev-python/mysql-python[${PYTHON_USEDEP}]
+ dev-python/psycopg[${PYTHON_USEDEP}]
+ ~dev-python/pysendfile-2.0.0[${PYTHON_USEDEP}]
+ dev-python/qpid-python[${PYTHON_USEDEP}]
+ >=dev-python/pyxattr-0.5.0[${PYTHON_USEDEP}]
+ >=dev-python/oslo-sphinx-2.2.0[${PYTHON_USEDEP}]
+ )"
#note to self, wsgiref is a python builtin, no need to package it
#>=dev-python/wsgiref-0.1.2[${PYTHON_USEDEP}]
@@ -51,52 +54,29 @@ DEPEND="dev-python/setuptools[${PYTHON_USEDEP}]
RDEPEND="
>=dev-python/greenlet-0.3.2[${PYTHON_USEDEP}]
sqlite? (
- || (
- (
- >=dev-python/sqlalchemy-0.8.4[sqlite,${PYTHON_USEDEP}]
- <=dev-python/sqlalchemy-0.8.99[sqlite,${PYTHON_USEDEP}]
- )
- (
- >=dev-python/sqlalchemy-0.9.7[sqlite,${PYTHON_USEDEP}]
- <=dev-python/sqlalchemy-0.9.99[sqlite,${PYTHON_USEDEP}]
- )
- )
+ >=dev-python/sqlalchemy-0.9.7[sqlite,${PYTHON_USEDEP}]
+ <=dev-python/sqlalchemy-0.9.99[sqlite,${PYTHON_USEDEP}]
)
mysql? (
dev-python/mysql-python
- || (
- (
- >=dev-python/sqlalchemy-0.8.4[${PYTHON_USEDEP}]
- <=dev-python/sqlalchemy-0.8.99[${PYTHON_USEDEP}]
- )
- (
- >=dev-python/sqlalchemy-0.9.7[${PYTHON_USEDEP}]
- <=dev-python/sqlalchemy-0.9.99[${PYTHON_USEDEP}]
- )
- )
+ >=dev-python/sqlalchemy-0.9.7[${PYTHON_USEDEP}]
+ <=dev-python/sqlalchemy-0.9.99[${PYTHON_USEDEP}]
)
postgres? (
dev-python/psycopg:2
- || (
- (
- >=dev-python/sqlalchemy-0.8.4[${PYTHON_USEDEP}]
- <=dev-python/sqlalchemy-0.8.99[${PYTHON_USEDEP}]
- )
- (
- >=dev-python/sqlalchemy-0.9.7[${PYTHON_USEDEP}]
- <=dev-python/sqlalchemy-0.9.99[${PYTHON_USEDEP}]
- )
- )
+ >=dev-python/sqlalchemy-0.9.7[${PYTHON_USEDEP}]
+ <=dev-python/sqlalchemy-0.9.99[${PYTHON_USEDEP}]
)
>=dev-python/anyjson-0.3.3[${PYTHON_USEDEP}]
>=dev-python/eventlet-0.15.1[${PYTHON_USEDEP}]
+ <dev-python/eventlet-0.16.0[${PYTHON_USEDEP}]
>=dev-python/pastedeploy-1.5.0[${PYTHON_USEDEP}]
>=dev-python/routes-1.12.3[${PYTHON_USEDEP}]
!~dev-python/routes-2.0[${PYTHON_USEDEP}]
>=dev-python/webob-1.2.3[${PYTHON_USEDEP}]
>=dev-python/boto-2.32.1[${PYTHON_USEDEP}]
- >=dev-python/sqlalchemy-migrate-0.9.1[${PYTHON_USEDEP}]
- !~dev-python/sqlalchemy-migrate-0.9.2[${PYTHON_USEDEP}]
+ >=dev-python/boto-2.35.0[${PYTHON_USEDEP}]
+ ~dev-python/sqlalchemy-migrate-0.9.1[${PYTHON_USEDEP}]
>=dev-python/httplib2-0.7.5[${PYTHON_USEDEP}]
>=dev-python/kombu-2.5.0[${PYTHON_USEDEP}]
>=dev-python/pycrypto-2.6[${PYTHON_USEDEP}]
@@ -112,6 +92,7 @@ RDEPEND="
>=dev-python/python-swiftclient-2.2.0[${PYTHON_USEDEP}]
)
>=dev-python/oslo-vmware-0.6.0[${PYTHON_USEDEP}]
+ <dev-python/oslo-vmware-0.9.0[${PYTHON_USEDEP}]
dev-python/paste[${PYTHON_USEDEP}]
>=dev-python/jsonschema-2.0.0[${PYTHON_USEDEP}]
<dev-python/jsonschema-3.0.0[${PYTHON_USEDEP}]
@@ -120,15 +101,19 @@ RDEPEND="
>=dev-python/pyopenssl-0.11[${PYTHON_USEDEP}]
>=dev-python/six-1.7.0[${PYTHON_USEDEP}]
>=dev-python/oslo-db-1.0.0[${PYTHON_USEDEP}]
+ <dev-python/oslo-db-1.1.0[${PYTHON_USEDEP}]
>=dev-python/oslo-i18n-1.0.0[${PYTHON_USEDEP}]
>=dev-python/oslo-messaging-1.4.0[${PYTHON_USEDEP}]
!~dev-python/oslo-messaging-1.5.0[${PYTHON_USEDEP}]
+ <dev-python/oslo-messaging-1.6.0[${PYTHON_USEDEP}]
>=dev-python/retrying-1.2.2[${PYTHON_USEDEP}]
!~dev-python/retrying-1.3.0[${PYTHON_USEDEP}]
>=dev-python/osprofiler-0.3.0[${PYTHON_USEDEP}]
>=dev-python/glance_store-0.1.1[${PYTHON_USEDEP}]"
-PATCHES=( "${FILESDIR}/${PN}-2013.2-sphinx_mapping.patch" )
+PATCHES=(
+ "${FILESDIR}/${PN}-2013.2-sphinx_mapping.patch"
+)
pkg_setup() {
enewgroup glance
diff --git a/app-admin/glance/glance-9999.ebuild b/app-admin/glance/glance-9999.ebuild
deleted file mode 100644
index cdbd8821afe8..000000000000
--- a/app-admin/glance/glance-9999.ebuild
+++ /dev/null
@@ -1,139 +0,0 @@
-# Copyright 1999-2014 Gentoo Foundation
-# Distributed under the terms of the GNU General Public License v2
-# $Header: /var/cvsroot/gentoo-x86/app-admin/glance/glance-9999.ebuild,v 1.12 2014/08/01 05:12:09 prometheanfire Exp $
-
-EAPI=5
-PYTHON_COMPAT=( python2_7 )
-
-inherit git-2 distutils-r1 user
-
-DESCRIPTION="Provides services for discovering, registering, and retrieving
-virtual machine images with Openstack"
-HOMEPAGE="https://launchpad.net/glance"
-EGIT_REPO_URI="https://github.com/openstack/glance.git"
-
-LICENSE="Apache-2.0"
-SLOT="0"
-KEYWORDS=""
-IUSE="doc mysql postgres +sqlite +swift test"
-REQUIRED_USE="|| ( mysql postgres sqlite )"
-
-DEPEND="dev-python/setuptools[${PYTHON_USEDEP}]
- >=dev-python/pbr-0.6.0[${PYTHON_USEDEP}]
- <dev-python/pbr-1.0[${PYTHON_USEDEP}]
- test? ( >=dev-python/hacking-0.8.0[${PYTHON_USEDEP}]
- <dev-python/hacking-0.9[${PYTHON_USEDEP}]
- >=dev-python/Babel-1.3[${PYTHON_USEDEP}]
- >=dev-python/coverage-3.6[${PYTHON_USEDEP}]
- >=dev-python/fixtures-0.3.14[${PYTHON_USEDEP}]
- >=dev-python/mock-1.0[${PYTHON_USEDEP}]
- >=dev-python/mox-0.5.3[${PYTHON_USEDEP}]
- >=dev-python/sphinx-1.1.2[${PYTHON_USEDEP}]
- <dev-python/sphinx-1.2[${PYTHON_USEDEP}]
- >=dev-python/requests-1.1[${PYTHON_USEDEP}]
- >=dev-python/testrepository-0.0.18[${PYTHON_USEDEP}]
- >=dev-python/testtools-0.9.34[${PYTHON_USEDEP}]
- >=dev-python/psutil-1.1.1[${PYTHON_USEDEP}]
- dev-python/mysql-python[${PYTHON_USEDEP}]
- dev-python/psycopg[${PYTHON_USEDEP}]
- ~dev-python/pysendfile-2.0.0[${PYTHON_USEDEP}]
- dev-python/qpid-python[${PYTHON_USEDEP}]
- >=dev-python/pyxattr-0.5.0[${PYTHON_USEDEP}]
- dev-python/oslo-sphinx[${PYTHON_USEDEP}] )"
-
-#note to self, wsgiref is a python builtin, no need to package it
-#>=dev-python/wsgiref-0.1.2[${PYTHON_USEDEP}]
-
-RDEPEND=">=dev-python/greenlet-0.3.2[${PYTHON_USEDEP}]
- sqlite? (
- >=dev-python/sqlalchemy-0.8.0[sqlite,${PYTHON_USEDEP}]
- !~dev-python/sqlalchemy-0.9.5[sqlite,${PYTHON_USEDEP}]
- <=dev-python/sqlalchemy-0.9.99[sqlite,${PYTHON_USEDEP}]
- )
- mysql? (
- dev-python/mysql-python
- >=dev-python/sqlalchemy-0.8.0[${PYTHON_USEDEP}]
- !~dev-python/sqlalchemy-0.9.5[${PYTHON_USEDEP}]
- <=dev-python/sqlalchemy-0.9.99[${PYTHON_USEDEP}]
- )
- postgres? (
- dev-python/psycopg:2
- >=dev-python/sqlalchemy-0.8.0[${PYTHON_USEDEP}]
- !~dev-python/sqlalchemy-0.9.5[${PYTHON_USEDEP}]
- <=dev-python/sqlalchemy-0.9.99[${PYTHON_USEDEP}]
- )
- >=dev-python/anyjson-0.3.3[${PYTHON_USEDEP}]
- >=dev-python/eventlet-0.13.0[${PYTHON_USEDEP}]
- >=dev-python/pastedeploy-1.5.0[${PYTHON_USEDEP}]
- >=dev-python/routes-1.12.3[${PYTHON_USEDEP}]
- >=dev-python/webob-1.2.3[${PYTHON_USEDEP}]
- >=dev-python/boto-2.12.0[${PYTHON_USEDEP}]
- !~dev-python/boto-2.13.0[${PYTHON_USEDEP}]
- >=dev-python/sqlalchemy-migrate-0.9[${PYTHON_USEDEP}]
- >=dev-python/httplib2-0.7.5[${PYTHON_USEDEP}]
- >=dev-python/kombu-2.4.8[${PYTHON_USEDEP}]
- >=dev-python/pycrypto-2.6[${PYTHON_USEDEP}]
- >=dev-python/iso8601-0.1.9[${PYTHON_USEDEP}]
- >=dev-python/oslo-config-1.2.1[${PYTHON_USEDEP}]
- >=dev-python/stevedore-0.14[${PYTHON_USEDEP}]
- swift? (
- >=dev-python/python-swiftclient-1.6[${PYTHON_USEDEP}]
- )
- dev-python/paste[${PYTHON_USEDEP}]
- >=dev-python/jsonschema-2.0.0[${PYTHON_USEDEP}]
- <dev-python/jsonschema-3.0.0[${PYTHON_USEDEP}]
- >=dev-python/python-cinderclient-1.0.6[${PYTHON_USEDEP}]
- >=dev-python/python-keystoneclient-0.7.0[${PYTHON_USEDEP}]
- >=dev-python/pyopenssl-0.11[${PYTHON_USEDEP}]
- >=dev-python/six-1.6.0[${PYTHON_USEDEP}]
- >=dev-python/oslo-messaging-1.3.0[${PYTHON_USEDEP}]
- >=dev-python/oslo-vmware-0.2[${PYTHON_USEDEP}]"
-
-PATCHES=( "${FILESDIR}"/${PN}-2013.2-sphinx_mapping.patch )
-
-pkg_setup() {
- enewgroup glance
- enewuser glance -1 -1 /var/lib/glance glance
-}
-
-python_compile_all() {
- use doc && "${PYTHON}" setup.py build_sphinx
-}
-
-python_test() {
- # https://bugs.launchpad.net/glance/+bug/1251105
- # https://bugs.launchpad.net/glance/+bug/1242501
- nosetests glance/ || die "tests failed under python2.7"
-}
-
-python_install() {
- distutils-r1_python_install
-
- for svc in api registry scrubber; do
- newinitd "${FILESDIR}/glance.initd" glance-${svc}
- done
-
- diropts -m 0750 -o glance -g glance
- dodir /var/log/glance /var/lib/glance/images /var/lib/glance/scrubber
- keepdir /etc/glance
- keepdir /var/log/glance
- keepdir /var/lib/glance/images
- keepdir /var/lib/glance/scrubber
-
- insinto /etc/glance
- insopts -m 0640 -o glance -g glance
- doins "etc/glance-api-paste.ini"
- doins "etc/glance-api.conf"
- doins "etc/glance-cache.conf"
- doins "etc/glance-registry-paste.ini"
- doins "etc/glance-registry.conf"
- doins "etc/glance-scrubber.conf"
- doins "etc/logging.cnf.sample"
- doins "etc/policy.json"
- doins "etc/schema-image.json"
-}
-
-python_install_all() {
- use doc && local HTML_DOCS=( doc/build/html/. )
- distutils-r1_python_install_all
-}