diff --git a/nova/cmd/api_metadata.py b/nova/cmd/api_metadata.py index 26b4ffd5e418..4cbb9c76e185 100644 --- a/nova/cmd/api_metadata.py +++ b/nova/cmd/api_metadata.py @@ -42,9 +42,7 @@ def main(): gmr.TextGuruMeditation.setup_autorun(version) - if not CONF.conductor.use_local: - objects_base.NovaObject.indirection_api = \ - conductor_rpcapi.ConductorAPI() + objects_base.NovaObject.indirection_api = conductor_rpcapi.ConductorAPI() should_use_ssl = 'metadata' in CONF.enabled_ssl_apis server = service.WSGIService('metadata', use_ssl=should_use_ssl) diff --git a/nova/cmd/compute.py b/nova/cmd/compute.py index af321e008ac7..628b058c0e99 100644 --- a/nova/cmd/compute.py +++ b/nova/cmd/compute.py @@ -28,7 +28,6 @@ from nova.cmd import common as cmd_common from nova.conductor import rpcapi as conductor_rpcapi import nova.conf from nova import config -from nova.i18n import _LW from nova import objects from nova.objects import base as objects_base from nova import service @@ -50,16 +49,10 @@ def main(): gmr.TextGuruMeditation.setup_autorun(version) - if not CONF.conductor.use_local: - cmd_common.block_db_access('nova-compute') - objects_base.NovaObject.indirection_api = \ - conductor_rpcapi.ConductorAPI() - else: - LOG.warning(_LW('Conductor local mode is deprecated and will ' - 'be removed in a subsequent release')) + cmd_common.block_db_access('nova-compute') + objects_base.NovaObject.indirection_api = conductor_rpcapi.ConductorAPI() server = service.Service.create(binary='nova-compute', - topic=CONF.compute_topic, - db_allowed=CONF.conductor.use_local) + topic=CONF.compute_topic) service.serve(server) service.wait() diff --git a/nova/cmd/dhcpbridge.py b/nova/cmd/dhcpbridge.py index e6e7c0de0815..2550a5f653e8 100644 --- a/nova/cmd/dhcpbridge.py +++ b/nova/cmd/dhcpbridge.py @@ -33,7 +33,7 @@ from nova.conductor import rpcapi as conductor_rpcapi import nova.conf from nova import config from nova import context -from nova.i18n import _LE, _LW +from nova.i18n import _LE from nova.network import rpcapi as network_rpcapi from nova import objects from nova.objects import base as objects_base @@ -117,13 +117,8 @@ def main(): objects.register_all() - if not CONF.conductor.use_local: - cmd_common.block_db_access('nova-dhcpbridge') - objects_base.NovaObject.indirection_api = \ - conductor_rpcapi.ConductorAPI() - else: - LOG.warning(_LW('Conductor local mode is deprecated and will ' - 'be removed in a subsequent release')) + cmd_common.block_db_access('nova-dhcpbridge') + objects_base.NovaObject.indirection_api = conductor_rpcapi.ConductorAPI() if CONF.action.name in ['add', 'del']: LOG.debug("Called '%(action)s' for mac '%(mac)s' with IP '%(ip)s'", diff --git a/nova/cmd/network.py b/nova/cmd/network.py index 1a83e6529843..0e1733dda469 100644 --- a/nova/cmd/network.py +++ b/nova/cmd/network.py @@ -44,18 +44,12 @@ def main(): gmr.TextGuruMeditation.setup_autorun(version) - if not CONF.conductor.use_local: - cmd_common.block_db_access('nova-network') - objects_base.NovaObject.indirection_api = \ - conductor_rpcapi.ConductorAPI() - else: - LOG.warning(_LW('Conductor local mode is deprecated and will ' - 'be removed in a subsequent release')) + cmd_common.block_db_access('nova-network') + objects_base.NovaObject.indirection_api = conductor_rpcapi.ConductorAPI() LOG.warning(_LW('Nova network is deprecated and will be removed ' 'in the future')) server = service.Service.create(binary='nova-network', - topic=CONF.network_topic, - db_allowed=CONF.conductor.use_local) + topic=CONF.network_topic) service.serve(server) service.wait() diff --git a/nova/conductor/__init__.py b/nova/conductor/__init__.py index 395a95ba7f2e..749ed9a67483 100644 --- a/nova/conductor/__init__.py +++ b/nova/conductor/__init__.py @@ -14,24 +14,7 @@ from nova.conductor import api as conductor_api -import nova.conf - -CONF = nova.conf.CONF -def API(*args, **kwargs): - use_local = kwargs.pop('use_local', False) - if CONF.conductor.use_local or use_local: - api = conductor_api.LocalAPI - else: - api = conductor_api.API - return api(*args, **kwargs) - - -def ComputeTaskAPI(*args, **kwargs): - use_local = kwargs.pop('use_local', False) - if CONF.conductor.use_local or use_local: - api = conductor_api.LocalComputeTaskAPI - else: - api = conductor_api.ComputeTaskAPI - return api(*args, **kwargs) +API = conductor_api.API +ComputeTaskAPI = conductor_api.ComputeTaskAPI diff --git a/nova/conductor/api.py b/nova/conductor/api.py index c12e7cdd1f85..296b76d5980b 100644 --- a/nova/conductor/api.py +++ b/nova/conductor/api.py @@ -16,122 +16,28 @@ from oslo_log import log as logging import oslo_messaging as messaging -from oslo_versionedobjects import base as ovo_base from nova import baserpc -from nova.conductor import manager from nova.conductor import rpcapi import nova.conf from nova.i18n import _LI, _LW -from nova import utils CONF = nova.conf.CONF LOG = logging.getLogger(__name__) -class LocalAPI(object): - """A local version of the conductor API that does database updates - locally instead of via RPC. - """ - - def __init__(self): - # TODO(danms): This needs to be something more generic for - # other/future users of this sort of functionality. - self._manager = utils.ExceptionHelper(manager.ConductorManager()) - - def wait_until_ready(self, context, *args, **kwargs): - # nothing to wait for in the local case. - pass - - def object_backport(self, context, objinst, target_version): - # NOTE(hanlind): This shouldn't be called anymore but leaving it for - # now just in case. Collect the object version manifest and redirect - # to the newer backport call. - object_versions = ovo_base.obj_tree_get_versions(objinst.obj_name()) - return self.object_backport_versions(context, objinst, object_versions) - - def object_backport_versions(self, context, objinst, object_versions): - return self._manager.object_backport_versions(context, objinst, - object_versions) - - -class LocalComputeTaskAPI(object): - def __init__(self): - # TODO(danms): This needs to be something more generic for - # other/future users of this sort of functionality. - self._manager = utils.ExceptionHelper( - manager.ComputeTaskManager()) - - def resize_instance(self, context, instance, extra_instance_updates, - scheduler_hint, flavor, reservations, - clean_shutdown=True, request_spec=None): - # NOTE(comstud): 'extra_instance_updates' is not used here but is - # needed for compatibility with the cells_rpcapi version of this - # method. - self._manager.migrate_server( - context, instance, scheduler_hint, live=False, rebuild=False, - flavor=flavor, block_migration=None, disk_over_commit=None, - reservations=reservations, clean_shutdown=clean_shutdown, - request_spec=request_spec) - - def live_migrate_instance(self, context, instance, host_name, - block_migration, disk_over_commit, - request_spec=None, async=False): - scheduler_hint = {'host': host_name} - if async: - wrap = lambda *args: utils.spawn_n(*args) - else: - wrap = lambda *args: args[0](*args[1:]) - - wrap(self._manager.live_migrate_instance, context, instance, - scheduler_hint, block_migration, disk_over_commit, request_spec) - - def build_instances(self, context, instances, image, - filter_properties, admin_password, injected_files, - requested_networks, security_groups, block_device_mapping, - legacy_bdm=True): - utils.spawn_n(self._manager.build_instances, context, - instances=instances, image=image, - filter_properties=filter_properties, - admin_password=admin_password, injected_files=injected_files, - requested_networks=requested_networks, - security_groups=security_groups, - block_device_mapping=block_device_mapping, - legacy_bdm=legacy_bdm) - - def unshelve_instance(self, context, instance, request_spec=None): - utils.spawn_n(self._manager.unshelve_instance, context, - instance=instance, request_spec=request_spec) - - def rebuild_instance(self, context, instance, orig_image_ref, image_ref, - injected_files, new_pass, orig_sys_metadata, - bdms, recreate=False, on_shared_storage=False, - preserve_ephemeral=False, host=None, - request_spec=None, kwargs=None): - # kwargs unused but required for cell compatibility. - utils.spawn_n(self._manager.rebuild_instance, context, - instance=instance, - new_pass=new_pass, - injected_files=injected_files, - image_ref=image_ref, - orig_image_ref=orig_image_ref, - orig_sys_metadata=orig_sys_metadata, - bdms=bdms, - recreate=recreate, - on_shared_storage=on_shared_storage, - host=host, - preserve_ephemeral=preserve_ephemeral, - request_spec=request_spec) - - -class API(LocalAPI): +class API(object): """Conductor API that does updates via RPC to the ConductorManager.""" def __init__(self): - self._manager = rpcapi.ConductorAPI() + self.conductor_rpcapi = rpcapi.ConductorAPI() self.base_rpcapi = baserpc.BaseAPI(topic=CONF.conductor.topic) + def object_backport_versions(self, context, objinst, object_versions): + return self.conductor_rpcapi.object_backport_versions(context, objinst, + object_versions) + def wait_until_ready(self, context, early_timeout=10, early_attempts=10): '''Wait until a conductor service is up and running. diff --git a/nova/conf/conductor.py b/nova/conf/conductor.py index c1dcb20f892e..30633108a8ee 100644 --- a/nova/conf/conductor.py +++ b/nova/conf/conductor.py @@ -26,18 +26,6 @@ and finally, how many worker processes will be used. ) ALL_OPTS = [ - cfg.BoolOpt( - 'use_local', - default=False, - deprecated_for_removal=True, - deprecated_since='13.0.0', - help=""" -Perform nova-conductor operations locally. This legacy mode was -introduced to bridge a gap during the transition to the conductor service. -It no longer represents a reasonable alternative for deployers. - -Removal may be as early as 14.0. -"""), cfg.StrOpt( 'topic', default='conductor', diff --git a/nova/service.py b/nova/service.py index 8d85b502eb09..2b7580b38d04 100644 --- a/nova/service.py +++ b/nova/service.py @@ -80,8 +80,7 @@ class Service(service.Service): def __init__(self, host, binary, topic, manager, report_interval=None, periodic_enable=None, periodic_fuzzy_delay=None, - periodic_interval_max=None, db_allowed=True, - *args, **kwargs): + periodic_interval_max=None, *args, **kwargs): super(Service, self).__init__() self.host = host self.binary = binary @@ -97,8 +96,9 @@ class Service(service.Service): self.periodic_interval_max = periodic_interval_max self.saved_args, self.saved_kwargs = args, kwargs self.backdoor_port = None - self.conductor_api = conductor.API(use_local=db_allowed) - self.conductor_api.wait_until_ready(context.get_admin_context()) + if objects_base.NovaObject.indirection_api: + conductor_api = conductor.API() + conductor_api.wait_until_ready(context.get_admin_context()) def __repr__(self): return "<%(cls_name)s: host=%(host)s, binary=%(binary)s, " \ @@ -177,8 +177,7 @@ class Service(service.Service): @classmethod def create(cls, host=None, binary=None, topic=None, manager=None, report_interval=None, periodic_enable=None, - periodic_fuzzy_delay=None, periodic_interval_max=None, - db_allowed=True): + periodic_fuzzy_delay=None, periodic_interval_max=None): """Instantiates class and passes back application object. :param host: defaults to CONF.host @@ -214,8 +213,7 @@ class Service(service.Service): report_interval=report_interval, periodic_enable=periodic_enable, periodic_fuzzy_delay=periodic_fuzzy_delay, - periodic_interval_max=periodic_interval_max, - db_allowed=db_allowed) + periodic_interval_max=periodic_interval_max) return service_obj diff --git a/nova/tests/unit/conductor/test_conductor.py b/nova/tests/unit/conductor/test_conductor.py index 68c5c8d3174f..754734717c2c 100644 --- a/nova/tests/unit/conductor/test_conductor.py +++ b/nova/tests/unit/conductor/test_conductor.py @@ -28,7 +28,6 @@ from nova.compute import flavors from nova.compute import rpcapi as compute_rpcapi from nova.compute import task_states from nova.compute import vm_states -from nova import conductor from nova.conductor import api as conductor_api from nova.conductor import manager as conductor_manager from nova.conductor import rpcapi as conductor_rpcapi @@ -279,53 +278,6 @@ class ConductorAPITestCase(_BaseTestCase, test.TestCase): self.assertEqual(timeouts.count(10), 10) self.assertIn(None, timeouts) - @mock.patch('oslo_versionedobjects.base.obj_tree_get_versions') - def test_object_backport_redirect(self, mock_ovo): - mock_ovo.return_value = mock.sentinel.obj_versions - mock_objinst = mock.Mock() - - with mock.patch.object(self.conductor, - 'object_backport_versions') as mock_call: - self.conductor.object_backport(mock.sentinel.ctxt, - mock_objinst, - mock.sentinel.target_version) - mock_call.assert_called_once_with(mock.sentinel.ctxt, - mock_objinst, - mock.sentinel.obj_versions) - - -class ConductorLocalAPITestCase(ConductorAPITestCase): - """Conductor LocalAPI Tests.""" - def setUp(self): - super(ConductorLocalAPITestCase, self).setUp() - self.conductor = conductor_api.LocalAPI() - self.conductor_manager = self.conductor._manager._target - - def test_wait_until_ready(self): - # Override test in ConductorAPITestCase - pass - - -class ConductorImportTest(test.NoDBTestCase): - def test_import_conductor_local(self): - self.flags(use_local=True, group='conductor') - self.assertIsInstance(conductor.API(), conductor_api.LocalAPI) - self.assertIsInstance(conductor.ComputeTaskAPI(), - conductor_api.LocalComputeTaskAPI) - - def test_import_conductor_rpc(self): - self.flags(use_local=False, group='conductor') - self.assertIsInstance(conductor.API(), conductor_api.API) - self.assertIsInstance(conductor.ComputeTaskAPI(), - conductor_api.ComputeTaskAPI) - - def test_import_conductor_override_to_local(self): - self.flags(use_local=False, group='conductor') - self.assertIsInstance(conductor.API(use_local=True), - conductor_api.LocalAPI) - self.assertIsInstance(conductor.ComputeTaskAPI(use_local=True), - conductor_api.LocalComputeTaskAPI) - class _BaseTaskTestCase(object): def setUp(self): @@ -395,8 +347,7 @@ class _BaseTaskTestCase(object): scheduler_hint = {'filter_properties': {}} - if isinstance(self.conductor, (conductor_api.ComputeTaskAPI, - conductor_api.LocalComputeTaskAPI)): + if isinstance(self.conductor, conductor_api.ComputeTaskAPI): # The API method is actually 'resize_instance'. It gets # converted into 'migrate_server' when doing RPC. self.conductor.resize_instance( @@ -2111,59 +2062,3 @@ class ConductorTaskAPITestCase(_BaseTaskTestCase, test_compute.BaseTestCase): self.context, inst_obj, {'host': 'destination'}, True, False, None, 'block_migration', 'disk_over_commit', None, request_spec=None) - - -class ConductorLocalComputeTaskAPITestCase(ConductorTaskAPITestCase): - """Conductor LocalComputeTaskAPI Tests.""" - def setUp(self): - super(ConductorLocalComputeTaskAPITestCase, self).setUp() - self.conductor = conductor_api.LocalComputeTaskAPI() - self.conductor_manager = self.conductor._manager._target - - @mock.patch('nova.objects.Migration') - def test_live_migrate(self, migobj): - inst = fake_instance.fake_db_instance() - inst_obj = objects.Instance._from_db_object( - self.context, objects.Instance(), inst, []) - - migration = migobj() - task = mock.MagicMock() - with mock.patch.object(self.conductor_manager, - '_build_live_migrate_task', - return_value=task) as mock_build_task: - self.conductor.live_migrate_instance(self.context, inst_obj, - 'destination', 'block_migration', 'disk_over_commit', - async=False) - mock_build_task.assert_called_once_with(self.context, inst_obj, - 'destination', - 'block_migration', - 'disk_over_commit', - migration, None) - task.execute.assert_called_once() - self.assertEqual('accepted', migration.status) - self.assertEqual('destination', migration.dest_compute) - self.assertEqual(inst_obj.host, migration.source_compute) - - @mock.patch('nova.objects.Migration') - def test_live_migrate_async(self, migobj): - inst = fake_instance.fake_db_instance() - inst_obj = objects.Instance._from_db_object( - self.context, objects.Instance(), inst, []) - - migration = migobj() - task = mock.MagicMock() - with mock.patch.object(self.conductor_manager, - '_build_live_migrate_task', - return_value=task) as mock_build_task: - self.conductor.live_migrate_instance(self.context, inst_obj, - 'destination', 'block_migration', 'disk_over_commit', - async=True) - mock_build_task.assert_called_once_with(self.context, inst_obj, - 'destination', - 'block_migration', - 'disk_over_commit', - migration, None) - task.execute.assert_called_once() - self.assertEqual('accepted', migration.status) - self.assertEqual('destination', migration.dest_compute) - self.assertEqual(inst_obj.host, migration.source_compute) diff --git a/releasenotes/notes/rm-conductor-local-apis-f121afaee99f6fa4.yaml b/releasenotes/notes/rm-conductor-local-apis-f121afaee99f6fa4.yaml new file mode 100644 index 000000000000..a619c85c1c42 --- /dev/null +++ b/releasenotes/notes/rm-conductor-local-apis-f121afaee99f6fa4.yaml @@ -0,0 +1,9 @@ +--- +upgrade: + - | + The ''use_local'' option, which made it possible to + perform nova-conductor operations locally, has been + removed. This legacy mode was introduced to bridge a + gap during the transition to the conductor service. + It no longer represents a reasonable alternative for + deployers.