Skip to content

Commit

Permalink
Merge "[OVN] Hash Ring: Set nodes as offline upon exit" into stable/zed
Browse files Browse the repository at this point in the history
  • Loading branch information
Zuul authored and openstack-gerrit committed Jul 14, 2023
2 parents 872b4b2 + ad78bd4 commit 78735be
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 13 deletions.
8 changes: 4 additions & 4 deletions neutron/cmd/ovn/neutron_ovn_db_sync_util.py
Expand Up @@ -58,12 +58,12 @@ def post_fork_initialize(self, resource, event, trigger, **kwargs):
def ovn_client(self):
return self._ovn_client

def _clean_hash_ring(self):
"""Don't clean the hash ring.
def _set_hash_ring_nodes_offline(self):
"""Don't set hash ring nodes as offline.
If this method was not overridden, cleanup would be performed when
calling the db sync and running neutron server would lose all the nodes
from the ring.
calling the db sync and running neutron server would mark all the
nodes from the ring as offline.
"""

# Since we are not using the ovn mechanism driver while syncing,
Expand Down
12 changes: 10 additions & 2 deletions neutron/db/ovn_hash_ring_db.py
Expand Up @@ -50,10 +50,12 @@ def remove_nodes_from_host(context, group_name):
CONF.host, group_name)


def _touch(context, **filter_args):
def _touch(context, updated_at=None, **filter_args):
if updated_at is None:
updated_at = timeutils.utcnow()
with db_api.CONTEXT_WRITER.using(context):
context.session.query(ovn_models.OVNHashRing).filter_by(
**filter_args).update({'updated_at': timeutils.utcnow()})
**filter_args).update({'updated_at': updated_at})


def touch_nodes_from_host(context, group_name):
Expand Down Expand Up @@ -92,3 +94,9 @@ def get_active_nodes(context, interval, group_name, from_host=False):
def count_offline_nodes(context, interval, group_name):
query = _get_nodes_query(context, interval, group_name, offline=True)
return query.count()


def set_nodes_from_host_as_offline(context, group_name):
timestamp = datetime.datetime(day=26, month=10, year=1985, hour=9)
_touch(context, updated_at=timestamp, hostname=CONF.host,
group_name=group_name)
16 changes: 10 additions & 6 deletions neutron/plugins/ml2/drivers/ovn/mech_driver/mech_driver.py
Expand Up @@ -278,15 +278,17 @@ def subscribe(self):
resources.SECURITY_GROUP_RULE,
events.BEFORE_DELETE)

def _clean_hash_ring(self, *args, **kwargs):
def _set_hash_ring_nodes_offline(self, *args, **kwargs):
admin_context = n_context.get_admin_context()
ovn_hash_ring_db.remove_nodes_from_host(admin_context,
self.hash_ring_group)
ovn_hash_ring_db.set_nodes_from_host_as_offline(
admin_context, self.hash_ring_group)
LOG.info('Hash Ring nodes from host "%s" marked as offline',
cfg.CONF.host)

def pre_fork_initialize(self, resource, event, trigger, payload=None):
"""Pre-initialize the ML2/OVN driver."""
atexit.register(self._clean_hash_ring)
signal.signal(signal.SIGTERM, self._clean_hash_ring)
atexit.register(self._set_hash_ring_nodes_offline)
signal.signal(signal.SIGTERM, self._set_hash_ring_nodes_offline)
ovn_utils.create_neutron_pg_drop()

@staticmethod
Expand All @@ -306,7 +308,9 @@ def _setup_hash_ring(self):
"""
admin_context = n_context.get_admin_context()
if not self._hash_ring_probe_event.is_set():
self._clean_hash_ring()
# Clear existing entries
ovn_hash_ring_db.remove_nodes_from_host(admin_context,
self.hash_ring_group)
self.node_uuid = ovn_hash_ring_db.add_node(admin_context,
self.hash_ring_group)
self._hash_ring_thread = maintenance.MaintenanceThread()
Expand Down
3 changes: 2 additions & 1 deletion neutron/tests/functional/base.py
Expand Up @@ -362,7 +362,8 @@ def trigger(self):
self.addCleanup(self.stop)
# NOTE(ralonsoh): do not access to the DB at exit when the SQL
# connection is already closed, to avoid useless exception messages.
mock.patch.object(self.mech_driver, '_clean_hash_ring').start()
mock.patch.object(
self.mech_driver, '_set_hash_ring_nodes_offline').start()
self.mech_driver.pre_fork_initialize(
mock.ANY, mock.ANY, trigger_cls.trigger)

Expand Down
14 changes: 14 additions & 0 deletions neutron/tests/unit/db/test_ovn_hash_ring_db.py
Expand Up @@ -269,3 +269,17 @@ def test_count_offline_nodes(self):
# Assert no nodes are considered offline
self.assertEqual(0, ovn_hash_ring_db.count_offline_nodes(
self.admin_ctx, interval=60, group_name=HASH_RING_TEST_GROUP))

def test_set_nodes_from_host_as_offline(self):
self._add_nodes_and_assert_exists(count=3)

active_nodes = ovn_hash_ring_db.get_active_nodes(
self.admin_ctx, interval=60, group_name=HASH_RING_TEST_GROUP)
self.assertEqual(3, len(active_nodes))

ovn_hash_ring_db.set_nodes_from_host_as_offline(
self.admin_ctx, HASH_RING_TEST_GROUP)

active_nodes = ovn_hash_ring_db.get_active_nodes(
self.admin_ctx, interval=60, group_name=HASH_RING_TEST_GROUP)
self.assertEqual(0, len(active_nodes))

0 comments on commit 78735be

Please sign in to comment.