From ede3fcf062cc60ceb6c1d90c7723887335b17d27 Mon Sep 17 00:00:00 2001 From: Sukhdev Date: Thu, 18 Sep 2014 17:15:10 -0700 Subject: [PATCH] Indicate the begin and end of the sync process to EOS Send a trigger to EOS when a sync operation is initiated, and, another trigger when the sync operation is complete. Additionally, sync_interval value (from ml2_conf_arista.ini) is passed down to EOS. This is used by EOS to timeout the transaction. Change-Id: I5110b24380ad848d03719e94283d69a7bc0ce972 Closes-Bug: 1371324 --- .../ml2/drivers/arista/mechanism_arista.py | 40 ++++++++++++++++++- .../arista/test_arista_mechanism_driver.py | 20 ++++++++++ 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/neutron/plugins/ml2/drivers/arista/mechanism_arista.py b/neutron/plugins/ml2/drivers/arista/mechanism_arista.py index 990cca983..195e9e85e 100644 --- a/neutron/plugins/ml2/drivers/arista/mechanism_arista.py +++ b/neutron/plugins/ml2/drivers/arista/mechanism_arista.py @@ -44,6 +44,7 @@ class AristaRPCWrapper(object): self._server = jsonrpclib.Server(self._eapi_host_url()) self.keystone_conf = cfg.CONF.keystone_authtoken self.region = cfg.CONF.ml2_arista.region_name + self.sync_interval = cfg.CONF.ml2_arista.sync_interval self._region_updated_time = None # The cli_commands dict stores the mapping between the CLI command key # and the actual CLI command. @@ -199,6 +200,18 @@ class AristaRPCWrapper(object): 'exit'] self._run_openstack_cmds(cmds) + def sync_start(self): + """Sends indication to EOS that ML2->EOS sync has started.""" + + sync_start_cmd = ['sync start'] + self._run_openstack_cmds(sync_start_cmd) + + def sync_end(self): + """Sends indication to EOS that ML2->EOS sync has completed.""" + + sync_end_cmd = ['sync end'] + self._run_openstack_cmds(sync_end_cmd) + def create_network(self, tenant_id, network): """Creates a single network on Arista hardware @@ -390,6 +403,11 @@ class AristaRPCWrapper(object): self.keystone_conf.admin_user, '******', self.keystone_conf.admin_tenant_name)] + + sync_interval_cmd = 'sync interval %d' % self.sync_interval + cmds.append(sync_interval_cmd) + log_cmds.append(sync_interval_cmd) + self._run_openstack_cmds(cmds, commands_to_log=log_cmds) def clear_region_updated_time(self): @@ -529,7 +547,7 @@ class AristaRPCWrapper(object): class SyncService(object): - """Synchronizatin of information between Neutron and EOS + """Synchronization of information between Neutron and EOS Periodically (through configuration option), this service ensures that Networks and VMs configured on EOS/Arista HW @@ -540,6 +558,24 @@ class SyncService(object): self._ndb = neutron_db self._force_sync = True + def do_synchronize(self): + try: + # Send trigger to EOS that the ML2->EOS sync has started. + self._rpc.sync_start() + LOG.info(_('Sync start trigger sent to EOS')) + except arista_exc.AristaRpcError: + LOG.warning(EOS_UNREACHABLE_MSG) + return + + # Perform the sync + self.synchronize() + + try: + # Send trigger to EOS that the ML2->EOS sync is Complete. + self._rpc.sync_end() + except arista_exc.AristaRpcError: + LOG.warning(EOS_UNREACHABLE_MSG) + def synchronize(self): """Sends data to EOS which differs from neutron DB.""" @@ -1006,7 +1042,7 @@ class AristaDriver(driver_api.MechanismDriver): def _synchronization_thread(self): with self.eos_sync_lock: - self.eos.synchronize() + self.eos.do_synchronize() self.timer = threading.Timer(self.sync_timeout, self._synchronization_thread) diff --git a/neutron/tests/unit/ml2/drivers/arista/test_arista_mechanism_driver.py b/neutron/tests/unit/ml2/drivers/arista/test_arista_mechanism_driver.py index 7eeb97cac..aff8e0293 100644 --- a/neutron/tests/unit/ml2/drivers/arista/test_arista_mechanism_driver.py +++ b/neutron/tests/unit/ml2/drivers/arista/test_arista_mechanism_driver.py @@ -29,6 +29,7 @@ def setup_arista_wrapper_config(value=''): cfg.CONF.keystone_authtoken = fake_keystone_info_class() cfg.CONF.set_override('eapi_host', value, "ml2_arista") cfg.CONF.set_override('eapi_username', value, "ml2_arista") + cfg.CONF.set_override('sync_interval', 10, "ml2_arista") def setup_valid_config(): @@ -219,6 +220,24 @@ class PositiveRPCWrapperValidConfigTestCase(base.BaseTestCase): def test_no_exception_on_correct_configuration(self): self.assertIsNotNone(self.drv) + def test_sync_start(self): + self.drv.sync_start() + cmds = ['enable', 'configure', 'cvx', 'service openstack', + 'region RegionOne', + 'sync start', + 'exit', 'exit', 'exit'] + + self.drv._server.runCmds.assert_called_once_with(version=1, cmds=cmds) + + def test_sync_end(self): + self.drv.sync_end() + cmds = ['enable', 'configure', 'cvx', 'service openstack', + 'region RegionOne', + 'sync end', + 'exit', 'exit', 'exit'] + + self.drv._server.runCmds.assert_called_once_with(version=1, cmds=cmds) + def test_plug_host_into_network(self): tenant_id = 'ten-1' vm_id = 'vm-1' @@ -519,6 +538,7 @@ class PositiveRPCWrapperValidConfigTestCase(base.BaseTestCase): 'service openstack', 'region %s' % self.region, auth_cmd, + 'sync interval %d' % cfg.CONF.ml2_arista.sync_interval, 'exit', 'exit', 'exit', -- 2.45.2