Skip to content

Commit

Permalink
Merge "[OVN] Fix the revision number retrieval method" into stable/20…
Browse files Browse the repository at this point in the history
…23.1
  • Loading branch information
Zuul authored and openstack-gerrit committed Nov 6, 2024
2 parents 7e48691 + 989892e commit 161a6b5
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 8 deletions.
28 changes: 23 additions & 5 deletions neutron/db/ovn_revision_numbers_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,12 @@ class UnknownResourceType(n_exc.NeutronException):
message = 'Uknown resource type: %(resource_type)s'


# NOTE(ralonsoh): to be moved to neutron-lib
class RevisionNumberNotDefined(n_exc.NeutronException):
message = ('Unique revision number not found for %(resource_uuid)s, '
'the resource type is required in query')


def _get_standard_attr_id(context, resource_uuid, resource_type):
try:
row = context.session.query(STD_ATTR_MAP[resource_type]).filter_by(
Expand Down Expand Up @@ -151,14 +157,26 @@ def _ensure_revision_row_exist(context, resource, resource_type, std_attr_id):


@db_api.retry_if_session_inactive()
def get_revision_row(context, resource_uuid):
@db_api.CONTEXT_READER
def get_revision_row(context, resource_uuid, resource_type=None):
"""Retrieve the resource revision number
Only the Neutron ports can have two revision number registers, one for the
Logical_Switch_Port and another for the Logical_Router_Port, if this port
is a router interface. It is not strictly needed to filter by resource_type
if the resource is not a port.
"""
try:
with db_api.CONTEXT_READER.using(context):
return context.session.query(
ovn_models.OVNRevisionNumbers).filter_by(
resource_uuid=resource_uuid).one()
filters = {'resource_uuid': resource_uuid}
if resource_type:
filters['resource_type'] = resource_type
return context.session.query(
ovn_models.OVNRevisionNumbers).filter_by(
**filters).one()
except exc.NoResultFound:
pass
except exc.MultipleResultsFound:
raise RevisionNumberNotDefined(resource_uuid=resource_uuid)


@db_api.retry_if_session_inactive()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -823,7 +823,8 @@ def delete_port(self, context, port_id, port_object=None):
# to allow at least one maintenance cycle before we delete the
# revision number so that the port doesn't stale and eventually
# gets deleted by the maintenance task.
rev_row = db_rev.get_revision_row(context, port_id)
rev_row = db_rev.get_revision_row(
context, port_id, resource_type=ovn_const.TYPE_PORTS)
time_ = (timeutils.utcnow() - datetime.timedelta(
seconds=ovn_const.DB_CONSISTENCY_CHECK_INTERVAL + 30))
if rev_row and rev_row.created_at >= time_:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,8 @@ def test_port(self):
# Assert the revision number no longer exists
self.assertIsNone(db_rev.get_revision_row(
self.context,
neutron_obj['id']))
neutron_obj['id'],
resource_type=ovn_const.TYPE_PORTS))

def test_subnet_global_dhcp4_opts(self):
obj_name = 'globaltestsubnet'
Expand Down
20 changes: 19 additions & 1 deletion neutron/tests/unit/db/test_ovn_revision_numbers_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

from neutron.api import extensions
from neutron.common import config
from neutron.common.ovn import constants as ovn_const
from neutron.db.models import ovn as ovn_models
from neutron.db import ovn_revision_numbers_db as ovn_rn_db
import neutron.extensions
Expand All @@ -32,7 +33,6 @@
from neutron.tests.unit.extensions import test_l3
from neutron.tests.unit.extensions import test_securitygroup


EXTENSIONS_PATH = ':'.join(neutron.extensions.__path__)
PLUGIN_CLASS = (
'neutron.tests.unit.db.test_ovn_revision_numbers_db.TestMaintenancePlugin')
Expand Down Expand Up @@ -123,6 +123,24 @@ def test_create_initial_revision_may_exist_duplicated_entry(self):
self.fail("create_initial_revision shouldn't raise "
"DBDuplicateEntry when may_exist is True")

def test_get_revision_row_ports(self):
res = self._create_port(self.fmt, self.net['id'])
port = self.deserialize(self.fmt, res)['port']
with db_api.CONTEXT_WRITER.using(self.ctx):
for resource_type in (ovn_const.TYPE_PORTS,
ovn_const.TYPE_ROUTER_PORTS):
self._create_initial_revision(port['id'], resource_type)

for resource_type in (ovn_const.TYPE_PORTS,
ovn_const.TYPE_ROUTER_PORTS):
row = ovn_rn_db.get_revision_row(
self.ctx, port['id'], resource_type=resource_type)
self.assertEqual(resource_type, row.resource_type)
self.assertEqual(port['id'], row.resource_uuid)

self.assertRaises(ovn_rn_db.RevisionNumberNotDefined,
ovn_rn_db.get_revision_row, self.ctx, port['id'])


class TestMaintenancePlugin(test_securitygroup.SecurityGroupTestPlugin,
test_l3.TestL3NatBasePlugin):
Expand Down

0 comments on commit 161a6b5

Please sign in to comment.