From 2674bcaccfc83da5b2cf3e09fa4912a453870714 Mon Sep 17 00:00:00 2001 From: Nikolay Sokolov Date: Fri, 22 Jul 2011 17:26:11 +0400 Subject: [PATCH 01/47] Moved restaring instances from livbirt driver to ComputeManager. --- nova/flags.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nova/flags.py b/nova/flags.py index 49355b43..23ca38b1 100644 --- a/nova/flags.py +++ b/nova/flags.py @@ -387,3 +387,6 @@ DEFINE_list('zone_capabilities', 'Key/Multi-value list representng capabilities of this zone') DEFINE_string('build_plan_encryption_key', None, '128bit (hex) encryption key for scheduler build plans.') + +DEFINE_bool('start_guests_on_host_boot', False, + 'Whether to restart guests when the host reboots') From 4f59665d3ed88bb03135b39329a2b4c8cb0ac66a Mon Sep 17 00:00:00 2001 From: Nikolay Sokolov Date: Tue, 26 Jul 2011 00:31:42 +0400 Subject: [PATCH 02/47] Fixed old libvirt semantics, added resume_guests_state_on_host_boot flag. --- nova/flags.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nova/flags.py b/nova/flags.py index 23ca38b1..6c7e448a 100644 --- a/nova/flags.py +++ b/nova/flags.py @@ -390,3 +390,5 @@ DEFINE_string('build_plan_encryption_key', None, DEFINE_bool('start_guests_on_host_boot', False, 'Whether to restart guests when the host reboots') +DEFINE_bool('resume_guests_state_on_host_boot', False, + 'Whether to start guests, that was running before the host reboot') From fe1a028ba953414e11120d69fcff20cc060c7b62 Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Mon, 25 Jul 2011 22:55:37 -0400 Subject: [PATCH 03/47] removing xenapi_image_service flag --- nova/tests/test_xenapi.py | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py index 4cb7447d..87e2e93b 100644 --- a/nova/tests/test_xenapi.py +++ b/nova/tests/test_xenapi.py @@ -429,7 +429,7 @@ class XenAPIVMTestCase(test.TestCase): self.assertTrue(instance.architecture) def test_spawn_not_enough_memory(self): - FLAGS.xenapi_image_service = 'glance' + FLAGS.image_service = 'nova.image.glance.GlanceImageService' self.assertRaises(Exception, self._test_spawn, 1, 2, 3, "4") # m1.xlarge @@ -441,7 +441,7 @@ class XenAPIVMTestCase(test.TestCase): """ vdi_recs_start = self._list_vdis() - FLAGS.xenapi_image_service = 'glance' + FLAGS.image_service = 'nova.image.glance.GlanceImageService' stubs.stubout_fetch_image_glance_disk(self.stubs) self.assertRaises(xenapi_fake.Failure, self._test_spawn, 1, 2, 3) @@ -456,7 +456,7 @@ class XenAPIVMTestCase(test.TestCase): """ vdi_recs_start = self._list_vdis() - FLAGS.xenapi_image_service = 'glance' + FLAGS.image_service = 'nova.image.glance.GlanceImageService' stubs.stubout_create_vm(self.stubs) self.assertRaises(xenapi_fake.Failure, self._test_spawn, 1, 2, 3) @@ -465,21 +465,21 @@ class XenAPIVMTestCase(test.TestCase): self._check_vdis(vdi_recs_start, vdi_recs_end) def test_spawn_raw_objectstore(self): - FLAGS.xenapi_image_service = 'objectstore' + FLAGS.image_service = 'nova.image.s3.S3ImageService' self._test_spawn(1, None, None) def test_spawn_objectstore(self): - FLAGS.xenapi_image_service = 'objectstore' + FLAGS.image_service = 'nova.image.s3.S3ImageService' self._test_spawn(1, 2, 3) @stub_vm_utils_with_vdi_attached_here def test_spawn_raw_glance(self): - FLAGS.xenapi_image_service = 'glance' + FLAGS.image_service = 'nova.image.glance.GlanceImageService' self._test_spawn(glance_stubs.FakeGlance.IMAGE_RAW, None, None) self.check_vm_params_for_linux() def test_spawn_vhd_glance_linux(self): - FLAGS.xenapi_image_service = 'glance' + FLAGS.image_service = 'nova.image.glance.GlanceImageService' self._test_spawn(glance_stubs.FakeGlance.IMAGE_VHD, None, None, os_type="linux", architecture="x86-64") self.check_vm_params_for_linux() @@ -508,20 +508,20 @@ class XenAPIVMTestCase(test.TestCase): self.assertEqual(len(self.vm['VBDs']), 1) def test_spawn_vhd_glance_windows(self): - FLAGS.xenapi_image_service = 'glance' + FLAGS.image_service = 'nova.image.glance.GlanceImageService' self._test_spawn(glance_stubs.FakeGlance.IMAGE_VHD, None, None, os_type="windows", architecture="i386") self.check_vm_params_for_windows() def test_spawn_glance(self): - FLAGS.xenapi_image_service = 'glance' + FLAGS.image_service = 'nova.image.glance.GlanceImageService' self._test_spawn(glance_stubs.FakeGlance.IMAGE_MACHINE, glance_stubs.FakeGlance.IMAGE_KERNEL, glance_stubs.FakeGlance.IMAGE_RAMDISK) self.check_vm_params_for_linux_with_external_kernel() def test_spawn_netinject_file(self): - FLAGS.xenapi_image_service = 'glance' + FLAGS.image_service = 'nova.image.glance.GlanceImageService' db_fakes.stub_out_db_instance_api(self.stubs, injected=True) self._tee_executed = False @@ -547,7 +547,7 @@ class XenAPIVMTestCase(test.TestCase): # Capture the sudo tee .../etc/network/interfaces command (r'(sudo\s+)?tee.*interfaces', _tee_handler), ]) - FLAGS.xenapi_image_service = 'glance' + FLAGS.image_service = 'nova.image.glance.GlanceImageService' self._test_spawn(glance_stubs.FakeGlance.IMAGE_MACHINE, glance_stubs.FakeGlance.IMAGE_KERNEL, glance_stubs.FakeGlance.IMAGE_RAMDISK, @@ -555,7 +555,7 @@ class XenAPIVMTestCase(test.TestCase): self.assertTrue(self._tee_executed) def test_spawn_netinject_xenstore(self): - FLAGS.xenapi_image_service = 'glance' + FLAGS.image_service = 'nova.image.glance.GlanceImageService' db_fakes.stub_out_db_instance_api(self.stubs, injected=True) self._tee_executed = False @@ -601,7 +601,7 @@ class XenAPIVMTestCase(test.TestCase): @test.skip_test("Never gets an address, not sure why") def test_spawn_vlanmanager(self): - self.flags(xenapi_image_service='glance', + self.flags(image_service='nova.image.glance.GlanceImageService', network_manager='nova.network.manager.VlanManager', network_driver='nova.network.xenapi_net', vlan_interface='fake0') @@ -784,6 +784,7 @@ class XenAPIMigrateInstance(test.TestCase): conn.migrate_disk_and_power_off(instance, '127.0.0.1') def test_finish_resize(self): + FLAGS.image_service = 'nova.image.glance.GlanceImageService' instance = db.instance_create(self.context, self.values) stubs.stubout_session(self.stubs, stubs.FakeSessionForMigrationTests) stubs.stubout_loopingcall_start(self.stubs) @@ -827,7 +828,7 @@ class XenAPIDetermineDiskImageTestCase(test.TestCase): def test_instance_disk(self): """If a kernel is specified, the image type is DISK (aka machine).""" - FLAGS.xenapi_image_service = 'objectstore' + FLAGS.image_service = 'nova.image.s3.S3ImageService' self.fake_instance.image_ref = glance_stubs.FakeGlance.IMAGE_MACHINE self.fake_instance.kernel_id = glance_stubs.FakeGlance.IMAGE_KERNEL self.assert_disk_type(vm_utils.ImageType.DISK) @@ -837,7 +838,7 @@ class XenAPIDetermineDiskImageTestCase(test.TestCase): If the kernel isn't specified, and we're not using Glance, then DISK_RAW is assumed. """ - FLAGS.xenapi_image_service = 'objectstore' + FLAGS.image_service = 'nova.image.s3.S3ImageService' self.fake_instance.image_ref = glance_stubs.FakeGlance.IMAGE_RAW self.fake_instance.kernel_id = None self.assert_disk_type(vm_utils.ImageType.DISK_RAW) @@ -847,7 +848,7 @@ class XenAPIDetermineDiskImageTestCase(test.TestCase): If we're using Glance, then defer to the image_type field, which in this case will be 'raw'. """ - FLAGS.xenapi_image_service = 'glance' + FLAGS.image_service = 'nova.image.glance.GlanceImageService' self.fake_instance.image_ref = glance_stubs.FakeGlance.IMAGE_RAW self.fake_instance.kernel_id = None self.assert_disk_type(vm_utils.ImageType.DISK_RAW) @@ -857,7 +858,7 @@ class XenAPIDetermineDiskImageTestCase(test.TestCase): If we're using Glance, then defer to the image_type field, which in this case will be 'vhd'. """ - FLAGS.xenapi_image_service = 'glance' + FLAGS.image_service = 'nova.image.glance.GlanceImageService' self.fake_instance.image_ref = glance_stubs.FakeGlance.IMAGE_VHD self.fake_instance.kernel_id = None self.assert_disk_type(vm_utils.ImageType.DISK_VHD) From 1a64e29d14c8ec23fefcc9fc4e4e09660a7aeca4 Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Tue, 26 Jul 2011 11:26:33 -0400 Subject: [PATCH 04/47] removing objectstore and image_service flag checking --- nova/tests/test_xenapi.py | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py index 87e2e93b..77d3062b 100644 --- a/nova/tests/test_xenapi.py +++ b/nova/tests/test_xenapi.py @@ -429,7 +429,6 @@ class XenAPIVMTestCase(test.TestCase): self.assertTrue(instance.architecture) def test_spawn_not_enough_memory(self): - FLAGS.image_service = 'nova.image.glance.GlanceImageService' self.assertRaises(Exception, self._test_spawn, 1, 2, 3, "4") # m1.xlarge @@ -441,7 +440,6 @@ class XenAPIVMTestCase(test.TestCase): """ vdi_recs_start = self._list_vdis() - FLAGS.image_service = 'nova.image.glance.GlanceImageService' stubs.stubout_fetch_image_glance_disk(self.stubs) self.assertRaises(xenapi_fake.Failure, self._test_spawn, 1, 2, 3) @@ -456,7 +454,6 @@ class XenAPIVMTestCase(test.TestCase): """ vdi_recs_start = self._list_vdis() - FLAGS.image_service = 'nova.image.glance.GlanceImageService' stubs.stubout_create_vm(self.stubs) self.assertRaises(xenapi_fake.Failure, self._test_spawn, 1, 2, 3) @@ -464,22 +461,12 @@ class XenAPIVMTestCase(test.TestCase): vdi_recs_end = self._list_vdis() self._check_vdis(vdi_recs_start, vdi_recs_end) - def test_spawn_raw_objectstore(self): - FLAGS.image_service = 'nova.image.s3.S3ImageService' - self._test_spawn(1, None, None) - - def test_spawn_objectstore(self): - FLAGS.image_service = 'nova.image.s3.S3ImageService' - self._test_spawn(1, 2, 3) - @stub_vm_utils_with_vdi_attached_here def test_spawn_raw_glance(self): - FLAGS.image_service = 'nova.image.glance.GlanceImageService' self._test_spawn(glance_stubs.FakeGlance.IMAGE_RAW, None, None) self.check_vm_params_for_linux() def test_spawn_vhd_glance_linux(self): - FLAGS.image_service = 'nova.image.glance.GlanceImageService' self._test_spawn(glance_stubs.FakeGlance.IMAGE_VHD, None, None, os_type="linux", architecture="x86-64") self.check_vm_params_for_linux() @@ -508,20 +495,17 @@ class XenAPIVMTestCase(test.TestCase): self.assertEqual(len(self.vm['VBDs']), 1) def test_spawn_vhd_glance_windows(self): - FLAGS.image_service = 'nova.image.glance.GlanceImageService' self._test_spawn(glance_stubs.FakeGlance.IMAGE_VHD, None, None, os_type="windows", architecture="i386") self.check_vm_params_for_windows() def test_spawn_glance(self): - FLAGS.image_service = 'nova.image.glance.GlanceImageService' self._test_spawn(glance_stubs.FakeGlance.IMAGE_MACHINE, glance_stubs.FakeGlance.IMAGE_KERNEL, glance_stubs.FakeGlance.IMAGE_RAMDISK) self.check_vm_params_for_linux_with_external_kernel() def test_spawn_netinject_file(self): - FLAGS.image_service = 'nova.image.glance.GlanceImageService' db_fakes.stub_out_db_instance_api(self.stubs, injected=True) self._tee_executed = False @@ -547,7 +531,6 @@ class XenAPIVMTestCase(test.TestCase): # Capture the sudo tee .../etc/network/interfaces command (r'(sudo\s+)?tee.*interfaces', _tee_handler), ]) - FLAGS.image_service = 'nova.image.glance.GlanceImageService' self._test_spawn(glance_stubs.FakeGlance.IMAGE_MACHINE, glance_stubs.FakeGlance.IMAGE_KERNEL, glance_stubs.FakeGlance.IMAGE_RAMDISK, @@ -555,7 +538,6 @@ class XenAPIVMTestCase(test.TestCase): self.assertTrue(self._tee_executed) def test_spawn_netinject_xenstore(self): - FLAGS.image_service = 'nova.image.glance.GlanceImageService' db_fakes.stub_out_db_instance_api(self.stubs, injected=True) self._tee_executed = False @@ -784,7 +766,6 @@ class XenAPIMigrateInstance(test.TestCase): conn.migrate_disk_and_power_off(instance, '127.0.0.1') def test_finish_resize(self): - FLAGS.image_service = 'nova.image.glance.GlanceImageService' instance = db.instance_create(self.context, self.values) stubs.stubout_session(self.stubs, stubs.FakeSessionForMigrationTests) stubs.stubout_loopingcall_start(self.stubs) @@ -828,7 +809,6 @@ class XenAPIDetermineDiskImageTestCase(test.TestCase): def test_instance_disk(self): """If a kernel is specified, the image type is DISK (aka machine).""" - FLAGS.image_service = 'nova.image.s3.S3ImageService' self.fake_instance.image_ref = glance_stubs.FakeGlance.IMAGE_MACHINE self.fake_instance.kernel_id = glance_stubs.FakeGlance.IMAGE_KERNEL self.assert_disk_type(vm_utils.ImageType.DISK) @@ -838,7 +818,6 @@ class XenAPIDetermineDiskImageTestCase(test.TestCase): If the kernel isn't specified, and we're not using Glance, then DISK_RAW is assumed. """ - FLAGS.image_service = 'nova.image.s3.S3ImageService' self.fake_instance.image_ref = glance_stubs.FakeGlance.IMAGE_RAW self.fake_instance.kernel_id = None self.assert_disk_type(vm_utils.ImageType.DISK_RAW) @@ -848,7 +827,6 @@ class XenAPIDetermineDiskImageTestCase(test.TestCase): If we're using Glance, then defer to the image_type field, which in this case will be 'raw'. """ - FLAGS.image_service = 'nova.image.glance.GlanceImageService' self.fake_instance.image_ref = glance_stubs.FakeGlance.IMAGE_RAW self.fake_instance.kernel_id = None self.assert_disk_type(vm_utils.ImageType.DISK_RAW) @@ -858,7 +836,6 @@ class XenAPIDetermineDiskImageTestCase(test.TestCase): If we're using Glance, then defer to the image_type field, which in this case will be 'vhd'. """ - FLAGS.image_service = 'nova.image.glance.GlanceImageService' self.fake_instance.image_ref = glance_stubs.FakeGlance.IMAGE_VHD self.fake_instance.kernel_id = None self.assert_disk_type(vm_utils.ImageType.DISK_VHD) From 8f0ed530f85e2790c40f23c2e18305ba412104f1 Mon Sep 17 00:00:00 2001 From: John Tran Date: Tue, 26 Jul 2011 10:03:16 -0700 Subject: [PATCH 05/47] added warning when size of subnet(s) being created are larger than FLAG.network_size in attempt to alleviate confusion. For example, currently when 'nova-manage network create foo 192.168.0.0/16', the result is that it creates a 192.168.0.0/24 instead without any indication to why. --- bin/nova-manage | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/bin/nova-manage b/bin/nova-manage index b63bd326..da9538e3 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -56,6 +56,7 @@ import gettext import glob import json +import math import netaddr import os import sys @@ -669,6 +670,14 @@ class NetworkCommands(object): num_networks = FLAGS.num_networks if not network_size: network_size = FLAGS.network_size + fixnet = netaddr.IPNetwork(fixed_range) + each_subnet_size = fixnet.size / int(num_networks) + if each_subnet_size > network_size: + subnet = 32 - int(math.log(network_size, 2)) + oversize_msg = _('Subnet(s) too large, defaulting to /%s.' + ' To override, specify network_size flag.' + % subnet) + print oversize_msg if not multi_host: multi_host = FLAGS.multi_host else: From 4a7d8d520196851fe6d68c99309b0c0cf13d760c Mon Sep 17 00:00:00 2001 From: John Tran Date: Tue, 26 Jul 2011 13:12:34 -0700 Subject: [PATCH 06/47] fixed per peer review --- bin/nova-manage | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/nova-manage b/bin/nova-manage index da9538e3..ca60d28d 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -676,7 +676,7 @@ class NetworkCommands(object): subnet = 32 - int(math.log(network_size, 2)) oversize_msg = _('Subnet(s) too large, defaulting to /%s.' ' To override, specify network_size flag.' - % subnet) + ) % subnet print oversize_msg if not multi_host: multi_host = FLAGS.multi_host From fbcd71bea88b39e0063bc10d9c2216bb419e1a45 Mon Sep 17 00:00:00 2001 From: "Kevin L. Mitchell" Date: Wed, 27 Jul 2011 17:16:46 +0000 Subject: [PATCH 07/47] Add context argument a lot more places and make unit tests work --- nova/tests/test_libvirt.py | 6 +++--- nova/tests/test_xenapi.py | 16 +++++++++------- nova/tests/xenapi/stubs.py | 4 ++-- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/nova/tests/test_libvirt.py b/nova/tests/test_libvirt.py index ad0931a8..c4af3842 100644 --- a/nova/tests/test_libvirt.py +++ b/nova/tests/test_libvirt.py @@ -365,7 +365,7 @@ class LibvirtConnTestCase(test.TestCase): self.mox.ReplayAll() conn = connection.LibvirtConnection(False) - conn.snapshot(instance_ref, recv_meta['id']) + conn.snapshot(self.context, instance_ref, recv_meta['id']) snapshot = image_service.show(context, recv_meta['id']) self.assertEquals(snapshot['properties']['image_state'], 'available') @@ -405,7 +405,7 @@ class LibvirtConnTestCase(test.TestCase): self.mox.ReplayAll() conn = connection.LibvirtConnection(False) - conn.snapshot(instance_ref, recv_meta['id']) + conn.snapshot(self.context, instance_ref, recv_meta['id']) snapshot = image_service.show(context, recv_meta['id']) self.assertEquals(snapshot['properties']['image_state'], 'available') @@ -775,7 +775,7 @@ class LibvirtConnTestCase(test.TestCase): network_info = [(network, mapping)] try: - conn.spawn(instance, network_info) + conn.spawn(context.get_admin_context(), instance, network_info) except Exception, e: count = (0 <= str(e.message).find('Unexpected method call')) diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py index 199a8bc5..fd841642 100644 --- a/nova/tests/test_xenapi.py +++ b/nova/tests/test_xenapi.py @@ -227,7 +227,7 @@ class XenAPIVMTestCase(test.TestCase): 'mac': 'DE:AD:BE:EF:00:00', 'rxtx_cap': 3})] instance = db.instance_create(self.context, values) - self.conn.spawn(instance, network_info) + self.conn.spawn(self.context, instance, network_info) gt1 = eventlet.spawn(_do_build, 1, self.project.id, self.user.id) gt2 = eventlet.spawn(_do_build, 2, self.project.id, self.user.id) @@ -257,14 +257,15 @@ class XenAPIVMTestCase(test.TestCase): instance = self._create_instance() name = "MySnapshot" - self.assertRaises(exception.Error, self.conn.snapshot, instance, name) + self.assertRaises(exception.Error, self.conn.snapshot, + self.context, instance, name) def test_instance_snapshot(self): stubs.stubout_instance_snapshot(self.stubs) instance = self._create_instance() name = "MySnapshot" - template_vm_ref = self.conn.snapshot(instance, name) + template_vm_ref = self.conn.snapshot(self.context, instance, name) def ensure_vm_was_torn_down(): vm_labels = [] @@ -422,7 +423,7 @@ class XenAPIVMTestCase(test.TestCase): 'label': 'fake', 'mac': 'DE:AD:BE:EF:00:00', 'rxtx_cap': 3})] - self.conn.spawn(instance, network_info) + self.conn.spawn(self.context, instance, network_info) self.create_vm_record(self.conn, os_type, instance_id) self.check_vm_record(self.conn, check_injection) self.assertTrue(instance.os_type) @@ -691,7 +692,7 @@ class XenAPIVMTestCase(test.TestCase): 'label': 'fake', 'mac': 'DE:AD:BE:EF:00:00', 'rxtx_cap': 3})] - self.conn.spawn(instance, network_info) + self.conn.spawn(self.context, instance, network_info) return instance @@ -802,8 +803,9 @@ class XenAPIMigrateInstance(test.TestCase): 'label': 'fake', 'mac': 'DE:AD:BE:EF:00:00', 'rxtx_cap': 3})] - conn.finish_resize(instance, dict(base_copy='hurr', cow='durr'), - network_info) + conn.finish_resize(self.context, instance, + dict(base_copy='hurr', cow='durr'), + network_info) class XenAPIDetermineDiskImageTestCase(test.TestCase): diff --git a/nova/tests/xenapi/stubs.py b/nova/tests/xenapi/stubs.py index 66c79d46..3a142081 100644 --- a/nova/tests/xenapi/stubs.py +++ b/nova/tests/xenapi/stubs.py @@ -28,8 +28,8 @@ from nova import utils def stubout_instance_snapshot(stubs): @classmethod - def fake_fetch_image(cls, session, instance_id, image, user, project, - type): + def fake_fetch_image(cls, context, session, instance_id, image, user, + project, type): from nova.virt.xenapi.fake import create_vdi name_label = "instance-%s" % instance_id #TODO: create fake SR record From fe38716fb1a2320f0fa10f94490dd48ec0cef3e0 Mon Sep 17 00:00:00 2001 From: "Kevin L. Mitchell" Date: Wed, 27 Jul 2011 17:56:12 +0000 Subject: [PATCH 08/47] Fix context argument in a test; add TODOs --- nova/tests/test_libvirt.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/tests/test_libvirt.py b/nova/tests/test_libvirt.py index c4af3842..d4f8f00d 100644 --- a/nova/tests/test_libvirt.py +++ b/nova/tests/test_libvirt.py @@ -775,7 +775,7 @@ class LibvirtConnTestCase(test.TestCase): network_info = [(network, mapping)] try: - conn.spawn(context.get_admin_context(), instance, network_info) + conn.spawn(self.context, instance, network_info) except Exception, e: count = (0 <= str(e.message).find('Unexpected method call')) From 17a836240f76e8d4815d844b6747935a3fc88721 Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Thu, 28 Jul 2011 08:34:27 -0700 Subject: [PATCH 09/47] make payload json serializable --- nova/notifier/api.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/nova/notifier/api.py b/nova/notifier/api.py index 98969fd3..45105d00 100644 --- a/nova/notifier/api.py +++ b/nova/notifier/api.py @@ -80,6 +80,12 @@ def notify(publisher_id, event_type, priority, payload): if priority not in log_levels: raise BadPriorityException( _('%s not in valid priorities' % priority)) + + # Ensure everything is JSON serializable. + for k, v in payload.iteritems(): + if not isinstance(v, (basestring, int, long, float)): + payload[k] = str(v) + driver = utils.import_object(FLAGS.notification_driver) msg = dict(message_id=str(uuid.uuid4()), publisher_id=publisher_id, From e851d58bc04b31154194cad71f785272665dc3ff Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Thu, 28 Jul 2011 08:44:01 -0700 Subject: [PATCH 10/47] unicode instead of str() --- nova/notifier/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/notifier/api.py b/nova/notifier/api.py index 45105d00..8eea2a03 100644 --- a/nova/notifier/api.py +++ b/nova/notifier/api.py @@ -84,7 +84,7 @@ def notify(publisher_id, event_type, priority, payload): # Ensure everything is JSON serializable. for k, v in payload.iteritems(): if not isinstance(v, (basestring, int, long, float)): - payload[k] = str(v) + payload[k] = unicode(v) driver = utils.import_object(FLAGS.notification_driver) msg = dict(message_id=str(uuid.uuid4()), From 150a3483023c498b68ef0cf02bd617ddb71ad743 Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Fri, 29 Jul 2011 07:05:27 -0700 Subject: [PATCH 11/47] added instance support to to_primitive and tests --- nova/notifier/api.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/nova/notifier/api.py b/nova/notifier/api.py index 8eea2a03..70264efa 100644 --- a/nova/notifier/api.py +++ b/nova/notifier/api.py @@ -82,9 +82,7 @@ def notify(publisher_id, event_type, priority, payload): _('%s not in valid priorities' % priority)) # Ensure everything is JSON serializable. - for k, v in payload.iteritems(): - if not isinstance(v, (basestring, int, long, float)): - payload[k] = unicode(v) + payload = utils.to_primitive(payload) driver = utils.import_object(FLAGS.notification_driver) msg = dict(message_id=str(uuid.uuid4()), From 05ec14bc3840ec8ad0ef5325a71de822c8b4741d Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Fri, 29 Jul 2011 12:21:46 -0400 Subject: [PATCH 12/47] updating HACKING --- HACKING | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 63 insertions(+), 6 deletions(-) diff --git a/HACKING b/HACKING index 2f364c89..2dcb7659 100644 --- a/HACKING +++ b/HACKING @@ -10,13 +10,14 @@ Imports - thou shalt not import objects, only modules - thou shalt not import more than one module per line - thou shalt not make relative imports +- thou shalt order your imports by the full module path - thou shalt organize your imports according to the following template :: # vim: tabstop=4 shiftwidth=4 softtabstop=4 - {{stdlib imports in human alphabetical order}} + {{stdlib imports in human alphabetical order by module name}} \n - {{nova imports in human alphabetical order}} + {{nova imports in human alphabetical order by module name}} \n \n {{begin your code}} @@ -42,11 +43,12 @@ Human Alphabetical Order Examples import time import unittest - from nova import flags - from nova import test + import nova.api.ec2 + from nova.api import openstack from nova.auth import users - from nova.endpoint import api + import nova.flags from nova.endpoint import cloud + from nova import test Docstrings ---------- @@ -70,6 +72,61 @@ Docstrings :param foo: the foo parameter :param bar: the bar parameter - :returns: description of the return value + :returns: return_type -- description of the return value + :raises: AttributeError, KeyError """ + +Dictionaries/Lists +------------------ + If a dictionary (dict) or list object is longer than 80 characters, its + items should be split with newlines. Embedded iterables should have their + items indented. Additionally, the last item in the dictionary should have + a trailing comma. This increases readability and simplifies future diffs. + + Example: + + my_dictionary = { + "image": { + "name": "Just a Snapshot", + "size": 2749573, + "properties": { + "user_id": 12, + "arch": "x86_64", + }, + "things": [ + "thing_one", + "thing_two", + ], + "status": "ACTIVE", + }, + } + +Method Signatures +----------------- + Calls to methods 80 characters or longer should format each argument with + newlines. This is mainly for readability. + + unnecessarily_long_function_name('string one', + 'string two', + kwarg1=constants.ACTIVE, + kwarg2=['a', 'b', 'c']) + + + Rather than constructing parameters inline, it is better to break things up: + + list_of_strings = [ + 'what_a_long_string', + 'not as long', + ] + + dict_of_numbers = { + 'one': 1, + 'two': 2, + 'twenty four': 24, + } + + object_one.call_a_method('string three', + 'string four', + kwarg1=list_of_strings, + kwarg2=dict_of_numbers) From 39e1c6595be9cf52e040642796bad6e2e7f72ea6 Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Fri, 29 Jul 2011 12:44:11 -0400 Subject: [PATCH 13/47] expanding --- HACKING | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/HACKING b/HACKING index 2dcb7659..ee919e20 100644 --- a/HACKING +++ b/HACKING @@ -50,6 +50,7 @@ Human Alphabetical Order Examples from nova.endpoint import cloud from nova import test + Docstrings ---------- """A one line docstring looks like this and ends in a period.""" @@ -77,6 +78,7 @@ Docstrings """ + Dictionaries/Lists ------------------ If a dictionary (dict) or list object is longer than 80 characters, its @@ -101,9 +103,38 @@ Dictionaries/Lists "status": "ACTIVE", }, } + + Only use the dict constructor for casting. Do not use it to create a new + dictionary. -Method Signatures ------------------ + Example (BAD): + + my_dictionary = dict(key1='param1', key2='param2', key3=['a', 'b']) + + +Defining Methods +---------------- + Method signatures longer than 80 characters are very unreadable. If you + encounter this problem, first you should determine if your method is + too big. Otherwise, you should compress your keyword arguments with a + '**kwargs' parameter. You should use the 'kwargs' in your method as a + dictionary to retrieve the necessary keyword arguments. + + Example (BAD): + + def my_method(argument_one, argument_two, kwarg_one='default_one', + kwarg_two='default_two', kwarg_three='default_three'): + + Example (GOOD): + + def my_method(argumet_one, argument_two, **kwargs): + kwarg_one = kwargs.get('kwarg_one', 'default_one') + kwarg_two = kwargs.get('kwarg_one', 'default_one') + kwarg_three = kwargs.get('kwarg_three', 'default_three') + + +Calling Methods +--------------- Calls to methods 80 characters or longer should format each argument with newlines. This is mainly for readability. @@ -130,3 +161,26 @@ Method Signatures 'string four', kwarg1=list_of_strings, kwarg2=dict_of_numbers) + +Internationalization (i18n) Strings +---------------------------- + In order to support multiple languages, we have a mechanism to support + automatic translations of exception and log strings. + + Example: + msg = _("An error occurred") + raise HTTPBadRequest(explanation=msg) + + If you have a variable to place within the string, first internationalize + the template string then do the replacement. + + Example: + msg = _("Missing parameter: %s") % ("flavor",) + LOG.error(msg) + + If you have multiple variables to place in the string, use keyword + parameters. This helps our translators reorder parameters when needed. + + Example: + msg = _("The server with id %(s_id)s has no key %(m_key)s") + LOG.error(msg % (s_id="1234, m_key="imageId")) From 79f7ec7d7ac3a5221550918c847bd3c98a1b5309 Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Fri, 29 Jul 2011 12:49:48 -0400 Subject: [PATCH 14/47] upgrades --- HACKING | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/HACKING b/HACKING index ee919e20..82ccdb96 100644 --- a/HACKING +++ b/HACKING @@ -5,13 +5,23 @@ Step 1: Read http://www.python.org/dev/peps/pep-0008/ Step 2: Read http://www.python.org/dev/peps/pep-0008/ again Step 3: Read on + +General +------- +- Put two newlines twixt toplevel code (funcs, classes, etc) +- Put one newline twixt methods in classes and anywhere else +- Do not write "except:", use "except Exception:" at the very least +- Include your name with TODOs as in "TODO(termie)" +- Do not name anything the same name as a builtin or reserved word + + Imports ------- -- thou shalt not import objects, only modules -- thou shalt not import more than one module per line -- thou shalt not make relative imports -- thou shalt order your imports by the full module path -- thou shalt organize your imports according to the following template +- Do not import objects, only modules +- Do not import more than one module per line +- Do not make relative imports +- Order your imports by the full module path +- Organize your imports according to the following template :: # vim: tabstop=4 shiftwidth=4 softtabstop=4 @@ -23,16 +33,6 @@ Imports {{begin your code}} -General -------- -- thou shalt put two newlines twixt toplevel code (funcs, classes, etc) -- thou shalt put one newline twixt methods in classes and anywhere else -- thou shalt not write "except:", use "except Exception:" at the very least -- thou shalt include your name with TODOs as in "TODO(termie)" -- thou shalt not name anything the same name as a builtin or reserved word -- thou shalt not violate causality in our time cone, or else - - Human Alphabetical Order Examples --------------------------------- :: From 1d849d4deaa17c3011f5b6209b85cf5c571a36ee Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Fri, 29 Jul 2011 12:54:55 -0400 Subject: [PATCH 15/47] one last change --- HACKING | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/HACKING b/HACKING index 82ccdb96..9d6b43b9 100644 --- a/HACKING +++ b/HACKING @@ -8,11 +8,11 @@ Step 3: Read on General ------- -- Put two newlines twixt toplevel code (funcs, classes, etc) -- Put one newline twixt methods in classes and anywhere else +- Put two newlines between top-level code (funcs, classes, etc) +- Put one newline between methods in classes and anywhere else - Do not write "except:", use "except Exception:" at the very least -- Include your name with TODOs as in "TODO(termie)" -- Do not name anything the same name as a builtin or reserved word +- Include your name with TODOs as in "#TODO(termie)" +- Do not name anything the same name as a built-in or reserved word Imports From cccdbcae9a79e3a293b9eb13af75b2268b7dc047 Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Fri, 29 Jul 2011 13:00:09 -0400 Subject: [PATCH 16/47] rewording --- HACKING | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HACKING b/HACKING index 9d6b43b9..cb5f696d 100644 --- a/HACKING +++ b/HACKING @@ -136,7 +136,7 @@ Defining Methods Calling Methods --------------- Calls to methods 80 characters or longer should format each argument with - newlines. This is mainly for readability. + newlines. This is not a requirement, but a guideline. unnecessarily_long_function_name('string one', 'string two', From 9f93a5f69b30bd6dc538e397df131ba7cd5ca706 Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Fri, 29 Jul 2011 13:46:24 -0400 Subject: [PATCH 17/47] rewording --- HACKING | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/HACKING b/HACKING index cb5f696d..4c519377 100644 --- a/HACKING +++ b/HACKING @@ -116,16 +116,12 @@ Defining Methods ---------------- Method signatures longer than 80 characters are very unreadable. If you encounter this problem, first you should determine if your method is - too big. Otherwise, you should compress your keyword arguments with a - '**kwargs' parameter. You should use the 'kwargs' in your method as a - dictionary to retrieve the necessary keyword arguments. + too big. If not, you can compress your keyword arguments with a + '**kwargs' parameter. You can then use 'kwargs' in your method as a + dictionary to retrieve the necessary keyword arguments. This is just a + guideline, not a requirement. - Example (BAD): - - def my_method(argument_one, argument_two, kwarg_one='default_one', - kwarg_two='default_two', kwarg_three='default_three'): - - Example (GOOD): + Example: def my_method(argumet_one, argument_two, **kwargs): kwarg_one = kwargs.get('kwarg_one', 'default_one') From 2f83a5edb026f17c8dde8df9a8341a27f73b32af Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Fri, 29 Jul 2011 13:51:49 -0400 Subject: [PATCH 18/47] removing 'Defining Methods' paragraph --- HACKING | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/HACKING b/HACKING index 4c519377..ea018814 100644 --- a/HACKING +++ b/HACKING @@ -112,23 +112,6 @@ Dictionaries/Lists my_dictionary = dict(key1='param1', key2='param2', key3=['a', 'b']) -Defining Methods ----------------- - Method signatures longer than 80 characters are very unreadable. If you - encounter this problem, first you should determine if your method is - too big. If not, you can compress your keyword arguments with a - '**kwargs' parameter. You can then use 'kwargs' in your method as a - dictionary to retrieve the necessary keyword arguments. This is just a - guideline, not a requirement. - - Example: - - def my_method(argumet_one, argument_two, **kwargs): - kwarg_one = kwargs.get('kwarg_one', 'default_one') - kwarg_two = kwargs.get('kwarg_one', 'default_one') - kwarg_three = kwargs.get('kwarg_three', 'default_three') - - Calling Methods --------------- Calls to methods 80 characters or longer should format each argument with @@ -158,6 +141,7 @@ Calling Methods kwarg1=list_of_strings, kwarg2=dict_of_numbers) + Internationalization (i18n) Strings ---------------------------- In order to support multiple languages, we have a mechanism to support From 8f178e3f86330ec4ed59a05c32de9ca1e1f17eba Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Fri, 29 Jul 2011 12:09:17 -0700 Subject: [PATCH 19/47] made the whole instance handling thing optional --- nova/notifier/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nova/notifier/api.py b/nova/notifier/api.py index 70264efa..e18f3e28 100644 --- a/nova/notifier/api.py +++ b/nova/notifier/api.py @@ -82,7 +82,7 @@ def notify(publisher_id, event_type, priority, payload): _('%s not in valid priorities' % priority)) # Ensure everything is JSON serializable. - payload = utils.to_primitive(payload) + payload = utils.to_primitive(payload, convert_instances=True) driver = utils.import_object(FLAGS.notification_driver) msg = dict(message_id=str(uuid.uuid4()), From fe1c31195cfa4a2487cc6373a0884fa547ca3ed6 Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Fri, 29 Jul 2011 15:26:14 -0400 Subject: [PATCH 20/47] adding more on return_type in docstrings --- HACKING | 1 + 1 file changed, 1 insertion(+) diff --git a/HACKING b/HACKING index ea018814..2f33fd19 100644 --- a/HACKING +++ b/HACKING @@ -74,6 +74,7 @@ Docstrings :param foo: the foo parameter :param bar: the bar parameter :returns: return_type -- description of the return value + :returns: description of the return value :raises: AttributeError, KeyError """ From 0c8bfbf777bb974c730763c46ede20ad7d848021 Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Fri, 29 Jul 2011 15:32:27 -0400 Subject: [PATCH 21/47] removing dict() comment --- HACKING | 7 ------- 1 file changed, 7 deletions(-) diff --git a/HACKING b/HACKING index 2f33fd19..9e1b2966 100644 --- a/HACKING +++ b/HACKING @@ -105,13 +105,6 @@ Dictionaries/Lists }, } - Only use the dict constructor for casting. Do not use it to create a new - dictionary. - - Example (BAD): - - my_dictionary = dict(key1='param1', key2='param2', key3=['a', 'b']) - Calling Methods --------------- From e8a2c08d5c8e4cc06ee7209fba32d286630eee68 Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Fri, 29 Jul 2011 15:42:10 -0400 Subject: [PATCH 22/47] removing extra verbage --- HACKING | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/HACKING b/HACKING index 9e1b2966..70b2b09e 100644 --- a/HACKING +++ b/HACKING @@ -25,9 +25,9 @@ Imports :: # vim: tabstop=4 shiftwidth=4 softtabstop=4 - {{stdlib imports in human alphabetical order by module name}} + {{stdlib imports in human alphabetical order}} \n - {{nova imports in human alphabetical order by module name}} + {{nova imports in human alphabetical order}} \n \n {{begin your code}} From d1b508a11d7586c21f03b1b40b161dfcb9c84357 Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Fri, 29 Jul 2011 15:43:23 -0400 Subject: [PATCH 23/47] fixing underline --- HACKING | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HACKING b/HACKING index 70b2b09e..3d79e9e8 100644 --- a/HACKING +++ b/HACKING @@ -137,7 +137,7 @@ Calling Methods Internationalization (i18n) Strings ----------------------------- +----------------------------------- In order to support multiple languages, we have a mechanism to support automatic translations of exception and log strings. From 02eb2bd11bfd6a14bce8ab26453ba2a3614c48c2 Mon Sep 17 00:00:00 2001 From: Jason Koelker Date: Fri, 29 Jul 2011 14:53:38 -0500 Subject: [PATCH 24/47] require either v4 or v6 --- bin/nova-manage | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/bin/nova-manage b/bin/nova-manage index 75d74903..3c50e4fc 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -662,8 +662,9 @@ class NetworkCommands(object): # check for certain required inputs if not label: raise exception.NetworkNotCreated(req='--label') - if not fixed_range_v4: - raise exception.NetworkNotCreated(req='--fixed_range_v4') + if not (fixed_range_v4 or fixed_range_v6): + req = '--fixed_range_v4 or --fixed_range_v6' + raise exception.NetworkNotCreated(req=req) bridge = bridge or FLAGS.flat_network_bridge if not bridge: From 4da751f64b171a5417f2e9bc839b116c44117647 Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Fri, 29 Jul 2011 15:58:41 -0400 Subject: [PATCH 25/47] typo --- HACKING | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HACKING b/HACKING index 3d79e9e8..232a353f 100644 --- a/HACKING +++ b/HACKING @@ -157,4 +157,4 @@ Internationalization (i18n) Strings Example: msg = _("The server with id %(s_id)s has no key %(m_key)s") - LOG.error(msg % (s_id="1234, m_key="imageId")) + LOG.error(msg % {"s_id": "1234", "m_key": "imageId"}) From c10f77cd59b1e47822989880a7c744eabd5036b5 Mon Sep 17 00:00:00 2001 From: Jason Koelker Date: Fri, 29 Jul 2011 15:05:53 -0500 Subject: [PATCH 26/47] stwart the switch to just fixed_range --- bin/nova-manage | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/bin/nova-manage b/bin/nova-manage index 3c50e4fc..1c3bd998 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -632,6 +632,7 @@ class NetworkCommands(object): @args('--label', dest="label", metavar='