summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Estabrook <jestabro@vyos.io>2024-10-02 12:36:41 -0500
committerJohn Estabrook <jestabro@vyos.io>2024-10-05 00:27:19 -0500
commit4d5f2a58bbf5a366c43871ef27b75d31b3b2a114 (patch)
treecb3047407f14d724b0556df3040007629cee3459 /src
parentf9c81b121b146fbcf3c458273b2b47e6e571f2e2 (diff)
downloadvyos-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-xsrc/conf_mode/system_config-management.py6
-rwxr-xr-xsrc/helpers/commit-confirm-notify.py42
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)