summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Thode <prometheanfire@gentoo.org>2014-04-06 06:32:20 +0000
committerMatthew Thode <prometheanfire@gentoo.org>2014-04-06 06:32:20 +0000
commit23c0e71812e108809bcca973cea36b19f5ca9e0a (patch)
treeb1cd2fb35a6df1b2cd227b90aeedb1eb71bb3cc3 /sys-cluster
parent2013.2.3 (diff)
downloadgentoo-2-23c0e71812e108809bcca973cea36b19f5ca9e0a.tar.gz
gentoo-2-23c0e71812e108809bcca973cea36b19f5ca9e0a.tar.bz2
gentoo-2-23c0e71812e108809bcca973cea36b19f5ca9e0a.zip
2013.2.3
(Portage version: 2.2.8-r1/cvs/Linux x86_64, signed Manifest commit with key 0x2471eb3e40ac5ac3)
Diffstat (limited to 'sys-cluster')
-rw-r--r--sys-cluster/nova/ChangeLog9
-rw-r--r--sys-cluster/nova/files/2013.2.2-CVE-2014-0134.patch732
-rw-r--r--sys-cluster/nova/nova-2013.2.3.ebuild (renamed from sys-cluster/nova/nova-2013.2.2-r1.ebuild)39
-rw-r--r--sys-cluster/nova/nova-2013.2.9999.ebuild4
4 files changed, 24 insertions, 760 deletions
diff --git a/sys-cluster/nova/ChangeLog b/sys-cluster/nova/ChangeLog
index 9d5e539a0861..fc37b78f545e 100644
--- a/sys-cluster/nova/ChangeLog
+++ b/sys-cluster/nova/ChangeLog
@@ -1,6 +1,13 @@
# ChangeLog for sys-cluster/nova
# Copyright 1999-2014 Gentoo Foundation; Distributed under the GPL v2
-# $Header: /var/cvsroot/gentoo-x86/sys-cluster/nova/ChangeLog,v 1.57 2014/04/06 05:05:47 prometheanfire Exp $
+# $Header: /var/cvsroot/gentoo-x86/sys-cluster/nova/ChangeLog,v 1.58 2014/04/06 06:32:19 prometheanfire Exp $
+
+*nova-2013.2.3 (06 Apr 2014)
+
+ 06 Apr 2014; Matthew Thode <prometheanfire@gentoo.org> +nova-2013.2.3.ebuild,
+ -files/2013.2.2-CVE-2014-0134.patch, -nova-2013.2.2-r1.ebuild,
+ nova-2013.2.9999.ebuild:
+ 2013.2.3
06 Apr 2014; Matthew Thode <prometheanfire@gentoo.org> -nova-2013.1.5.ebuild,
-nova-2013.1.9999.ebuild:
diff --git a/sys-cluster/nova/files/2013.2.2-CVE-2014-0134.patch b/sys-cluster/nova/files/2013.2.2-CVE-2014-0134.patch
deleted file mode 100644
index 04d14cae392a..000000000000
--- a/sys-cluster/nova/files/2013.2.2-CVE-2014-0134.patch
+++ /dev/null
@@ -1,732 +0,0 @@
-From 25e761acd56d4c820273fc0245ada06c500c1637 Mon Sep 17 00:00:00 2001
-From: David Ripton <dripton@redhat.com>
-Date: Tue, 28 Jan 2014 16:38:51 -0500
-Subject: [PATCH] Persist image format to a file, to prevent attacks based on
- changing it
-
-The attack is based on creating a raw image that looks like a qcow2
-image, and taking advantage of the code that used 'qemu-img info' to
-autodetect the image format.
-
-Now we store the image format to a 'disk.info' file, for Qcow2 and Raw
-images, and only autodetect for images that have never been written to
-that file.
-
-SecurityImpact
-
-Conflicts:
- nova/virt/libvirt/imagebackend.py
-
-Manual tweaks to some mocking in test_imagebackend.py
-
-Change-Id: I2016efdb3f49a44ec4d677ac596eacc97871f30a
-Co-authored-by: Nikola Dipanov <ndipanov@redhat.com>
-Closes-bug: #1221190
----
- nova/exception.py | 8 +
- nova/tests/virt/libvirt/test_imagebackend.py | 359 ++++++++++++++++++++++-----
- nova/tests/virt/libvirt/test_libvirt.py | 3 +
- nova/tests/virt/test_virt_drivers.py | 7 +
- nova/utils.py | 14 ++
- nova/virt/libvirt/imagebackend.py | 76 +++++-
- 6 files changed, 403 insertions(+), 64 deletions(-)
-
-diff --git a/nova/exception.py b/nova/exception.py
-index 7c17803..770a700 100644
---- a/nova/exception.py
-+++ b/nova/exception.py
-@@ -449,6 +449,14 @@ class InvalidDiskFormat(Invalid):
- msg_fmt = _("Disk format %(disk_format)s is not acceptable")
-
-
-+class InvalidDiskInfo(Invalid):
-+ msg_fmt = _("Disk info file is invalid: %(reason)s")
-+
-+
-+class DiskInfoReadWriteFail(Invalid):
-+ msg_fmt = _("Failed to read or write disk info file: %(reason)s")
-+
-+
- class ImageUnacceptable(Invalid):
- msg_fmt = _("Image %(image_id)s is unacceptable: %(reason)s")
-
-diff --git a/nova/tests/virt/libvirt/test_imagebackend.py b/nova/tests/virt/libvirt/test_imagebackend.py
-index 5bfa94d..5424f7b 100644
---- a/nova/tests/virt/libvirt/test_imagebackend.py
-+++ b/nova/tests/virt/libvirt/test_imagebackend.py
-@@ -16,6 +16,8 @@
- # under the License.
-
- import os
-+import shutil
-+import tempfile
-
- import fixtures
- from oslo.config import cfg
-@@ -27,13 +29,13 @@
- from nova import test
- from nova.tests import fake_processutils
- from nova.tests.virt.libvirt import fake_libvirt_utils
-+from nova import utils
- from nova.virt.libvirt import imagebackend
-
- CONF = cfg.CONF
-
-
- class _ImageTestCase(object):
-- INSTANCES_PATH = '/instances_path'
-
- def mock_create_image(self, image):
- def create_image(fn, base, size, *args, **kwargs):
-@@ -42,10 +44,13 @@ def create_image(fn, base, size, *args, **kwargs):
-
- def setUp(self):
- super(_ImageTestCase, self).setUp()
-+ self.INSTANCES_PATH = tempfile.mkdtemp(suffix='instances')
- self.flags(disable_process_locking=True,
- instances_path=self.INSTANCES_PATH)
- self.INSTANCE = {'name': 'instance',
- 'uuid': uuidutils.generate_uuid()}
-+ self.DISK_INFO_PATH = os.path.join(self.INSTANCES_PATH,
-+ self.INSTANCE['uuid'], 'disk.info')
- self.NAME = 'fake.vm'
- self.TEMPLATE = 'template'
-
-@@ -63,6 +68,78 @@ def setUp(self):
- 'nova.virt.libvirt.imagebackend.libvirt_utils',
- fake_libvirt_utils))
-
-+ def fake_chown(path, owner_uid=None):
-+ return None
-+ self.stubs.Set(utils, 'chown', fake_chown)
-+
-+ def tearDown(self):
-+ super(_ImageTestCase, self).tearDown()
-+ shutil.rmtree(self.INSTANCES_PATH)
-+
-+ def test_prealloc_image(self):
-+ CONF.set_override('preallocate_images', 'space')
-+
-+ fake_processutils.fake_execute_clear_log()
-+ fake_processutils.stub_out_processutils_execute(self.stubs)
-+ image = self.image_class(self.INSTANCE, self.NAME)
-+
-+ def fake_fetch(target, *args, **kwargs):
-+ return
-+
-+ self.stubs.Set(os.path, 'exists', lambda _: True)
-+ self.stubs.Set(os, 'access', lambda p, w: True)
-+
-+ # Call twice to verify testing fallocate is only called once.
-+ image.cache(fake_fetch, self.TEMPLATE_PATH, self.SIZE)
-+ image.cache(fake_fetch, self.TEMPLATE_PATH, self.SIZE)
-+
-+ self.assertEqual(fake_processutils.fake_execute_get_log(),
-+ ['fallocate -n -l 1 %s.fallocate_test' % self.PATH,
-+ 'fallocate -n -l %s %s' % (self.SIZE, self.PATH),
-+ 'fallocate -n -l %s %s' % (self.SIZE, self.PATH)])
-+
-+ def test_prealloc_image_without_write_access(self):
-+ CONF.set_override('preallocate_images', 'space')
-+
-+ fake_processutils.fake_execute_clear_log()
-+ fake_processutils.stub_out_processutils_execute(self.stubs)
-+ image = self.image_class(self.INSTANCE, self.NAME)
-+
-+ def fake_fetch(target, *args, **kwargs):
-+ return
-+
-+ self.stubs.Set(image, 'check_image_exists', lambda: True)
-+ self.stubs.Set(image, '_can_fallocate', lambda: True)
-+ self.stubs.Set(os.path, 'exists', lambda _: True)
-+ self.stubs.Set(os, 'access', lambda p, w: False)
-+
-+ # Testing fallocate is only called when user has write access.
-+ image.cache(fake_fetch, self.TEMPLATE_PATH, self.SIZE)
-+
-+ self.assertEqual(fake_processutils.fake_execute_get_log(), [])
-+
-+
-+class RawTestCase(_ImageTestCase, test.NoDBTestCase):
-+
-+ SIZE = 1024
-+
-+ def setUp(self):
-+ self.image_class = imagebackend.Raw
-+ super(RawTestCase, self).setUp()
-+ self.stubs.Set(imagebackend.Raw, 'correct_format', lambda _: None)
-+
-+ def fake_chown(path, owner_uid=None):
-+ return None
-+ self.stubs.Set(utils, 'chown', fake_chown)
-+
-+ def prepare_mocks(self):
-+ fn = self.mox.CreateMockAnything()
-+ self.mox.StubOutWithMock(imagebackend.utils.synchronized,
-+ '__call__')
-+ self.mox.StubOutWithMock(imagebackend.libvirt_utils, 'copy_image')
-+ self.mox.StubOutWithMock(imagebackend.disk, 'extend')
-+ return fn
-+
- def test_cache(self):
- self.mox.StubOutWithMock(os.path, 'exists')
- if self.OLD_STYLE_INSTANCE_PATH:
-@@ -130,66 +207,6 @@ def test_cache_template_exists(self):
-
- self.mox.VerifyAll()
-
-- def test_prealloc_image(self):
-- CONF.set_override('preallocate_images', 'space')
--
-- fake_processutils.fake_execute_clear_log()
-- fake_processutils.stub_out_processutils_execute(self.stubs)
-- image = self.image_class(self.INSTANCE, self.NAME)
--
-- def fake_fetch(target, *args, **kwargs):
-- return
--
-- self.stubs.Set(os.path, 'exists', lambda _: True)
-- self.stubs.Set(os, 'access', lambda p, w: True)
--
-- # Call twice to verify testing fallocate is only called once.
-- image.cache(fake_fetch, self.TEMPLATE_PATH, self.SIZE)
-- image.cache(fake_fetch, self.TEMPLATE_PATH, self.SIZE)
--
-- self.assertEqual(fake_processutils.fake_execute_get_log(),
-- ['fallocate -n -l 1 %s.fallocate_test' % self.PATH,
-- 'fallocate -n -l %s %s' % (self.SIZE, self.PATH),
-- 'fallocate -n -l %s %s' % (self.SIZE, self.PATH)])
--
-- def test_prealloc_image_without_write_access(self):
-- CONF.set_override('preallocate_images', 'space')
--
-- fake_processutils.fake_execute_clear_log()
-- fake_processutils.stub_out_processutils_execute(self.stubs)
-- image = self.image_class(self.INSTANCE, self.NAME)
--
-- def fake_fetch(target, *args, **kwargs):
-- return
--
-- self.stubs.Set(image, 'check_image_exists', lambda: True)
-- self.stubs.Set(image, '_can_fallocate', lambda: True)
-- self.stubs.Set(os.path, 'exists', lambda _: True)
-- self.stubs.Set(os, 'access', lambda p, w: False)
--
-- # Testing fallocate is only called when user has write access.
-- image.cache(fake_fetch, self.TEMPLATE_PATH, self.SIZE)
--
-- self.assertEqual(fake_processutils.fake_execute_get_log(), [])
--
--
--class RawTestCase(_ImageTestCase, test.NoDBTestCase):
--
-- SIZE = 1024
--
-- def setUp(self):
-- self.image_class = imagebackend.Raw
-- super(RawTestCase, self).setUp()
-- self.stubs.Set(imagebackend.Raw, 'correct_format', lambda _: None)
--
-- def prepare_mocks(self):
-- fn = self.mox.CreateMockAnything()
-- self.mox.StubOutWithMock(imagebackend.utils.synchronized,
-- '__call__')
-- self.mox.StubOutWithMock(imagebackend.libvirt_utils, 'copy_image')
-- self.mox.StubOutWithMock(imagebackend.disk, 'extend')
-- return fn
--
- def test_create_image(self):
- fn = self.prepare_mocks()
- fn(target=self.TEMPLATE_PATH, max_size=None, image_id=None)
-@@ -224,16 +241,21 @@ def test_create_image_extend(self):
- self.mox.VerifyAll()
-
- def test_correct_format(self):
-- info = self.mox.CreateMockAnything()
- self.stubs.UnsetAll()
-
- self.mox.StubOutWithMock(os.path, 'exists')
- self.mox.StubOutWithMock(imagebackend.images, 'qemu_img_info')
-
-+ def fake_chown(path, owner_uid=None):
-+ return None
-+ self.stubs.Set(utils, 'chown', fake_chown)
-+
- os.path.exists(self.PATH).AndReturn(True)
-+ os.path.exists(self.DISK_INFO_PATH).AndReturn(False)
- info = self.mox.CreateMockAnything()
- info.file_format = 'foo'
- imagebackend.images.qemu_img_info(self.PATH).AndReturn(info)
-+ os.path.exists(CONF.instances_path).AndReturn(True)
- self.mox.ReplayAll()
-
- image = self.image_class(self.INSTANCE, self.NAME, path=self.PATH)
-@@ -241,6 +263,11 @@ def test_correct_format(self):
-
- self.mox.VerifyAll()
-
-+ def test_resolve_driver_format(self):
-+ image = self.image_class(self.INSTANCE, self.NAME)
-+ driver_format = image.resolve_driver_format()
-+ self.assertEqual(driver_format, 'raw')
-+
-
- class Qcow2TestCase(_ImageTestCase, test.NoDBTestCase):
- SIZE = 1024 * 1024 * 1024
-@@ -251,6 +278,10 @@ def setUp(self):
- self.QCOW2_BASE = (self.TEMPLATE_PATH +
- '_%d' % (self.SIZE / (1024 * 1024 * 1024)))
-
-+ def fake_chown(path, owner_uid=None):
-+ return None
-+ self.stubs.Set(utils, 'chown', fake_chown)
-+
- def prepare_mocks(self):
- fn = self.mox.CreateMockAnything()
- self.mox.StubOutWithMock(imagebackend.utils.synchronized,
-@@ -261,6 +292,80 @@ def prepare_mocks(self):
- self.mox.StubOutWithMock(imagebackend.disk, 'extend')
- return fn
-
-+ def test_cache(self):
-+ self.mox.StubOutWithMock(os.path, 'exists')
-+ if self.OLD_STYLE_INSTANCE_PATH:
-+ os.path.exists(self.OLD_STYLE_INSTANCE_PATH).AndReturn(False)
-+ os.path.exists(self.DISK_INFO_PATH).AndReturn(False)
-+ os.path.exists(CONF.instances_path).AndReturn(True)
-+ os.path.exists(self.TEMPLATE_DIR).AndReturn(False)
-+ os.path.exists(self.INSTANCES_PATH).AndReturn(True)
-+ os.path.exists(self.PATH).AndReturn(False)
-+ os.path.exists(self.TEMPLATE_PATH).AndReturn(False)
-+ fn = self.mox.CreateMockAnything()
-+ fn(target=self.TEMPLATE_PATH)
-+ self.mox.ReplayAll()
-+
-+ image = self.image_class(self.INSTANCE, self.NAME)
-+ self.mock_create_image(image)
-+ image.cache(fn, self.TEMPLATE)
-+
-+ self.mox.VerifyAll()
-+
-+ def test_cache_image_exists(self):
-+ self.mox.StubOutWithMock(os.path, 'exists')
-+ if self.OLD_STYLE_INSTANCE_PATH:
-+ os.path.exists(self.OLD_STYLE_INSTANCE_PATH).AndReturn(False)
-+ os.path.exists(self.DISK_INFO_PATH).AndReturn(False)
-+ os.path.exists(self.INSTANCES_PATH).AndReturn(True)
-+ os.path.exists(self.TEMPLATE_DIR).AndReturn(True)
-+ os.path.exists(self.PATH).AndReturn(True)
-+ os.path.exists(self.TEMPLATE_PATH).AndReturn(True)
-+ self.mox.ReplayAll()
-+
-+ image = self.image_class(self.INSTANCE, self.NAME)
-+ image.cache(None, self.TEMPLATE)
-+
-+ self.mox.VerifyAll()
-+
-+ def test_cache_base_dir_exists(self):
-+ self.mox.StubOutWithMock(os.path, 'exists')
-+ if self.OLD_STYLE_INSTANCE_PATH:
-+ os.path.exists(self.OLD_STYLE_INSTANCE_PATH).AndReturn(False)
-+ os.path.exists(self.DISK_INFO_PATH).AndReturn(False)
-+ os.path.exists(self.INSTANCES_PATH).AndReturn(True)
-+ os.path.exists(self.TEMPLATE_DIR).AndReturn(True)
-+ os.path.exists(self.PATH).AndReturn(False)
-+ os.path.exists(self.TEMPLATE_PATH).AndReturn(False)
-+ fn = self.mox.CreateMockAnything()
-+ fn(target=self.TEMPLATE_PATH)
-+ self.mox.ReplayAll()
-+
-+ image = self.image_class(self.INSTANCE, self.NAME)
-+ self.mock_create_image(image)
-+ image.cache(fn, self.TEMPLATE)
-+
-+ self.mox.VerifyAll()
-+
-+ def test_cache_template_exists(self):
-+ self.mox.StubOutWithMock(os.path, 'exists')
-+ if self.OLD_STYLE_INSTANCE_PATH:
-+ os.path.exists(self.OLD_STYLE_INSTANCE_PATH).AndReturn(False)
-+ os.path.exists(self.DISK_INFO_PATH).AndReturn(False)
-+ os.path.exists(self.INSTANCES_PATH).AndReturn(True)
-+ os.path.exists(self.TEMPLATE_DIR).AndReturn(True)
-+ os.path.exists(self.PATH).AndReturn(False)
-+ os.path.exists(self.TEMPLATE_PATH).AndReturn(False)
-+ fn = self.mox.CreateMockAnything()
-+ fn(target=self.TEMPLATE_PATH)
-+ self.mox.ReplayAll()
-+
-+ image = self.image_class(self.INSTANCE, self.NAME)
-+ self.mock_create_image(image)
-+ image.cache(fn, self.TEMPLATE)
-+
-+ self.mox.VerifyAll()
-+
- def test_create_image(self):
- fn = self.prepare_mocks()
- fn(max_size=None, target=self.TEMPLATE_PATH)
-@@ -279,6 +384,8 @@ def test_create_image_with_size(self):
- self.mox.StubOutWithMock(os.path, 'exists')
- if self.OLD_STYLE_INSTANCE_PATH:
- os.path.exists(self.OLD_STYLE_INSTANCE_PATH).AndReturn(False)
-+ os.path.exists(self.DISK_INFO_PATH).AndReturn(False)
-+ os.path.exists(self.INSTANCES_PATH).AndReturn(True)
- os.path.exists(self.TEMPLATE_PATH).AndReturn(False)
- os.path.exists(self.PATH).AndReturn(False)
- os.path.exists(self.PATH).AndReturn(False)
-@@ -298,6 +405,8 @@ def test_create_image_too_small(self):
- 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.DISK_INFO_PATH).AndReturn(False)
-+ os.path.exists(self.INSTANCES_PATH).AndReturn(True)
- os.path.exists(self.TEMPLATE_PATH).AndReturn(True)
- imagebackend.disk.get_disk_size(self.TEMPLATE_PATH
- ).AndReturn(self.SIZE)
-@@ -316,6 +425,8 @@ def test_generate_resized_backing_files(self):
- 'get_disk_backing_file')
- if self.OLD_STYLE_INSTANCE_PATH:
- os.path.exists(self.OLD_STYLE_INSTANCE_PATH).AndReturn(False)
-+ os.path.exists(self.DISK_INFO_PATH).AndReturn(False)
-+ os.path.exists(CONF.instances_path).AndReturn(True)
- os.path.exists(self.TEMPLATE_PATH).AndReturn(False)
- os.path.exists(self.PATH).AndReturn(True)
-
-@@ -342,6 +453,9 @@ def test_qcow2_exists_and_has_no_backing_file(self):
- 'get_disk_backing_file')
- if self.OLD_STYLE_INSTANCE_PATH:
- os.path.exists(self.OLD_STYLE_INSTANCE_PATH).AndReturn(False)
-+ os.path.exists(self.DISK_INFO_PATH).AndReturn(False)
-+ os.path.exists(self.INSTANCES_PATH).AndReturn(True)
-+
- os.path.exists(self.TEMPLATE_PATH).AndReturn(False)
- os.path.exists(self.PATH).AndReturn(True)
-
-@@ -355,6 +469,53 @@ def test_qcow2_exists_and_has_no_backing_file(self):
-
- self.mox.VerifyAll()
-
-+ def test_resolve_driver_format(self):
-+ image = self.image_class(self.INSTANCE, self.NAME)
-+ driver_format = image.resolve_driver_format()
-+ self.assertEqual(driver_format, 'qcow2')
-+
-+ def test_prealloc_image(self):
-+ CONF.set_override('preallocate_images', 'space')
-+
-+ fake_processutils.fake_execute_clear_log()
-+ fake_processutils.stub_out_processutils_execute(self.stubs)
-+ image = self.image_class(self.INSTANCE, self.NAME)
-+
-+ def fake_fetch(target, *args, **kwargs):
-+ return
-+
-+ self.stubs.Set(os.path, 'exists', lambda _: True)
-+ self.stubs.Set(os, 'access', lambda p, w: True)
-+
-+ # Call twice to verify testing fallocate is only called once.
-+ image.cache(fake_fetch, self.TEMPLATE_PATH, self.SIZE)
-+ image.cache(fake_fetch, self.TEMPLATE_PATH, self.SIZE)
-+
-+ self.assertEqual(fake_processutils.fake_execute_get_log(),
-+ ['fallocate -n -l 1 %s.fallocate_test' % self.PATH,
-+ 'fallocate -n -l %s %s' % (self.SIZE, self.PATH),
-+ 'fallocate -n -l %s %s' % (self.SIZE, self.PATH)])
-+
-+ def test_prealloc_image_without_write_access(self):
-+ CONF.set_override('preallocate_images', 'space')
-+
-+ fake_processutils.fake_execute_clear_log()
-+ fake_processutils.stub_out_processutils_execute(self.stubs)
-+ image = self.image_class(self.INSTANCE, self.NAME)
-+
-+ def fake_fetch(target, *args, **kwargs):
-+ return
-+
-+ self.stubs.Set(image, 'check_image_exists', lambda: True)
-+ self.stubs.Set(image, '_can_fallocate', lambda: True)
-+ self.stubs.Set(os.path, 'exists', lambda _: True)
-+ self.stubs.Set(os, 'access', lambda p, w: False)
-+
-+ # Testing fallocate is only called when user has write access.
-+ image.cache(fake_fetch, self.TEMPLATE_PATH, self.SIZE)
-+
-+ self.assertEqual(fake_processutils.fake_execute_get_log(), [])
-+
-
- class LvmTestCase(_ImageTestCase, test.NoDBTestCase):
- VG = 'FakeVG'
-@@ -431,6 +592,58 @@ def _create_image_resize(self, sparse):
-
- self.mox.VerifyAll()
-
-+ def test_cache(self):
-+ self.mox.StubOutWithMock(os.path, 'exists')
-+ if self.OLD_STYLE_INSTANCE_PATH:
-+ os.path.exists(self.OLD_STYLE_INSTANCE_PATH).AndReturn(False)
-+ os.path.exists(self.TEMPLATE_DIR).AndReturn(False)
-+ os.path.exists(self.PATH).AndReturn(False)
-+ os.path.exists(self.TEMPLATE_PATH).AndReturn(False)
-+
-+ fn = self.mox.CreateMockAnything()
-+ fn(target=self.TEMPLATE_PATH)
-+ self.mox.StubOutWithMock(imagebackend.fileutils, 'ensure_tree')
-+ imagebackend.fileutils.ensure_tree(self.TEMPLATE_DIR)
-+ self.mox.ReplayAll()
-+
-+ image = self.image_class(self.INSTANCE, self.NAME)
-+ self.mock_create_image(image)
-+ image.cache(fn, self.TEMPLATE)
-+
-+ self.mox.VerifyAll()
-+
-+ def test_cache_image_exists(self):
-+ self.mox.StubOutWithMock(os.path, 'exists')
-+ if self.OLD_STYLE_INSTANCE_PATH:
-+ os.path.exists(self.OLD_STYLE_INSTANCE_PATH).AndReturn(False)
-+ os.path.exists(self.TEMPLATE_DIR).AndReturn(True)
-+ os.path.exists(self.PATH).AndReturn(True)
-+ os.path.exists(self.TEMPLATE_PATH).AndReturn(True)
-+ self.mox.ReplayAll()
-+
-+ image = self.image_class(self.INSTANCE, self.NAME)
-+ image.cache(None, self.TEMPLATE)
-+
-+ self.mox.VerifyAll()
-+
-+ def test_cache_base_dir_exists(self):
-+ self.mox.StubOutWithMock(os.path, 'exists')
-+ if self.OLD_STYLE_INSTANCE_PATH:
-+ os.path.exists(self.OLD_STYLE_INSTANCE_PATH).AndReturn(False)
-+ os.path.exists(self.TEMPLATE_DIR).AndReturn(True)
-+ os.path.exists(self.PATH).AndReturn(False)
-+ os.path.exists(self.TEMPLATE_PATH).AndReturn(False)
-+ fn = self.mox.CreateMockAnything()
-+ fn(target=self.TEMPLATE_PATH)
-+ self.mox.StubOutWithMock(imagebackend.fileutils, 'ensure_tree')
-+ self.mox.ReplayAll()
-+
-+ image = self.image_class(self.INSTANCE, self.NAME)
-+ self.mock_create_image(image)
-+ image.cache(fn, self.TEMPLATE)
-+
-+ self.mox.VerifyAll()
-+
- def test_create_image(self):
- self._create_image(False)
-
-@@ -596,6 +809,21 @@ def test_cache_template_exists(self):
-
- self.mox.VerifyAll()
-
-+ def test_cache_base_dir_exists(self):
-+ self.mox.StubOutWithMock(os.path, 'exists')
-+ os.path.exists(self.TEMPLATE_DIR).AndReturn(True)
-+ os.path.exists(self.TEMPLATE_PATH).AndReturn(False)
-+ fn = self.mox.CreateMockAnything()
-+ fn(target=self.TEMPLATE_PATH)
-+ self.mox.StubOutWithMock(imagebackend.fileutils, 'ensure_tree')
-+ self.mox.ReplayAll()
-+
-+ image = self.image_class(self.INSTANCE, self.NAME)
-+ self.mock_create_image(image)
-+ image.cache(fn, self.TEMPLATE)
-+
-+ self.mox.VerifyAll()
-+
- def test_create_image(self):
- fn = self.prepare_mocks()
- fn(max_size=None, rbd=self.rbd, target=self.TEMPLATE_PATH)
-@@ -642,6 +870,13 @@ class BackendTestCase(test.NoDBTestCase):
- 'uuid': uuidutils.generate_uuid()}
- NAME = 'fake-name.suffix'
-
-+ def setUp(self):
-+ super(BackendTestCase, self).setUp()
-+
-+ def fake_chown(path, owner_uid=None):
-+ return None
-+ self.stubs.Set(utils, 'chown', fake_chown)
-+
- def get_image(self, use_cow, image_type):
- return imagebackend.Backend(use_cow).image(self.INSTANCE,
- self.NAME,
-diff --git a/nova/tests/virt/libvirt/test_libvirt.py b/nova/tests/virt/libvirt/test_libvirt.py
-index ba842ad..ea8ac13 100644
---- a/nova/tests/virt/libvirt/test_libvirt.py
-+++ b/nova/tests/virt/libvirt/test_libvirt.py
-@@ -390,6 +390,9 @@ def fake_extend(image, size, use_cow=False):
-
- self.stubs.Set(libvirt_driver.disk, 'extend', fake_extend)
-
-+ self.stubs.Set(imagebackend.Image, 'resolve_driver_format',
-+ imagebackend.Image._get_driver_format)
-+
- class FakeConn():
- def getCapabilities(self):
- """Ensure standard capabilities being returned."""
-diff --git a/nova/tests/virt/test_virt_drivers.py b/nova/tests/virt/test_virt_drivers.py
-index 832d9d6..8f1bd23 100644
---- a/nova/tests/virt/test_virt_drivers.py
-+++ b/nova/tests/virt/test_virt_drivers.py
-@@ -30,6 +30,7 @@
- from nova.tests.virt.libvirt import fake_libvirt_utils
- from nova.virt import event as virtevent
- from nova.virt import fake
-+from nova.virt.libvirt import imagebackend
-
- LOG = logging.getLogger(__name__)
-
-@@ -201,6 +202,12 @@ def setUp(self):
- fake.FakeVirtAPI())
- self.ctxt = test_utils.get_test_admin_context()
- self.image_service = fake_image.FakeImageService()
-+ # NOTE(dripton): resolve_driver_format does some file reading and
-+ # writing and chowning that complicate testing too much by requiring
-+ # using real directories with proper permissions. Just stub it out
-+ # here; we test it in test_imagebackend.py
-+ self.stubs.Set(imagebackend.Image, 'resolve_driver_format',
-+ imagebackend.Image._get_driver_format)
-
- def _get_running_instance(self):
- instance_ref = test_utils.get_test_instance()
-diff --git a/nova/utils.py b/nova/utils.py
-index 599cb64..4757f3a 100755
---- a/nova/utils.py
-+++ b/nova/utils.py
-@@ -924,6 +924,20 @@ def temporary_chown(path, owner_uid=None):
- execute('chown', orig_uid, path, run_as_root=True)
-
-
-+def chown(path, owner_uid=None):
-+ """chown a path.
-+
-+ :param owner_uid: UID of owner (defaults to current user)
-+ """
-+ if owner_uid is None:
-+ owner_uid = os.getuid()
-+
-+ orig_uid = os.stat(path).st_uid
-+
-+ if orig_uid != owner_uid:
-+ execute('chown', owner_uid, path, run_as_root=True)
-+
-+
- @contextlib.contextmanager
- def tempdir(**kwargs):
- argdict = kwargs.copy()
-diff --git a/nova/virt/libvirt/imagebackend.py b/nova/virt/libvirt/imagebackend.py
-index 51872cf..ed11c90 100644
---- a/nova/virt/libvirt/imagebackend.py
-+++ b/nova/virt/libvirt/imagebackend.py
-@@ -88,6 +88,11 @@ def __init__(self, source_type, driver_format, is_block_dev=False):
- self.is_block_dev = is_block_dev
- self.preallocate = False
-
-+ # NOTE(dripton): We store lines of json (path, disk_format) in this
-+ # file, for some image types, to prevent attacks based on changing the
-+ # disk_format.
-+ self.disk_info_path = None
-+
- # NOTE(mikal): We need a lock directory which is shared along with
- # instance files, to cover the scenario where multiple compute nodes
- # are trying to create a base file at the same time
-@@ -232,6 +237,65 @@ def snapshot_extract(self, target, out_format):
- def snapshot_delete(self):
- raise NotImplementedError()
-
-+ def _get_driver_format(self):
-+ return self.driver_format
-+
-+ def resolve_driver_format(self):
-+ """Return the driver format for self.path.
-+
-+ First checks self.disk_info_path for an entry.
-+ If it's not there, calls self._get_driver_format(), and then
-+ stores the result in self.disk_info_path
-+
-+ See https://bugs.launchpad.net/nova/+bug/1221190
-+ """
-+ def _dict_from_line(line):
-+ if not line:
-+ return {}
-+ try:
-+ return jsonutils.loads(line)
-+ except (TypeError, ValueError) as e:
-+ msg = (_("Could not load line %(line)s, got error "
-+ "%(error)s") %
-+ {'line': line, 'error': unicode(e)})
-+ raise exception.InvalidDiskInfo(reason=msg)
-+
-+ @utils.synchronized(self.disk_info_path, external=False,
-+ lock_path=self.lock_path)
-+ def write_to_disk_info_file():
-+ # Use os.open to create it without group or world write permission.
-+ fd = os.open(self.disk_info_path, os.O_RDWR | os.O_CREAT, 0o644)
-+ with os.fdopen(fd, "r+") as disk_info_file:
-+ line = disk_info_file.read().rstrip()
-+ dct = _dict_from_line(line)
-+ if self.path in dct:
-+ msg = _("Attempted overwrite of an existing value.")
-+ raise exception.InvalidDiskInfo(reason=msg)
-+ dct.update({self.path: driver_format})
-+ disk_info_file.seek(0)
-+ disk_info_file.truncate()
-+ disk_info_file.write('%s\n' % jsonutils.dumps(dct))
-+ # Ensure the file is always owned by the nova user so qemu can't
-+ # write it.
-+ utils.chown(self.disk_info_path, owner_uid=os.getuid())
-+
-+ try:
-+ if (self.disk_info_path is not None and
-+ os.path.exists(self.disk_info_path)):
-+ with open(self.disk_info_path) as disk_info_file:
-+ line = disk_info_file.read().rstrip()
-+ dct = _dict_from_line(line)
-+ for path, driver_format in dct.iteritems():
-+ if path == self.path:
-+ return driver_format
-+ driver_format = self._get_driver_format()
-+ if self.disk_info_path is not None:
-+ fileutils.ensure_tree(os.path.dirname(self.disk_info_path))
-+ write_to_disk_info_file()
-+ except OSError as e:
-+ raise exception.DiskInfoReadWriteFail(reason=unicode(e))
-+ return driver_format
-+
-
- class Raw(Image):
- def __init__(self, instance=None, disk_name=None, path=None,
-@@ -243,12 +307,17 @@ def __init__(self, instance=None, disk_name=None, path=None,
- disk_name))
- self.snapshot_name = snapshot_name
- self.preallocate = CONF.preallocate_images != 'none'
-+ self.disk_info_path = os.path.join(os.path.dirname(self.path),
-+ 'disk.info')
- self.correct_format()
-
-+ def _get_driver_format(self):
-+ data = images.qemu_img_info(self.path)
-+ return data.file_format or 'raw'
-+
- def correct_format(self):
- if os.path.exists(self.path):
-- data = images.qemu_img_info(self.path)
-- self.driver_format = data.file_format or 'raw'
-+ self.driver_format = self.resolve_driver_format()
-
- def create_image(self, prepare_template, base, size, *args, **kwargs):
- @utils.synchronized(base, external=True, lock_path=self.lock_path)
-@@ -291,6 +360,9 @@ def __init__(self, instance=None, disk_name=None, path=None,
- disk_name))
- self.snapshot_name = snapshot_name
- self.preallocate = CONF.preallocate_images != 'none'
-+ self.disk_info_path = os.path.join(os.path.dirname(self.path),
-+ 'disk.info')
-+ self.resolve_driver_format()
-
- def create_image(self, prepare_template, base, size, *args, **kwargs):
- @utils.synchronized(base, external=True, lock_path=self.lock_path)
---
-1.8.5.5
-
diff --git a/sys-cluster/nova/nova-2013.2.2-r1.ebuild b/sys-cluster/nova/nova-2013.2.3.ebuild
index 917e62cd12d4..2571904f99ba 100644
--- a/sys-cluster/nova/nova-2013.2.2-r1.ebuild
+++ b/sys-cluster/nova/nova-2013.2.3.ebuild
@@ -1,6 +1,6 @@
# Copyright 1999-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-# $Header: /var/cvsroot/gentoo-x86/sys-cluster/nova/nova-2013.2.2-r1.ebuild,v 1.1 2014/03/25 20:51:33 prometheanfire Exp $
+# $Header: /var/cvsroot/gentoo-x86/sys-cluster/nova/nova-2013.2.3.ebuild,v 1.1 2014/04/06 06:32:19 prometheanfire Exp $
EAPI=5
PYTHON_COMPAT=( python2_7 )
@@ -14,7 +14,7 @@ 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"
+IUSE="+compute +kvm +network +novncproxy sqlite mysql postgres xen"
REQUIRED_USE="|| ( mysql postgres sqlite )
|| ( kvm xen )"
@@ -64,6 +64,7 @@ RDEPEND="sqlite? ( >=dev-python/sqlalchemy-0.7.8[sqlite,${PYTHON_USEDEP}]
novncproxy? ( www-apps/novnc )
sys-apps/iproute2
net-misc/openvswitch
+ net-misc/rabbitmq-server
sys-fs/sysfsutils
sys-fs/multipath-tools
kvm? ( app-emulation/qemu )
@@ -71,7 +72,6 @@ RDEPEND="sqlite? ( >=dev-python/sqlalchemy-0.7.8[sqlite,${PYTHON_USEDEP}]
app-emulation/xen-tools )"
PATCHES=(
- "${FILESDIR}/2013.2.2-CVE-2014-0134.patch"
)
pkg_setup() {
@@ -81,47 +81,36 @@ pkg_setup() {
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
+ for svc in api cert compute conductor consoleauth network scheduler spicehtml5proxy xvpvncproxy; do
+ newinitd "${FILESDIR}/nova.initd" "nova-${svc}"
+ done
+ use compute && newinitd "${FILESDIR}/nova.initd" "nova-compute"
+ use novncproxy && newinitd "${FILESDIR}/nova.initd" "nova-novncproxy"
- diropts -m 0755
- dodir /var/lib/nova/instances
- fowners nova:nova /var/lib/nova/instances
+ diropts -m 0750 -o nova -g nova
+ dodir /var/log/nova /var/lib/nova/instances
- keepdir /etc/nova
insinto /etc/nova
+ insopts -m 0640 -o nova -g 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"
+ #rootwrap filters
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"
+ cp -R "${S}/nova/CA" "${D}/usr/$(get_libdir)/python2.7/site-packages/nova/" || die "installing CA files failed"
#add sudoers definitions for user nova
insinto /etc/sudoers.d/
+ insopts -m 0600 -o root -g root
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 5326994f18e9..71685f993c32 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-2014 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.12 2014/04/01 03:46:51 prometheanfire Exp $
+# $Header: /var/cvsroot/gentoo-x86/sys-cluster/nova/nova-2013.2.9999.ebuild,v 1.13 2014/04/06 06:32:19 prometheanfire Exp $
EAPI=5
PYTHON_COMPAT=( python2_7 )
@@ -108,7 +108,7 @@ python_install() {
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"
+ cp -R "${S}/nova/CA" "${D}/usr/$(get_libdir)/python2.7/site-packages/nova/" || die "installing CA files failed"
#add sudoers definitions for user nova
insinto /etc/sudoers.d/