Merge "Lower spacing time of the OVN maintenance tasks which should be run once"
This commit is contained in:
commit
394c7774da
@ -275,6 +275,8 @@ _TYPES_PRIORITY_ORDER = (
|
||||
TYPE_SECURITY_GROUP_RULES)
|
||||
|
||||
DB_CONSISTENCY_CHECK_INTERVAL = 300 # 5 minutes
|
||||
MAINTENANCE_TASK_RETRY_LIMIT = 100 # times
|
||||
MAINTENANCE_ONE_RUN_TASK_SPACING = 5 # seconds
|
||||
|
||||
# The order in which the resources should be created or updated by the
|
||||
# maintenance task: Root ones first and leafs at the end.
|
||||
|
@ -56,14 +56,28 @@ INCONSISTENCY_TYPE_CREATE_UPDATE = 'create/update'
|
||||
INCONSISTENCY_TYPE_DELETE = 'delete'
|
||||
|
||||
|
||||
def has_lock_periodic(*args, **kwargs):
|
||||
def has_lock_periodic(*args, periodic_run_limit=0, **kwargs):
|
||||
def wrapper(f):
|
||||
_retries = 0
|
||||
|
||||
@functools.wraps(f)
|
||||
@periodics.periodic(*args, **kwargs)
|
||||
def decorator(self, *args, **kwargs):
|
||||
# This periodic task is included in DBInconsistenciesPeriodics
|
||||
# since it uses the lock to ensure only one worker is executing
|
||||
# additonally, if periodic_run_limit parameter with value > 0 is
|
||||
# provided and lock is not acquired for periodic_run_limit
|
||||
# times, task will not be run anymore by this maintenance worker
|
||||
nonlocal _retries
|
||||
if not self.has_lock:
|
||||
if periodic_run_limit > 0:
|
||||
if _retries >= periodic_run_limit:
|
||||
LOG.debug("Have not been able to acquire lock to run "
|
||||
"task '%s' after %s tries, limit reached. "
|
||||
"No more attempts will be made.",
|
||||
f, _retries)
|
||||
raise periodics.NeverAgain()
|
||||
_retries += 1
|
||||
return
|
||||
return f(self, *args, **kwargs)
|
||||
return decorator
|
||||
@ -444,7 +458,10 @@ class DBInconsistenciesPeriodics(SchemaAwarePeriodicsBase):
|
||||
|
||||
# A static spacing value is used here, but this method will only run
|
||||
# once per lock due to the use of periodics.NeverAgain().
|
||||
@has_lock_periodic(spacing=600, run_immediately=True)
|
||||
@has_lock_periodic(
|
||||
periodic_run_limit=ovn_const.MAINTENANCE_TASK_RETRY_LIMIT,
|
||||
spacing=ovn_const.MAINTENANCE_ONE_RUN_TASK_SPACING,
|
||||
run_immediately=True)
|
||||
def check_global_dhcp_opts(self):
|
||||
if (not ovn_conf.get_global_dhcpv4_opts() and
|
||||
not ovn_conf.get_global_dhcpv6_opts()):
|
||||
@ -474,7 +491,10 @@ class DBInconsistenciesPeriodics(SchemaAwarePeriodicsBase):
|
||||
|
||||
# A static spacing value is used here, but this method will only run
|
||||
# once per lock due to the use of periodics.NeverAgain().
|
||||
@has_lock_periodic(spacing=600, run_immediately=True)
|
||||
@has_lock_periodic(
|
||||
periodic_run_limit=ovn_const.MAINTENANCE_TASK_RETRY_LIMIT,
|
||||
spacing=ovn_const.MAINTENANCE_ONE_RUN_TASK_SPACING,
|
||||
run_immediately=True)
|
||||
def check_for_igmp_snoop_support(self):
|
||||
snooping_conf = ovs_conf.get_igmp_snooping_enabled()
|
||||
flood_conf = ovs_conf.get_igmp_flood_unregistered()
|
||||
@ -504,7 +524,10 @@ class DBInconsistenciesPeriodics(SchemaAwarePeriodicsBase):
|
||||
# TODO(czesla): Remove this in the A+4 cycle
|
||||
# A static spacing value is used here, but this method will only run
|
||||
# once per lock due to the use of periodics.NeverAgain().
|
||||
@has_lock_periodic(spacing=600, run_immediately=True)
|
||||
@has_lock_periodic(
|
||||
periodic_run_limit=ovn_const.MAINTENANCE_TASK_RETRY_LIMIT,
|
||||
spacing=ovn_const.MAINTENANCE_ONE_RUN_TASK_SPACING,
|
||||
run_immediately=True)
|
||||
def check_port_has_address_scope(self):
|
||||
ports = self._nb_idl.db_find_rows(
|
||||
"Logical_Switch_Port", ("type", "!=", ovn_const.LSP_TYPE_LOCALNET)
|
||||
@ -539,7 +562,10 @@ class DBInconsistenciesPeriodics(SchemaAwarePeriodicsBase):
|
||||
|
||||
# A static spacing value is used here, but this method will only run
|
||||
# once per lock due to the use of periodics.NeverAgain().
|
||||
@has_lock_periodic(spacing=600, run_immediately=True)
|
||||
@has_lock_periodic(
|
||||
periodic_run_limit=ovn_const.MAINTENANCE_TASK_RETRY_LIMIT,
|
||||
spacing=ovn_const.MAINTENANCE_ONE_RUN_TASK_SPACING,
|
||||
run_immediately=True)
|
||||
def check_for_ha_chassis_group(self):
|
||||
# If external ports is not supported stop running
|
||||
# this periodic task
|
||||
@ -567,7 +593,10 @@ class DBInconsistenciesPeriodics(SchemaAwarePeriodicsBase):
|
||||
# TODO(lucasagomes): Remove this in the B+3 cycle
|
||||
# A static spacing value is used here, but this method will only run
|
||||
# once per lock due to the use of periodics.NeverAgain().
|
||||
@has_lock_periodic(spacing=600, run_immediately=True)
|
||||
@has_lock_periodic(
|
||||
periodic_run_limit=ovn_const.MAINTENANCE_TASK_RETRY_LIMIT,
|
||||
spacing=ovn_const.MAINTENANCE_ONE_RUN_TASK_SPACING,
|
||||
run_immediately=True)
|
||||
def check_for_mcast_flood_reports(self):
|
||||
mcast_flood_conf = ovs_conf.get_igmp_flood()
|
||||
mcast_flood_reports_conf = ovs_conf.get_igmp_flood_reports()
|
||||
@ -625,7 +654,10 @@ class DBInconsistenciesPeriodics(SchemaAwarePeriodicsBase):
|
||||
|
||||
# A static spacing value is used here, but this method will only run
|
||||
# once per lock due to the use of periodics.NeverAgain().
|
||||
@has_lock_periodic(spacing=600, run_immediately=True)
|
||||
@has_lock_periodic(
|
||||
periodic_run_limit=ovn_const.MAINTENANCE_TASK_RETRY_LIMIT,
|
||||
spacing=ovn_const.MAINTENANCE_ONE_RUN_TASK_SPACING,
|
||||
run_immediately=True)
|
||||
def check_localnet_port_has_learn_fdb(self):
|
||||
ports = self._nb_idl.db_find_rows(
|
||||
"Logical_Switch_Port", ("type", "=", ovn_const.LSP_TYPE_LOCALNET)
|
||||
@ -652,7 +684,10 @@ class DBInconsistenciesPeriodics(SchemaAwarePeriodicsBase):
|
||||
|
||||
# A static spacing value is used here, but this method will only run
|
||||
# once per lock due to the use of periodics.NeverAgain().
|
||||
@has_lock_periodic(spacing=600, run_immediately=True)
|
||||
@has_lock_periodic(
|
||||
periodic_run_limit=ovn_const.MAINTENANCE_TASK_RETRY_LIMIT,
|
||||
spacing=ovn_const.MAINTENANCE_ONE_RUN_TASK_SPACING,
|
||||
run_immediately=True)
|
||||
def check_redirect_type_router_gateway_ports(self):
|
||||
"""Check OVN router gateway ports
|
||||
Check for the option "redirect-type=bridged" value for
|
||||
@ -714,7 +749,10 @@ class DBInconsistenciesPeriodics(SchemaAwarePeriodicsBase):
|
||||
|
||||
# A static spacing value is used here, but this method will only run
|
||||
# once per lock due to the use of periodics.NeverAgain().
|
||||
@has_lock_periodic(spacing=600, run_immediately=True)
|
||||
@has_lock_periodic(
|
||||
periodic_run_limit=ovn_const.MAINTENANCE_TASK_RETRY_LIMIT,
|
||||
spacing=ovn_const.MAINTENANCE_ONE_RUN_TASK_SPACING,
|
||||
run_immediately=True)
|
||||
def check_vlan_distributed_ports(self):
|
||||
"""Check VLAN distributed ports
|
||||
Check for the option "reside-on-redirect-chassis" value for
|
||||
@ -749,7 +787,10 @@ class DBInconsistenciesPeriodics(SchemaAwarePeriodicsBase):
|
||||
|
||||
# A static spacing value is used here, but this method will only run
|
||||
# once per lock due to the use of periodics.NeverAgain().
|
||||
@has_lock_periodic(spacing=600, run_immediately=True)
|
||||
@has_lock_periodic(
|
||||
periodic_run_limit=ovn_const.MAINTENANCE_TASK_RETRY_LIMIT,
|
||||
spacing=ovn_const.MAINTENANCE_ONE_RUN_TASK_SPACING,
|
||||
run_immediately=True)
|
||||
def check_fdb_aging_settings(self):
|
||||
"""Check FDB aging settings
|
||||
Ensure FDB aging settings are enforced.
|
||||
@ -785,7 +826,10 @@ class DBInconsistenciesPeriodics(SchemaAwarePeriodicsBase):
|
||||
|
||||
# A static spacing value is used here, but this method will only run
|
||||
# once per lock due to the use of periodics.NeverAgain().
|
||||
@has_lock_periodic(spacing=600, run_immediately=True)
|
||||
@has_lock_periodic(
|
||||
periodic_run_limit=ovn_const.MAINTENANCE_TASK_RETRY_LIMIT,
|
||||
spacing=ovn_const.MAINTENANCE_ONE_RUN_TASK_SPACING,
|
||||
run_immediately=True)
|
||||
def update_mac_aging_settings(self):
|
||||
"""Ensure that MAC_Binding aging options are set"""
|
||||
with self._nb_idl.transaction(check_error=True) as txn:
|
||||
@ -801,7 +845,10 @@ class DBInconsistenciesPeriodics(SchemaAwarePeriodicsBase):
|
||||
# "external_ids:OVN_GW_PORT_EXT_ID_KEY" from to each router.
|
||||
# A static spacing value is used here, but this method will only run
|
||||
# once per lock due to the use of periodics.NeverAgain().
|
||||
@has_lock_periodic(spacing=600, run_immediately=True)
|
||||
@has_lock_periodic(
|
||||
periodic_run_limit=ovn_const.MAINTENANCE_TASK_RETRY_LIMIT,
|
||||
spacing=ovn_const.MAINTENANCE_ONE_RUN_TASK_SPACING,
|
||||
run_immediately=True)
|
||||
def remove_gw_ext_ids_from_logical_router(self):
|
||||
"""Remove `gw_port_id` and `gw_network_id` external_ids from LRs"""
|
||||
cmds = []
|
||||
@ -829,7 +876,10 @@ class DBInconsistenciesPeriodics(SchemaAwarePeriodicsBase):
|
||||
|
||||
# A static spacing value is used here, but this method will only run
|
||||
# once per lock due to the use of periodics.NeverAgain().
|
||||
@has_lock_periodic(spacing=600, run_immediately=True)
|
||||
@has_lock_periodic(
|
||||
periodic_run_limit=ovn_const.MAINTENANCE_TASK_RETRY_LIMIT,
|
||||
spacing=ovn_const.MAINTENANCE_ONE_RUN_TASK_SPACING,
|
||||
run_immediately=True)
|
||||
def check_baremetal_ports_dhcp_options(self):
|
||||
"""Update baremetal ports DHCP options
|
||||
|
||||
@ -878,7 +928,10 @@ class DBInconsistenciesPeriodics(SchemaAwarePeriodicsBase):
|
||||
raise periodics.NeverAgain()
|
||||
|
||||
# TODO(ralonsoh): Remove this in the Antelope+4 cycle
|
||||
@has_lock_periodic(spacing=600, run_immediately=True)
|
||||
@has_lock_periodic(
|
||||
periodic_run_limit=ovn_const.MAINTENANCE_TASK_RETRY_LIMIT,
|
||||
spacing=ovn_const.MAINTENANCE_ONE_RUN_TASK_SPACING,
|
||||
run_immediately=True)
|
||||
def create_router_extra_attributes_registers(self):
|
||||
"""Create missing ``RouterExtraAttributes`` registers.
|
||||
|
||||
@ -899,7 +952,10 @@ class DBInconsistenciesPeriodics(SchemaAwarePeriodicsBase):
|
||||
raise periodics.NeverAgain()
|
||||
|
||||
# TODO(slaweq): Remove this in the E cycle (C+2 as it will be next SLURP)
|
||||
@has_lock_periodic(spacing=600, run_immediately=True)
|
||||
@has_lock_periodic(
|
||||
periodic_run_limit=ovn_const.MAINTENANCE_TASK_RETRY_LIMIT,
|
||||
spacing=ovn_const.MAINTENANCE_ONE_RUN_TASK_SPACING,
|
||||
run_immediately=True)
|
||||
def add_gw_port_info_to_logical_router_port(self):
|
||||
"""Add info if LRP is connecting internal subnet or ext gateway."""
|
||||
cmds = []
|
||||
@ -935,7 +991,10 @@ class DBInconsistenciesPeriodics(SchemaAwarePeriodicsBase):
|
||||
txn.add(cmd)
|
||||
raise periodics.NeverAgain()
|
||||
|
||||
@has_lock_periodic(spacing=600, run_immediately=True)
|
||||
@has_lock_periodic(
|
||||
periodic_run_limit=ovn_const.MAINTENANCE_TASK_RETRY_LIMIT,
|
||||
spacing=ovn_const.MAINTENANCE_ONE_RUN_TASK_SPACING,
|
||||
run_immediately=True)
|
||||
def check_router_default_route_empty_dst_ip(self):
|
||||
"""Check routers with default route with empty dst-ip (LP: #2002993).
|
||||
"""
|
||||
@ -962,7 +1021,10 @@ class DBInconsistenciesPeriodics(SchemaAwarePeriodicsBase):
|
||||
raise periodics.NeverAgain()
|
||||
|
||||
# TODO(ralonsoh): Remove this in the Antelope+4 cycle
|
||||
@has_lock_periodic(spacing=600, run_immediately=True)
|
||||
@has_lock_periodic(
|
||||
periodic_run_limit=ovn_const.MAINTENANCE_TASK_RETRY_LIMIT,
|
||||
spacing=ovn_const.MAINTENANCE_ONE_RUN_TASK_SPACING,
|
||||
run_immediately=True)
|
||||
def add_vnic_type_and_pb_capabilities_to_lsp(self):
|
||||
"""Add the port VNIC type and port binding capabilities to the LSP.
|
||||
|
||||
@ -994,7 +1056,10 @@ class DBInconsistenciesPeriodics(SchemaAwarePeriodicsBase):
|
||||
|
||||
raise periodics.NeverAgain()
|
||||
|
||||
@has_lock_periodic(spacing=600, run_immediately=True)
|
||||
@has_lock_periodic(
|
||||
periodic_run_limit=ovn_const.MAINTENANCE_TASK_RETRY_LIMIT,
|
||||
spacing=ovn_const.MAINTENANCE_ONE_RUN_TASK_SPACING,
|
||||
run_immediately=True)
|
||||
def check_fair_meter_consistency(self):
|
||||
"""Update the logging meter after neutron-server reload
|
||||
|
||||
@ -1057,7 +1122,10 @@ class DBInconsistenciesPeriodics(SchemaAwarePeriodicsBase):
|
||||
|
||||
raise periodics.NeverAgain()
|
||||
|
||||
@has_lock_periodic(spacing=600, run_immediately=True)
|
||||
@has_lock_periodic(
|
||||
periodic_run_limit=ovn_const.MAINTENANCE_TASK_RETRY_LIMIT,
|
||||
spacing=ovn_const.MAINTENANCE_ONE_RUN_TASK_SPACING,
|
||||
run_immediately=True)
|
||||
def update_nat_floating_ip_with_gateway_port_reference(self):
|
||||
"""Set NAT rule gateway_port column to any floating IP without
|
||||
router gateway port uuid reference - LP#2035281.
|
||||
@ -1104,7 +1172,10 @@ class DBInconsistenciesPeriodics(SchemaAwarePeriodicsBase):
|
||||
raise periodics.NeverAgain()
|
||||
|
||||
# TODO(ralonsoh): Remove this method in the C+2 cycle (next SLURP release)
|
||||
@has_lock_periodic(spacing=600, run_immediately=True)
|
||||
@has_lock_periodic(
|
||||
periodic_run_limit=ovn_const.MAINTENANCE_TASK_RETRY_LIMIT,
|
||||
spacing=ovn_const.MAINTENANCE_ONE_RUN_TASK_SPACING,
|
||||
run_immediately=True)
|
||||
def add_provider_resource_association_to_routers(self):
|
||||
"""Add the ``ProviderResourceAssociation`` register to all routers"""
|
||||
provider_name = 'ovn'
|
||||
@ -1123,7 +1194,10 @@ class DBInconsistenciesPeriodics(SchemaAwarePeriodicsBase):
|
||||
raise periodics.NeverAgain()
|
||||
|
||||
# TODO(ralonsoh): Remove this method in the C+2 cycle (next SLURP release)
|
||||
@has_lock_periodic(spacing=600, run_immediately=True)
|
||||
@has_lock_periodic(
|
||||
periodic_run_limit=ovn_const.MAINTENANCE_TASK_RETRY_LIMIT,
|
||||
spacing=ovn_const.MAINTENANCE_ONE_RUN_TASK_SPACING,
|
||||
run_immediately=True)
|
||||
def remove_invalid_gateway_chassis_from_unbound_lrp(self):
|
||||
"""Removes all invalid 'Gateway_Chassis' from unbound LRPs"""
|
||||
is_gw = ovn_const.OVN_ROUTER_IS_EXT_GW
|
||||
@ -1146,7 +1220,10 @@ class DBInconsistenciesPeriodics(SchemaAwarePeriodicsBase):
|
||||
raise periodics.NeverAgain()
|
||||
|
||||
# TODO(ralonsoh): Remove this method in the E cycle (SLURP release)
|
||||
@has_lock_periodic(spacing=600, run_immediately=True)
|
||||
@has_lock_periodic(
|
||||
periodic_run_limit=ovn_const.MAINTENANCE_TASK_RETRY_LIMIT,
|
||||
spacing=ovn_const.MAINTENANCE_ONE_RUN_TASK_SPACING,
|
||||
run_immediately=True)
|
||||
def set_network_type(self):
|
||||
"""Add the network type to the Logical_Switch registers"""
|
||||
context = n_context.get_admin_context()
|
||||
@ -1169,7 +1246,10 @@ class DBInconsistenciesPeriodics(SchemaAwarePeriodicsBase):
|
||||
|
||||
raise periodics.NeverAgain()
|
||||
|
||||
@has_lock_periodic(spacing=600, run_immediately=True)
|
||||
@has_lock_periodic(
|
||||
periodic_run_limit=ovn_const.MAINTENANCE_TASK_RETRY_LIMIT,
|
||||
spacing=ovn_const.MAINTENANCE_ONE_RUN_TASK_SPACING,
|
||||
run_immediately=True)
|
||||
def check_network_broadcast_arps_to_all_routers(self):
|
||||
"""Check the broadcast-arps-to-all-routers config
|
||||
|
||||
|
@ -32,12 +32,69 @@ from neutron.db.models import ovn as ovn_models
|
||||
from neutron.db import ovn_revision_numbers_db
|
||||
from neutron.objects import ports as ports_obj
|
||||
from neutron.plugins.ml2.drivers.ovn.mech_driver.ovsdb import maintenance
|
||||
from neutron.tests import base
|
||||
from neutron.tests.unit import fake_resources as fakes
|
||||
from neutron.tests.unit.plugins.ml2 import test_security_group as test_sg
|
||||
from neutron.tests.unit import testlib_api
|
||||
from neutron_lib import exceptions as n_exc
|
||||
|
||||
|
||||
class TestHasLockPeriodicDecorator(base.BaseTestCase):
|
||||
|
||||
def test_decorator_no_limit_have_lock(self):
|
||||
run_counter = 0
|
||||
|
||||
@maintenance.has_lock_periodic(
|
||||
periodic_run_limit=0, spacing=30)
|
||||
def test_maintenance_task(worker):
|
||||
nonlocal run_counter
|
||||
run_counter += 1
|
||||
|
||||
worker_mock = mock.MagicMock()
|
||||
worker_mock.has_lock = True
|
||||
|
||||
for _ in range(3):
|
||||
test_maintenance_task(worker_mock)
|
||||
self.assertEqual(3, run_counter)
|
||||
|
||||
def test_decorator_no_lock_no_limit(self):
|
||||
run_counter = 0
|
||||
|
||||
@maintenance.has_lock_periodic(
|
||||
periodic_run_limit=0, spacing=30)
|
||||
def test_maintenance_task(worker):
|
||||
nonlocal run_counter
|
||||
run_counter += 1
|
||||
|
||||
worker_mock = mock.MagicMock()
|
||||
has_lock_values = [False, False, True]
|
||||
|
||||
for has_lock in has_lock_values:
|
||||
worker_mock.has_lock = has_lock
|
||||
test_maintenance_task(worker_mock)
|
||||
self.assertEqual(1, run_counter)
|
||||
|
||||
def test_decorator_no_lock_with_limit(self):
|
||||
run_counter = 0
|
||||
|
||||
@maintenance.has_lock_periodic(
|
||||
periodic_run_limit=1, spacing=30)
|
||||
def test_maintenance_task(worker):
|
||||
nonlocal run_counter
|
||||
run_counter += 1
|
||||
|
||||
worker_mock = mock.MagicMock()
|
||||
|
||||
worker_mock.has_lock = False
|
||||
test_maintenance_task(worker_mock)
|
||||
self.assertEqual(0, run_counter)
|
||||
|
||||
worker_mock.has_lock = False
|
||||
self.assertRaises(periodics.NeverAgain,
|
||||
test_maintenance_task, worker_mock)
|
||||
self.assertEqual(0, run_counter)
|
||||
|
||||
|
||||
class TestSchemaAwarePeriodicsBase(testlib_api.SqlTestCaseLight):
|
||||
|
||||
def test__set_schema_aware_periodics(self):
|
||||
|
Loading…
Reference in New Issue
Block a user