From 8d4333a0c81dc278b773e70936b1367d30f4d5bf Mon Sep 17 00:00:00 2001 From: Pádraig Brady Date: May 29 2012 12:26:13 +0000 Subject: Update to folsom milestone 1 --- diff --git a/.gitignore b/.gitignore index a36abb7..962688d 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ /nova-2012.1~e4.tar.gz /nova-2012.1~rc1.tar.gz /nova-2012.1.tar.gz +/nova-2012.2~f1.tar.gz diff --git a/0001-Ensure-we-don-t-access-the-net-when-building-docs.patch b/0001-Ensure-we-don-t-access-the-net-when-building-docs.patch new file mode 100644 index 0000000..e49e0b5 --- /dev/null +++ b/0001-Ensure-we-don-t-access-the-net-when-building-docs.patch @@ -0,0 +1,25 @@ +From b1707ce900149be87ec03f0156b27bbdf9ff05d4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?P=C3=A1draig=20Brady?= +Date: Fri, 6 Jan 2012 12:16:34 +0000 +Subject: [PATCH] Ensure we don't access the net when building docs + +(Note, this has not been sent upstream) + +Change-Id: I9d02fb4053a8106672aded1614a2850e21603eb2 +--- + doc/source/conf.py | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/doc/source/conf.py b/doc/source/conf.py +index 8ced294..7df59cd 100644 +--- a/doc/source/conf.py ++++ b/doc/source/conf.py +@@ -25,7 +25,7 @@ sys.path.insert(0, os.path.abspath('./')) + # Add any Sphinx extension module names here, as strings. They can be extensions + # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. + +-extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx', 'ext.nova_todo', 'sphinx.ext.coverage', 'sphinx.ext.pngmath', 'sphinx.ext.ifconfig','sphinx.ext.graphviz'] ++extensions = ['sphinx.ext.autodoc', 'ext.nova_todo', 'sphinx.ext.coverage', 'sphinx.ext.pngmath', 'sphinx.ext.ifconfig','sphinx.ext.graphviz'] + + # autodoc generation is a bit aggressive and a nuisance when doing heavy text edit cycles. + # execute "export SPHINX_DEBUG=1" in your terminal to disable diff --git a/0001-fix-bug-where-nova-ignores-glance-host-in-imageref.patch b/0001-fix-bug-where-nova-ignores-glance-host-in-imageref.patch deleted file mode 100644 index fe2481e..0000000 --- a/0001-fix-bug-where-nova-ignores-glance-host-in-imageref.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 155c7b2a8f05e75a9b08764bb4f9404c26036f99 Mon Sep 17 00:00:00 2001 -From: Mike Lundy -Date: Wed, 4 Apr 2012 11:38:54 -0700 -Subject: [PATCH] fix bug where nova ignores glance host in imageref - -This is related to bug 883328. - -Change-Id: Iadd1aec8d1bda3bd75bd0ab7f6797b643626db90 ---- - nova/image/glance.py | 8 ++++---- - nova/tests/image/test_glance.py | 3 ++- - 2 files changed, 6 insertions(+), 5 deletions(-) - -diff --git a/nova/image/glance.py b/nova/image/glance.py -index a5f9e68..97a60cb 100644 ---- a/nova/image/glance.py -+++ b/nova/image/glance.py -@@ -111,13 +111,13 @@ def get_glance_client(context, image_href): - - else: - try: -- (image_id, host, port) = _parse_image_ref(image_href) -+ (image_id, glance_host, glance_port) = _parse_image_ref(image_href) -+ glance_client = _create_glance_client(context, -+ glance_host, -+ glance_port) - except ValueError: - raise exception.InvalidImageRef(image_href=image_href) - -- glance_client = _create_glance_client(context, -- glance_host, -- glance_port) - return (glance_client, image_id) - - -diff --git a/nova/tests/image/test_glance.py b/nova/tests/image/test_glance.py -index bc5969a..8fa136a 100644 ---- a/nova/tests/image/test_glance.py -+++ b/nova/tests/image/test_glance.py -@@ -578,6 +578,7 @@ class TestGlanceImageService(test.TestCase): - def test_glance_client_image_ref(self): - fixture = self._make_fixture(name='test image') - image_id = self.service.create(self.context, fixture)['id'] -- image_url = 'http://foo/%s' % image_id -+ image_url = 'http://something-less-likely/%s' % image_id - client, same_id = glance.get_glance_client(self.context, image_url) - self.assertEquals(same_id, image_id) -+ self.assertEquals(client.host, 'something-less-likely') diff --git a/0002-Stop-libvirt-test-from-deleting-instances-dir.patch b/0002-Stop-libvirt-test-from-deleting-instances-dir.patch deleted file mode 100644 index 7889d57..0000000 --- a/0002-Stop-libvirt-test-from-deleting-instances-dir.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 4acfab6a7b368d34295afdace678563e1c3fa058 Mon Sep 17 00:00:00 2001 -From: Vishvananda Ishaya -Date: Thu, 5 Apr 2012 17:00:25 -0700 -Subject: [PATCH] Stop libvirt test from deleting instances dir - - * fixes bug 974293 - -Change-Id: Id41ab20193a70246ad2e3e1cc18edf47059d312d ---- - nova/tests/test_libvirt.py | 37 ++++++++++++------------------------- - 1 files changed, 12 insertions(+), 25 deletions(-) - -diff --git a/nova/tests/test_libvirt.py b/nova/tests/test_libvirt.py -index 6b0f668..4ce91cb 100644 ---- a/nova/tests/test_libvirt.py -+++ b/nova/tests/test_libvirt.py -@@ -2148,25 +2148,8 @@ class LibvirtConnectionTestCase(test.TestCase): - """Test for nova.virt.libvirt.connection.LibvirtConnection.""" - def setUp(self): - super(LibvirtConnectionTestCase, self).setUp() -- - self.libvirtconnection = connection.LibvirtConnection(read_only=True) - -- self.temp_path = os.path.join(flags.FLAGS.instances_path, -- 'instance-00000001/', '') -- try: -- os.makedirs(self.temp_path) -- except Exception: -- print 'testcase init error' -- pass -- -- def tearDown(self): -- super(LibvirtConnectionTestCase, self).tearDown() -- -- try: -- shutil.rmtree(flags.FLAGS.instances_path) -- except Exception: -- pass -- - def _create_instance(self, params=None): - """Create a test instance""" - if not params: -@@ -2374,11 +2357,15 @@ class LibvirtConnectionTestCase(test.TestCase): - self.stubs.Set(self.libvirtconnection, '_create_new_domain', - fake_create_new_domain) - -- ins_ref = self._create_instance() -- libvirt_xml_path = os.path.join(flags.FLAGS.instances_path, -- ins_ref['name'], 'libvirt.xml') -- f = open(libvirt_xml_path, 'w') -- f.close() -- -- ref = self.libvirtconnection.finish_revert_migration(ins_ref, None) -- self.assertTrue(isinstance(ref, eventlet.event.Event)) -+ with utils.tempdir() as tmpdir: -+ self.flags(instances_path=tmpdir) -+ ins_ref = self._create_instance() -+ os.mkdir(os.path.join(tmpdir, ins_ref['name'])) -+ libvirt_xml_path = os.path.join(tmpdir, -+ ins_ref['name'], -+ 'libvirt.xml') -+ f = open(libvirt_xml_path, 'w') -+ f.close() -+ -+ ref = self.libvirtconnection.finish_revert_migration(ins_ref, None) -+ self.assertTrue(isinstance(ref, eventlet.event.Event)) diff --git a/0002-fix-useexisting-deprecation-warnings.patch b/0002-fix-useexisting-deprecation-warnings.patch new file mode 100644 index 0000000..da9f1e0 --- /dev/null +++ b/0002-fix-useexisting-deprecation-warnings.patch @@ -0,0 +1,25 @@ +From 5879d62063e7d699e76cdda2ce2b4ed5c2d9d428 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?P=C3=A1draig=20Brady?= +Date: Tue, 29 May 2012 12:50:03 +0100 +Subject: [PATCH] fix useexisting deprecation warnings + +Fixes deprecation warnings when using sqlalchemy >= 0.7.0 +Fixes bug 941951 + +Change-Id: Iaa57153f99c60c67a14c1dca849188937bdc5dee +--- + .../versions/087_add_uuid_to_bw_usage_cache.py | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/nova/db/sqlalchemy/migrate_repo/versions/087_add_uuid_to_bw_usage_cache.py b/nova/db/sqlalchemy/migrate_repo/versions/087_add_uuid_to_bw_usage_cache.py +index 1c4ac26..c9b9feb 100644 +--- a/nova/db/sqlalchemy/migrate_repo/versions/087_add_uuid_to_bw_usage_cache.py ++++ b/nova/db/sqlalchemy/migrate_repo/versions/087_add_uuid_to_bw_usage_cache.py +@@ -53,6 +53,6 @@ def downgrade(migrate_engine): + Column('last_refreshed', DateTime(timezone=False)), + Column('bw_in', BigInteger()), + Column('bw_out', BigInteger()), +- useexisting=True) ++ extend_existing=True) + + bw_usage_cache.drop_column('uuid') diff --git a/0003-Allow-unprivileged-RADOS-users-to-access-rbd-volumes.patch b/0003-Allow-unprivileged-RADOS-users-to-access-rbd-volumes.patch deleted file mode 100644 index 5fc6c9a..0000000 --- a/0003-Allow-unprivileged-RADOS-users-to-access-rbd-volumes.patch +++ /dev/null @@ -1,169 +0,0 @@ -From d4e96fe0294bd3d6e84a1d0a7e754662b23f8d13 Mon Sep 17 00:00:00 2001 -From: Josh Durgin -Date: Wed, 4 Apr 2012 00:38:59 -0700 -Subject: [PATCH] Allow unprivileged RADOS users to access rbd volumes. - -This makes it possible to access rbd volumes with RADOS users with -restricted privileges. Previously, the admin user was always used. - -This requires libvirt 0.9.8 or higher. - -This is a backport of commit 01f24caba86c987b0109f743979a4e99e8afed11 -from master. - -Fixes bug 975335. - -Change-Id: I3fbb2c03e5f63940c3a42f2d4f8d03ee16b30f7e ---- - .mailmap | 1 + - Authors | 2 +- - nova/tests/test_libvirt.py | 51 +++++++++++++++++++++++++++++++++++++++++++ - nova/virt/libvirt/volume.py | 24 ++++++++++++++++---- - nova/volume/driver.py | 15 +++++++++++- - 5 files changed, 85 insertions(+), 8 deletions(-) - -diff --git a/.mailmap b/.mailmap -index 4f9e4e6..7fd6cb6 100644 -diff --git a/Authors b/Authors -index e1a947c..a229313 100644 ---- a/Authors -+++ b/Authors -@@ -98,7 +98,7 @@ Jonathan Bryce - Jordan Rinke - Joseph Suh - Joseph W. Breu --Josh Durgin -+Josh Durgin - Josh Kearney - Josh Kleinpeter - Joshua Harlow -diff --git a/nova/tests/test_libvirt.py b/nova/tests/test_libvirt.py -index 4ce91cb..ad4bb06 100644 ---- a/nova/tests/test_libvirt.py -+++ b/nova/tests/test_libvirt.py -@@ -240,6 +240,57 @@ class LibvirtVolumeTestCase(test.TestCase): - self.assertEqual(tree.find('./source').get('protocol'), 'rbd') - rbd_name = '%s/%s' % (FLAGS.rbd_pool, name) - self.assertEqual(tree.find('./source').get('name'), rbd_name) -+ self.assertEqual(tree.find('./source/auth'), None) -+ libvirt_driver.disconnect_volume(connection_info, mount_device) -+ connection_info = vol_driver.terminate_connection(vol, self.connr) -+ -+ def test_libvirt_rbd_driver_auth_enabled(self): -+ vol_driver = volume_driver.RBDDriver() -+ libvirt_driver = volume.LibvirtNetVolumeDriver(self.fake_conn) -+ name = 'volume-00000001' -+ vol = {'id': 1, 'name': name} -+ connection_info = vol_driver.initialize_connection(vol, self.connr) -+ uuid = '875a8070-d0b9-4949-8b31-104d125c9a64' -+ user = 'foo' -+ secret_type = 'ceph' -+ connection_info['data']['auth_enabled'] = True -+ connection_info['data']['auth_username'] = user -+ connection_info['data']['secret_type'] = secret_type -+ connection_info['data']['secret_uuid'] = uuid -+ mount_device = "vde" -+ xml = libvirt_driver.connect_volume(connection_info, mount_device) -+ tree = ElementTree.fromstring(xml) -+ self.assertEqual(tree.get('type'), 'network') -+ self.assertEqual(tree.find('./source').get('protocol'), 'rbd') -+ rbd_name = '%s/%s' % (FLAGS.rbd_pool, name) -+ self.assertEqual(tree.find('./source').get('name'), rbd_name) -+ self.assertEqual(tree.find('./auth').get('username'), user) -+ self.assertEqual(tree.find('./auth/secret').get('type'), secret_type) -+ self.assertEqual(tree.find('./auth/secret').get('uuid'), uuid) -+ libvirt_driver.disconnect_volume(connection_info, mount_device) -+ connection_info = vol_driver.terminate_connection(vol, self.connr) -+ -+ def test_libvirt_rbd_driver_auth_disabled(self): -+ vol_driver = volume_driver.RBDDriver() -+ libvirt_driver = volume.LibvirtNetVolumeDriver(self.fake_conn) -+ name = 'volume-00000001' -+ vol = {'id': 1, 'name': name} -+ connection_info = vol_driver.initialize_connection(vol, self.connr) -+ uuid = '875a8070-d0b9-4949-8b31-104d125c9a64' -+ user = 'foo' -+ secret_type = 'ceph' -+ connection_info['data']['auth_enabled'] = False -+ connection_info['data']['auth_username'] = user -+ connection_info['data']['secret_type'] = secret_type -+ connection_info['data']['secret_uuid'] = uuid -+ mount_device = "vde" -+ xml = libvirt_driver.connect_volume(connection_info, mount_device) -+ tree = ElementTree.fromstring(xml) -+ self.assertEqual(tree.get('type'), 'network') -+ self.assertEqual(tree.find('./source').get('protocol'), 'rbd') -+ rbd_name = '%s/%s' % (FLAGS.rbd_pool, name) -+ self.assertEqual(tree.find('./source').get('name'), rbd_name) -+ self.assertEqual(tree.find('./auth'), None) - libvirt_driver.disconnect_volume(connection_info, mount_device) - connection_info = vol_driver.terminate_connection(vol, self.connr) - -diff --git a/nova/virt/libvirt/volume.py b/nova/virt/libvirt/volume.py -index 784867e..10338c2 100644 ---- a/nova/virt/libvirt/volume.py -+++ b/nova/virt/libvirt/volume.py -@@ -76,11 +76,25 @@ class LibvirtNetVolumeDriver(LibvirtVolumeDriver): - driver = self._pick_volume_driver() - protocol = connection_info['driver_volume_type'] - name = connection_info['data']['name'] -- xml = """ -- -- -- -- """ % (driver, protocol, name, mount_device) -+ if connection_info['data'].get('auth_enabled'): -+ username = connection_info['data']['auth_username'] -+ secret_type = connection_info['data']['secret_type'] -+ secret_uuid = connection_info['data']['secret_uuid'] -+ xml = """ -+ -+ -+ -+ -+ -+ -+ """ % (driver, protocol, name, username, -+ secret_type, secret_uuid, mount_device) -+ else: -+ xml = """ -+ -+ -+ -+ """ % (driver, protocol, name, mount_device) - return xml - - -diff --git a/nova/volume/driver.py b/nova/volume/driver.py -index ffdd1f5..8b316be 100644 ---- a/nova/volume/driver.py -+++ b/nova/volume/driver.py -@@ -56,7 +56,14 @@ volume_opts = [ - help='The port that the iSCSI daemon is listening on'), - cfg.StrOpt('rbd_pool', - default='rbd', -- help='the rbd pool in which volumes are stored'), -+ help='the RADOS pool in which rbd volumes are stored'), -+ cfg.StrOpt('rbd_user', -+ default=None, -+ help='the RADOS client name for accessing rbd volumes'), -+ cfg.StrOpt('rbd_secret_uuid', -+ default=None, -+ help='the libvirt uuid of the secret for the rbd_user' -+ 'volumes'), - ] - - FLAGS = flags.FLAGS -@@ -546,7 +553,11 @@ class RBDDriver(VolumeDriver): - return { - 'driver_volume_type': 'rbd', - 'data': { -- 'name': '%s/%s' % (FLAGS.rbd_pool, volume['name']) -+ 'name': '%s/%s' % (FLAGS.rbd_pool, volume['name']), -+ 'auth_enabled': FLAGS.rbd_secret_uuid is not None, -+ 'auth_username': FLAGS.rbd_user, -+ 'secret_type': 'ceph', -+ 'secret_uuid': FLAGS.rbd_secret_uuid, - } - } - diff --git a/0004-Fixed-bug-962840-added-a-test-case.patch b/0004-Fixed-bug-962840-added-a-test-case.patch deleted file mode 100644 index 6d3cf1b..0000000 --- a/0004-Fixed-bug-962840-added-a-test-case.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 3b14c746910abf95e8136e409085873fd6ac970d Mon Sep 17 00:00:00 2001 -From: Yun Mao -Date: Tue, 3 Apr 2012 11:17:50 -0400 -Subject: [PATCH] Fixed bug 962840, added a test case. - -eventlet.tpool.Proxy doesn't work with old-style class in __str__() -or __repr__() calls. See bug #962840 for details. -We perform a monkey patch to replace those two instance methods. - -Change-Id: Ia51bbd3e71cad7df45da5b3b27eef70f9d9e9002 ---- - nova/tests/test_libvirt.py | 18 ++++++++++++++++++ - nova/virt/libvirt/connection.py | 18 ++++++++++++++++++ - 2 files changed, 36 insertions(+), 0 deletions(-) - -diff --git a/nova/tests/test_libvirt.py b/nova/tests/test_libvirt.py -index ad4bb06..cdc9121 100644 ---- a/nova/tests/test_libvirt.py -+++ b/nova/tests/test_libvirt.py -@@ -2420,3 +2420,21 @@ class LibvirtConnectionTestCase(test.TestCase): - - ref = self.libvirtconnection.finish_revert_migration(ins_ref, None) - self.assertTrue(isinstance(ref, eventlet.event.Event)) -+ -+ -+class LibvirtNonblockingTestCase(test.TestCase): -+ """Test libvirt_nonblocking option""" -+ -+ def setUp(self): -+ super(LibvirtNonblockingTestCase, self).setUp() -+ self.flags(libvirt_nonblocking=True, libvirt_uri="test:///default") -+ -+ def tearDown(self): -+ super(LibvirtNonblockingTestCase, self).tearDown() -+ -+ @test.skip_if(missing_libvirt(), "Test requires libvirt") -+ def test_connection_to_primitive(self): -+ """Test bug 962840""" -+ import nova.virt.libvirt.connection -+ connection = nova.virt.libvirt.connection.get_connection('') -+ utils.to_primitive(connection._conn, convert_instances=True) -diff --git a/nova/virt/libvirt/connection.py b/nova/virt/libvirt/connection.py -index 5379eac..888be92 100644 ---- a/nova/virt/libvirt/connection.py -+++ b/nova/virt/libvirt/connection.py -@@ -170,6 +170,24 @@ flags.DECLARE('live_migration_retry_count', 'nova.compute.manager') - flags.DECLARE('vncserver_proxyclient_address', 'nova.vnc') - - -+def patch_tpool_proxy(): -+ """eventlet.tpool.Proxy doesn't work with old-style class in __str__() -+ or __repr__() calls. See bug #962840 for details. -+ We perform a monkey patch to replace those two instance methods. -+ """ -+ def str_method(self): -+ return str(self._obj) -+ -+ def repr_method(self): -+ return repr(self._obj) -+ -+ tpool.Proxy.__str__ = str_method -+ tpool.Proxy.__repr__ = repr_method -+ -+ -+patch_tpool_proxy() -+ -+ - def get_connection(read_only): - # These are loaded late so that there's no need to install these - # libraries when not using libvirt. diff --git a/0005-Fix-errors-in-os-networks-extension.patch b/0005-Fix-errors-in-os-networks-extension.patch deleted file mode 100644 index cfd06eb..0000000 --- a/0005-Fix-errors-in-os-networks-extension.patch +++ /dev/null @@ -1,306 +0,0 @@ -From 84db03cf67e8708cfaeac29508d805115c582cc6 Mon Sep 17 00:00:00 2001 -From: Vishvananda Ishaya -Date: Mon, 9 Apr 2012 22:11:10 -0700 -Subject: [PATCH] Fix errors in os-networks extension - - * Makes sure the uuid is returned as id if it exists - * Simplifies db get for manager.get_networks - * Removes direct db access from manager which was breaking test - * Updates tests to verify the new logic - * Makes sure Remote NotFounds are turned into 404s - (The RemoteError blocks can be removed once - https://review.openstack.org/5749 lands) - * Fixes bug 977712 - * Fixes bug 977723 - -Change-Id: I6aa815960782c7ae5165aeebd83bdaaa62c19b04 ---- - nova/api/openstack/compute/contrib/networks.py | 21 +++++++++++- - nova/network/manager.py | 17 +++------ - .../api/openstack/compute/contrib/test_networks.py | 34 +++++++++++++------- - nova/tests/fake_network.py | 3 ++ - nova/tests/network/test_manager.py | 28 ++++++++-------- - 5 files changed, 65 insertions(+), 38 deletions(-) - -diff --git a/nova/api/openstack/compute/contrib/networks.py b/nova/api/openstack/compute/contrib/networks.py -index 32a4af5..ac99c8c 100644 ---- a/nova/api/openstack/compute/contrib/networks.py -+++ b/nova/api/openstack/compute/contrib/networks.py -@@ -24,6 +24,7 @@ from nova import exception - from nova import flags - from nova import log as logging - import nova.network.api -+from nova.rpc import common - - - FLAGS = flags.FLAGS -@@ -40,7 +41,10 @@ def network_dict(network): - 'netmask', 'injected', 'cidr', 'vpn_public_address', - 'multi_host', 'dns1', 'host', 'gateway_v6', 'netmask_v6', - 'created_at') -- return dict((field, network[field]) for field in fields) -+ result = dict((field, network[field]) for field in fields) -+ if 'uuid' in network: -+ result['id'] = network['uuid'] -+ return result - else: - return {} - -@@ -72,6 +76,11 @@ class NetworkController(object): - self.network_api.disassociate(context, network_id) - except exception.NetworkNotFound: - raise exc.HTTPNotFound(_("Network not found")) -+ except common.RemoteError as ex: -+ if ex.exc_type in ["NetworkNotFound", "NetworkNotFoundForUUID"]: -+ raise exc.HTTPNotFound(_("Network not found")) -+ else: -+ raise - return exc.HTTPAccepted() - - def index(self, req): -@@ -89,6 +98,11 @@ class NetworkController(object): - network = self.network_api.get(context, id) - except exception.NetworkNotFound: - raise exc.HTTPNotFound(_("Network not found")) -+ except common.RemoteError as ex: -+ if ex.exc_type in ["NetworkNotFound", "NetworkNotFoundForUUID"]: -+ raise exc.HTTPNotFound(_("Network not found")) -+ else: -+ raise - return {'network': network_dict(network)} - - def delete(self, req, id): -@@ -99,6 +113,11 @@ class NetworkController(object): - self.network_api.delete(context, id) - except exception.NetworkNotFound: - raise exc.HTTPNotFound(_("Network not found")) -+ except common.RemoteError as ex: -+ if ex.exc_type in ["NetworkNotFound", "NetworkNotFoundForUUID"]: -+ raise exc.HTTPNotFound(_("Network not found")) -+ else: -+ raise - return exc.HTTPAccepted() - - def create(self, req, id, body=None): -diff --git a/nova/network/manager.py b/nova/network/manager.py -index 8b89e26..9ecc6e2 100644 ---- a/nova/network/manager.py -+++ b/nova/network/manager.py -@@ -55,7 +55,6 @@ import netaddr - - from nova.compute import api as compute_api - from nova import context --from nova import db - from nova import exception - from nova import flags - from nova import ipv6 -@@ -1414,15 +1413,16 @@ class NetworkManager(manager.SchedulerDependentManager): - require_disassociated=True): - - # Prefer uuid but we'll also take cidr for backwards compatibility -+ elevated = context.elevated() - if uuid: -- network = db.network_get_by_uuid(context.elevated(), uuid) -+ network = self.db.network_get_by_uuid(elevated, uuid) - elif fixed_range: -- network = db.network_get_by_cidr(context.elevated(), fixed_range) -+ network = self.db.network_get_by_cidr(elevated, fixed_range) - - if require_disassociated and network.project_id is not None: - raise ValueError(_('Network must be disassociated from project %s' - ' before delete') % network.project_id) -- db.network_delete_safe(context, network.id) -+ self.db.network_delete_safe(context, network.id) - - @property - def _bottom_reserved_ips(self): # pylint: disable=R0201 -@@ -1559,12 +1559,7 @@ class NetworkManager(manager.SchedulerDependentManager): - - @wrap_check_policy - def get_network(self, context, network_uuid): -- networks = self._get_networks_by_uuids(context, [network_uuid]) -- try: -- network = networks[0] -- except (IndexError, TypeError): -- raise exception.NetworkNotFound(network_id=network_uuid) -- -+ network = self.db.network_get_by_uuid(context.elevated(), network_uuid) - return dict(network.iteritems()) - - @wrap_check_policy -@@ -1848,7 +1843,7 @@ class VlanManager(RPCAllocateFixedIP, FloatingIP, NetworkManager): - net = {} - address = FLAGS.vpn_ip - net['vpn_public_address'] = address -- network = db.network_update(context, network['id'], net) -+ network = self.db.network_update(context, network['id'], net) - else: - address = network['vpn_public_address'] - network['dhcp_server'] = self._get_dhcp_ip(context, network) -diff --git a/nova/tests/api/openstack/compute/contrib/test_networks.py b/nova/tests/api/openstack/compute/contrib/test_networks.py -index 78c8ad3..c0580c6 100644 ---- a/nova/tests/api/openstack/compute/contrib/test_networks.py -+++ b/nova/tests/api/openstack/compute/contrib/test_networks.py -@@ -20,6 +20,7 @@ import webob - - from nova.api.openstack.compute.contrib import networks - from nova import exception -+from nova.rpc import common - from nova import test - from nova.tests.api.openstack import fakes - -@@ -28,7 +29,8 @@ FAKE_NETWORKS = [ - { - 'bridge': 'br100', 'vpn_public_port': 1000, - 'dhcp_start': '10.0.0.3', 'bridge_interface': 'eth0', -- 'updated_at': '2011-08-16 09:26:13.048257', 'id': 1, -+ 'updated_at': '2011-08-16 09:26:13.048257', -+ 'id': 1, 'uuid': '20c8acc0-f747-4d71-a389-46d078ebf047', - 'cidr_v6': None, 'deleted_at': None, - 'gateway': '10.0.0.1', 'label': 'mynet_0', - 'project_id': '1234', -@@ -68,21 +70,21 @@ class FakeNetworkAPI(object): - if network['id'] == network_id: - del self.networks[0] - return True -- raise exception.NetworkNotFound() -+ raise exception.NetworkNotFoundForUUID() - - #NOTE(bcwaldon): this does nothing other than check for existance - def disassociate(self, context, network_id): - for i, network in enumerate(self.networks): -- if network['id'] == network_id: -+ if network.get('uuid') == network_id: - return True -- raise exception.NetworkNotFound() -+ raise common.RemoteError(type(exception.NetworkNotFound()).__name__) - - def get_all(self, context): - return self.networks - - def get(self, context, network_id): - for network in self.networks: -- if network['id'] == network_id: -+ if network.get('uuid') == network_id: - return network - raise exception.NetworkNotFound() - -@@ -99,11 +101,15 @@ class NetworksTest(test.TestCase): - def test_network_list_all(self): - req = fakes.HTTPRequest.blank('/v2/1234/os-networks') - res_dict = self.controller.index(req) -- self.assertEquals(res_dict, {'networks': FAKE_NETWORKS}) -+ expected = copy.deepcopy(FAKE_NETWORKS) -+ expected[0]['id'] = expected[0]['uuid'] -+ del expected[0]['uuid'] -+ self.assertEquals(res_dict, {'networks': expected}) - - def test_network_disassociate(self): -- req = fakes.HTTPRequest.blank('/v2/1234/os-networks/1/action') -- res = self.controller.action(req, 1, {'disassociate': None}) -+ uuid = FAKE_NETWORKS[0]['uuid'] -+ req = fakes.HTTPRequest.blank('/v2/1234/os-networks/%s/action' % uuid) -+ res = self.controller.action(req, uuid, {'disassociate': None}) - self.assertEqual(res.status_int, 202) - - def test_network_disassociate_not_found(self): -@@ -113,9 +119,12 @@ class NetworksTest(test.TestCase): - req, 100, {'disassociate': None}) - - def test_network_get(self): -- req = fakes.HTTPRequest.blank('/v2/1234/os-networks/1') -- res_dict = self.controller.show(req, 1) -- expected = {'network': FAKE_NETWORKS[0]} -+ uuid = FAKE_NETWORKS[0]['uuid'] -+ req = fakes.HTTPRequest.blank('/v2/1234/os-networks/%s' % uuid) -+ res_dict = self.controller.show(req, uuid) -+ expected = {'network': copy.deepcopy(FAKE_NETWORKS[0])} -+ expected['network']['id'] = expected['network']['uuid'] -+ del expected['network']['uuid'] - self.assertEqual(res_dict, expected) - - def test_network_get_not_found(self): -@@ -124,7 +133,8 @@ class NetworksTest(test.TestCase): - self.controller.show, req, 100) - - def test_network_delete(self): -- req = fakes.HTTPRequest.blank('/v2/1234/os-networks/1') -+ uuid = FAKE_NETWORKS[0]['uuid'] -+ req = fakes.HTTPRequest.blank('/v2/1234/os-networks/%s' % uuid) - res = self.controller.delete(req, 1) - self.assertEqual(res.status_int, 202) - -diff --git a/nova/tests/fake_network.py b/nova/tests/fake_network.py -index 9d0a5b9..03ad472 100644 ---- a/nova/tests/fake_network.py -+++ b/nova/tests/fake_network.py -@@ -120,6 +120,9 @@ class FakeNetworkManager(network_manager.NetworkManager): - def network_get(self, context, network_id): - return {'cidr_v6': '2001:db8:69:%x::/64' % network_id} - -+ def network_get_by_uuid(self, context, network_uuid): -+ raise exception.NetworkNotFoundForUUID() -+ - def network_get_all(self, context): - raise exception.NoNetworksFound() - -diff --git a/nova/tests/network/test_manager.py b/nova/tests/network/test_manager.py -index 50d49b1..3b33296 100644 ---- a/nova/tests/network/test_manager.py -+++ b/nova/tests/network/test_manager.py -@@ -1266,10 +1266,9 @@ class CommonNetworkTestCase(test.TestCase): - def test_get_network(self): - manager = fake_network.FakeNetworkManager() - fake_context = context.RequestContext('user', 'project') -- self.mox.StubOutWithMock(manager.db, 'network_get_all_by_uuids') -- manager.db.network_get_all_by_uuids( -- mox.IgnoreArg(), -- mox.IgnoreArg()).AndReturn(networks) -+ self.mox.StubOutWithMock(manager.db, 'network_get_by_uuid') -+ manager.db.network_get_by_uuid(mox.IgnoreArg(), -+ mox.IgnoreArg()).AndReturn(networks[0]) - self.mox.ReplayAll() - uuid = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' - network = manager.get_network(fake_context, uuid) -@@ -1278,9 +1277,10 @@ class CommonNetworkTestCase(test.TestCase): - def test_get_network_not_found(self): - manager = fake_network.FakeNetworkManager() - fake_context = context.RequestContext('user', 'project') -- self.mox.StubOutWithMock(manager.db, 'network_get_all_by_uuids') -- manager.db.network_get_all_by_uuids(mox.IgnoreArg(), -- mox.IgnoreArg()).AndReturn([]) -+ self.mox.StubOutWithMock(manager.db, 'network_get_by_uuid') -+ manager.db.network_get_by_uuid( -+ mox.IgnoreArg(), -+ mox.IgnoreArg()).AndRaise(exception.NetworkNotFoundForUUID) - self.mox.ReplayAll() - uuid = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee' - self.assertRaises(exception.NetworkNotFound, -@@ -1302,10 +1302,9 @@ class CommonNetworkTestCase(test.TestCase): - def test_disassociate_network(self): - manager = fake_network.FakeNetworkManager() - fake_context = context.RequestContext('user', 'project') -- self.mox.StubOutWithMock(manager.db, 'network_get_all_by_uuids') -- manager.db.network_get_all_by_uuids( -- mox.IgnoreArg(), -- mox.IgnoreArg()).AndReturn(networks) -+ self.mox.StubOutWithMock(manager.db, 'network_get_by_uuid') -+ manager.db.network_get_by_uuid(mox.IgnoreArg(), -+ mox.IgnoreArg()).AndReturn(networks[0]) - self.mox.ReplayAll() - uuid = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' - manager.disassociate_network(fake_context, uuid) -@@ -1313,9 +1312,10 @@ class CommonNetworkTestCase(test.TestCase): - def test_disassociate_network_not_found(self): - manager = fake_network.FakeNetworkManager() - fake_context = context.RequestContext('user', 'project') -- self.mox.StubOutWithMock(manager.db, 'network_get_all_by_uuids') -- manager.db.network_get_all_by_uuids(mox.IgnoreArg(), -- mox.IgnoreArg()).AndReturn([]) -+ self.mox.StubOutWithMock(manager.db, 'network_get_by_uuid') -+ manager.db.network_get_by_uuid( -+ mox.IgnoreArg(), -+ mox.IgnoreArg()).AndRaise(exception.NetworkNotFoundForUUID) - self.mox.ReplayAll() - uuid = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee' - self.assertRaises(exception.NetworkNotFound, diff --git a/0006-Create-compute.api.BaseAPI-for-compute-APIs-to-use.patch b/0006-Create-compute.api.BaseAPI-for-compute-APIs-to-use.patch deleted file mode 100644 index 220241d..0000000 --- a/0006-Create-compute.api.BaseAPI-for-compute-APIs-to-use.patch +++ /dev/null @@ -1,146 +0,0 @@ -From d0b32e693eadf6fdc9e885dbe09656a69d5e3662 Mon Sep 17 00:00:00 2001 -From: Chris Behrens -Date: Mon, 9 Apr 2012 19:23:03 +0000 -Subject: [PATCH] Create compute.api.BaseAPI for compute APIs to use - -Fixes bug 960226 where compute.api.HostAPI called non-existent methods - -Regression was introduced here: -https://review.openstack.org/#change,5252 - -Added tests for HostAPI - -Change-Id: Id17927bc608ff638ea9b0b5509f0f0bb14503f85 ---- - nova/compute/api.py | 36 ++++++++++++++++++-------------- - nova/tests/test_compute.py | 48 +++++++++++++++++++++++++++++++++++++++++++- - 2 files changed, 67 insertions(+), 17 deletions(-) - -diff --git a/nova/compute/api.py b/nova/compute/api.py -index 6edfefd..92adea1 100644 ---- a/nova/compute/api.py -+++ b/nova/compute/api.py -@@ -106,17 +106,10 @@ def check_policy(context, action, target): - nova.policy.enforce(context, _action, target) - - --class API(base.Base): -- """API for interacting with the compute manager.""" -- -- def __init__(self, image_service=None, network_api=None, volume_api=None, -- **kwargs): -- self.image_service = (image_service or -- nova.image.get_default_image_service()) -- -- self.network_api = network_api or network.API() -- self.volume_api = volume_api or volume.API() -- super(API, self).__init__(**kwargs) -+class BaseAPI(base.Base): -+ """Base API class.""" -+ def __init__(self, **kwargs): -+ super(BaseAPI, self).__init__(**kwargs) - - def _cast_or_call_compute_message(self, rpc_method, compute_method, - context, instance=None, host=None, params=None): -@@ -157,10 +150,24 @@ class API(base.Base): - """Generic handler for RPC calls to compute.""" - return self._cast_or_call_compute_message(rpc.call, *args, **kwargs) - -- def _cast_scheduler_message(self, context, args): -+ @staticmethod -+ def _cast_scheduler_message(context, args): - """Generic handler for RPC calls to the scheduler.""" - rpc.cast(context, FLAGS.scheduler_topic, args) - -+ -+class API(BaseAPI): -+ """API for interacting with the compute manager.""" -+ -+ def __init__(self, image_service=None, network_api=None, volume_api=None, -+ **kwargs): -+ self.image_service = (image_service or -+ nova.image.get_default_image_service()) -+ -+ self.network_api = network_api or network.API() -+ self.volume_api = volume_api or volume.API() -+ super(API, self).__init__(**kwargs) -+ - def _check_injected_file_quota(self, context, injected_files): - """Enforce quota limits on injected files. - -@@ -1677,11 +1684,8 @@ class API(base.Base): - return self.db.instance_fault_get_by_instance_uuids(context, uuids) - - --class HostAPI(base.Base): -+class HostAPI(BaseAPI): - """Sub-set of the Compute Manager API for managing host operations.""" -- def __init__(self, **kwargs): -- super(HostAPI, self).__init__(**kwargs) -- - def set_host_enabled(self, context, host, enabled): - """Sets the specified host's ability to accept new instances.""" - # NOTE(comstud): No instance_uuid argument to this compute manager -diff --git a/nova/tests/test_compute.py b/nova/tests/test_compute.py -index 305282c..2e7e7de 100644 ---- a/nova/tests/test_compute.py -+++ b/nova/tests/test_compute.py -@@ -24,7 +24,6 @@ import sys - import time - - import mox --import webob.exc - - import nova - import nova.common.policy -@@ -3643,3 +3642,50 @@ class ComputePolicyTestCase(BaseTestCase): - self.assertRaises(exception.PolicyNotAuthorized, - self.compute_api.get_instance_faults, - self.context, instances) -+ -+ -+class ComputeHostAPITestCase(BaseTestCase): -+ def setUp(self): -+ super(ComputeHostAPITestCase, self).setUp() -+ self.host_api = compute_api.HostAPI() -+ -+ def _rpc_call_stub(self, call_info): -+ def fake_rpc_call(context, topic, msg): -+ call_info['context'] = context -+ call_info['topic'] = topic -+ call_info['msg'] = msg -+ self.stubs.Set(rpc, 'call', fake_rpc_call) -+ -+ def test_set_host_enabled(self): -+ ctxt = context.RequestContext('fake', 'fake') -+ call_info = {} -+ self._rpc_call_stub(call_info) -+ -+ self.host_api.set_host_enabled(ctxt, 'fake_host', 'fake_enabled') -+ self.assertEqual(call_info['context'], ctxt) -+ self.assertEqual(call_info['topic'], 'compute.fake_host') -+ self.assertEqual(call_info['msg'], -+ {'method': 'set_host_enabled', -+ 'args': {'enabled': 'fake_enabled'}}) -+ -+ def test_host_power_action(self): -+ ctxt = context.RequestContext('fake', 'fake') -+ call_info = {} -+ self._rpc_call_stub(call_info) -+ self.host_api.host_power_action(ctxt, 'fake_host', 'fake_action') -+ self.assertEqual(call_info['context'], ctxt) -+ self.assertEqual(call_info['topic'], 'compute.fake_host') -+ self.assertEqual(call_info['msg'], -+ {'method': 'host_power_action', -+ 'args': {'action': 'fake_action'}}) -+ -+ def test_set_host_maintenance(self): -+ ctxt = context.RequestContext('fake', 'fake') -+ call_info = {} -+ self._rpc_call_stub(call_info) -+ self.host_api.set_host_maintenance(ctxt, 'fake_host', 'fake_mode') -+ self.assertEqual(call_info['context'], ctxt) -+ self.assertEqual(call_info['topic'], 'compute.fake_host') -+ self.assertEqual(call_info['msg'], -+ {'method': 'host_maintenance_mode', -+ 'args': {'host': 'fake_host', 'mode': 'fake_mode'}}) diff --git a/0007-Populate-image-properties-with-project_id-again.patch b/0007-Populate-image-properties-with-project_id-again.patch deleted file mode 100644 index 3b96d35..0000000 --- a/0007-Populate-image-properties-with-project_id-again.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 6e988ed75c5ba507d79818bc24a1bd2f8250ce2b Mon Sep 17 00:00:00 2001 -From: Adam Gandelman -Date: Tue, 10 Apr 2012 16:44:27 -0700 -Subject: [PATCH] Populate image properties with project_id again - -This allows ec2 image publishing to function on Essex for users -who are still using deprecated auth. This isn't targetted toward -master and is proposed to stable/essex for the sake of aiding -users transition to Keystone during upgrades from diablo + -deprecated_auth. - -Fixes bug 977765 - -Change-Id: I809b669e88fe25234569d0c744d14aff6bbd4713 ---- - nova/api/ec2/cloud.py | 6 +++++- - nova/image/s3.py | 3 +++ - 2 files changed, 8 insertions(+), 1 deletions(-) - -diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py -index 8e187d6..88590db 100644 ---- a/nova/api/ec2/cloud.py -+++ b/nova/api/ec2/cloud.py -@@ -1398,7 +1398,11 @@ class CloudController(object): - ramdisk_id = image['properties'].get('ramdisk_id') - if ramdisk_id: - i['ramdiskId'] = ec2utils.image_ec2_id(ramdisk_id, 'ari') -- i['imageOwnerId'] = image.get('owner') -+ -+ if FLAGS.auth_strategy == 'deprecated': -+ i['imageOwnerId'] = image['properties'].get('owner_id') -+ else: -+ i['imageOwnerId'] = image.get('owner') - - img_loc = image['properties'].get('image_location') - if img_loc: -diff --git a/nova/image/s3.py b/nova/image/s3.py -index fdf9555..36cf818 100644 ---- a/nova/image/s3.py -+++ b/nova/image/s3.py -@@ -232,6 +232,9 @@ class S3ImageService(object): - properties = metadata['properties'] - properties['architecture'] = arch - -+ if FLAGS.auth_strategy == 'deprecated': -+ properties['project_id'] = context.project_id -+ - def _translate_dependent_image_id(image_key, image_id): - image_uuid = ec2utils.ec2_id_to_glance_id(context, image_id) - properties[image_key] = image_uuid diff --git a/0008-Use-project_id-in-ec2.cloud._format_image.patch b/0008-Use-project_id-in-ec2.cloud._format_image.patch deleted file mode 100644 index a4846da..0000000 --- a/0008-Use-project_id-in-ec2.cloud._format_image.patch +++ /dev/null @@ -1,28 +0,0 @@ -From b1d11b8d517733c052c524319c9a153fbb495153 Mon Sep 17 00:00:00 2001 -From: Adam Gandelman -Date: Wed, 11 Apr 2012 15:12:51 -0700 -Subject: [PATCH] Use project_id in ec2.cloud._format_image() - -The previous change (2f8250ce2b) reverted an earlier change verbatim -that broke image publication using deprecated auth. As it turns out, -image metadata formatting in EC2 should use project_id with -deprecated_auth, not owner_id as it once was in the past. - -Change-Id: I0e3bad0149577e71a97916398f665566b529a696 ---- - nova/api/ec2/cloud.py | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py -index 88590db..16df626 100644 ---- a/nova/api/ec2/cloud.py -+++ b/nova/api/ec2/cloud.py -@@ -1400,7 +1400,7 @@ class CloudController(object): - i['ramdiskId'] = ec2utils.image_ec2_id(ramdisk_id, 'ari') - - if FLAGS.auth_strategy == 'deprecated': -- i['imageOwnerId'] = image['properties'].get('owner_id') -+ i['imageOwnerId'] = image['properties'].get('project_id') - else: - i['imageOwnerId'] = image.get('owner') - diff --git a/0009-Implement-quotas-for-security-groups.patch b/0009-Implement-quotas-for-security-groups.patch deleted file mode 100644 index 781228f..0000000 --- a/0009-Implement-quotas-for-security-groups.patch +++ /dev/null @@ -1,476 +0,0 @@ -From a67db4586f70ed881d65e80035b2a25be195ce64 Mon Sep 17 00:00:00 2001 -From: Dan Prince -Date: Wed, 11 Apr 2012 21:21:02 -0400 -Subject: [PATCH] Implement quotas for security groups. - -Fixes LP Bug #969545 for Essex. - -Change-Id: I3c6a34b43f0e997b45d5e0f97faadd6720bf7752 ---- - nova/api/ec2/cloud.py | 12 +++++++ - nova/api/openstack/compute/contrib/quotas.py | 2 +- - .../openstack/compute/contrib/security_groups.py | 12 +++++++ - nova/db/api.py | 10 ++++++ - nova/db/sqlalchemy/api.py | 16 +++++++++ - nova/quota.py | 34 ++++++++++++++++++++ - nova/tests/api/ec2/test_cloud.py | 25 ++++++++++++++ - .../api/openstack/compute/contrib/test_quotas.py | 29 ++++++++++++++--- - .../compute/contrib/test_security_groups.py | 31 ++++++++++++++++++ - nova/tests/test_quota.py | 28 ++++++++++++++++ - 10 files changed, 193 insertions(+), 6 deletions(-) - -diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py -index 16df626..9e2a22e 100644 ---- a/nova/api/ec2/cloud.py -+++ b/nova/api/ec2/cloud.py -@@ -42,6 +42,7 @@ from nova.image import s3 - from nova import log as logging - from nova import network - from nova.rpc import common as rpc_common -+from nova import quota - from nova import utils - from nova import volume - -@@ -727,6 +728,13 @@ class CloudController(object): - raise exception.EC2APIError(err % values_for_rule) - postvalues.append(values_for_rule) - -+ allowed = quota.allowed_security_group_rules(context, -+ security_group['id'], -+ 1) -+ if allowed < 1: -+ msg = _("Quota exceeded, too many security group rules.") -+ raise exception.EC2APIError(msg) -+ - rule_ids = [] - for values_for_rule in postvalues: - security_group_rule = db.security_group_rule_create( -@@ -784,6 +792,10 @@ class CloudController(object): - msg = _('group %s already exists') - raise exception.EC2APIError(msg % group_name) - -+ if quota.allowed_security_groups(context, 1) < 1: -+ msg = _("Quota exceeded, too many security groups.") -+ raise exception.EC2APIError(msg) -+ - group = {'user_id': context.user_id, - 'project_id': context.project_id, - 'name': group_name, -diff --git a/nova/api/openstack/compute/contrib/quotas.py b/nova/api/openstack/compute/contrib/quotas.py -index 53e8264..6db3d92 100644 ---- a/nova/api/openstack/compute/contrib/quotas.py -+++ b/nova/api/openstack/compute/contrib/quotas.py -@@ -31,7 +31,7 @@ authorize = extensions.extension_authorizer('compute', 'quotas') - - quota_resources = ['metadata_items', 'injected_file_content_bytes', - 'volumes', 'gigabytes', 'ram', 'floating_ips', 'instances', -- 'injected_files', 'cores'] -+ 'injected_files', 'cores', 'security_groups', 'security_group_rules'] - - - class QuotaTemplate(xmlutil.TemplateBuilder): -diff --git a/nova/api/openstack/compute/contrib/security_groups.py b/nova/api/openstack/compute/contrib/security_groups.py -index 0d85c7b..281cc8c 100644 ---- a/nova/api/openstack/compute/contrib/security_groups.py -+++ b/nova/api/openstack/compute/contrib/security_groups.py -@@ -31,6 +31,7 @@ from nova import db - from nova import exception - from nova import flags - from nova import log as logging -+from nova import quota - from nova import utils - - -@@ -289,6 +290,10 @@ class SecurityGroupController(SecurityGroupControllerBase): - group_name = group_name.strip() - group_description = group_description.strip() - -+ if quota.allowed_security_groups(context, 1) < 1: -+ msg = _("Quota exceeded, too many security groups.") -+ raise exc.HTTPBadRequest(explanation=msg) -+ - LOG.audit(_("Create Security Group %s"), group_name, context=context) - self.compute_api.ensure_default_security_group(context) - if db.security_group_exists(context, context.project_id, group_name): -@@ -376,6 +381,13 @@ class SecurityGroupRulesController(SecurityGroupControllerBase): - msg = _('This rule already exists in group %s') % parent_group_id - raise exc.HTTPBadRequest(explanation=msg) - -+ allowed = quota.allowed_security_group_rules(context, -+ parent_group_id, -+ 1) -+ if allowed < 1: -+ msg = _("Quota exceeded, too many security group rules.") -+ raise exc.HTTPBadRequest(explanation=msg) -+ - security_group_rule = db.security_group_rule_create(context, values) - self.sgh.trigger_security_group_rule_create_refresh( - context, [security_group_rule['id']]) -diff --git a/nova/db/api.py b/nova/db/api.py -index b51e1e1..27f80f6 100644 ---- a/nova/db/api.py -+++ b/nova/db/api.py -@@ -1118,6 +1118,11 @@ def security_group_destroy(context, security_group_id): - return IMPL.security_group_destroy(context, security_group_id) - - -+def security_group_count_by_project(context, project_id): -+ """Count number of security groups in a project.""" -+ return IMPL.security_group_count_by_project(context, project_id) -+ -+ - #################### - - -@@ -1149,6 +1154,11 @@ def security_group_rule_get(context, security_group_rule_id): - return IMPL.security_group_rule_get(context, security_group_rule_id) - - -+def security_group_rule_count_by_group(context, security_group_id): -+ """Count rules in a given security group.""" -+ return IMPL.security_group_rule_count_by_group(context, security_group_id) -+ -+ - ################### - - -diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py -index 69e44cd..f2c3062 100644 ---- a/nova/db/sqlalchemy/api.py -+++ b/nova/db/sqlalchemy/api.py -@@ -2813,6 +2813,13 @@ def security_group_destroy(context, security_group_id): - 'updated_at': literal_column('updated_at')}) - - -+@require_context -+def security_group_count_by_project(context, project_id): -+ authorize_project_context(context, project_id) -+ return model_query(context, models.SecurityGroup, read_deleted="no").\ -+ filter_by(project_id=project_id).\ -+ count() -+ - ################### - - -@@ -2871,6 +2878,14 @@ def security_group_rule_destroy(context, security_group_rule_id): - security_group_rule.delete(session=session) - - -+@require_context -+def security_group_rule_count_by_group(context, security_group_id): -+ return model_query(context, models.SecurityGroupIngressRule, -+ read_deleted="no").\ -+ filter_by(parent_group_id=security_group_id).\ -+ count() -+ -+# - ################### - - -@@ -3018,6 +3033,7 @@ def user_update(context, user_id, values): - user_ref.save(session=session) - - -+# - ################### - - -diff --git a/nova/quota.py b/nova/quota.py -index fc49de0..12dd146 100644 ---- a/nova/quota.py -+++ b/nova/quota.py -@@ -54,6 +54,12 @@ quota_opts = [ - cfg.IntOpt('quota_max_injected_file_path_bytes', - default=255, - help='number of bytes allowed per injected file path'), -+ cfg.IntOpt('quota_security_groups', -+ default=10, -+ help='number of security groups per project'), -+ cfg.IntOpt('quota_security_group_rules', -+ default=20, -+ help='number of security rules per security group'), - ] - - FLAGS = flags.FLAGS -@@ -72,6 +78,8 @@ def _get_default_quotas(): - 'injected_files': FLAGS.quota_max_injected_files, - 'injected_file_content_bytes': - FLAGS.quota_max_injected_file_content_bytes, -+ 'security_groups': FLAGS.quota_security_groups, -+ 'security_group_rules': FLAGS.quota_security_group_rules, - } - # -1 in the quota flags means unlimited - for key in defaults.keys(): -@@ -152,6 +160,32 @@ def allowed_floating_ips(context, requested_floating_ips): - return min(requested_floating_ips, allowed_floating_ips) - - -+def allowed_security_groups(context, requested_security_groups): -+ """Check quota and return min(requested, allowed) security groups.""" -+ project_id = context.project_id -+ context = context.elevated() -+ used_sec_groups = db.security_group_count_by_project(context, project_id) -+ quota = get_project_quotas(context, project_id) -+ allowed_sec_groups = _get_request_allotment(requested_security_groups, -+ used_sec_groups, -+ quota['security_groups']) -+ return min(requested_security_groups, allowed_sec_groups) -+ -+ -+def allowed_security_group_rules(context, security_group_id, -+ requested_rules): -+ """Check quota and return min(requested, allowed) sec group rules.""" -+ project_id = context.project_id -+ context = context.elevated() -+ used_rules = db.security_group_rule_count_by_group(context, -+ security_group_id) -+ quota = get_project_quotas(context, project_id) -+ allowed_rules = _get_request_allotment(requested_rules, -+ used_rules, -+ quota['security_group_rules']) -+ return min(requested_rules, allowed_rules) -+ -+ - def _calculate_simple_quota(context, resource, requested): - """Check quota for resource; return min(requested, allowed).""" - quota = get_project_quotas(context, context.project_id) -diff --git a/nova/tests/api/ec2/test_cloud.py b/nova/tests/api/ec2/test_cloud.py -index 9ddc730..427509c 100644 ---- a/nova/tests/api/ec2/test_cloud.py -+++ b/nova/tests/api/ec2/test_cloud.py -@@ -271,6 +271,18 @@ class CloudTestCase(test.TestCase): - delete = self.cloud.delete_security_group - self.assertTrue(delete(self.context, 'testgrp')) - -+ def test_security_group_quota_limit(self): -+ self.flags(quota_security_groups=10) -+ for i in range(1, 10): -+ name = 'test name %i' % i -+ descript = 'test description %i' % i -+ create = self.cloud.create_security_group -+ result = create(self.context, name, descript) -+ -+ # 11'th group should fail -+ self.assertRaises(exception.EC2APIError, -+ create, self.context, 'foo', 'bar') -+ - def test_delete_security_group_by_id(self): - sec = db.security_group_create(self.context, - {'project_id': self.context.project_id, -@@ -436,6 +448,19 @@ class CloudTestCase(test.TestCase): - self.assertRaises(exception.EC2APIError, authz, self.context, - group_name=sec['name'], **kwargs) - -+ def test_security_group_ingress_quota_limit(self): -+ self.flags(quota_security_group_rules=20) -+ kwargs = {'project_id': self.context.project_id, 'name': 'test'} -+ sec_group = db.security_group_create(self.context, kwargs) -+ authz = self.cloud.authorize_security_group_ingress -+ for i in range(100, 120): -+ kwargs = {'to_port': i, 'from_port': i, 'ip_protocol': 'tcp'} -+ authz(self.context, group_id=sec_group['id'], **kwargs) -+ -+ kwargs = {'to_port': 121, 'from_port': 121, 'ip_protocol': 'tcp'} -+ self.assertRaises(exception.EC2APIError, authz, self.context, -+ group_id=sec_group['id'], **kwargs) -+ - def _test_authorize_security_group_no_ports_with_source_group(self, proto): - kwargs = {'project_id': self.context.project_id, 'name': 'test'} - sec = db.security_group_create(self.context, kwargs) -diff --git a/nova/tests/api/openstack/compute/contrib/test_quotas.py b/nova/tests/api/openstack/compute/contrib/test_quotas.py -index 9808717..8f7084a 100644 ---- a/nova/tests/api/openstack/compute/contrib/test_quotas.py -+++ b/nova/tests/api/openstack/compute/contrib/test_quotas.py -@@ -28,7 +28,8 @@ def quota_set(id): - return {'quota_set': {'id': id, 'metadata_items': 128, 'volumes': 10, - 'gigabytes': 1000, 'ram': 51200, 'floating_ips': 10, - 'instances': 10, 'injected_files': 5, 'cores': 20, -- 'injected_file_content_bytes': 10240}} -+ 'injected_file_content_bytes': 10240, -+ 'security_groups': 10, 'security_group_rules': 20}} - - - def quota_set_list(): -@@ -52,7 +53,10 @@ class QuotaSetsTest(test.TestCase): - 'metadata_items': 128, - 'gigabytes': 1000, - 'injected_files': 5, -- 'injected_file_content_bytes': 10240} -+ 'injected_file_content_bytes': 10240, -+ 'security_groups': 10, -+ 'security_group_rules': 20, -+ } - - quota_set = quotas.QuotaSetsController()._format_quota_set('1234', - raw_quota_set) -@@ -68,6 +72,8 @@ class QuotaSetsTest(test.TestCase): - self.assertEqual(qs['metadata_items'], 128) - self.assertEqual(qs['injected_files'], 5) - self.assertEqual(qs['injected_file_content_bytes'], 10240) -+ self.assertEqual(qs['security_groups'], 10) -+ self.assertEqual(qs['security_group_rules'], 20) - - def test_quotas_defaults(self): - uri = '/v2/fake_tenant/os-quota-sets/fake_tenant/defaults' -@@ -85,7 +91,10 @@ class QuotaSetsTest(test.TestCase): - 'floating_ips': 10, - 'metadata_items': 128, - 'injected_files': 5, -- 'injected_file_content_bytes': 10240}} -+ 'injected_file_content_bytes': 10240, -+ 'security_groups': 10, -+ 'security_group_rules': 20, -+ }} - - self.assertEqual(res_dict, expected) - -@@ -106,7 +115,9 @@ class QuotaSetsTest(test.TestCase): - 'ram': 51200, 'volumes': 10, - 'gigabytes': 1000, 'floating_ips': 10, - 'metadata_items': 128, 'injected_files': 5, -- 'injected_file_content_bytes': 10240}} -+ 'injected_file_content_bytes': 10240, -+ 'security_groups': 10, -+ 'security_group_rules': 20}} - - req = fakes.HTTPRequest.blank('/v2/fake4/os-quota-sets/update_me', - use_admin_context=True) -@@ -119,7 +130,9 @@ class QuotaSetsTest(test.TestCase): - 'ram': 51200, 'volumes': 10, - 'gigabytes': 1000, 'floating_ips': 10, - 'metadata_items': 128, 'injected_files': 5, -- 'injected_file_content_bytes': 10240}} -+ 'injected_file_content_bytes': 10240, -+ 'security_groups': 10, -+ 'security_group_rules': 20}} - - req = fakes.HTTPRequest.blank('/v2/fake4/os-quota-sets/update_me') - self.assertRaises(webob.exc.HTTPForbidden, self.controller.update, -@@ -143,6 +156,8 @@ class QuotaXMLSerializerTest(test.TestCase): - floating_ips=60, - instances=70, - injected_files=80, -+ security_groups=10, -+ security_group_rules=20, - cores=90)) - text = self.serializer.serialize(exemplar) - -@@ -166,6 +181,8 @@ class QuotaXMLSerializerTest(test.TestCase): - floating_ips='60', - instances='70', - injected_files='80', -+ security_groups='10', -+ security_group_rules='20', - cores='90')) - intext = ("\n" - '' -@@ -178,6 +195,8 @@ class QuotaXMLSerializerTest(test.TestCase): - '60' - '70' - '80' -+ '10' -+ '20' - '90' - '') - -diff --git a/nova/tests/api/openstack/compute/contrib/test_security_groups.py b/nova/tests/api/openstack/compute/contrib/test_security_groups.py -index 0cf66ec..8cc4cc6 100644 ---- a/nova/tests/api/openstack/compute/contrib/test_security_groups.py -+++ b/nova/tests/api/openstack/compute/contrib/test_security_groups.py -@@ -25,12 +25,15 @@ from nova.api.openstack.compute.contrib import security_groups - from nova.api.openstack import wsgi - import nova.db - from nova import exception -+from nova import flags - from nova import test - from nova.tests.api.openstack import fakes - - - FAKE_UUID = 'a47ae74e-ab08-447f-8eee-ffd43fc46c16' - -+FLAGS = flags.FLAGS -+ - - class AttrDict(dict): - def __getattr__(self, k): -@@ -219,6 +222,18 @@ class TestSecurityGroups(test.TestCase): - self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create, - req, {'security_group': sg}) - -+ def test_create_security_group_quota_limit(self): -+ req = fakes.HTTPRequest.blank('/v2/fake/os-security-groups') -+ for num in range(1, FLAGS.quota_security_groups): -+ name = 'test%s' % num -+ sg = security_group_template(name=name) -+ res_dict = self.controller.create(req, {'security_group': sg}) -+ self.assertEqual(res_dict['security_group']['name'], name) -+ -+ sg = security_group_template() -+ self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create, -+ req, {'security_group': sg}) -+ - def test_get_security_group_list(self): - groups = [] - for i, name in enumerate(['default', 'test']): -@@ -894,6 +909,22 @@ class TestSecurityGroupRules(test.TestCase): - self.assertRaises(webob.exc.HTTPNotFound, self.controller.delete, - req, '22222222222222') - -+ def test_create_rule_quota_limit(self): -+ req = fakes.HTTPRequest.blank('/v2/fake/os-security-group-rules') -+ for num in range(100, 100 + FLAGS.quota_security_group_rules): -+ rule = { -+ 'ip_protocol': 'tcp', 'from_port': num, -+ 'to_port': num, 'parent_group_id': '2', 'group_id': '1' -+ } -+ self.controller.create(req, {'security_group_rule': rule}) -+ -+ rule = { -+ 'ip_protocol': 'tcp', 'from_port': '121', 'to_port': '121', -+ 'parent_group_id': '2', 'group_id': '1' -+ } -+ self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create, -+ req, {'security_group_rule': rule}) -+ - - class TestSecurityGroupRulesXMLDeserializer(unittest.TestCase): - -diff --git a/nova/tests/test_quota.py b/nova/tests/test_quota.py -index 28c92ca..8cc5577 100644 ---- a/nova/tests/test_quota.py -+++ b/nova/tests/test_quota.py -@@ -235,6 +235,34 @@ class QuotaTestCase(test.TestCase): - floating_ips = quota.allowed_floating_ips(self.context, 101) - self.assertEqual(floating_ips, 101) - -+ def test_unlimited_security_groups(self): -+ self.flags(quota_security_groups=10) -+ security_groups = quota.allowed_security_groups(self.context, 100) -+ self.assertEqual(security_groups, 10) -+ db.quota_create(self.context, self.project_id, 'security_groups', None) -+ security_groups = quota.allowed_security_groups(self.context, 100) -+ self.assertEqual(security_groups, 100) -+ security_groups = quota.allowed_security_groups(self.context, 101) -+ self.assertEqual(security_groups, 101) -+ -+ def test_unlimited_security_group_rules(self): -+ -+ def fake_security_group_rule_count_by_group(context, sec_group_id): -+ return 0 -+ -+ self.stubs.Set(db, 'security_group_rule_count_by_group', -+ fake_security_group_rule_count_by_group) -+ -+ self.flags(quota_security_group_rules=20) -+ rules = quota.allowed_security_group_rules(self.context, 1234, 100) -+ self.assertEqual(rules, 20) -+ db.quota_create(self.context, self.project_id, 'security_group_rules', -+ None) -+ rules = quota.allowed_security_group_rules(self.context, 1234, 100) -+ self.assertEqual(rules, 100) -+ rules = quota.allowed_security_group_rules(self.context, 1234, 101) -+ self.assertEqual(rules, 101) -+ - def test_unlimited_metadata_items(self): - self.flags(quota_metadata_items=10) - items = quota.allowed_metadata_items(self.context, 100) diff --git a/0010-Delete-fixed_ips-when-network-is-deleted.patch b/0010-Delete-fixed_ips-when-network-is-deleted.patch deleted file mode 100644 index 03ce059..0000000 --- a/0010-Delete-fixed_ips-when-network-is-deleted.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 015744e92e601036ddcd77bd2fbed966172cb759 Mon Sep 17 00:00:00 2001 -From: Vishvananda Ishaya -Date: Tue, 3 Apr 2012 11:30:57 -0700 -Subject: [PATCH] Delete fixed_ips when network is deleted - - * adds failing test - * adds exception that is raised when network is in use - * fixes bug 754900 - -Change-Id: Ib95dc5927561b979b1eea237d4d6dc323483d4a5 ---- - nova/db/sqlalchemy/api.py | 13 +++++++++++++ - nova/exception.py | 4 ++++ - nova/tests/test_db_api.py | 19 +++++++++++++++++++ - 3 files changed, 36 insertions(+), 0 deletions(-) - -diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py -index f2c3062..03ac987 100644 ---- a/nova/db/sqlalchemy/api.py -+++ b/nova/db/sqlalchemy/api.py -@@ -1898,8 +1898,21 @@ def network_create_safe(context, values): - def network_delete_safe(context, network_id): - session = get_session() - with session.begin(): -+ result = session.query(models.FixedIp).\ -+ filter_by(network_id=network_id).\ -+ filter_by(deleted=False).\ -+ filter_by(allocated=True).\ -+ all() -+ if result: -+ raise exception.NetworkInUse(network_id=network_id) - network_ref = network_get(context, network_id=network_id, - session=session) -+ session.query(models.FixedIp).\ -+ filter_by(network_id=network_id).\ -+ filter_by(deleted=False).\ -+ update({'deleted': True, -+ 'updated_at': literal_column('updated_at'), -+ 'deleted_at': utils.utcnow()}) - session.delete(network_ref) - - -diff --git a/nova/exception.py b/nova/exception.py -index eb0bf38..da067b6 100644 ---- a/nova/exception.py -+++ b/nova/exception.py -@@ -525,6 +525,10 @@ class StorageRepositoryNotFound(NotFound): - message = _("Cannot find SR to read/write VDI.") - - -+class NetworkInUse(NovaException): -+ message = _("Network %(network_id)s is still in use.") -+ -+ - class NetworkNotCreated(NovaException): - message = _("%(req)s is required to create a network.") - -diff --git a/nova/tests/test_db_api.py b/nova/tests/test_db_api.py -index 8b73580..28f3558 100644 ---- a/nova/tests/test_db_api.py -+++ b/nova/tests/test_db_api.py -@@ -136,6 +136,25 @@ class DbApiTestCase(test.TestCase): - db_network = db.network_get(ctxt, network.id) - self.assertEqual(network.uuid, db_network.uuid) - -+ def test_network_delete_safe(self): -+ ctxt = context.get_admin_context() -+ values = {'host': 'localhost', 'project_id': 'project1'} -+ network = db.network_create_safe(ctxt, values) -+ db_network = db.network_get(ctxt, network.id) -+ values = {'network_id': network['id'], 'address': 'fake1'} -+ address1 = db.fixed_ip_create(ctxt, values) -+ values = {'network_id': network['id'], -+ 'address': 'fake2', -+ 'allocated': True} -+ address2 = db.fixed_ip_create(ctxt, values) -+ self.assertRaises(exception.NetworkInUse, -+ db.network_delete_safe, ctxt, network['id']) -+ db.fixed_ip_update(ctxt, address2, {'allocated': False}) -+ network = db.network_delete_safe(ctxt, network['id']) -+ ctxt = ctxt.elevated(read_deleted='yes') -+ fixed_ip = db.fixed_ip_get_by_address(ctxt, address1) -+ self.assertTrue(fixed_ip['deleted']) -+ - def test_network_create_with_duplicate_vlan(self): - ctxt = context.get_admin_context() - values1 = {'host': 'localhost', 'project_id': 'project1', 'vlan': 1} diff --git a/0011-Xen-Pass-session-to-destroy_vdi.patch b/0011-Xen-Pass-session-to-destroy_vdi.patch deleted file mode 100644 index 2212baa..0000000 --- a/0011-Xen-Pass-session-to-destroy_vdi.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 6c68ef55d966e6c8a2591886535a1590a6da72ad Mon Sep 17 00:00:00 2001 -From: Renuka Apte -Date: Wed, 25 Apr 2012 15:55:14 -0700 -Subject: [PATCH] Xen: Pass session to destroy_vdi - -fixes bug 988615 - -Change-Id: I34c59ff536abfdff9221cdb3d9ecc45d1e7a1a90 ---- - nova/virt/xenapi/volumeops.py | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/nova/virt/xenapi/volumeops.py b/nova/virt/xenapi/volumeops.py -index 2f3aafb..8333c08 100644 ---- a/nova/virt/xenapi/volumeops.py -+++ b/nova/virt/xenapi/volumeops.py -@@ -63,7 +63,7 @@ class VolumeOps(object): - if vdi_ref is None: - raise exception.Error(_('Could not find VDI ref')) - -- vm_utils.VMHelper.destroy_vdi(vdi_ref) -+ vm_utils.VMHelper.destroy_vdi(self._session, vdi_ref) - - def create_sr(self, label, params): - LOG.debug(_("Creating SR %s") % label) diff --git a/0012-add-libvirt_inject_key-flag.patch b/0012-add-libvirt_inject_key-flag.patch deleted file mode 100644 index 81f726a..0000000 --- a/0012-add-libvirt_inject_key-flag.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 5ab505191c3600fc4f4b7b128a04f5c9c8f74bc1 Mon Sep 17 00:00:00 2001 -From: Peng Yong -Date: Mon, 2 Apr 2012 23:36:20 +0800 -Subject: [PATCH] add libvirt_inject_key flag fix bug #971640 - -Change-Id: I48efc5babdd9b233342a33c87c461aabf5f5915b ---- - nova/virt/libvirt/connection.py | 5 ++++- - 1 files changed, 4 insertions(+), 1 deletions(-) - -diff --git a/nova/virt/libvirt/connection.py b/nova/virt/libvirt/connection.py -index 888be92..1a00db6 100644 ---- a/nova/virt/libvirt/connection.py -+++ b/nova/virt/libvirt/connection.py -@@ -105,6 +105,9 @@ libvirt_opts = [ - default=False, - help='Inject the admin password at boot time, ' - 'without an agent.'), -+ cfg.BoolOpt('libvirt_inject_key', -+ default=True, -+ help='Inject the ssh public key at boot time'), - cfg.BoolOpt('use_usb_tablet', - default=True, - help='Sync virtual and real mouse cursors in Windows VMs'), -@@ -1294,7 +1297,7 @@ class LibvirtConnection(driver.ComputeDriver): - self._create_local(basepath('disk.config'), 64, unit='M', - fs_format='msdos', label=label) # 64MB - -- if instance['key_data']: -+ if FLAGS.libvirt_inject_key and instance['key_data']: - key = str(instance['key_data']) - else: - key = None diff --git a/0013-Cloudpipe-tap-vpn-not-always-working.patch b/0013-Cloudpipe-tap-vpn-not-always-working.patch deleted file mode 100644 index 0ce7544..0000000 --- a/0013-Cloudpipe-tap-vpn-not-always-working.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 7c64de95f422add711bcdf5821310435e7be0199 Mon Sep 17 00:00:00 2001 -From: Cor Cornelisse -Date: Fri, 6 Apr 2012 15:54:16 +0200 -Subject: [PATCH] Cloudpipe tap vpn not always working - -Fixes bug 975043 - -Since Essex, all instances will have an eth0 MAC address in the range -of FA:16:3E, which is near the end of the MAC address space. - -When openvpn is started, a TAP interface is created with a random -generated MAC address. Chances are high the generated MAC address is -lower in value than the eth0 MAC address. Once the tap interface is -added to the bridge interface, the bridge interface will no longer have -the eth0 MAC address, but take over the TAP MAC address. This is a -feature of the linux kernel, whereby a bridge interface will take the -MAC address with the lowest value amongst its interfaces. After the ARP -entries expire, this will result in the cloudpipe instance being no -longer reachable. - -This fix, randomly generates a MAC address starting with FA:17:3E, which -is greater than FA, and will thus ensure the brige will keep the eth0 MAC -address. - -Change-Id: I0bd994b6dc7a92738ed23cd62ee42a021fd394e2 ---- - nova/cloudpipe/bootscript.template | 5 +++++ - 1 files changed, 5 insertions(+), 0 deletions(-) - -diff --git a/nova/cloudpipe/bootscript.template b/nova/cloudpipe/bootscript.template -index 94dea3f..0fe38b7 100755 ---- a/nova/cloudpipe/bootscript.template -+++ b/nova/cloudpipe/bootscript.template -@@ -24,6 +24,10 @@ export VPN_IP=`ifconfig | grep 'inet addr:'| grep -v '127.0.0.1' | cut -d: -f2 - export BROADCAST=`ifconfig | grep 'inet addr:'| grep -v '127.0.0.1' | cut -d: -f3 | awk '{print $$1}'` - export DHCP_MASK=`ifconfig | grep 'inet addr:'| grep -v '127.0.0.1' | cut -d: -f4 | awk '{print $$1}'` - export GATEWAY=`netstat -r | grep default | cut -d' ' -f10` -+# Need a higher valued MAC address than eth0, to prevent the TAP MAC address -+# from becoming the bridge MAC address. Since Essex eth0 MAC starts with -+# FA:16:3E, we'll thus generate a MAC starting with FA:17:3E to be higher than eth0. -+export RANDOM_TAP_MAC=`openssl rand -hex 8 | sed 's/\(..\)/\1:/g' | cut -b-8 | awk '{print "FA:17:3E:"$$1}'` - - DHCP_LOWER=`echo $$BROADCAST | awk -F. '{print $$1"."$$2"."$$3"." $$4 - ${num_vpn} }'` - DHCP_UPPER=`echo $$BROADCAST | awk -F. '{print $$1"."$$2"."$$3"." $$4 - 1 }'` -@@ -47,5 +51,6 @@ sed -i -e s/max-clients\ 1/max-clients\ 10/g server.conf - echo "push \"route ${dmz_net} ${dmz_mask} $$GATEWAY\"" >> server.conf - echo "duplicate-cn" >> server.conf - echo "crl-verify /etc/openvpn/crl.pem" >> server.conf -+echo "lladdr $$RANDOM_TAP_MAC" >> server.conf - - /etc/init.d/openvpn start diff --git a/0014-Don-t-leak-RPC-connections-on-timeouts-or-other-exce.patch b/0014-Don-t-leak-RPC-connections-on-timeouts-or-other-exce.patch deleted file mode 100644 index db2b4d3..0000000 --- a/0014-Don-t-leak-RPC-connections-on-timeouts-or-other-exce.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 48a07680b46b9973cd7de1b30ae80bd93861e1bb Mon Sep 17 00:00:00 2001 -From: Chris Behrens -Date: Wed, 25 Apr 2012 17:34:53 +0000 -Subject: [PATCH] Don't leak RPC connections on timeouts or other exceptions - -Fixes bug 968843 - -Change-Id: I9e0f1e306cab203bf4c865050b7a45f96127062e ---- - nova/rpc/amqp.py | 7 ++++++- - 1 files changed, 6 insertions(+), 1 deletions(-) - -diff --git a/nova/rpc/amqp.py b/nova/rpc/amqp.py -index 444ade4..4ebd9a4 100644 ---- a/nova/rpc/amqp.py -+++ b/nova/rpc/amqp.py -@@ -39,6 +39,7 @@ from nova import flags - from nova import local - from nova import log as logging - import nova.rpc.common as rpc_common -+from nova import utils - - LOG = logging.getLogger(__name__) - -@@ -296,7 +297,11 @@ class MulticallWaiter(object): - if self._done: - raise StopIteration - while True: -- self._iterator.next() -+ try: -+ self._iterator.next() -+ except Exception: -+ with utils.save_and_reraise_exception(): -+ self.done() - if self._got_ending: - self.done() - raise StopIteration diff --git a/0015-Fixes-bug-987335.patch b/0015-Fixes-bug-987335.patch deleted file mode 100644 index e7737f6..0000000 --- a/0015-Fixes-bug-987335.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 108e74b3e770a1d12eda5ed8dea7ca58d5e90cff Mon Sep 17 00:00:00 2001 -From: Alvaro Lopez Garcia -Date: Mon, 23 Apr 2012 16:40:38 +0200 -Subject: [PATCH] Fixes bug 987335. - -Revert bug introduced by commit a837f92e that removed -console_log from get_console_output() - -Change-Id: I22a14b5f50c2df0486420b38137328ac87844c1f ---- - nova/virt/libvirt/connection.py | 10 +++++++--- - 1 files changed, 7 insertions(+), 3 deletions(-) - -diff --git a/nova/virt/libvirt/connection.py b/nova/virt/libvirt/connection.py -index 888be92..eb0649b 100644 ---- a/nova/virt/libvirt/connection.py -+++ b/nova/virt/libvirt/connection.py -@@ -1006,6 +1006,7 @@ class LibvirtConnection(driver.ComputeDriver): - - self._chown_console_log_for_instance(instance['name']) - data = self._flush_libvirt_console(pty) -+ console_log = self._get_console_log_path(instance_name) - fpath = self._append_to_file(data, console_log) - - return libvirt_utils.load_file(fpath) -@@ -1147,9 +1148,12 @@ class LibvirtConnection(driver.ComputeDriver): - libvirt_utils.mkfs('swap', target) - - @staticmethod -- def _chown_console_log_for_instance(instance_name): -- console_log = os.path.join(FLAGS.instances_path, instance_name, -- 'console.log') -+ def _get_console_log_path(instance_name): -+ return os.path.join(FLAGS.instances_path, instance_name, -+ 'console.log') -+ -+ def _chown_console_log_for_instance(self, instance_name): -+ console_log = self._get_console_log_path(instance_name) - if os.path.exists(console_log): - libvirt_utils.chown(console_log, os.getuid()) - diff --git a/0016-Fix-timeout-in-EC2-CloudController.create_image.patch b/0016-Fix-timeout-in-EC2-CloudController.create_image.patch deleted file mode 100644 index cd705f7..0000000 --- a/0016-Fix-timeout-in-EC2-CloudController.create_image.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 1209af45525ed5a58d620a9da92939d39a3d2d9f Mon Sep 17 00:00:00 2001 -From: Eoghan Glynn -Date: Fri, 27 Apr 2012 15:11:57 +0100 -Subject: [PATCH] Fix timeout in EC2 CloudController.create_image() - -Fixes bug 989764 - -The timeout bounding the wait for the instance to stop is intended -to be 1 hour, but the code incorrectly specifies 60 hours instead -(no practical client is going to wait that long for a response). - -Change-Id: I7aa4b539393df15f3b2c950cf7aeca4691ed3d73 ---- - nova/api/ec2/cloud.py | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py -index 9e2a22e..52def33 100644 ---- a/nova/api/ec2/cloud.py -+++ b/nova/api/ec2/cloud.py -@@ -1614,7 +1614,7 @@ class CloudController(object): - # NOTE(yamahata): timeout and error. 1 hour for now for safety. - # Is it too short/long? - # Or is there any better way? -- timeout = 1 * 60 * 60 * 60 -+ timeout = 1 * 60 * 60 - if time.time() > start_time + timeout: - raise exception.EC2APIError( - _('Couldn\'t stop instance with in %d sec') % timeout) diff --git a/0017-Update-KillFilter-to-handle-deleted-exe-s.patch b/0017-Update-KillFilter-to-handle-deleted-exe-s.patch deleted file mode 100644 index ef4267b..0000000 --- a/0017-Update-KillFilter-to-handle-deleted-exe-s.patch +++ /dev/null @@ -1,61 +0,0 @@ -From facb936f0bfc6c78fdce93785078e78223b0ddf7 Mon Sep 17 00:00:00 2001 -From: Dan Prince -Date: Wed, 28 Mar 2012 22:00:11 -0400 -Subject: [PATCH] Update KillFilter to handle 'deleted' exe's. - -Updates KillFilter so that it handles the case where the executable -linked to by /proc/PID/exe is updated or deleted. - -Fixes LP Bug #967931. - -Also added a unit test to test that 'deleted' exe's are -filtered correctly. - -(cherry picked from commit b24c11b and commit 3d28e3d) - -Change-Id: I368a01383bf62b64b7579d573b8b84640dec03ae ---- - nova/rootwrap/filters.py | 4 ++++ - nova/tests/test_nova_rootwrap.py | 14 ++++++++++++++ - 2 files changed, 18 insertions(+), 0 deletions(-) - -diff --git a/nova/rootwrap/filters.py b/nova/rootwrap/filters.py -index a8fd513..a51ecae 100755 ---- a/nova/rootwrap/filters.py -+++ b/nova/rootwrap/filters.py -@@ -117,6 +117,10 @@ class KillFilter(CommandFilter): - return False - try: - command = os.readlink("/proc/%d/exe" % int(args[1])) -+ # NOTE(dprince): /proc/PID/exe may have ' (deleted)' on -+ # the end if an executable is updated or deleted -+ if command.endswith(" (deleted)"): -+ command = command[:command.rindex(" ")] - if command not in self.args[1]: - # Affected executable not in accepted list - return False -diff --git a/nova/tests/test_nova_rootwrap.py b/nova/tests/test_nova_rootwrap.py -index ee687ea..ca2626b 100644 ---- a/nova/tests/test_nova_rootwrap.py -+++ b/nova/tests/test_nova_rootwrap.py -@@ -103,6 +103,20 @@ class RootwrapTestCase(test.TestCase): - usercmd = ['kill', 'notapid'] - self.assertFalse(f.match(usercmd)) - -+ def test_KillFilter_deleted_exe(self): -+ """Makes sure deleted exe's are killed correctly""" -+ # See bug #967931. -+ def fake_readlink(blah): -+ return '/bin/commandddddd (deleted)' -+ -+ f = filters.KillFilter("/bin/kill", "root", -+ [""], -+ ["/bin/commandddddd"]) -+ usercmd = ['kill', 1234] -+ # Providing no signal should work -+ self.stubs.Set(os, 'readlink', fake_readlink) -+ self.assertTrue(f.match(usercmd)) -+ - def test_ReadFileFilter(self): - goodfn = '/good/file.name' - f = filters.ReadFileFilter(goodfn) diff --git a/0018-Get-unit-tests-functional-in-OS-X.patch b/0018-Get-unit-tests-functional-in-OS-X.patch deleted file mode 100644 index 4e381ff..0000000 --- a/0018-Get-unit-tests-functional-in-OS-X.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 76b525ab22ac63282153e5a7eb9cf5947da10413 Mon Sep 17 00:00:00 2001 -From: Matt Stephenson -Date: Tue, 3 Apr 2012 14:38:09 -0700 -Subject: [PATCH] Get unit tests functional in OS X - -* Add detection for directio to ensure the python runtime is built with O_DIRECT -* Extend stubbing in test_libvirt to also stub out _supports_direct_io - -Change-Id: Id793d4039311396f0b3c3a52d2a1d951ec3c5e48 -(cherry picked from commit cf7c0a7c10723495953be9bf99aedbe3838e0787) ---- - nova/tests/test_libvirt.py | 7 +++++++ - nova/virt/libvirt/connection.py | 6 ++++++ - 2 files changed, 13 insertions(+), 0 deletions(-) - -diff --git a/nova/tests/test_libvirt.py b/nova/tests/test_libvirt.py -index cdc9121..5163b32 100644 ---- a/nova/tests/test_libvirt.py -+++ b/nova/tests/test_libvirt.py -@@ -899,6 +899,13 @@ class LibvirtConnTestCase(test.TestCase): - - self.stubs.Set(os, 'open', os_open_stub) - -+ def connection_supports_direct_io_stub(*args, **kwargs): -+ return directio_supported -+ -+ self.stubs.Set(connection.LibvirtConnection, -+ '_supports_direct_io', -+ connection_supports_direct_io_stub) -+ - user_context = context.RequestContext(self.user_id, self.project_id) - instance_ref = db.instance_create(user_context, self.test_instance) - network_info = _fake_network_info(self.stubs, 1) -diff --git a/nova/virt/libvirt/connection.py b/nova/virt/libvirt/connection.py -index 5facc10..00345d2 100644 ---- a/nova/virt/libvirt/connection.py -+++ b/nova/virt/libvirt/connection.py -@@ -1037,7 +1037,13 @@ class LibvirtConnection(driver.ComputeDriver): - - @staticmethod - def _supports_direct_io(dirpath): -+ -+ if not hasattr(os, 'O_DIRECT'): -+ LOG.debug("This python runtime does not support direct I/O") -+ return False -+ - testfile = os.path.join(dirpath, ".directio.test") -+ - hasDirectIO = True - try: - f = os.open(testfile, os.O_CREAT | os.O_WRONLY | os.O_DIRECT) diff --git a/0019-Introduced-flag-base_dir_name.-Fixes-bug-973194.patch b/0019-Introduced-flag-base_dir_name.-Fixes-bug-973194.patch deleted file mode 100644 index 094f4d9..0000000 --- a/0019-Introduced-flag-base_dir_name.-Fixes-bug-973194.patch +++ /dev/null @@ -1,179 +0,0 @@ -From 7028d66ae97c68f888a2bbf2d3b431702f72b4c5 Mon Sep 17 00:00:00 2001 -From: Mandar Vaze -Date: Thu, 5 Apr 2012 01:33:34 -0700 -Subject: [PATCH] Introduced flag base_dir_name. Fixes bug 973194 - -rebased from master. - -If user faces locking related problem when two nova-compute hosts -sharing same disk area via nfs, try to download same image into -cache concurrently - Then base_dir_name can be set to "_base_$my_ip" in -nova.conf - -Default value for base_dir_name is "_base" thus retaining existing -behavior. - -Change-Id: Icff10ed75ba83f7256731614dc9e01e578b347a4 ---- - Authors | 1 + - nova/compute/manager.py | 6 ++++++ - nova/tests/test_imagecache.py | 8 +++++--- - nova/tests/test_libvirt.py | 7 ++++--- - nova/virt/libvirt/connection.py | 3 ++- - nova/virt/libvirt/imagecache.py | 6 ++++-- - 6 files changed, 22 insertions(+), 9 deletions(-) - -diff --git a/Authors b/Authors -index a229313..b9ad28b 100644 ---- a/Authors -+++ b/Authors -@@ -122,6 +122,7 @@ Likitha Shetty - Loganathan Parthipan - Lorin Hochstein - Lvov Maxim -+Mandar Vaze - Mandell Degerness - Mark McClain - Mark McLoughlin -diff --git a/nova/compute/manager.py b/nova/compute/manager.py -index 48e135b..053e80e 100644 ---- a/nova/compute/manager.py -+++ b/nova/compute/manager.py -@@ -28,6 +28,7 @@ terminating it. - **Related Flags** - - :instances_path: Where instances are kept on disk -+:base_dir_name: Where cached images are stored under instances_path - :compute_driver: Name of class that is used to handle virtualization, loaded - by :func:`nova.utils.import_object` - -@@ -72,6 +73,11 @@ compute_opts = [ - cfg.StrOpt('instances_path', - default='$state_path/instances', - help='where instances are stored on disk'), -+ cfg.StrOpt('base_dir_name', -+ default='_base', -+ help="where cached images are stored under $instances_path" -+ "This is NOT full path - just a folder name" -+ "For per-compute-host cached images, Set to _base_$my_ip"), - cfg.StrOpt('compute_driver', - default='nova.virt.connection.get_connection', - help='Driver to use for controlling virtualization'), -diff --git a/nova/tests/test_imagecache.py b/nova/tests/test_imagecache.py -index 9cf4003..f1d5aa5 100644 ---- a/nova/tests/test_imagecache.py -+++ b/nova/tests/test_imagecache.py -@@ -36,6 +36,7 @@ from nova.virt.libvirt import utils as virtutils - - - flags.DECLARE('instances_path', 'nova.compute.manager') -+flags.DECLARE('base_dir_name', 'nova.compute.manager') - FLAGS = flags.FLAGS - - LOG = log.getLogger(__name__) -@@ -155,7 +156,7 @@ class ImageCacheManagerTestCase(test.TestCase): - self.stubs.Set(virtutils, 'get_disk_backing_file', - lambda x: 'e97222e91fc4241f49a7f520d1dcf446751129b3_sm') - -- found = os.path.join(FLAGS.instances_path, '_base', -+ found = os.path.join(FLAGS.instances_path, FLAGS.base_dir_name, - 'e97222e91fc4241f49a7f520d1dcf446751129b3_sm') - - image_cache_manager = imagecache.ImageCacheManager() -@@ -177,7 +178,7 @@ class ImageCacheManagerTestCase(test.TestCase): - lambda x: ('e97222e91fc4241f49a7f520d1dcf446751129b3_' - '10737418240')) - -- found = os.path.join(FLAGS.instances_path, '_base', -+ found = os.path.join(FLAGS.instances_path, FLAGS.base_dir_name, - 'e97222e91fc4241f49a7f520d1dcf446751129b3_' - '10737418240') - -@@ -198,7 +199,7 @@ class ImageCacheManagerTestCase(test.TestCase): - self.stubs.Set(virtutils, 'get_disk_backing_file', - lambda x: 'e97222e91fc4241f49a7f520d1dcf446751129b3_sm') - -- found = os.path.join(FLAGS.instances_path, '_base', -+ found = os.path.join(FLAGS.instances_path, FLAGS.base_dir_name, - 'e97222e91fc4241f49a7f520d1dcf446751129b3_sm') - - image_cache_manager = imagecache.ImageCacheManager() -@@ -521,6 +522,7 @@ class ImageCacheManagerTestCase(test.TestCase): - hashed_42 = '92cfceb39d57d914ed8b14d0e37643de0797ae56' - - self.flags(instances_path='/instance_path') -+ self.flags(base_dir_name='_base') - self.flags(remove_unused_base_images=True) - - base_file_list = ['00000001', -diff --git a/nova/tests/test_libvirt.py b/nova/tests/test_libvirt.py -index cdc9121..f12cad4 100644 ---- a/nova/tests/test_libvirt.py -+++ b/nova/tests/test_libvirt.py -@@ -322,7 +322,7 @@ class CacheConcurrencyTestCase(test.TestCase): - self.flags(instances_path='nova.compute.manager') - - def fake_exists(fname): -- basedir = os.path.join(FLAGS.instances_path, '_base') -+ basedir = os.path.join(FLAGS.instances_path, FLAGS.base_dir_name) - if fname == basedir: - return True - return False -@@ -1317,9 +1317,10 @@ class LibvirtConnTestCase(test.TestCase): - if os.path.isdir(path): - shutil.rmtree(path) - -- path = os.path.join(FLAGS.instances_path, '_base') -+ path = os.path.join(FLAGS.instances_path, FLAGS.base_dir_name) - if os.path.isdir(path): -- shutil.rmtree(os.path.join(FLAGS.instances_path, '_base')) -+ shutil.rmtree(os.path.join(FLAGS.instances_path, -+ FLAGS.base_dir_name)) - - def test_get_host_ip_addr(self): - conn = connection.LibvirtConnection(False) -diff --git a/nova/virt/libvirt/connection.py b/nova/virt/libvirt/connection.py -index 5facc10..f1e5680 100644 ---- a/nova/virt/libvirt/connection.py -+++ b/nova/virt/libvirt/connection.py -@@ -1090,7 +1090,8 @@ class LibvirtConnection(driver.ComputeDriver): - - generating = 'image_id' not in kwargs - if not os.path.exists(target): -- base_dir = os.path.join(FLAGS.instances_path, '_base') -+ base_dir = os.path.join(FLAGS.instances_path, FLAGS.base_dir_name) -+ - if not os.path.exists(base_dir): - libvirt_utils.ensure_tree(base_dir) - base = os.path.join(base_dir, fname) -diff --git a/nova/virt/libvirt/imagecache.py b/nova/virt/libvirt/imagecache.py -index f92376a..adf8214 100644 ---- a/nova/virt/libvirt/imagecache.py -+++ b/nova/virt/libvirt/imagecache.py -@@ -58,6 +58,7 @@ imagecache_opts = [ - ] - - flags.DECLARE('instances_path', 'nova.compute.manager') -+flags.DECLARE('base_dir_name', 'nova.compute.manager') - FLAGS = flags.FLAGS - FLAGS.register_opts(imagecache_opts) - -@@ -178,7 +179,8 @@ class ImageCacheManager(object): - 'backing': backing_file}) - - backing_path = os.path.join(FLAGS.instances_path, -- '_base', backing_file) -+ FLAGS.base_dir_name, -+ backing_file) - if not backing_path in inuse_images: - inuse_images.append(backing_path) - -@@ -372,7 +374,7 @@ class ImageCacheManager(object): - # created, but may remain from previous versions. - self._reset_state() - -- base_dir = os.path.join(FLAGS.instances_path, '_base') -+ base_dir = os.path.join(FLAGS.instances_path, FLAGS.base_dir_name) - if not os.path.exists(base_dir): - LOG.debug(_('Skipping verification, no base directory at %s'), - base_dir) diff --git a/0020-Fix-bug-983206-_try_convert-parsing-string.patch b/0020-Fix-bug-983206-_try_convert-parsing-string.patch deleted file mode 100644 index 7b4a028..0000000 --- a/0020-Fix-bug-983206-_try_convert-parsing-string.patch +++ /dev/null @@ -1,103 +0,0 @@ -From 21e918a8f6e0fd144287ff7fc2ab3d262ac9edd7 Mon Sep 17 00:00:00 2001 -From: Joe Gordon -Date: Fri, 13 Apr 2012 15:12:04 -0400 -Subject: [PATCH] Fix bug 983206 : _try_convert parsing string - -* _try_convert in ec2utils.py didn't handle strings starting with "0x" -* Added tests to cover bug -* Add better float support -* remove unused complex number support - -Change-Id: I382d36f4a8671bcceccfa1ebdbae89a9d2aca207 -(cherry picked from commit c95162e52899618fc269fb536f6a2d3b26b7794d) ---- - nova/api/ec2/ec2utils.py | 35 +++++++++++------------------------ - nova/tests/test_api.py | 12 ++++++++++++ - 2 files changed, 23 insertions(+), 24 deletions(-) - -diff --git a/nova/api/ec2/ec2utils.py b/nova/api/ec2/ec2utils.py -index 1a6bb96..0f4aeb0 100644 ---- a/nova/api/ec2/ec2utils.py -+++ b/nova/api/ec2/ec2utils.py -@@ -166,6 +166,10 @@ def _try_convert(value): - * try conversion to int, float, complex, fallback value - - """ -+ def _negative_zero(value): -+ epsilon = 1e-7 -+ return 0 if abs(value) < epsilon else value -+ - if len(value) == 0: - return '' - if value == 'None': -@@ -175,31 +179,14 @@ def _try_convert(value): - return True - if lowered_value == 'false': - return False -- valueneg = value[1:] if value[0] == '-' else value -- if valueneg == '0': -- return 0 -- if valueneg == '': -- return value -- if valueneg[0] == '0': -- if valueneg[1] in 'xX': -- return int(value, 16) -- elif valueneg[1] in 'bB': -- return int(value, 2) -- else: -- try: -- return int(value, 8) -- except ValueError: -- pass -- try: -- return int(value) -- except ValueError: -- pass -- try: -- return float(value) -- except ValueError: -- pass -+ for prefix, base in [('0x', 16), ('0b', 2), ('0', 8), ('', 10)]: -+ try: -+ if lowered_value.startswith((prefix, "-" + prefix)): -+ return int(lowered_value, base) -+ except ValueError: -+ pass - try: -- return complex(value) -+ return _negative_zero(float(value)) - except ValueError: - return value - -diff --git a/nova/tests/test_api.py b/nova/tests/test_api.py -index baaee98..a52319f 100644 ---- a/nova/tests/test_api.py -+++ b/nova/tests/test_api.py -@@ -96,8 +96,10 @@ class XmlConversionTestCase(test.TestCase): - conv = ec2utils._try_convert - self.assertEqual(conv('None'), None) - self.assertEqual(conv('True'), True) -+ self.assertEqual(conv('TRUE'), True) - self.assertEqual(conv('true'), True) - self.assertEqual(conv('False'), False) -+ self.assertEqual(conv('FALSE'), False) - self.assertEqual(conv('false'), False) - self.assertEqual(conv('0'), 0) - self.assertEqual(conv('42'), 42) -@@ -107,6 +109,16 @@ class XmlConversionTestCase(test.TestCase): - self.assertEqual(conv('-0x57'), -0x57) - self.assertEqual(conv('-'), '-') - self.assertEqual(conv('-0'), 0) -+ self.assertEqual(conv('0.0'), 0.0) -+ self.assertEqual(conv('1e-8'), 0.0) -+ self.assertEqual(conv('-1e-8'), 0.0) -+ self.assertEqual(conv('0xDD8G'), '0xDD8G') -+ self.assertEqual(conv('0XDD8G'), '0XDD8G') -+ self.assertEqual(conv('-stringy'), '-stringy') -+ self.assertEqual(conv('stringy'), 'stringy') -+ self.assertEqual(conv('add'), 'add') -+ self.assertEqual(conv('remove'), 'remove') -+ self.assertEqual(conv(''), '') - - - class Ec2utilsTestCase(test.TestCase): diff --git a/0021-QuantumManager-will-start-dnsmasq-during-startup.-Fi.patch b/0021-QuantumManager-will-start-dnsmasq-during-startup.-Fi.patch deleted file mode 100644 index 3f37ff0..0000000 --- a/0021-QuantumManager-will-start-dnsmasq-during-startup.-Fi.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 26dc6b75c73f10c2da7628ce59e225d1006d9d1c Mon Sep 17 00:00:00 2001 -From: Mandar Vaze -Date: Wed, 11 Apr 2012 01:43:22 -0700 -Subject: [PATCH] QuantumManager will start dnsmasq during startup. Fixes bug - 977759 - -Added _setup_network_on_host method, which calls update_dhcp -if quantum_use_dhcp is set. - -Change-Id: I193212037873001a03da7b7a484f61a5c13b5de8 ---- - Authors | 1 + - nova/network/quantum/manager.py | 17 +++++++++++++++++ - 2 files changed, 18 insertions(+), 0 deletions(-) - -diff --git a/nova/network/quantum/manager.py b/nova/network/quantum/manager.py -index eb0f389..498b5f0 100644 ---- a/nova/network/quantum/manager.py -+++ b/nova/network/quantum/manager.py -@@ -88,6 +88,7 @@ class QuantumManager(manager.FloatingIP, manager.FlatManager): - def init_host(self): - # Initialize general L3 networking - self.l3driver.initialize() -+ super(QuantumManager, self).init_host() - # Initialize floating ip support (only works for nova ipam currently) - if FLAGS.quantum_ipam_lib == 'nova.network.quantum.nova_ipam_lib': - LOG.debug("Initializing FloatingIP support") -@@ -107,6 +108,22 @@ class QuantumManager(manager.FloatingIP, manager.FlatManager): - for c in cidrs: - self.l3driver.initialize_network(c) - -+ # Similar to FlatDHCPMananger, except we check for quantum_use_dhcp flag -+ # before we try to update_dhcp -+ def _setup_network_on_host(self, context, network): -+ """Sets up network on this host.""" -+ network['dhcp_server'] = self._get_dhcp_ip(context, network) -+ self.l3driver.initialize_gateway(network) -+ -+ if FLAGS.quantum_use_dhcp and not FLAGS.fake_network: -+ dev = self.driver.get_dev(network) -+ self.driver.update_dhcp(context, dev, network) -+ if FLAGS.use_ipv6: -+ self.driver.update_ra(context, dev, network) -+ gateway = utils.get_my_linklocal(dev) -+ self.db.network_update(context, network['id'], -+ {'gateway_v6': gateway}) -+ - def _update_network_host(self, context, net_uuid): - """Set the host column in the networks table: note that this won't - work with multi-host but QuantumManager doesn't support that diff --git a/0022-Fixes-bug-952176.patch b/0022-Fixes-bug-952176.patch deleted file mode 100644 index 2447930..0000000 --- a/0022-Fixes-bug-952176.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 9e9a554cba9e52430c2b2857bed744aba2ff8f9e Mon Sep 17 00:00:00 2001 -From: MotoKen -Date: Mon, 9 Apr 2012 10:33:55 +0800 -Subject: [PATCH] Fixes bug 952176 - -Checks if value is string or not before decode. - -Change-Id: I3f839770fdd7b00223ce02b95b2a265d903fa00e ---- - bin/nova-manage | 4 +++- - 1 files changed, 3 insertions(+), 1 deletions(-) - -diff --git a/bin/nova-manage b/bin/nova-manage -index c0009bc..f5491bc 100755 ---- a/bin/nova-manage -+++ b/bin/nova-manage -@@ -1721,8 +1721,10 @@ def main(): - for k, v in fn_kwargs.items(): - if v is None: - del fn_kwargs[k] -- else: -+ elif isinstance(v, basestring): - fn_kwargs[k] = v.decode('utf-8') -+ else: -+ fn_kwargs[k] = v - - fn_args = [arg.decode('utf-8') for arg in fn_args] - diff --git a/0023-Fix-nova.tests.test_nova_rootwrap-on-Fedora-17.patch b/0023-Fix-nova.tests.test_nova_rootwrap-on-Fedora-17.patch deleted file mode 100644 index c95fcf3..0000000 --- a/0023-Fix-nova.tests.test_nova_rootwrap-on-Fedora-17.patch +++ /dev/null @@ -1,38 +0,0 @@ -From e5e890f3117c792544d6a87d887543d502d1cb55 Mon Sep 17 00:00:00 2001 -From: Russell Bryant -Date: Tue, 1 May 2012 18:29:04 -0400 -Subject: [PATCH] Fix nova.tests.test_nova_rootwrap on Fedora 17. - -Fix bug 992916 - -This patch resolves a unit test failure on Fedora 17. The root cause is -that 'sleep' is '/usr/bin/sleep' instead of '/bin/sleep'. Update the -test to allow that. - -Change-Id: I5c8e04baec7159a8c10c9beb96cff58fd383e71c ---- - nova/tests/test_nova_rootwrap.py | 4 ++-- - 1 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/nova/tests/test_nova_rootwrap.py b/nova/tests/test_nova_rootwrap.py -index ca2626b..4cd6818 100644 ---- a/nova/tests/test_nova_rootwrap.py -+++ b/nova/tests/test_nova_rootwrap.py -@@ -69,7 +69,7 @@ class RootwrapTestCase(test.TestCase): - p = subprocess.Popen(["/bin/sleep", "5"]) - f = filters.KillFilter("/bin/kill", "root", - ["-ALRM"], -- ["/bin/sleep"]) -+ ["/bin/sleep", "/usr/bin/sleep"]) - usercmd = ['kill', '-9', p.pid] - # Incorrect signal should fail - self.assertFalse(f.match(usercmd)) -@@ -79,7 +79,7 @@ class RootwrapTestCase(test.TestCase): - - f = filters.KillFilter("/bin/kill", "root", - ["-9", ""], -- ["/bin/sleep"]) -+ ["/bin/sleep", "/usr/bin/sleep"]) - usercmd = ['kill', '-9', os.getpid()] - # Our own PID does not match /bin/sleep, so it should fail - self.assertFalse(f.match(usercmd)) diff --git a/0024-ensure-atomic-manipulation-of-libvirt-disk-images.patch b/0024-ensure-atomic-manipulation-of-libvirt-disk-images.patch deleted file mode 100644 index f4a760f..0000000 --- a/0024-ensure-atomic-manipulation-of-libvirt-disk-images.patch +++ /dev/null @@ -1,218 +0,0 @@ -From 6a3eabcd01981c6ccead47e2b610bd82b5d6be80 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= -Date: Fri, 16 Mar 2012 03:43:49 +0000 -Subject: [PATCH] ensure atomic manipulation of libvirt disk images - -This pattern could probably be used elsewhere, -but only libvirt disk images are considered for now. -This change ensures there are no stale files left -anywhere in the path from glance, through the libvirt image cache. -These could cause subsequent operational errors either -directly or indirectly through disk wastage. - -* nova/utils.py: Add a new remove_path_on_error() context manager -that is used to remove the passed PATH on a raised exception. -* nova/virt/images.py: Ensure temporary downloaded and -converted images are protected. -* nova/virt/libvirt/connection.py: Ensure all the images in -the image cache and instance dirs are protected. - -Change-Id: I81a5407665a6998128c0dee41387ef00ebddeb4d ---- - nova/utils.py | 21 +++++++++-- - nova/virt/images.py | 69 +++++++++++++++++---------------------- - nova/virt/libvirt/connection.py | 16 ++++++--- - 3 files changed, 57 insertions(+), 49 deletions(-) - -diff --git a/nova/utils.py b/nova/utils.py -index 819929a..7188d98 100644 ---- a/nova/utils.py -+++ b/nova/utils.py -@@ -21,6 +21,7 @@ - - import contextlib - import datetime -+import errno - import functools - import hashlib - import inspect -@@ -1013,8 +1014,8 @@ def cleanup_file_locks(): - continue - try: - stat_info = os.stat(os.path.join(FLAGS.lock_path, filename)) -- except OSError as (errno, strerror): -- if errno == 2: # doesn't exist -+ except OSError as e: -+ if e.errno == errno.ENOENT: - continue - else: - raise -@@ -1033,8 +1034,8 @@ def delete_if_exists(pathname): - - try: - os.unlink(pathname) -- except OSError as (errno, strerror): -- if errno == 2: # doesn't exist -+ except OSError as e: -+ if e.errno == errno.ENOENT: - return - else: - raise -@@ -1344,6 +1345,18 @@ def logging_error(message): - LOG.exception(message) - - -+@contextlib.contextmanager -+def remove_path_on_error(path): -+ """Protect code that wants to operate on PATH atomically. -+ Any exception will cause PATH to be removed. -+ """ -+ try: -+ yield -+ except Exception: -+ with save_and_reraise_exception(): -+ delete_if_exists(path) -+ -+ - def make_dev_path(dev, partition=None, base='/dev'): - """Return a path to a particular device. - -diff --git a/nova/virt/images.py b/nova/virt/images.py -index 1e0ae0a..626f3ff 100644 ---- a/nova/virt/images.py -+++ b/nova/virt/images.py -@@ -51,18 +51,10 @@ def fetch(context, image_href, path, _user_id, _project_id): - # checked before we got here. - (image_service, image_id) = nova.image.get_image_service(context, - image_href) -- try: -+ with utils.remove_path_on_error(path): - with open(path, "wb") as image_file: - metadata = image_service.get(context, image_id, image_file) -- except Exception: -- with utils.save_and_reraise_exception(): -- try: -- os.unlink(path) -- except OSError, e: -- if e.errno != errno.ENOENT: -- LOG.warn("unable to remove stale image '%s': %s" % -- (path, e.strerror)) -- return metadata -+ return metadata - - - def fetch_to_raw(context, image_href, path, user_id, project_id): -@@ -85,37 +77,36 @@ def fetch_to_raw(context, image_href, path, user_id, project_id): - - return(data) - -- data = _qemu_img_info(path_tmp) -- -- fmt = data.get("file format") -- if fmt is None: -- os.unlink(path_tmp) -- raise exception.ImageUnacceptable( -- reason=_("'qemu-img info' parsing failed."), image_id=image_href) -- -- if "backing file" in data: -- backing_file = data['backing file'] -- os.unlink(path_tmp) -- raise exception.ImageUnacceptable(image_id=image_href, -- reason=_("fmt=%(fmt)s backed by: %(backing_file)s") % locals()) -- -- if fmt != "raw" and FLAGS.force_raw_images: -- staged = "%s.converted" % path -- LOG.debug("%s was %s, converting to raw" % (image_href, fmt)) -- out, err = utils.execute('qemu-img', 'convert', '-O', 'raw', -- path_tmp, staged) -- os.unlink(path_tmp) -- -- data = _qemu_img_info(staged) -- if data.get('file format', None) != "raw": -- os.unlink(staged) -+ with utils.remove_path_on_error(path_tmp): -+ data = _qemu_img_info(path_tmp) -+ -+ fmt = data.get("file format") -+ if fmt is None: -+ raise exception.ImageUnacceptable( -+ reason=_("'qemu-img info' parsing failed."), -+ image_id=image_href) -+ -+ if "backing file" in data: -+ backing_file = data['backing file'] - raise exception.ImageUnacceptable(image_id=image_href, -- reason=_("Converted to raw, but format is now %s") % -- data.get('file format', None)) -+ reason=_("fmt=%(fmt)s backed by: %(backing_file)s") % locals()) -+ -+ if fmt != "raw" and FLAGS.force_raw_images: -+ staged = "%s.converted" % path -+ LOG.debug("%s was %s, converting to raw" % (image_href, fmt)) -+ with utils.remove_path_on_error(staged): -+ out, err = utils.execute('qemu-img', 'convert', '-O', 'raw', -+ path_tmp, staged) -+ -+ data = _qemu_img_info(staged) -+ if data.get('file format', None) != "raw": -+ raise exception.ImageUnacceptable(image_id=image_href, -+ reason=_("Converted to raw, but format is now %s") % -+ data.get('file format', None)) - -- os.rename(staged, path) -+ os.rename(staged, path) - -- else: -- os.rename(path_tmp, path) -+ else: -+ os.rename(path_tmp, path) - - return metadata -diff --git a/nova/virt/libvirt/connection.py b/nova/virt/libvirt/connection.py -index 31e6511..dc16d05 100644 ---- a/nova/virt/libvirt/connection.py -+++ b/nova/virt/libvirt/connection.py -@@ -1105,7 +1105,8 @@ class LibvirtConnection(driver.ComputeDriver): - @utils.synchronized(fname) - def call_if_not_exists(base, fn, *args, **kwargs): - if not os.path.exists(base): -- fn(target=base, *args, **kwargs) -+ with utils.remove_path_on_error(base): -+ fn(target=base, *args, **kwargs) - - if cow or not generating: - call_if_not_exists(base, fn, *args, **kwargs) -@@ -1121,8 +1122,9 @@ class LibvirtConnection(driver.ComputeDriver): - size_gb = size / (1024 * 1024 * 1024) - cow_base += "_%d" % size_gb - if not os.path.exists(cow_base): -- libvirt_utils.copy_image(base, cow_base) -- disk.extend(cow_base, size) -+ with utils.remove_path_on_error(cow_base): -+ libvirt_utils.copy_image(base, cow_base) -+ disk.extend(cow_base, size) - libvirt_utils.create_cow_image(cow_base, target) - elif not generating: - libvirt_utils.copy_image(base, target) -@@ -1132,7 +1134,8 @@ class LibvirtConnection(driver.ComputeDriver): - if size: - disk.extend(target, size) - -- copy_and_extend(cow, generating, base, target, size) -+ with utils.remove_path_on_error(target): -+ copy_and_extend(cow, generating, base, target, size) - - @staticmethod - def _create_local(target, local_size, unit='G', -@@ -1305,8 +1308,9 @@ class LibvirtConnection(driver.ComputeDriver): - project_id=instance['project_id'],) - elif config_drive: - label = 'config' -- self._create_local(basepath('disk.config'), 64, unit='M', -- fs_format='msdos', label=label) # 64MB -+ with utils.remove_path_on_error(basepath('disk.config')): -+ self._create_local(basepath('disk.config'), 64, unit='M', -+ fs_format='msdos', label=label) # 64MB - - if FLAGS.libvirt_inject_key and instance['key_data']: - key = str(instance['key_data']) diff --git a/0025-Ensure-we-don-t-access-the-net-when-building-docs.patch b/0025-Ensure-we-don-t-access-the-net-when-building-docs.patch deleted file mode 100644 index 0f49ded..0000000 --- a/0025-Ensure-we-don-t-access-the-net-when-building-docs.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 73185a4a4abe3dc87efa7ec1b4e60f98c049b75b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= -Date: Fri, 6 Jan 2012 12:16:34 +0000 -Subject: [PATCH] Ensure we don't access the net when building docs - -(Note, this has not been sent upstream) - -Change-Id: I9d02fb4053a8106672aded1614a2850e21603eb2 ---- - doc/source/conf.py | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/doc/source/conf.py b/doc/source/conf.py -index 8ced294..7df59cd 100644 ---- a/doc/source/conf.py -+++ b/doc/source/conf.py -@@ -25,7 +25,7 @@ sys.path.insert(0, os.path.abspath('./')) - # Add any Sphinx extension module names here, as strings. They can be extensions - # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. - --extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx', 'ext.nova_todo', 'sphinx.ext.coverage', 'sphinx.ext.pngmath', 'sphinx.ext.ifconfig','sphinx.ext.graphviz'] -+extensions = ['sphinx.ext.autodoc', 'ext.nova_todo', 'sphinx.ext.coverage', 'sphinx.ext.pngmath', 'sphinx.ext.ifconfig','sphinx.ext.graphviz'] - - # autodoc generation is a bit aggressive and a nuisance when doing heavy text edit cycles. - # execute "export SPHINX_DEBUG=1" in your terminal to disable diff --git a/0026-fix-useexisting-deprecation-warnings.patch b/0026-fix-useexisting-deprecation-warnings.patch deleted file mode 100644 index dbc3a07..0000000 --- a/0026-fix-useexisting-deprecation-warnings.patch +++ /dev/null @@ -1,49 +0,0 @@ -From bf7f18bf91718babb30e8ded89410667bc940320 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= -Date: Thu, 8 Mar 2012 16:32:30 +0000 -Subject: [PATCH] fix useexisting deprecation warnings - -Fixes deprecation warnings when using sqlalchemy >= 0.7.0 -Fixes bug 941951 - -Change-Id: Iaa57153f99c60c67a14c1dca849188937bdc5dee ---- - .../075_convert_bw_usage_to_store_network_id.py | 4 ++-- - .../versions/081_drop_instance_id_bw_cache.py | 2 +- - 2 files changed, 3 insertions(+), 3 deletions(-) - -diff --git a/nova/db/sqlalchemy/migrate_repo/versions/075_convert_bw_usage_to_store_network_id.py b/nova/db/sqlalchemy/migrate_repo/versions/075_convert_bw_usage_to_store_network_id.py -index b275524..4ff3d99 100644 ---- a/nova/db/sqlalchemy/migrate_repo/versions/075_convert_bw_usage_to_store_network_id.py -+++ b/nova/db/sqlalchemy/migrate_repo/versions/075_convert_bw_usage_to_store_network_id.py -@@ -46,7 +46,7 @@ def upgrade(migrate_engine): - Column('last_refreshed', DateTime(timezone=False)), - Column('bw_in', BigInteger()), - Column('bw_out', BigInteger()), -- useexisting=True) -+ extend_existing=True) - mac_column = Column('mac', String(255)) - bw_usage_cache.create_column(mac_column) - -@@ -81,7 +81,7 @@ def downgrade(migrate_engine): - Column('last_refreshed', DateTime(timezone=False)), - Column('bw_in', BigInteger()), - Column('bw_out', BigInteger()), -- useexisting=True) -+ extend_existing=True) - - network_label_column = Column('network_label', String(255)) - bw_usage_cache.create_column(network_label_column) -diff --git a/nova/db/sqlalchemy/migrate_repo/versions/081_drop_instance_id_bw_cache.py b/nova/db/sqlalchemy/migrate_repo/versions/081_drop_instance_id_bw_cache.py -index c6687ac..a607ed3 100644 ---- a/nova/db/sqlalchemy/migrate_repo/versions/081_drop_instance_id_bw_cache.py -+++ b/nova/db/sqlalchemy/migrate_repo/versions/081_drop_instance_id_bw_cache.py -@@ -37,7 +37,7 @@ def upgrade(migrate_engine): - Column('last_refreshed', DateTime(timezone=False)), - Column('bw_in', BigInteger()), - Column('bw_out', BigInteger()), -- useexisting=True) -+ extend_existing=True) - - bw_usage_cache.drop_column('instance_id') - diff --git a/0027-support-a-configurable-libvirt-injection-partition.patch b/0027-support-a-configurable-libvirt-injection-partition.patch deleted file mode 100644 index 343b50e..0000000 --- a/0027-support-a-configurable-libvirt-injection-partition.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 862cb7a4bad82f7347f495ad3a91df31cad79214 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= -Date: Wed, 18 Apr 2012 23:27:31 +0100 -Subject: [PATCH] support a configurable libvirt injection partition - -This is useful if all guest images have the same structure, -and the root partition is not the first partition. - -This is also handy to enable inspection in libguestfs, -which can handle disparate and complicated image layouts. - -In future we may change to a StrOpt to support -searching by partition label. - -Change-Id: Ie94d61bec8fe4b41d6d2d6d3efa9a4364cf027fe - -Conflicts: - - nova/virt/libvirt/connection.py ---- - nova/virt/disk/mount.py | 6 ++++-- - nova/virt/libvirt/connection.py | 12 ++++++++---- - 2 files changed, 12 insertions(+), 6 deletions(-) - -diff --git a/nova/virt/disk/mount.py b/nova/virt/disk/mount.py -index 4fb5dda..11959b2 100644 ---- a/nova/virt/disk/mount.py -+++ b/nova/virt/disk/mount.py -@@ -58,7 +58,9 @@ class Mount(object): - """Map partitions of the device to the file system namespace.""" - assert(os.path.exists(self.device)) - -- if self.partition: -+ if self.partition == -1: -+ self.error = _('partition search unsupported with %s') % self.mode -+ elif self.partition: - map_path = '/dev/mapper/%sp%s' % (os.path.basename(self.device), - self.partition) - assert(not os.path.exists(map_path)) -@@ -73,7 +75,7 @@ class Mount(object): - # so given we only use it when we expect a partitioned image, fail - if not os.path.exists(map_path): - if not err: -- err = _('no partitions found') -+ err = _('partition %s not found') % self.partition - self.error = _('Failed to map partitions: %s') % err - else: - self.mapped_device = map_path -diff --git a/nova/virt/libvirt/connection.py b/nova/virt/libvirt/connection.py -index dc16d05..81fd587 100644 ---- a/nova/virt/libvirt/connection.py -+++ b/nova/virt/libvirt/connection.py -@@ -108,6 +108,11 @@ libvirt_opts = [ - cfg.BoolOpt('libvirt_inject_key', - default=True, - help='Inject the ssh public key at boot time'), -+ cfg.IntOpt('libvirt_inject_partition', -+ default=1, -+ help='The partition to inject to : ' -+ '-1 => inspect (libguestfs only), 0 => not partitioned, ' -+ '>0 => partition number'), - cfg.BoolOpt('use_usb_tablet', - default=True, - help='Sync virtual and real mouse cursors in Windows VMs'), -@@ -1285,12 +1290,11 @@ class LibvirtConnection(driver.ComputeDriver): - cow=FLAGS.use_cow_images, - swap_mb=swap_mb) - -- # For now, we assume that if we're not using a kernel, we're using a -- # partitioned disk image where the target partition is the first -- # partition - target_partition = None - if not instance['kernel_id']: -- target_partition = "1" -+ target_partition = FLAGS.libvirt_inject_partition -+ if target_partition == 0: -+ target_partition = None - - config_drive_id = instance.get('config_drive_id') - config_drive = instance.get('config_drive') diff --git a/0028-handle-updated-qemu-img-info-output.patch b/0028-handle-updated-qemu-img-info-output.patch deleted file mode 100644 index bb453f3..0000000 --- a/0028-handle-updated-qemu-img-info-output.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 4099a82112d192ba01cb3c5fb3a71b5ef8bb7683 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= -Date: Wed, 16 May 2012 13:44:46 +0100 -Subject: [PATCH] handle updated qemu-img info output - -Originally `qemu-img info` always output an (actual path: ...) -even if it was duplicated with that already on the line. - - $ instances=/var/lib/nova/instances/ - $ qemu-img info $instances/instance-00000017/disk | grep 'backing' - backing file: $instances/_base/24083... (actual path: $the_same) - -Whereas after the change referenced at: -https://lists.gnu.org/archive/html/qemu-devel/2012-05/msg01468.html -It suppresses a duplicate (actual path:) - - $ instances=/var/lib/nova/instances/ - $ qemu-img info $instances/instance-00000017/disk | grep 'backing' - backing file: $instances/_base/24083... - -* nova/virt/libvirt/utils.py (get_disk_backing_file): -Avoid an indexError exception when parsing the newer format. -Fixes bug 1000261 - -Change-Id: Ie2889b6da8a5c93e0e874e7a330529f6e6e71b0b ---- - nova/virt/libvirt/utils.py | 14 +++++++++++--- - 1 files changed, 11 insertions(+), 3 deletions(-) - -diff --git a/nova/virt/libvirt/utils.py b/nova/virt/libvirt/utils.py -index db7e11b..977eda8 100644 ---- a/nova/virt/libvirt/utils.py -+++ b/nova/virt/libvirt/utils.py -@@ -92,10 +92,18 @@ def get_disk_backing_file(path): - :returns: a path to the image's backing store - """ - out, err = execute('qemu-img', 'info', path) -- backing_file = [i.split('actual path:')[1].strip()[:-1] -- for i in out.split('\n') if 0 <= i.find('backing file')] -+ backing_file = None -+ -+ for line in out.split('\n'): -+ if line.startswith('backing file: '): -+ if 'actual path: ' in line: -+ backing_file = line.split('actual path: ')[1][:-1] -+ else: -+ backing_file = line.split('backing file: ')[1] -+ break - if backing_file: -- backing_file = os.path.basename(backing_file[0]) -+ backing_file = os.path.basename(backing_file) -+ - return backing_file - - diff --git a/openstack-nova-direct-api.service b/openstack-nova-direct-api.service deleted file mode 100644 index 531b0cd..0000000 --- a/openstack-nova-direct-api.service +++ /dev/null @@ -1,12 +0,0 @@ -[Unit] -Description=OpenStack Nova Direct API Server -After=syslog.target network.target - -[Service] -Type=simple -User=nova -ExecStart=/usr/bin/nova-direct-api --config-file /etc/nova/nova.conf --logfile /var/log/nova/direct-api.log - -[Install] -WantedBy=multi-user.target - diff --git a/openstack-nova.spec b/openstack-nova.spec index 82f27b2..2c5a960 100644 --- a/openstack-nova.spec +++ b/openstack-nova.spec @@ -1,14 +1,14 @@ %global with_doc %{!?_without_doc:1}%{?_without_doc:0} Name: openstack-nova -Version: 2012.1 -Release: 6%{?dist} +Version: 2012.2 +Release: 0.1.f1%{?dist} Summary: OpenStack Compute (nova) Group: Applications/System License: ASL 2.0 URL: http://openstack.org/projects/compute/ -Source0: http://launchpad.net/nova/essex/2012.1/+download/nova-2012.1.tar.gz +Source0: http://launchpad.net/nova/folsom/folsom-1/+download/nova-2012.2~f1.tar.gz Source1: nova.conf Source6: nova.logrotate @@ -19,7 +19,6 @@ Source13: openstack-nova-network.service Source14: openstack-nova-objectstore.service Source15: openstack-nova-scheduler.service Source16: openstack-nova-volume.service -Source17: openstack-nova-direct-api.service Source18: openstack-nova-xvpvncproxy.service Source19: openstack-nova-console.service Source20: openstack-nova-consoleauth.service @@ -30,36 +29,10 @@ Source22: nova-ifc-template Source24: nova-sudoers # -# patches_base=2012.1 +# patches_base=folsom-1 # -Patch0001: 0001-fix-bug-where-nova-ignores-glance-host-in-imageref.patch -Patch0002: 0002-Stop-libvirt-test-from-deleting-instances-dir.patch -Patch0003: 0003-Allow-unprivileged-RADOS-users-to-access-rbd-volumes.patch -Patch0004: 0004-Fixed-bug-962840-added-a-test-case.patch -Patch0005: 0005-Fix-errors-in-os-networks-extension.patch -Patch0006: 0006-Create-compute.api.BaseAPI-for-compute-APIs-to-use.patch -Patch0007: 0007-Populate-image-properties-with-project_id-again.patch -Patch0008: 0008-Use-project_id-in-ec2.cloud._format_image.patch -Patch0009: 0009-Implement-quotas-for-security-groups.patch -Patch0010: 0010-Delete-fixed_ips-when-network-is-deleted.patch -Patch0011: 0011-Xen-Pass-session-to-destroy_vdi.patch -Patch0012: 0012-add-libvirt_inject_key-flag.patch -Patch0013: 0013-Cloudpipe-tap-vpn-not-always-working.patch -Patch0014: 0014-Don-t-leak-RPC-connections-on-timeouts-or-other-exce.patch -Patch0015: 0015-Fixes-bug-987335.patch -Patch0016: 0016-Fix-timeout-in-EC2-CloudController.create_image.patch -Patch0017: 0017-Update-KillFilter-to-handle-deleted-exe-s.patch -Patch0018: 0018-Get-unit-tests-functional-in-OS-X.patch -Patch0019: 0019-Introduced-flag-base_dir_name.-Fixes-bug-973194.patch -Patch0020: 0020-Fix-bug-983206-_try_convert-parsing-string.patch -Patch0021: 0021-QuantumManager-will-start-dnsmasq-during-startup.-Fi.patch -Patch0022: 0022-Fixes-bug-952176.patch -Patch0023: 0023-Fix-nova.tests.test_nova_rootwrap-on-Fedora-17.patch -Patch0024: 0024-ensure-atomic-manipulation-of-libvirt-disk-images.patch -Patch0025: 0025-Ensure-we-don-t-access-the-net-when-building-docs.patch -Patch0026: 0026-fix-useexisting-deprecation-warnings.patch -Patch0027: 0027-support-a-configurable-libvirt-injection-partition.patch -Patch0028: 0028-handle-updated-qemu-img-info-output.patch +Patch0001: 0001-Ensure-we-don-t-access-the-net-when-building-docs.patch +Patch0002: 0002-fix-useexisting-deprecation-warnings.patch BuildArch: noarch BuildRequires: intltool @@ -116,7 +89,6 @@ Requires: python-amqplib Requires: python-daemon Requires: python-eventlet Requires: python-greenlet -Requires: python-gflags Requires: python-iso8601 Requires: python-lockfile Requires: python-lxml @@ -179,32 +151,6 @@ This package contains documentation files for nova. %patch0001 -p1 %patch0002 -p1 -%patch0003 -p1 -%patch0004 -p1 -%patch0005 -p1 -%patch0006 -p1 -%patch0007 -p1 -%patch0008 -p1 -%patch0009 -p1 -%patch0010 -p1 -%patch0011 -p1 -%patch0012 -p1 -%patch0013 -p1 -%patch0014 -p1 -%patch0015 -p1 -%patch0016 -p1 -%patch0017 -p1 -%patch0018 -p1 -%patch0019 -p1 -%patch0020 -p1 -%patch0021 -p1 -%patch0022 -p1 -%patch0023 -p1 -%patch0024 -p1 -%patch0025 -p1 -%patch0026 -p1 -%patch0027 -p1 -%patch0028 -p1 find . \( -name .gitignore -o -name .placeholder \) -delete @@ -242,9 +188,9 @@ install -p -D -m 644 build/man/*.1 %{buildroot}%{_mandir}/man1/ popd -# Give stack, instance-usage-audit and clear_rabbit_queues a reasonable prefix -mv %{buildroot}%{_bindir}/stack %{buildroot}%{_bindir}/nova-stack +# Give {instance,volume}-usage-audit and clear_rabbit_queues a reasonable prefix mv %{buildroot}%{_bindir}/instance-usage-audit %{buildroot}%{_bindir}/nova-instance-usage-audit +mv %{buildroot}%{_bindir}/volume-usage-audit %{buildroot}%{_bindir}/nova-volume-usage-audit mv %{buildroot}%{_bindir}/clear_rabbit_queues %{buildroot}%{_bindir}/nova-clear-rabbit-queues # Setup directories @@ -280,7 +226,6 @@ install -p -D -m 755 %{SOURCE13} %{buildroot}%{_unitdir}/openstack-nova-network. install -p -D -m 755 %{SOURCE14} %{buildroot}%{_unitdir}/openstack-nova-objectstore.service install -p -D -m 755 %{SOURCE15} %{buildroot}%{_unitdir}/openstack-nova-scheduler.service install -p -D -m 755 %{SOURCE16} %{buildroot}%{_unitdir}/openstack-nova-volume.service -install -p -D -m 755 %{SOURCE17} %{buildroot}%{_unitdir}/openstack-nova-direct-api.service install -p -D -m 755 %{SOURCE18} %{buildroot}%{_unitdir}/openstack-nova-xvpvncproxy.service install -p -D -m 755 %{SOURCE19} %{buildroot}%{_unitdir}/openstack-nova-console.service install -p -D -m 755 %{SOURCE20} %{buildroot}%{_unitdir}/openstack-nova-consoleauth.service @@ -298,7 +243,6 @@ install -d -m 755 %{buildroot}%{_localstatedir}/run/nova # Install template files install -p -D -m 644 nova/auth/novarc.template %{buildroot}%{_datarootdir}/nova/novarc.template install -p -D -m 644 nova/cloudpipe/client.ovpn.template %{buildroot}%{_datarootdir}/nova/client.ovpn.template -install -p -D -m 644 nova/virt/libvirt.xml.template %{buildroot}%{_datarootdir}/nova/libvirt.xml.template install -p -D -m 644 nova/virt/interfaces.template %{buildroot}%{_datarootdir}/nova/interfaces.template install -p -D -m 644 %{SOURCE22} %{buildroot}%{_datarootdir}/nova/interfaces.template @@ -332,7 +276,7 @@ fi %preun if [ $1 -eq 0 ] ; then - for svc in api cert compute network objectstore scheduler volume direct-api metadata-api console consoleauth xvpvncproxy; do + for svc in api cert compute network objectstore scheduler volume metadata-api console consoleauth xvpvncproxy; do /bin/systemctl --no-reload disable openstack-nova-${svc}.service > /dev/null 2>&1 || : /bin/systemctl stop openstack-nova-${svc}.service > /dev/null 2>&1 || : done @@ -342,7 +286,7 @@ fi /bin/systemctl daemon-reload >/dev/null 2>&1 || : if [ $1 -ge 1 ] ; then # Package upgrade, not uninstall - for svc in api cert compute network objectstore scheduler volume direct-api metadata-api console consoleauth xvpvncproxy; do + for svc in api cert compute network objectstore scheduler volume metadata-api console consoleauth xvpvncproxy; do /bin/systemctl try-restart openstack-nova-${svc}.service >/dev/null 2>&1 || : done fi @@ -402,6 +346,9 @@ fi %endif %changelog +* Tue May 29 2012 Pádraig Brady - 2012.2-0.1.f1 +- Update to folsom milestone 1 + * Wed May 16 2012 Alan Pevec - 2012.1-6 - Remove m2crypto and other dependencies no loner needed by Essex diff --git a/sources b/sources index a4d3345..f816299 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -4a7d2522058b90fb43a6177ea52def60 nova-2012.1.tar.gz +be940e127bfa505c4e38339d628209aa nova-2012.2~f1.tar.gz