15
15
16
16
import abc
17
17
import copy
18
+ import functools
18
19
import inspect
19
20
import re
20
21
import threading
53
54
INCONSISTENCY_TYPE_DELETE = 'delete'
54
55
55
56
57
+ def has_lock_periodic (* args , ** kwargs ):
58
+ def wrapper (f ):
59
+ @functools .wraps (f )
60
+ @periodics .periodic (* args , ** kwargs )
61
+ def decorator (self , * args , ** kwargs ):
62
+ # This periodic task is included in DBInconsistenciesPeriodics
63
+ # since it uses the lock to ensure only one worker is executing
64
+ if not self .has_lock :
65
+ return
66
+ return f (self , * args , ** kwargs )
67
+ return decorator
68
+ return wrapper
69
+
70
+
56
71
class MaintenanceThread (object ):
57
72
58
73
def __init__ (self ):
@@ -289,15 +304,10 @@ def _fix_create_update_subnet(self, context, row):
289
304
# is held by some other neutron-server instance in the cloud, we'll attempt
290
305
# to perform the migration every 10 seconds until completed.
291
306
# TODO(ihrachys): Remove the migration to stateful fips in Z+1.
292
- @periodics . periodic (spacing = 10 , run_immediately = True )
307
+ @has_lock_periodic (spacing = 10 , run_immediately = True )
293
308
@rerun_on_schema_updates
294
309
def migrate_to_stateful_fips (self ):
295
310
"""Perform the migration from stateless to stateful Floating IPs. """
296
- # Only the worker holding a valid lock within OVSDB will perform the
297
- # migration.
298
- if not self .has_lock :
299
- return
300
-
301
311
admin_context = n_context .get_admin_context ()
302
312
nb_sync = ovn_db_sync .OvnNbSynchronizer (
303
313
self ._ovn_client ._plugin , self ._nb_idl , self ._ovn_client ._sb_idl ,
@@ -358,14 +368,9 @@ def _log(inconsistencies, type_):
358
368
_log (create_update_inconsistencies , INCONSISTENCY_TYPE_CREATE_UPDATE )
359
369
_log (delete_inconsistencies , INCONSISTENCY_TYPE_DELETE )
360
370
361
- @periodics . periodic (spacing = ovn_const .DB_CONSISTENCY_CHECK_INTERVAL ,
362
- run_immediately = True )
371
+ @has_lock_periodic (spacing = ovn_const .DB_CONSISTENCY_CHECK_INTERVAL ,
372
+ run_immediately = True )
363
373
def check_for_inconsistencies (self ):
364
- # Only the worker holding a valid lock within OVSDB will run
365
- # this periodic
366
- if not self .has_lock :
367
- return
368
-
369
374
admin_context = n_context .get_admin_context ()
370
375
create_update_inconsistencies = (
371
376
revision_numbers_db .get_inconsistent_resources (admin_context ))
@@ -481,13 +486,8 @@ def _delete_floatingip_and_pf(self, context, fip_id):
481
486
482
487
# A static spacing value is used here, but this method will only run
483
488
# once per lock due to the use of periodics.NeverAgain().
484
- @periodics .periodic (spacing = 600 ,
485
- run_immediately = True )
489
+ @has_lock_periodic (spacing = 600 , run_immediately = True )
486
490
def check_global_dhcp_opts (self ):
487
- # This periodic task is included in DBInconsistenciesPeriodics since
488
- # it uses the lock to ensure only one worker is executing
489
- if not self .has_lock :
490
- return
491
491
if (not ovn_conf .get_global_dhcpv4_opts () and
492
492
not ovn_conf .get_global_dhcpv6_opts ()):
493
493
# No need to scan the subnets if the settings are unset.
@@ -516,11 +516,8 @@ def check_global_dhcp_opts(self):
516
516
517
517
# A static spacing value is used here, but this method will only run
518
518
# once per lock due to the use of periodics.NeverAgain().
519
- @periodics . periodic (spacing = 600 , run_immediately = True )
519
+ @has_lock_periodic (spacing = 600 , run_immediately = True )
520
520
def check_for_igmp_snoop_support (self ):
521
- if not self .has_lock :
522
- return
523
-
524
521
with self ._nb_idl .transaction (check_error = True ) as txn :
525
522
value = ('true' if ovn_conf .is_igmp_snooping_enabled ()
526
523
else 'false' )
@@ -539,11 +536,8 @@ def check_for_igmp_snoop_support(self):
539
536
# TODO(czesla): Remove this in the A+4 cycle
540
537
# A static spacing value is used here, but this method will only run
541
538
# once per lock due to the use of periodics.NeverAgain().
542
- @periodics . periodic (spacing = 600 , run_immediately = True )
539
+ @has_lock_periodic (spacing = 600 , run_immediately = True )
543
540
def check_port_has_address_scope (self ):
544
- if not self .has_lock :
545
- return
546
-
547
541
ports = self ._nb_idl .db_find_rows (
548
542
"Logical_Switch_Port" , ("type" , "!=" , ovn_const .LSP_TYPE_LOCALNET )
549
543
).execute (check_error = True )
@@ -618,11 +612,8 @@ def check_for_ha_chassis_group(self):
618
612
# TODO(lucasagomes): Remove this in the B+3 cycle
619
613
# A static spacing value is used here, but this method will only run
620
614
# once per lock due to the use of periodics.NeverAgain().
621
- @periodics . periodic (spacing = 600 , run_immediately = True )
615
+ @has_lock_periodic (spacing = 600 , run_immediately = True )
622
616
def check_for_mcast_flood_reports (self ):
623
- if not self .has_lock :
624
- return
625
-
626
617
cmds = []
627
618
for port in self ._nb_idl .lsp_list ().execute (check_error = True ):
628
619
port_type = port .type .strip ()
@@ -667,11 +658,8 @@ def check_for_mcast_flood_reports(self):
667
658
# TODO(lucasagomes): Remove this in the Z cycle
668
659
# A static spacing value is used here, but this method will only run
669
660
# once per lock due to the use of periodics.NeverAgain().
670
- @periodics . periodic (spacing = 600 , run_immediately = True )
661
+ @has_lock_periodic (spacing = 600 , run_immediately = True )
671
662
def check_router_mac_binding_options (self ):
672
- if not self .has_lock :
673
- return
674
-
675
663
cmds = []
676
664
for router in self ._nb_idl .lr_list ().execute (check_error = True ):
677
665
if (router .options .get ('always_learn_from_arp_request' ) and
@@ -726,14 +714,12 @@ def update_port_qos_with_external_ids_reference(self):
726
714
727
715
# A static spacing value is used here, but this method will only run
728
716
# once per lock due to the use of periodics.NeverAgain().
729
- @periodics . periodic (spacing = 600 , run_immediately = True )
717
+ @has_lock_periodic (spacing = 600 , run_immediately = True )
730
718
def check_redirect_type_router_gateway_ports (self ):
731
719
"""Check OVN router gateway ports
732
720
Check for the option "redirect-type=bridged" value for
733
721
router gateway ports.
734
722
"""
735
- if not self .has_lock :
736
- return
737
723
context = n_context .get_admin_context ()
738
724
cmds = []
739
725
gw_ports = self ._ovn_client ._plugin .get_ports (
@@ -786,14 +772,12 @@ def check_redirect_type_router_gateway_ports(self):
786
772
787
773
# A static spacing value is used here, but this method will only run
788
774
# once per lock due to the use of periodics.NeverAgain().
789
- @periodics . periodic (spacing = 600 , run_immediately = True )
775
+ @has_lock_periodic (spacing = 600 , run_immediately = True )
790
776
def check_vlan_distributed_ports (self ):
791
777
"""Check VLAN distributed ports
792
778
Check for the option "reside-on-redirect-chassis" value for
793
779
distributed VLAN ports.
794
780
"""
795
- if not self .has_lock :
796
- return
797
781
context = n_context .get_admin_context ()
798
782
cmds = []
799
783
# Get router ports belonging to VLAN networks
@@ -829,12 +813,9 @@ def check_vlan_distributed_ports(self):
829
813
# a gateway (that means, that has "external_ids:OVN_GW_PORT_EXT_ID_KEY").
830
814
# A static spacing value is used here, but this method will only run
831
815
# once per lock due to the use of periodics.NeverAgain().
832
- @periodics . periodic (spacing = 600 , run_immediately = True )
816
+ @has_lock_periodic (spacing = 600 , run_immediately = True )
833
817
def update_logical_router_with_gateway_network_id (self ):
834
818
"""Update all OVN logical router registers with the GW network ID"""
835
- if not self .has_lock :
836
- return
837
-
838
819
cmds = []
839
820
context = n_context .get_admin_context ()
840
821
for lr in self ._nb_idl .lr_list ().execute (check_error = True ):
@@ -911,16 +892,13 @@ def check_baremetal_ports_dhcp_options(self):
911
892
raise periodics .NeverAgain ()
912
893
913
894
# TODO(ralonsoh): Remove this in the Z+4 cycle
914
- @periodics . periodic (spacing = 600 , run_immediately = True )
895
+ @has_lock_periodic (spacing = 600 , run_immediately = True )
915
896
def update_port_virtual_type (self ):
916
897
"""Set type=virtual to those ports with parents
917
898
Before LP#1973276, any virtual port with "device_owner" defined, lost
918
899
its type=virtual. This task restores the type for those ports updated
919
900
before the fix https://review.opendev.org/c/openstack/neutron/+/841711.
920
901
"""
921
- if not self .has_lock :
922
- return
923
-
924
902
context = n_context .get_admin_context ()
925
903
cmds = []
926
904
for lsp in self ._nb_idl .lsp_list ().execute (check_error = True ):
@@ -948,7 +926,7 @@ def update_port_virtual_type(self):
948
926
raise periodics .NeverAgain ()
949
927
950
928
# TODO(ralonsoh): Remove this in the Antelope+4 cycle
951
- @periodics . periodic (spacing = 600 , run_immediately = True )
929
+ @has_lock_periodic (spacing = 600 , run_immediately = True )
952
930
def create_router_extra_attributes_registers (self ):
953
931
"""Create missing ``RouterExtraAttributes`` registers.
954
932
@@ -958,9 +936,6 @@ def create_router_extra_attributes_registers(self):
958
936
only execution method finds those ``Routers`` registers without the
959
937
child one and creates one with the default values.
960
938
"""
961
- if not self .has_lock :
962
- return
963
-
964
939
context = n_context .get_admin_context ()
965
940
for router_id in router_obj .Router .\
966
941
get_router_ids_without_router_std_attrs (context ):
@@ -1008,13 +983,10 @@ def add_gw_port_info_to_logical_router_port(self):
1008
983
txn .add (cmd )
1009
984
raise periodics .NeverAgain ()
1010
985
1011
- @periodics . periodic (spacing = 600 , run_immediately = True )
986
+ @has_lock_periodic (spacing = 600 , run_immediately = True )
1012
987
def check_router_default_route_empty_dst_ip (self ):
1013
988
"""Check routers with default route with empty dst-ip (LP: #2002993).
1014
989
"""
1015
- if not self .has_lock :
1016
- return
1017
-
1018
990
cmds = []
1019
991
for router in self ._nb_idl .lr_list ().execute (check_error = True ):
1020
992
if not router .external_ids .get (ovn_const .OVN_REV_NUM_EXT_ID_KEY ):
@@ -1036,7 +1008,7 @@ def check_router_default_route_empty_dst_ip(self):
1036
1008
raise periodics .NeverAgain ()
1037
1009
1038
1010
# TODO(ralonsoh): Remove this in the Antelope+4 cycle
1039
- @periodics . periodic (spacing = 600 , run_immediately = True )
1011
+ @has_lock_periodic (spacing = 600 , run_immediately = True )
1040
1012
def add_vnic_type_and_pb_capabilities_to_lsp (self ):
1041
1013
"""Add the port VNIC type and port binding capabilities to the LSP.
1042
1014
@@ -1047,9 +1019,6 @@ def add_vnic_type_and_pb_capabilities_to_lsp(self):
1047
1019
been added to the LSP the VNIC type and the port binding capabilities.
1048
1020
To implement LP#1998608, only direct ports are needed.
1049
1021
"""
1050
- if not self .has_lock :
1051
- return
1052
-
1053
1022
port_bindings = ports_obj .PortBinding .get_port_binding_by_vnic_type (
1054
1023
n_context .get_admin_context (), portbindings .VNIC_DIRECT )
1055
1024
with self ._nb_idl .transaction (check_error = True ) as txn :
@@ -1071,7 +1040,7 @@ def add_vnic_type_and_pb_capabilities_to_lsp(self):
1071
1040
1072
1041
raise periodics .NeverAgain ()
1073
1042
1074
- @periodics . periodic (spacing = 600 , run_immediately = True )
1043
+ @has_lock_periodic (spacing = 600 , run_immediately = True )
1075
1044
def check_fair_meter_consistency (self ):
1076
1045
"""Update the logging meter after neutron-server reload
1077
1046
@@ -1080,8 +1049,6 @@ def check_fair_meter_consistency(self):
1080
1049
driver after the OVN NB idl is loaded
1081
1050
1082
1051
"""
1083
- if not self .has_lock :
1084
- return
1085
1052
if log_driver .OVNDriver .network_logging_supported (self ._nb_idl ):
1086
1053
meter_name = (
1087
1054
cfg .CONF .network_log .local_output_log_base or "acl_log_meter" )
@@ -1146,7 +1113,7 @@ def remove_duplicated_chassis_registers(self):
1146
1113
for table in ('Chassis_Private' , 'Chassis' ):
1147
1114
txn .add (self ._sb_idl .db_destroy (table , ch .name ))
1148
1115
1149
- @periodics . periodic (spacing = 86400 , run_immediately = True )
1116
+ @has_lock_periodic (spacing = 86400 , run_immediately = True )
1150
1117
def cleanup_old_hash_ring_nodes (self ):
1151
1118
"""Daily task to cleanup old stable Hash Ring node entries.
1152
1119
@@ -1155,8 +1122,6 @@ def cleanup_old_hash_ring_nodes(self):
1155
1122
information.
1156
1123
1157
1124
"""
1158
- if not self .has_lock :
1159
- return
1160
1125
context = n_context .get_admin_context ()
1161
1126
hash_ring_db .cleanup_old_nodes (context , days = 5 )
1162
1127
0 commit comments