diff options
| author | Viacheslav Hletenko <v.gletenko@vyos.io> | 2025-09-25 21:48:14 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-09-25 21:48:14 +0300 |
| commit | 06e491caf2fdd8b4e2fe5f3b4396680fca61eeab (patch) | |
| tree | a10dd4180108eb0956ab6cdbb0529a8c61acd7b1 | |
| parent | 7a29b1596a100ea2f978dedd2c5a4dd6e5654db7 (diff) | |
| parent | e24f589cef57552cad3123b6668e459e1dfda1da (diff) | |
| download | vyos-1x-06e491caf2fdd8b4e2fe5f3b4396680fca61eeab.tar.gz vyos-1x-06e491caf2fdd8b4e2fe5f3b4396680fca61eeab.zip | |
Merge pull request #4745 from jestabro/catch-frr-exception
T7855: redirect stdout and catch exceptions on frr render
| -rwxr-xr-x | src/services/vyos-commitd | 43 | ||||
| -rwxr-xr-x | src/services/vyos-configd | 41 |
2 files changed, 71 insertions, 13 deletions
diff --git a/src/services/vyos-commitd b/src/services/vyos-commitd index 3fa581f02..74d436488 100755 --- a/src/services/vyos-commitd +++ b/src/services/vyos-commitd @@ -288,6 +288,37 @@ def run_script(script_name: str, config: Config, args: list) -> tuple[bool, str] return True, '' +def call_frr_render(frr, config): + # pylint: disable=redefined-outer-name + def _call_frr_render(frr, config): + # pylint: disable=broad-exception-caught + try: + tmp = get_frrender_dict(config) + if frr.generate(tmp): + # only apply a new FRR configuration if anything changed + # in comparison to the previous applied configuration + frr.apply() + + except ConfigError as e: + logger.error(e) + return False, str(e) + except Exception: + tb = traceback.format_exc() + logger.error(tb) + return False, tb + + return True, '' + + with redirect_stdout(io.StringIO()) as o: + result, err_out = _call_frr_render(frr, config) + amb_out = o.getvalue() + o.close() + + out = amb_out + err_out + + return result, out + + def process_call_data(call: Call, config: Config, last: bool = False) -> None: # pylint: disable=too-many-locals @@ -319,8 +350,6 @@ def process_call_data(call: Call, config: Config, last: bool = False) -> None: out = amb_out + err_out - call.set_reply(success, out) - logger.info(f'[{script_name}] {out}') if last: @@ -328,11 +357,11 @@ def process_call_data(call: Call, config: Config, last: bool = False) -> None: logger.debug(f'scripts_called: {scripts_called}') if last and success: - tmp = get_frrender_dict(config) - if frr.generate(tmp): - # only apply a new FRR configuration if anything changed - # in comparison to the previous applied configuration - frr.apply() + s, o = call_frr_render(frr, config) + success = s + out = out + o + + call.set_reply(success, out) def process_session_data(session: Session) -> Session: diff --git a/src/services/vyos-configd b/src/services/vyos-configd index 22eb48102..ad2dcf119 100755 --- a/src/services/vyos-configd +++ b/src/services/vyos-configd @@ -276,6 +276,36 @@ def process_node_data(config, data, _last: bool = False) -> tuple[Response, str] return result, out +def call_frr_render(frr, config): + def _call_frr_render(frr, config): + # pylint: disable=broad-exception-caught + try: + tmp = get_frrender_dict(config) + if frr.generate(tmp): + # only apply a new FRR configuration if anything changed + # in comparison to the previous applied configuration + frr.apply() + + except ConfigError as e: + logger.error(e) + return Response.ERROR_COMMIT_APPLY, str(e) + except Exception: + tb = traceback.format_exc() + logger.error(tb) + return Response.ERROR_COMMIT_APPLY, tb + + return Response.SUCCESS, '' + + with redirect_stdout(io.StringIO()) as o: + result, err_out = _call_frr_render(frr, config) + amb_out = o.getvalue() + o.close() + + out = amb_out + err_out + + return result, out + + def send_result(sock, err, msg): err_no = err.value err_name = err.name @@ -345,17 +375,16 @@ if __name__ == '__main__': config = initialization(socket) elif message['type'] == 'node': res, out = process_node_data(config, message['data'], message['last']) - send_result(socket, res, out) if message['last'] and config: scripts_called = getattr(config, 'scripts_called', []) logger.debug(f'scripts_called: {scripts_called}') if res == Response.SUCCESS: - tmp = get_frrender_dict(config) - if frr.generate(tmp): - # only apply a new FRR configuration if anything changed - # in comparison to the previous applied configuration - frr.apply() + r, o = call_frr_render(frr, config) + res = r + out = out + o + + send_result(socket, res, out) else: logger.critical(f'Unexpected message: {message}') |
