summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorViacheslav Hletenko <v.gletenko@vyos.io>2025-09-25 21:48:14 +0300
committerGitHub <noreply@github.com>2025-09-25 21:48:14 +0300
commit06e491caf2fdd8b4e2fe5f3b4396680fca61eeab (patch)
treea10dd4180108eb0956ab6cdbb0529a8c61acd7b1
parent7a29b1596a100ea2f978dedd2c5a4dd6e5654db7 (diff)
parente24f589cef57552cad3123b6668e459e1dfda1da (diff)
downloadvyos-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-xsrc/services/vyos-commitd43
-rwxr-xr-xsrc/services/vyos-configd41
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}')