diff options
author | Matthew Thode <prometheanfire@gentoo.org> | 2013-12-19 03:18:20 +0000 |
---|---|---|
committer | Matthew Thode <prometheanfire@gentoo.org> | 2013-12-19 03:18:20 +0000 |
commit | d035941f830b65b294370ca5c7341517e48231b2 (patch) | |
tree | a4eb435f668d5a02e4cc029263feacd886a15bb2 /sys-cluster | |
parent | Remove old. (diff) | |
download | gentoo-2-d035941f830b65b294370ca5c7341517e48231b2.tar.gz gentoo-2-d035941f830b65b294370ca5c7341517e48231b2.tar.bz2 gentoo-2-d035941f830b65b294370ca5c7341517e48231b2.zip |
update for CVE-2013-2096
(Portage version: 2.2.7/cvs/Linux x86_64, signed Manifest commit with key 0x2471eb3e40ac5ac3)
Diffstat (limited to 'sys-cluster')
-rw-r--r-- | sys-cluster/nova/ChangeLog | 9 | ||||
-rw-r--r-- | sys-cluster/nova/files/CVE-2013-4463_4469-havana.patch | 452 | ||||
-rw-r--r-- | sys-cluster/nova/files/CVE-2013-6419_2013.2.patch | 186 | ||||
-rw-r--r-- | sys-cluster/nova/nova-2013.2.1.ebuild | 126 | ||||
-rw-r--r-- | sys-cluster/nova/nova-2013.2.9999.ebuild | 6 |
5 files changed, 137 insertions, 642 deletions
diff --git a/sys-cluster/nova/ChangeLog b/sys-cluster/nova/ChangeLog index af13d2e11ea1..f889d7a7ab01 100644 --- a/sys-cluster/nova/ChangeLog +++ b/sys-cluster/nova/ChangeLog @@ -1,6 +1,13 @@ # ChangeLog for sys-cluster/nova # Copyright 1999-2013 Gentoo Foundation; Distributed under the GPL v2 -# $Header: /var/cvsroot/gentoo-x86/sys-cluster/nova/ChangeLog,v 1.44 2013/12/13 21:10:35 prometheanfire Exp $ +# $Header: /var/cvsroot/gentoo-x86/sys-cluster/nova/ChangeLog,v 1.45 2013/12/19 03:18:19 prometheanfire Exp $ + +*nova-2013.2.1 (19 Dec 2013) + + 19 Dec 2013; Matthew Thode <prometheanfire@gentoo.org> +nova-2013.2.1.ebuild, + -files/CVE-2013-4463_4469-havana.patch, -files/CVE-2013-6419_2013.2.patch, + nova-2013.2.9999.ebuild: + update for CVE-2013-2096 *nova-2013.2-r3 (13 Dec 2013) *nova-2013.1.4-r2 (13 Dec 2013) diff --git a/sys-cluster/nova/files/CVE-2013-4463_4469-havana.patch b/sys-cluster/nova/files/CVE-2013-4463_4469-havana.patch deleted file mode 100644 index 575b11d9bbdf..000000000000 --- a/sys-cluster/nova/files/CVE-2013-4463_4469-havana.patch +++ /dev/null @@ -1,452 +0,0 @@ -From 3cdfe894ab58f7b91bf7fb690fc5bc724e44066f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= <pbrady@redhat.com> -Date: Fri, 27 Sep 2013 04:07:14 +0100 -Subject: [PATCH] ensure we don't boot oversized images - -Since we can't generally shrink incoming images, add extra checks -to ensure oversized images are not allowed through. -All cases when populating the libvirt image cache are now handled, -including the initial download from glance, where we avoid -converting to raw, as that could generate non sparse images -much larger than the downloaded image. - -* nova/virt/libvirt/utils.py (fetch_image): Allow passing through -of the max_size parameter. -* nova/virt/images.py (fetch_to_raw): Accept the max_size parameter, -and use it to discard images with larger (virtual) sizes. -* nova/virt/libvirt/imagebackend.py (verify_base_size): A new -refactored function to identify and raise exception to oversized images. -(Raw.create_image): Pass the max_size to the fetch function. -Also enforce virtual image size checking for already fetched images, -as this class (despite the name) can be handling qcow files. -(Qcow2.create_image): Pass the max_size to the fetch function, -or verify the virtual size for the instance as done previously. -(Lvm.create_image): Pass the max_size to the fetch function. -Also check the size before transferring to the volume to improve -efficiency by not even attempting the transfer of oversized images. -(Rbd.create_image): Likewise. -* nova/tests/virt/libvirt/fake_libvirt_utils.py: Support max_size arg. -* nova/tests/virt/libvirt/test_libvirt.py (test_fetch_raw_image): -Add a case to check oversized images are discarded. -* nova/tests/virt/libvirt/test_imagebackend.py -(test_create_image_too_small): Adjust to avoid the fetch size check. - -Fixes bug: 1177830 -Fixes bug: 1206081 -Change-Id: I3d47adaa2ad07434853f447feb27d7aae0e2e717 ---- - nova/tests/virt/libvirt/fake_libvirt_utils.py | 2 +- - nova/tests/virt/libvirt/test_imagebackend.py | 34 ++++++----------- - nova/tests/virt/libvirt/test_libvirt.py | 24 ++++++++++-- - nova/virt/images.py | 24 ++++++++++-- - nova/virt/libvirt/imagebackend.py | 55 +++++++++++++++++++-------- - nova/virt/libvirt/utils.py | 5 ++- - 6 files changed, 98 insertions(+), 46 deletions(-) - -diff --git a/nova/tests/virt/libvirt/fake_libvirt_utils.py b/nova/tests/virt/libvirt/fake_libvirt_utils.py -index e18f9df..4799837 100644 ---- a/nova/tests/virt/libvirt/fake_libvirt_utils.py -+++ b/nova/tests/virt/libvirt/fake_libvirt_utils.py -@@ -197,7 +197,7 @@ def get_fs_info(path): - 'free': 84 * (1024 ** 3)} - - --def fetch_image(context, target, image_id, user_id, project_id): -+def fetch_image(context, target, image_id, user_id, project_id, max_size=0): - pass - - -diff --git a/nova/tests/virt/libvirt/test_imagebackend.py b/nova/tests/virt/libvirt/test_imagebackend.py -index b862510..2455ec8 100644 ---- a/nova/tests/virt/libvirt/test_imagebackend.py -+++ b/nova/tests/virt/libvirt/test_imagebackend.py -@@ -190,7 +190,7 @@ def prepare_mocks(self): - - def test_create_image(self): - fn = self.prepare_mocks() -- fn(target=self.TEMPLATE_PATH, image_id=None) -+ fn(target=self.TEMPLATE_PATH, max_size=None, image_id=None) - imagebackend.libvirt_utils.copy_image(self.TEMPLATE_PATH, self.PATH) - self.mox.ReplayAll() - -@@ -211,7 +211,7 @@ def test_create_image_generated(self): - - def test_create_image_extend(self): - fn = self.prepare_mocks() -- fn(target=self.TEMPLATE_PATH, image_id=None) -+ fn(max_size=self.SIZE, target=self.TEMPLATE_PATH, image_id=None) - imagebackend.libvirt_utils.copy_image(self.TEMPLATE_PATH, self.PATH) - imagebackend.disk.extend(self.PATH, self.SIZE, use_cow=False) - self.mox.ReplayAll() -@@ -261,7 +261,7 @@ def prepare_mocks(self): - - def test_create_image(self): - fn = self.prepare_mocks() -- fn(target=self.TEMPLATE_PATH) -+ fn(max_size=None, target=self.TEMPLATE_PATH) - imagebackend.libvirt_utils.create_cow_image(self.TEMPLATE_PATH, - self.PATH) - self.mox.ReplayAll() -@@ -273,15 +273,12 @@ def test_create_image(self): - - def test_create_image_with_size(self): - fn = self.prepare_mocks() -- fn(target=self.TEMPLATE_PATH) -+ fn(max_size=self.SIZE, target=self.TEMPLATE_PATH) - self.mox.StubOutWithMock(os.path, 'exists') -- self.mox.StubOutWithMock(imagebackend.disk, 'get_disk_size') - if self.OLD_STYLE_INSTANCE_PATH: - os.path.exists(self.OLD_STYLE_INSTANCE_PATH).AndReturn(False) - os.path.exists(self.TEMPLATE_PATH).AndReturn(False) - os.path.exists(self.PATH).AndReturn(False) -- imagebackend.disk.get_disk_size(self.TEMPLATE_PATH -- ).AndReturn(self.SIZE) - os.path.exists(self.PATH).AndReturn(False) - imagebackend.libvirt_utils.create_cow_image(self.TEMPLATE_PATH, - self.PATH) -@@ -295,13 +292,11 @@ def test_create_image_with_size(self): - - def test_create_image_too_small(self): - fn = self.prepare_mocks() -- fn(target=self.TEMPLATE_PATH) - self.mox.StubOutWithMock(os.path, 'exists') - self.mox.StubOutWithMock(imagebackend.disk, 'get_disk_size') - if self.OLD_STYLE_INSTANCE_PATH: - os.path.exists(self.OLD_STYLE_INSTANCE_PATH).AndReturn(False) -- os.path.exists(self.TEMPLATE_PATH).AndReturn(False) -- os.path.exists(self.PATH).AndReturn(False) -+ os.path.exists(self.TEMPLATE_PATH).AndReturn(True) - imagebackend.disk.get_disk_size(self.TEMPLATE_PATH - ).AndReturn(self.SIZE) - self.mox.ReplayAll() -@@ -313,9 +308,8 @@ def test_create_image_too_small(self): - - def test_generate_resized_backing_files(self): - fn = self.prepare_mocks() -- fn(target=self.TEMPLATE_PATH) -+ fn(max_size=self.SIZE, target=self.TEMPLATE_PATH) - self.mox.StubOutWithMock(os.path, 'exists') -- self.mox.StubOutWithMock(imagebackend.disk, 'get_disk_size') - self.mox.StubOutWithMock(imagebackend.libvirt_utils, - 'get_disk_backing_file') - if self.OLD_STYLE_INSTANCE_PATH: -@@ -330,8 +324,6 @@ def test_generate_resized_backing_files(self): - self.QCOW2_BASE) - imagebackend.disk.extend(self.QCOW2_BASE, self.SIZE, use_cow=True) - -- imagebackend.disk.get_disk_size(self.TEMPLATE_PATH -- ).AndReturn(self.SIZE) - os.path.exists(self.PATH).AndReturn(True) - self.mox.ReplayAll() - -@@ -342,9 +334,8 @@ def test_generate_resized_backing_files(self): - - def test_qcow2_exists_and_has_no_backing_file(self): - fn = self.prepare_mocks() -- fn(target=self.TEMPLATE_PATH) -+ fn(max_size=self.SIZE, target=self.TEMPLATE_PATH) - self.mox.StubOutWithMock(os.path, 'exists') -- self.mox.StubOutWithMock(imagebackend.disk, 'get_disk_size') - self.mox.StubOutWithMock(imagebackend.libvirt_utils, - 'get_disk_backing_file') - if self.OLD_STYLE_INSTANCE_PATH: -@@ -354,8 +345,6 @@ def test_qcow2_exists_and_has_no_backing_file(self): - - imagebackend.libvirt_utils.get_disk_backing_file(self.PATH)\ - .AndReturn(None) -- imagebackend.disk.get_disk_size(self.TEMPLATE_PATH -- ).AndReturn(self.SIZE) - os.path.exists(self.PATH).AndReturn(True) - self.mox.ReplayAll() - -@@ -392,7 +381,7 @@ def prepare_mocks(self): - - def _create_image(self, sparse): - fn = self.prepare_mocks() -- fn(target=self.TEMPLATE_PATH) -+ fn(max_size=None, target=self.TEMPLATE_PATH) - self.libvirt_utils.create_lvm_image(self.VG, - self.LV, - self.TEMPLATE_SIZE, -@@ -424,7 +413,7 @@ def _create_image_generated(self, sparse): - - def _create_image_resize(self, sparse): - fn = self.prepare_mocks() -- fn(target=self.TEMPLATE_PATH) -+ fn(max_size=self.SIZE, target=self.TEMPLATE_PATH) - self.libvirt_utils.create_lvm_image(self.VG, self.LV, - self.SIZE, sparse=sparse) - self.disk.get_disk_size(self.TEMPLATE_PATH -@@ -463,7 +452,7 @@ def test_create_image_resize_sparsed(self): - - def test_create_image_negative(self): - fn = self.prepare_mocks() -- fn(target=self.TEMPLATE_PATH) -+ fn(max_size=self.SIZE, target=self.TEMPLATE_PATH) - self.libvirt_utils.create_lvm_image(self.VG, - self.LV, - self.SIZE, -@@ -607,7 +596,7 @@ def test_cache_template_exists(self): - - def test_create_image(self): - fn = self.prepare_mocks() -- fn(rbd=self.rbd, target=self.TEMPLATE_PATH) -+ fn(max_size=None, rbd=self.rbd, target=self.TEMPLATE_PATH) - - self.rbd.RBD_FEATURE_LAYERING = 1 - -@@ -635,6 +624,7 @@ def fake_fetch(target, *args, **kwargs): - return - - self.stubs.Set(os.path, 'exists', lambda _: True) -+ self.stubs.Set(image, 'check_image_exists', lambda: True) - - image.cache(fake_fetch, self.TEMPLATE_PATH, self.SIZE) - -diff --git a/nova/tests/virt/libvirt/test_libvirt.py b/nova/tests/virt/libvirt/test_libvirt.py -index ac36be4..5d1361e 100644 ---- a/nova/tests/virt/libvirt/test_libvirt.py -+++ b/nova/tests/virt/libvirt/test_libvirt.py -@@ -6308,7 +6308,8 @@ def test_fetch_image(self): - image_id = '4' - user_id = 'fake' - project_id = 'fake' -- images.fetch_to_raw(context, image_id, target, user_id, project_id) -+ images.fetch_to_raw(context, image_id, target, user_id, project_id, -+ max_size=0) - - self.mox.ReplayAll() - libvirt_utils.fetch_image(context, target, image_id, -@@ -6338,20 +6339,27 @@ class FakeImgInfo(object): - file_format = path.split('.')[-2] - elif file_format == 'converted': - file_format = 'raw' -+ - if 'backing' in path: - backing_file = 'backing' - else: - backing_file = None - -+ if 'big' in path: -+ virtual_size = 2 -+ else: -+ virtual_size = 1 -+ - FakeImgInfo.file_format = file_format - FakeImgInfo.backing_file = backing_file -+ FakeImgInfo.virtual_size = virtual_size - - return FakeImgInfo() - - self.stubs.Set(utils, 'execute', fake_execute) - self.stubs.Set(os, 'rename', fake_rename) - self.stubs.Set(os, 'unlink', fake_unlink) -- self.stubs.Set(images, 'fetch', lambda *_: None) -+ self.stubs.Set(images, 'fetch', lambda *_, **__: None) - self.stubs.Set(images, 'qemu_img_info', fake_qemu_img_info) - self.stubs.Set(fileutils, 'delete_if_exists', fake_rm_on_error) - -@@ -6373,7 +6381,8 @@ class FakeImgInfo(object): - 't.qcow2.part', 't.qcow2.converted'), - ('rm', 't.qcow2.part'), - ('mv', 't.qcow2.converted', 't.qcow2')] -- images.fetch_to_raw(context, image_id, target, user_id, project_id) -+ images.fetch_to_raw(context, image_id, target, user_id, project_id, -+ max_size=1) - self.assertEqual(self.executes, expected_commands) - - target = 't.raw' -@@ -6390,6 +6399,15 @@ class FakeImgInfo(object): - context, image_id, target, user_id, project_id) - self.assertEqual(self.executes, expected_commands) - -+ target = 'big.qcow2' -+ self.executes = [] -+ expected_commands = [('rm', '-f', 'big.qcow2.part')] -+ self.assertRaises(exception.InstanceTypeDiskTooSmall, -+ images.fetch_to_raw, -+ context, image_id, target, user_id, project_id, -+ max_size=1) -+ self.assertEqual(self.executes, expected_commands) -+ - del self.executes - - def test_get_disk_backing_file(self): -diff --git a/nova/virt/images.py b/nova/virt/images.py -index 9c4c101..6d20e65 100644 ---- a/nova/virt/images.py -+++ b/nova/virt/images.py -@@ -179,7 +179,7 @@ def convert_image(source, dest, out_format, run_as_root=False): - utils.execute(*cmd, run_as_root=run_as_root) - - --def fetch(context, image_href, path, _user_id, _project_id): -+def fetch(context, image_href, path, _user_id, _project_id, max_size=0): - # TODO(vish): Improve context handling and add owner and auth data - # when it is added to glance. Right now there is no - # auth checking in glance, so we assume that access was -@@ -190,9 +190,10 @@ def fetch(context, image_href, path, _user_id, _project_id): - image_service.download(context, image_id, dst_path=path) - - --def fetch_to_raw(context, image_href, path, user_id, project_id): -+def fetch_to_raw(context, image_href, path, user_id, project_id, max_size=0): - path_tmp = "%s.part" % path -- fetch(context, image_href, path_tmp, user_id, project_id) -+ fetch(context, image_href, path_tmp, user_id, project_id, -+ max_size=max_size) - - with fileutils.remove_path_on_error(path_tmp): - data = qemu_img_info(path_tmp) -@@ -209,6 +210,23 @@ def fetch_to_raw(context, image_href, path, user_id, project_id): - reason=(_("fmt=%(fmt)s backed by: %(backing_file)s") % - {'fmt': fmt, 'backing_file': backing_file})) - -+ # We can't generally shrink incoming images, so disallow -+ # images > size of the flavor we're booting. Checking here avoids -+ # an immediate DoS where we convert large qcow images to raw -+ # (which may compress well but not be sparse). -+ # TODO(p-draigbrady): loop through all flavor sizes, so that -+ # we might continue here and not discard the download. -+ # If we did that we'd have to do the higher level size checks -+ # irrespective of whether the base image was prepared or not. -+ disk_size = data.virtual_size -+ if max_size and max_size < disk_size: -+ msg = _('%(base)s virtual size %(disk_size)s ' -+ 'larger than flavor root disk size %(size)s') -+ LOG.error(msg % {'base': path, -+ 'disk_size': disk_size, -+ 'size': max_size}) -+ raise exception.InstanceTypeDiskTooSmall() -+ - if fmt != "raw" and CONF.force_raw_images: - staged = "%s.converted" % path - LOG.debug("%s was %s, converting to raw" % (image_href, fmt)) -diff --git a/nova/virt/libvirt/imagebackend.py b/nova/virt/libvirt/imagebackend.py -index 84c46e8..e900789 100644 ---- a/nova/virt/libvirt/imagebackend.py -+++ b/nova/virt/libvirt/imagebackend.py -@@ -193,6 +193,36 @@ def _can_fallocate(self): - (CONF.preallocate_images, self.path)) - return can_fallocate - -+ @staticmethod -+ def verify_base_size(base, size, base_size=0): -+ """Check that the base image is not larger than size. -+ Since images can't be generally shrunk, enforce this -+ constraint taking account of virtual image size. -+ """ -+ -+ # Note(pbrady): The size and min_disk parameters of a glance -+ # image are checked against the instance size before the image -+ # is even downloaded from glance, but currently min_disk is -+ # adjustable and doesn't currently account for virtual disk size, -+ # so we need this extra check here. -+ # NOTE(cfb): Having a flavor that sets the root size to 0 and having -+ # nova effectively ignore that size and use the size of the -+ # image is considered a feature at this time, not a bug. -+ -+ if size is None: -+ return -+ -+ if size and not base_size: -+ base_size = disk.get_disk_size(base) -+ -+ if size < base_size: -+ msg = _('%(base)s virtual size %(base_size)s ' -+ 'larger than flavor root disk size %(size)s') -+ LOG.error(msg % {'base': base, -+ 'base_size': base_size, -+ 'size': size}) -+ raise exception.InstanceTypeDiskTooSmall() -+ - def snapshot_create(self): - raise NotImplementedError() - -@@ -234,7 +264,8 @@ def copy_raw_image(base, target, size): - #Generating image in place - prepare_template(target=self.path, *args, **kwargs) - else: -- prepare_template(target=base, *args, **kwargs) -+ prepare_template(target=base, max_size=size, *args, **kwargs) -+ self.verify_base_size(base, size) - if not os.path.exists(self.path): - with fileutils.remove_path_on_error(self.path): - copy_raw_image(base, self.path, size) -@@ -273,7 +304,9 @@ def copy_qcow2_image(base, target, size): - - # Download the unmodified base image unless we already have a copy. - if not os.path.exists(base): -- prepare_template(target=base, *args, **kwargs) -+ prepare_template(target=base, max_size=size, *args, **kwargs) -+ else: -+ self.verify_base_size(base, size) - - legacy_backing_size = None - legacy_base = base -@@ -299,17 +332,6 @@ def copy_qcow2_image(base, target, size): - libvirt_utils.copy_image(base, legacy_base) - disk.extend(legacy_base, legacy_backing_size, use_cow=True) - -- # NOTE(cfb): Having a flavor that sets the root size to 0 and having -- # nova effectively ignore that size and use the size of the -- # image is considered a feature at this time, not a bug. -- disk_size = disk.get_disk_size(base) -- if size and size < disk_size: -- msg = _('%(base)s virtual size %(disk_size)s' -- 'larger than flavor root disk size %(size)s') -- LOG.error(msg % {'base': base, -- 'disk_size': disk_size, -- 'size': size}) -- raise exception.InstanceTypeDiskTooSmall() - if not os.path.exists(self.path): - with fileutils.remove_path_on_error(self.path): - copy_qcow2_image(base, self.path, size) -@@ -367,6 +389,7 @@ def create_image(self, prepare_template, base, size, *args, **kwargs): - @utils.synchronized(base, external=True, lock_path=self.lock_path) - def create_lvm_image(base, size): - base_size = disk.get_disk_size(base) -+ self.verify_base_size(base, size, base_size=base_size) - resize = size > base_size - size = size if resize else base_size - libvirt_utils.create_lvm_image(self.vg, self.lv, -@@ -384,7 +407,7 @@ def create_lvm_image(base, size): - with self.remove_volume_on_error(self.path): - prepare_template(target=self.path, *args, **kwargs) - else: -- prepare_template(target=base, *args, **kwargs) -+ prepare_template(target=base, max_size=size, *args, **kwargs) - with self.remove_volume_on_error(self.path): - create_lvm_image(base, size) - -@@ -514,7 +537,9 @@ def create_image(self, prepare_template, base, size, *args, **kwargs): - features = self.rbd.RBD_FEATURE_LAYERING - - if not os.path.exists(base): -- prepare_template(target=base, *args, **kwargs) -+ prepare_template(target=base, max_size=size, *args, **kwargs) -+ else: -+ self.verify_base_size(base, size) - - # keep using the command line import instead of librbd since it - # detects zeroes to preserve sparseness in the image -diff --git a/nova/virt/libvirt/utils.py b/nova/virt/libvirt/utils.py -index 66ff83e..d7c92b7 100644 ---- a/nova/virt/libvirt/utils.py -+++ b/nova/virt/libvirt/utils.py -@@ -639,9 +639,10 @@ def get_fs_info(path): - 'used': used} - - --def fetch_image(context, target, image_id, user_id, project_id): -+def fetch_image(context, target, image_id, user_id, project_id, max_size=0): - """Grab image.""" -- images.fetch_to_raw(context, image_id, target, user_id, project_id) -+ images.fetch_to_raw(context, image_id, target, user_id, project_id, -+ max_size=max_size) - - - def get_instance_path(instance, forceold=False, relative=False): --- -1.8.4 - diff --git a/sys-cluster/nova/files/CVE-2013-6419_2013.2.patch b/sys-cluster/nova/files/CVE-2013-6419_2013.2.patch deleted file mode 100644 index 1dcfe1b9b68f..000000000000 --- a/sys-cluster/nova/files/CVE-2013-6419_2013.2.patch +++ /dev/null @@ -1,186 +0,0 @@ -commit 2a95eee992b66cd65e401e31785c080f811476cf -Author: Aaron Rosen <arosen@nicira.com> -Date: Mon Oct 7 13:33:31 2013 -0700 - - Prevent spoofing instance_id from neturon to nova - - Previously, one could update a port's device_id in neutron to be that - of another tenant's instance_id and then be able to retrieve that instance's - metadata. This patch prevents this from occuring by checking that X-Tenant-ID - received from the metadata request matches the tenant_id in the nova database. - - DocImpact - This patch is dependent on another patch in neutron which adds - X-Tenant-ID to the request. Therefore to minimize downtime one - should upgrade Neutron first (then restart neutron-metadata-agent) - and lastly update nova. - - Fixes bug: 1235450 - -diff --git a/nova/api/metadata/handler.py b/nova/api/metadata/handler.py -index 27f4d4e..7ac9023 100644 ---- a/nova/api/metadata/handler.py -+++ b/nova/api/metadata/handler.py -@@ -140,29 +140,34 @@ class MetadataRequestHandler(wsgi.Application): - 'Please try your request again.') - raise webob.exc.HTTPInternalServerError(explanation=unicode(msg)) - - if meta_data is None: - LOG.error(_('Failed to get metadata for ip: %s'), remote_address) - - return meta_data - - def _handle_instance_id_request(self, req): - instance_id = req.headers.get('X-Instance-ID') -+ tenant_id = req.headers.get('X-Tenant-ID') - signature = req.headers.get('X-Instance-ID-Signature') - remote_address = req.headers.get('X-Forwarded-For') - - # Ensure that only one header was passed - - if instance_id is None: - msg = _('X-Instance-ID header is missing from request.') -+ elif tenant_id is None: -+ msg = _('X-Tenant-ID header is missing from request.') - elif not isinstance(instance_id, basestring): - msg = _('Multiple X-Instance-ID headers found within request.') -+ elif not isinstance(tenant_id, basestring): -+ msg = _('Multiple X-Tenant-ID headers found within request.') - else: - msg = None - - if msg: - raise webob.exc.HTTPBadRequest(explanation=msg) - - expected_signature = hmac.new( - CONF.neutron_metadata_proxy_shared_secret, - instance_id, - hashlib.sha256).hexdigest() -@@ -188,11 +193,19 @@ class MetadataRequestHandler(wsgi.Application): - LOG.exception(_('Failed to get metadata for instance id: %s'), - instance_id) - msg = _('An unknown error has occurred. ' - 'Please try your request again.') - raise webob.exc.HTTPInternalServerError(explanation=unicode(msg)) - - if meta_data is None: - LOG.error(_('Failed to get metadata for instance id: %s'), - instance_id) - -+ if meta_data.instance['project_id'] != tenant_id: -+ LOG.warning(_("Tenant_id %(tenant_id)s does not match tenant_id " -+ "of instance %(instance_id)s."), -+ {'tenant_id': tenant_id, -+ 'instance_id': instance_id}) -+ # causes a 404 to be raised -+ meta_data = None -+ - return meta_data -diff --git a/nova/tests/test_metadata.py b/nova/tests/test_metadata.py -index 50f0d07..e75b51f 100644 ---- a/nova/tests/test_metadata.py -+++ b/nova/tests/test_metadata.py -@@ -594,74 +594,104 @@ class MetadataHandlerTestCase(test.TestCase): - CONF.neutron_metadata_proxy_shared_secret, - expected_instance_id, - hashlib.sha256).hexdigest() - - # try a request with service disabled - response = fake_request( - self.stubs, self.mdinst, - relpath="/2009-04-04/user-data", - address="192.192.192.2", - headers={'X-Instance-ID': 'a-b-c-d', -+ 'X-Tenant-ID': 'test', - 'X-Instance-ID-Signature': signed}) - self.assertEqual(response.status_int, 200) - - # now enable the service - self.flags(service_neutron_metadata_proxy=True) - response = fake_request( - self.stubs, self.mdinst, - relpath="/2009-04-04/user-data", - address="192.192.192.2", - fake_get_metadata_by_instance_id=fake_get_metadata, - headers={'X-Forwarded-For': '192.192.192.2', - 'X-Instance-ID': 'a-b-c-d', -+ 'X-Tenant-ID': 'test', - 'X-Instance-ID-Signature': signed}) - - self.assertEqual(response.status_int, 200) - self.assertEqual(response.body, - base64.b64decode(self.instance['user_data'])) - - # mismatched signature - response = fake_request( - self.stubs, self.mdinst, - relpath="/2009-04-04/user-data", - address="192.192.192.2", - fake_get_metadata_by_instance_id=fake_get_metadata, - headers={'X-Forwarded-For': '192.192.192.2', - 'X-Instance-ID': 'a-b-c-d', -+ 'X-Tenant-ID': 'test', - 'X-Instance-ID-Signature': ''}) - - self.assertEqual(response.status_int, 403) - -+ # missing X-Tenant-ID from request -+ response = fake_request( -+ self.stubs, self.mdinst, -+ relpath="/2009-04-04/user-data", -+ address="192.192.192.2", -+ fake_get_metadata_by_instance_id=fake_get_metadata, -+ headers={'X-Forwarded-For': '192.192.192.2', -+ 'X-Instance-ID': 'a-b-c-d', -+ 'X-Instance-ID-Signature': signed}) -+ -+ self.assertEqual(response.status_int, 400) -+ -+ # mismatched X-Tenant-ID -+ response = fake_request( -+ self.stubs, self.mdinst, -+ relpath="/2009-04-04/user-data", -+ address="192.192.192.2", -+ fake_get_metadata_by_instance_id=fake_get_metadata, -+ headers={'X-Forwarded-For': '192.192.192.2', -+ 'X-Instance-ID': 'a-b-c-d', -+ 'X-Tenant-ID': 'FAKE', -+ 'X-Instance-ID-Signature': signed}) -+ -+ self.assertEqual(response.status_int, 404) -+ - # without X-Forwarded-For - response = fake_request( - self.stubs, self.mdinst, - relpath="/2009-04-04/user-data", - address="192.192.192.2", - fake_get_metadata_by_instance_id=fake_get_metadata, - headers={'X-Instance-ID': 'a-b-c-d', -+ 'X-Tenant-ID': 'test', - 'X-Instance-ID-Signature': signed}) - - self.assertEqual(response.status_int, 500) - - # unexpected Instance-ID - signed = hmac.new( - CONF.neutron_metadata_proxy_shared_secret, - 'z-z-z-z', - hashlib.sha256).hexdigest() - - response = fake_request( - self.stubs, self.mdinst, - relpath="/2009-04-04/user-data", - address="192.192.192.2", - fake_get_metadata_by_instance_id=fake_get_metadata, - headers={'X-Forwarded-For': '192.192.192.2', - 'X-Instance-ID': 'z-z-z-z', -+ 'X-Tenant-ID': 'test', - 'X-Instance-ID-Signature': signed}) - self.assertEqual(response.status_int, 500) - - - class MetadataPasswordTestCase(test.TestCase): - def setUp(self): - super(MetadataPasswordTestCase, self).setUp() - fake_network.stub_out_nw_api_get_instance_nw_info(self.stubs) - self.instance = copy.copy(INSTANCES[0]) - self.instance['system_metadata'] = get_default_sys_meta() diff --git a/sys-cluster/nova/nova-2013.2.1.ebuild b/sys-cluster/nova/nova-2013.2.1.ebuild new file mode 100644 index 000000000000..bd9f21fda68e --- /dev/null +++ b/sys-cluster/nova/nova-2013.2.1.ebuild @@ -0,0 +1,126 @@ +# Copyright 1999-2013 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: /var/cvsroot/gentoo-x86/sys-cluster/nova/nova-2013.2.1.ebuild,v 1.1 2013/12/19 03:18:19 prometheanfire Exp $ + +EAPI=5 +PYTHON_COMPAT=( python2_7 ) + +inherit distutils-r1 eutils multilib + +DESCRIPTION="A cloud computing fabric controller (main part of an IaaS system) written in Python." +HOMEPAGE="https://launchpad.net/nova" +SRC_URI="http://launchpad.net/${PN}/havana/${PV}/+download/${P}.tar.gz" + +LICENSE="Apache-2.0" +SLOT="0" +KEYWORDS="~amd64 ~x86" +IUSE="+api +cert +compute +conductor +consoleauth +kvm +network +novncproxy +scheduler +spicehtml5proxy +xvpvncproxy sqlite mysql postgres xen" +REQUIRED_USE="|| ( mysql postgres sqlite ) + || ( kvm xen )" + +DEPEND="dev-python/setuptools[${PYTHON_USEDEP}] + >=dev-python/pbr-0.5.21[${PYTHON_USEDEP}] + <dev-python/pbr-1.0[${PYTHON_USEDEP}] + app-admin/sudo" + +RDEPEND="sqlite? ( >=dev-python/sqlalchemy-0.7.8[sqlite,${PYTHON_USEDEP}] + <dev-python/sqlalchemy-0.7.99[sqlite,${PYTHON_USEDEP}] ) + mysql? ( >=dev-python/sqlalchemy-0.7.8[mysql,${PYTHON_USEDEP}] + <dev-python/sqlalchemy-0.7.99[mysql,${PYTHON_USEDEP}] ) + postgres? ( >=dev-python/sqlalchemy-0.7.8[postgres,${PYTHON_USEDEP}] + <dev-python/sqlalchemy-0.7.99[postgres,${PYTHON_USEDEP}] ) + >=dev-python/amqplib-0.6.1[${PYTHON_USEDEP}] + >=dev-python/anyjson-0.3.3[${PYTHON_USEDEP}] + virtual/python-argparse[${PYTHON_USEDEP}] + >=dev-python/boto-2.4.0[${PYTHON_USEDEP}] + !~dev-python/boto-2.13.0[${PYTHON_USEDEP}] + >=dev-python/eventlet-0.13.0[${PYTHON_USEDEP}] + dev-python/jinja[${PYTHON_USEDEP}] + >=dev-python/kombu-2.4.8[${PYTHON_USEDEP}] + >=dev-python/lxml-2.3[${PYTHON_USEDEP}] + >=dev-python/routes-1.12.3-r1[${PYTHON_USEDEP}] + >=dev-python/webob-1.2.3[${PYTHON_USEDEP}] + <dev-python/webob-1.3[${PYTHON_USEDEP}] + >=dev-python/greenlet-0.3.2[${PYTHON_USEDEP}] + >=dev-python/pastedeploy-1.5.0-r1[${PYTHON_USEDEP}] + dev-python/paste[${PYTHON_USEDEP}] + >=dev-python/sqlalchemy-migrate-0.7.2[${PYTHON_USEDEP}] + dev-python/netaddr[${PYTHON_USEDEP}] + >=dev-python/suds-0.4[${PYTHON_USEDEP}] + >=dev-python/paramiko-1.8.0[${PYTHON_USEDEP}] + dev-python/pyasn1[${PYTHON_USEDEP}] + >=dev-python/Babel-1.3[${PYTHON_USEDEP}] + >=dev-python/iso8601-0.1.8[${PYTHON_USEDEP}] + >=dev-python/python-cinderclient-1.0.5[${PYTHON_USEDEP}] + >=dev-python/python-neutronclient-2.3.0[${PYTHON_USEDEP}] + <=dev-python/python-neutronclient-3.0.0[${PYTHON_USEDEP}] + >=dev-python/python-glanceclient-0.9.0[${PYTHON_USEDEP}] + >=dev-python/python-keystoneclient-0.3.2[${PYTHON_USEDEP}] + >=dev-python/stevedore-0.10[${PYTHON_USEDEP}] + >=dev-python/websockify-0.5.1[${PYTHON_USEDEP}] + <dev-python/websockify-0.6[${PYTHON_USEDEP}] + >=dev-python/oslo-config-1.2.0[${PYTHON_USEDEP}] + dev-python/libvirt-python[${PYTHON_USEDEP}] + novncproxy? ( www-apps/novnc ) + sys-apps/iproute2 + net-misc/openvswitch + sys-fs/sysfsutils + sys-fs/multipath-tools + kvm? ( app-emulation/qemu ) + xen? ( app-emulation/xen + app-emulation/xen-tools )" + +PATCHES=( +) + +pkg_setup() { + enewgroup nova + enewuser nova -1 -1 /var/lib/nova nova +} + +python_install() { + distutils-r1_python_install + newconfd "${FILESDIR}/nova-confd" "nova" + newinitd "${FILESDIR}/nova-initd" "nova" + use api && dosym /etc/init.d/nova /etc/init.d/nova-api + use cert && dosym /etc/init.d/nova /etc/init.d/nova-cert + use compute && dosym /etc/init.d/nova /etc/init.d/nova-compute + use conductor && dosym /etc/init.d/nova /etc/init.d/nova-conductor + use consoleauth && dosym /etc/init.d/nova /etc/init.d/nova-consoleauth + use network && dosym /etc/init.d/nova /etc/init.d/nova-network + use novncproxy &&dosym /etc/init.d/nova /etc/init.d/nova-novncproxy + use scheduler && dosym /etc/init.d/nova /etc/init.d/nova-scheduler + use spicehtml5proxy && dosym /etc/init.d/nova /etc/init.d/nova-spicehtml5proxy + use xvpvncproxy && dosym /etc/init.d/nova /etc/init.d/nova-xvpncproxy + + diropts -m 0750 + dodir /var/run/nova /var/log/nova /var/lock/nova + fowners nova:nova /var/log/nova /var/lock/nova /var/run/nova + + diropts -m 0755 + dodir /var/lib/nova/instances + fowners nova:nova /var/lib/nova/instances + + keepdir /etc/nova + insinto /etc/nova + newins "etc/nova/nova.conf.sample" "nova.conf" + doins "etc/nova/api-paste.ini" + doins "etc/nova/logging_sample.conf" + doins "etc/nova/policy.json" + doins "etc/nova/rootwrap.conf" + insinto /etc/nova/rootwrap.d + doins "etc/nova/rootwrap.d/api-metadata.filters" + doins "etc/nova/rootwrap.d/compute.filters" + doins "etc/nova/rootwrap.d/network.filters" + + #copy migration conf file (not coppied on install via setup.py script) + insinto /usr/$(get_libdir)/python2.7/site-packages/nova/db/sqlalchemy/migrate_repo/ + doins "nova/db/sqlalchemy/migrate_repo/migrate.cfg" + + #copy the CA cert dir (not coppied on install via setup.py script) + cp -R "${S}/nova/CA" "${D}/usr/$(get_libdir)/python2.7/site-packages/nova/" || die "isntalling CA files failed" + + #add sudoers definitions for user nova + insinto /etc/sudoers.d/ + doins "${FILESDIR}/nova-sudoers" +} diff --git a/sys-cluster/nova/nova-2013.2.9999.ebuild b/sys-cluster/nova/nova-2013.2.9999.ebuild index d9a76c3f19c6..fdd850c93456 100644 --- a/sys-cluster/nova/nova-2013.2.9999.ebuild +++ b/sys-cluster/nova/nova-2013.2.9999.ebuild @@ -1,6 +1,6 @@ # Copyright 1999-2013 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -# $Header: /var/cvsroot/gentoo-x86/sys-cluster/nova/nova-2013.2.9999.ebuild,v 1.8 2013/12/03 20:14:39 prometheanfire Exp $ +# $Header: /var/cvsroot/gentoo-x86/sys-cluster/nova/nova-2013.2.9999.ebuild,v 1.9 2013/12/19 03:18:19 prometheanfire Exp $ EAPI=5 PYTHON_COMPAT=( python2_7 ) @@ -50,8 +50,8 @@ RDEPEND="sqlite? ( >=dev-python/sqlalchemy-0.7.8[sqlite,${PYTHON_USEDEP}] >=dev-python/suds-0.4[${PYTHON_USEDEP}] >=dev-python/paramiko-1.8.0[${PYTHON_USEDEP}] dev-python/pyasn1[${PYTHON_USEDEP}] - >=dev-python/Babel-0.9.6[${PYTHON_USEDEP}] - >=dev-python/iso8601-0.1.4[${PYTHON_USEDEP}] + >=dev-python/Babel-1.3[${PYTHON_USEDEP}] + >=dev-python/iso8601-0.1.8[${PYTHON_USEDEP}] >=dev-python/python-cinderclient-1.0.5[${PYTHON_USEDEP}] >=dev-python/python-neutronclient-2.3.0[${PYTHON_USEDEP}] <=dev-python/python-neutronclient-3.0.0[${PYTHON_USEDEP}] |