diff options
author | John Estabrook <jestabro@vyos.io> | 2024-10-02 12:36:41 -0500 |
---|---|---|
committer | John Estabrook <jestabro@vyos.io> | 2024-10-05 00:27:19 -0500 |
commit | 4d5f2a58bbf5a366c43871ef27b75d31b3b2a114 (patch) | |
tree | cb3047407f14d724b0556df3040007629cee3459 /src | |
parent | f9c81b121b146fbcf3c458273b2b47e6e571f2e2 (diff) | |
download | vyos-1x-4d5f2a58bbf5a366c43871ef27b75d31b3b2a114.tar.gz vyos-1x-4d5f2a58bbf5a366c43871ef27b75d31b3b2a114.zip |
config-mgmt: T5976: add option for commit-confirm to use 'soft' rollback
Commit-confirm will restore a previous configuration if a confirmation
is not received in N minutes. Traditionally, this was restored by a
reboot into the last configuration on disk; add a configurable option to
reload the last completed commit without a reboot. The default setting
is to reboot.
Diffstat (limited to 'src')
-rwxr-xr-x | src/conf_mode/system_config-management.py | 6 | ||||
-rwxr-xr-x | src/helpers/commit-confirm-notify.py | 42 |
2 files changed, 37 insertions, 11 deletions
diff --git a/src/conf_mode/system_config-management.py b/src/conf_mode/system_config-management.py index 99f25bef6..a1ee136cd 100755 --- a/src/conf_mode/system_config-management.py +++ b/src/conf_mode/system_config-management.py @@ -38,7 +38,11 @@ def get_config(config=None): return mgmt -def verify(_mgmt): +def verify(mgmt): + d = mgmt.config_dict + if d.get('commit_confirm', '') == 'reload' and 'commit_revisions' not in d: + raise ConfigError('commit-confirm reload requires non-zero commit-revisions') + return diff --git a/src/helpers/commit-confirm-notify.py b/src/helpers/commit-confirm-notify.py index 69dda5112..af6167651 100755 --- a/src/helpers/commit-confirm-notify.py +++ b/src/helpers/commit-confirm-notify.py @@ -2,34 +2,56 @@ import os import sys import time +from argparse import ArgumentParser # Minutes before reboot to trigger notification. intervals = [1, 5, 15, 60] +parser = ArgumentParser() +parser.add_argument( + 'minutes', type=int, help='minutes before rollback to trigger notification' +) +parser.add_argument( + '--reboot', action='store_true', help="use 'soft' rollback instead of reboot" +) -def notify(interval): + +def notify(interval, reboot=False): s = '' if interval == 1 else 's' time.sleep((minutes - interval) * 60) - message = ( - '"[commit-confirm] System is going to reboot in ' - f'{interval} minute{s} to rollback the last commit.\n' - 'Confirm your changes to cancel the reboot."' - ) - os.system('wall -n ' + message) + if reboot: + message = ( + '"[commit-confirm] System will reboot in ' + f'{interval} minute{s}\nto rollback the last commit.\n' + 'Confirm your changes to cancel the reboot."' + ) + os.system('wall -n ' + message) + else: + message = ( + '"[commit-confirm] System will reload previous config in ' + f'{interval} minute{s}\nto rollback the last commit.\n' + 'Confirm your changes to cancel the reload."' + ) + os.system('wall -n ' + message) if __name__ == '__main__': # Must be run as root to call wall(1) without a banner. - if len(sys.argv) != 2 or os.getuid() != 0: + if os.getuid() != 0: print('This script requires superuser privileges.', file=sys.stderr) exit(1) - minutes = int(sys.argv[1]) + + args = parser.parse_args() + + minutes = args.minutes + reboot = args.reboot + # Drop the argument from the list so that the notification # doesn't kick in immediately. if minutes in intervals: intervals.remove(minutes) for interval in sorted(intervals, reverse=True): if minutes >= interval: - notify(interval) + notify(interval, reboot=reboot) minutes -= minutes - interval exit(0) |