From ec80c75d677608da438a9360657d9729296afc73 Mon Sep 17 00:00:00 2001 From: Christian Breunig Date: Mon, 30 Dec 2024 20:35:08 +0100 Subject: frr: T6746: additional improvements after 10.2 upgrade (#4259) * smoketest: T6746: add substring search in getFRRconfig() Some daemons (e.g. bgpd) have several nested substrings/sections like router bgp 100 address-family ipv4 unicast .. exit-address-family exit We can now use getFRRconfig() with the substring option to extract only address-family ipv4 unicast .. exit-address-family Making config validation more granular * frrender: T6746: only re-render FRR config if config_dict did change * frrender: T6746: fix naming glitch isis/eigrp * frrender: T6746: add --stdout option when running with debug flags * smoketest: T6746: remove unneeded commit_guard time It was an invalid workarround as the underlaying issue seems to be a race condition in CStore. The commit process is not finished until all pending files from VYATTA_CHANGES_ONLY_DIR are copied to VYATTA_ACTIVE_CONFIGURATION_DIR. This is done inside libvyatta-cfg1 and the FUSE UnionFS part. On large non-interactive commits FUSE UnionFS might not replicate the real state in time, leading to errors when querying the working and effective configuration. TO BE DELETED AFTER SWITCH TO IN MEMORY CONFIG --- python/vyos/frrender.py | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) (limited to 'python/vyos/frrender.py') diff --git a/python/vyos/frrender.py b/python/vyos/frrender.py index badc5d59f..776e893d9 100644 --- a/python/vyos/frrender.py +++ b/python/vyos/frrender.py @@ -218,11 +218,11 @@ def get_frrender_dict(conf, argv=None) -> dict: # values present on the CLI - that's why we have if conf.exists() eigrp_cli_path = ['protocols', 'eigrp'] if conf.exists(eigrp_cli_path): - isis = conf.get_config_dict(eigrp_cli_path, key_mangling=('-', '_'), - get_first_key=True, - no_tag_node_value_mangle=True, - with_recursive_defaults=True) - dict.update({'eigrp' : isis}) + eigrp = conf.get_config_dict(eigrp_cli_path, key_mangling=('-', '_'), + get_first_key=True, + no_tag_node_value_mangle=True, + with_recursive_defaults=True) + dict.update({'eigrp' : eigrp}) elif conf.exists_effective(eigrp_cli_path): dict.update({'eigrp' : {'deleted' : ''}}) @@ -537,14 +537,25 @@ def get_frrender_dict(conf, argv=None) -> dict: return dict class FRRender: + cached_config_dict = {} def __init__(self): self._frr_conf = '/run/frr/config/vyos.frr.conf' def generate(self, config_dict) -> None: + """ + Generate FRR configuration file + Returns False if no changes to configuration were made, otherwise True + """ if not isinstance(config_dict, dict): tmp = type(config_dict) raise ValueError(f'Config must be of type "dict" and not "{tmp}"!') + + if self.cached_config_dict == config_dict: + debug('FRR: NO CHANGES DETECTED') + return False + self.cached_config_dict = config_dict + def inline_helper(config_dict) -> str: output = '!\n' if 'babel' in config_dict and 'deleted' not in config_dict['babel']: @@ -639,7 +650,7 @@ class FRRender: debug(output) write_file(self._frr_conf, output) debug('FRR: RENDERING CONFIG COMPLETE') - return None + return True def apply(self, count_max=5): count = 0 @@ -649,7 +660,7 @@ class FRRender: debug(f'FRR: reloading configuration - tries: {count} | Python class ID: {id(self)}') cmdline = '/usr/lib/frr/frr-reload.py --reload' if os.path.exists(frr_debug_enable): - cmdline += ' --debug' + cmdline += ' --debug --stdout' rc, emsg = rc_cmd(f'{cmdline} {self._frr_conf}') if rc != 0: sleep(2) -- cgit v1.2.3