From bd30eb36bbf2c5164ac47256355c543f6b77e064 Mon Sep 17 00:00:00 2001 From: Monsyne Dragon Date: Tue, 24 Apr 2012 12:39:15 +0000 Subject: Add additional capabilities for computes This allows compute hosts to advertise additional capabilities for use by custom schedulers. This is an interim solution to provide this functionality until it is replaced by more general HostAggregate functionality later in Folsom. Change-Id: Ia288146fa92aec61f50641c2e4f7a3580ab03a32 --- nova/compute/manager.py | 30 +++++++++++++++++++++++++++--- nova/tests/test_compute.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 3 deletions(-) (limited to 'nova') diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 0fe261948..0366b4568 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -124,7 +124,15 @@ compute_opts = [ cfg.IntOpt("heal_instance_info_cache_interval", default=60, help="Number of seconds between instance info_cache self " - "healing updates") + "healing updates"), + cfg.ListOpt('additional_compute_capabilities', + default=[], + help='a list of additional capabilities for this compute ' + 'host to advertise. Valid entries are name=value pairs ' + 'this functionality will be replaced when HostAggregates ' + 'become more funtional for general grouping in Folsom. (see: ' + 'http://etherpad.openstack.org/FolsomNovaHostAggregates-v2)'), + ] FLAGS = flags.FLAGS @@ -190,6 +198,21 @@ def _get_image_meta(context, image_ref): return image_service.show(context, image_id) +def _get_additional_capabilities(): + """Return additional capabilities to advertise for this compute host + This will be replaced once HostAggrgates are able to handle more general + host grouping for custom schedulers.""" + capabilities = {} + for cap in FLAGS.additional_compute_capabilities: + if '=' in cap: + name, value = cap.split('=', 1) + else: + name = cap + value = True + capabilities[name] = value + return capabilities + + class ComputeManager(manager.SchedulerDependentManager): """Manages the running instances from creation to destruction.""" @@ -2265,8 +2288,9 @@ class ComputeManager(manager.SchedulerDependentManager): LOG.info(_("Updating host status")) # This will grab info about the host and queue it # to be sent to the Schedulers. - self.update_service_capabilities( - self.driver.get_host_stats(refresh=True)) + capabilities = _get_additional_capabilities() + capabilities.update(self.driver.get_host_stats(refresh=True)) + self.update_service_capabilities(capabilities) @manager.periodic_task(ticks_between_runs=10) def _sync_power_states(self, context): diff --git a/nova/tests/test_compute.py b/nova/tests/test_compute.py index adb50806d..348a7af0f 100644 --- a/nova/tests/test_compute.py +++ b/nova/tests/test_compute.py @@ -56,6 +56,7 @@ LOG = logging.getLogger(__name__) FLAGS = flags.FLAGS flags.DECLARE('stub_network', 'nova.compute.manager') flags.DECLARE('live_migration_retry_count', 'nova.compute.manager') +flags.DECLARE('additional_compute_capabilities', 'nova.compute.manager') orig_rpc_call = rpc.call @@ -1616,6 +1617,36 @@ class ComputeTestCase(BaseTestCase): self.compute.add_instance_fault_from_exc(ctxt, instance_uuid, NotImplementedError('test')) + def test_get_additional_capabilities(self): + self.flags(additional_compute_capabilities=['test3=xyzzy', + 'test4', + 'nothertest=blat']) + caps = compute_manager._get_additional_capabilities() + all_caps = dict(test3='xyzzy', + test4=True, + nothertest='blat') + for c, val in all_caps.items(): + self.assertTrue(c in caps, c) + self.assertEquals(val, caps[c]) + + def test_report_driver_status(self): + test_caps = dict(test1=1024, test2='foo', nothertest='bar') + self.flags(additional_compute_capabilities=['test3=xyzzy', + 'test4', + 'nothertest=blat']) + self.mox.StubOutWithMock(self.compute.driver, 'get_host_stats') + self.compute.driver.get_host_stats(refresh=True).AndReturn(test_caps) + self.compute._last_host_check = 0 + self.mox.ReplayAll() + + self.compute._report_driver_status(context) + caps = self.compute.last_capabilities + all_caps = dict(test1=1024, test2='foo', test3='xyzzy', + test4=True, nothertest='bar') + for c, val in all_caps.items(): + self.assertTrue(c in caps, c) + self.assertEquals(val, caps[c]) + def test_cleanup_running_deleted_instances(self): admin_context = context.get_admin_context() deleted_at = utils.utcnow() - datetime.timedelta(hours=1, minutes=5) -- cgit