diff options
Diffstat (limited to 'src/services/vyos-commitd')
| -rwxr-xr-x | src/services/vyos-commitd | 81 |
1 files changed, 67 insertions, 14 deletions
diff --git a/src/services/vyos-commitd b/src/services/vyos-commitd index 8dbd39058..b8e430b93 100755 --- a/src/services/vyos-commitd +++ b/src/services/vyos-commitd @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2025 VyOS maintainers and contributors +# Copyright VyOS maintainers and contributors <maintainers@vyos.io> # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 or later as @@ -42,6 +42,7 @@ from vyos.defaults import directories from vyos.utils.boot import boot_configuration_complete from vyos.configsource import ConfigSourceCache from vyos.configsource import ConfigSourceError +from vyos.configdiff import get_commit_scripts from vyos.config import Config from vyos.frrender import FRRender from vyos.frrender import get_frrender_dict @@ -72,8 +73,9 @@ class Session: # pylint: disable=too-many-instance-attributes session_id: str = '' - named_active: str = None - named_proposed: str = None + session_pid: int = None + sudo_user: str = None + user: str = None dry_run: bool = False atomic: bool = False background: bool = False @@ -229,14 +231,30 @@ def initialization(session: Session) -> Session: config = Config(config_source=configsource) + # required by protobuf schema; non-existence will raise early error + if session.session_pid: + os.environ['SESSION_PID'] = str(session.session_pid) + + # required by protobuf schema; may be empty string + if session.sudo_user: + os.environ['SUDO_USER'] = session.sudo_user + + # required by protobuf schema; may be empty string + if session.user: + os.environ['USER'] = session.user + dependent_func: dict[str, list[typing.Callable]] = {} setattr(config, 'dependent_func', dependent_func) + commit_scripts = get_commit_scripts(config) + logger.debug(f'commit_scripts: {commit_scripts}') + scripts_called = [] setattr(config, 'scripts_called', scripts_called) - dry_run = False - setattr(config, 'dry_run', dry_run) + dry_run = session.dry_run + config.set_bool_attr('dry_run', dry_run) + logger.debug(f'commit dry_run is {dry_run}') session.config = config @@ -249,11 +267,16 @@ def run_script(script_name: str, config: Config, args: list) -> tuple[bool, str] script = conf_mode_scripts[script_name] script.argv = args config.set_level([]) + dry_run = config.get_bool_attr('dry_run') try: c = script.get_config(config) script.verify(c) - script.generate(c) - script.apply(c) + if not dry_run: + script.generate(c) + script.apply(c) + else: + if hasattr(script, 'call_dependents'): + script.call_dependents() except ConfigError as e: logger.error(e) return False, str(e) @@ -265,6 +288,38 @@ 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 + logger.info(out) + + return result, out + + def process_call_data(call: Call, config: Config, last: bool = False) -> None: # pylint: disable=too-many-locals @@ -296,8 +351,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: @@ -305,11 +358,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: |
