diff options
-rw-r--r-- | interface-definitions/vrrp.xml | 14 | ||||
-rw-r--r-- | python/vyos/keepalived.py | 9 | ||||
-rwxr-xr-x | src/conf_mode/vrrp.py | 21 | ||||
-rwxr-xr-x | src/op_mode/vrrp.py | 3 | ||||
-rwxr-xr-x | src/system/vrrp-script-wrapper.py | 10 |
5 files changed, 49 insertions, 8 deletions
diff --git a/interface-definitions/vrrp.xml b/interface-definitions/vrrp.xml index 2884ef613..36b75f28a 100644 --- a/interface-definitions/vrrp.xml +++ b/interface-definitions/vrrp.xml @@ -197,6 +197,20 @@ </constraint> </properties> </leafNode> + <leafNode name="stop"> + <properties> + <help>Script to run on VRRP state transition to stop</help> + <constraint> + <validator name="script"/> + </constraint> + </properties> + </leafNode> + <leafNode name="mode-force"> + <properties> + <help>Don't check previously VRRP scripts states</help> + <valueless/> + </properties> + </leafNode> </children> </node> <leafNode name="virtual-address"> diff --git a/python/vyos/keepalived.py b/python/vyos/keepalived.py index 4114aa736..6d1dbe12c 100644 --- a/python/vyos/keepalived.py +++ b/python/vyos/keepalived.py @@ -38,6 +38,15 @@ def vrrp_running(): def keepalived_running(): return vyos.util.process_running(pid_file) +# Clear VRRP data after showing +def remove_vrrp_data(data_file): + if data_file == "json" and os.path.exists(json_file): + os.remove(json_file) + elif data_file == "stats" and os.path.exists(stats_file): + os.remove(stats_file) + elif data_file == "state" and os.path.exists(state_file): + os.remove(state_file) + def force_state_data_dump(): pid = vyos.util.read_file(pid_file) os.kill(int(pid), signal.SIGUSR1) diff --git a/src/conf_mode/vrrp.py b/src/conf_mode/vrrp.py index 04bce9d39..79ecf0c95 100755 --- a/src/conf_mode/vrrp.py +++ b/src/conf_mode/vrrp.py @@ -35,6 +35,11 @@ config_tmpl = """ # Do not edit this file, all your changes will be lost # on next commit or reboot +global_defs { + dynamic_interfaces + script_user root +} + {% for group in groups -%} {% if group.health_check_script -%} @@ -103,15 +108,19 @@ vrrp_instance {{ group.name }} { {% endif -%} {% if group.master_script -%} - notify_master "/usr/libexec/vyos/system/vrrp-script-wrapper.py --state master --group {{ group.name }} --interface {{ group.interface }} {{ group.master_script }}" + notify_master "/usr/libexec/vyos/system/vrrp-script-wrapper.py --state master --group {{ group.name }} --interface {{ group.interface }} --force {{ group.mode_force }} {{ group.master_script }}" {% endif -%} {% if group.backup_script -%} - notify_backup "/usr/libexec/vyos/system/vrrp-script-wrapper.py --state backup --group {{ group.name }} --interface {{ group.interface }} {{ group.backup_script }}" + notify_backup "/usr/libexec/vyos/system/vrrp-script-wrapper.py --state backup --group {{ group.name }} --interface {{ group.interface }} --force {{ group.mode_force }} {{ group.backup_script }}" {% endif -%} {% if group.fault_script -%} - notify_fault "/usr/libexec/vyos/system/vrrp-script-wrapper.py --state fault --group {{ group.name }} --interface {{ group.interface }} {{ group.fault_script }}" + notify_fault "/usr/libexec/vyos/system/vrrp-script-wrapper.py --state fault --group {{ group.name }} --interface {{ group.interface }} --force {{ group.mode_force }} {{ group.fault_script }}" + {% endif -%} + + {% if group.stop_script -%} + notify_stop "/usr/libexec/vyos/system/vrrp-script-wrapper.py --state stop --group {{ group.name }} --interface {{ group.interface }} --force {{ group.mode_force }} {{ group.stop_script }}" {% endif -%} } @@ -155,7 +164,7 @@ def get_config(): config.set_level("high-availability vrrp group {0}".format(group_name)) # Retrieve the values - group = {"preempt": True, "use_vmac": False, "disable": False} + group = {"preempt": True, "use_vmac": False, "disable": False, "mode_force": "disable"} if config.exists("disable"): group["disable"] = True @@ -182,6 +191,10 @@ def get_config(): group["master_script"] = config.return_value("transition-script master") group["backup_script"] = config.return_value("transition-script backup") group["fault_script"] = config.return_value("transition-script fault") + group["stop_script"] = config.return_value("transition-script stop") + + if config.exists("transition-script mode-force"): + group["mode_force"] = "enable" if config.exists("no-preempt"): group["preempt"] = False diff --git a/src/op_mode/vrrp.py b/src/op_mode/vrrp.py index 54e1bfb57..8d1369823 100755 --- a/src/op_mode/vrrp.py +++ b/src/op_mode/vrrp.py @@ -32,6 +32,7 @@ def print_summary(): # Replace with inotify or similar if it proves problematic time.sleep(0.2) json_data = vyos.keepalived.get_json_data() + vyos.keepalived.remove_vrrp_data("json") except: print("VRRP information is not available") sys.exit(1) @@ -63,6 +64,7 @@ def print_statistics(): time.sleep(0.2) output = vyos.keepalived.get_statistics() print(output) + vyos.keepalived.remove_vrrp_data("stats") except: print("VRRP statistics are not available") sys.exit(1) @@ -73,6 +75,7 @@ def print_state_data(): time.sleep(0.2) output = vyos.keepalived.get_state_data() print(output) + vyos.keepalived.remove_vrrp_data("state") except: print("VRRP information is not available") sys.exit(1) diff --git a/src/system/vrrp-script-wrapper.py b/src/system/vrrp-script-wrapper.py index ccd640128..fff7ee154 100755 --- a/src/system/vrrp-script-wrapper.py +++ b/src/system/vrrp-script-wrapper.py @@ -30,6 +30,7 @@ parser = argparse.ArgumentParser() parser.add_argument("-t", "--state", type=str, help="VRRP state") parser.add_argument("-g", "--group", type=str, help="VRRP group") parser.add_argument("-i", "--interface", type=str, help="Network interface") +parser.add_argument("-f", "--force", type=str, help="enable|disable force mode") parser.add_argument("script", nargs='+') syslog.openlog('vyos-vrrp-wrapper') @@ -48,12 +49,13 @@ args.script = " ".join(args.script) # in command line options to avoid executing scripts if no real transition occured. # This is necessary because keepalived does not keep persistent state data even between # config reloads and will cheerfully execute everything whether it's required or not. +if args.force != "enable": + old_state = vyos.keepalived.get_old_state(args.group) +else: + old_state = None -old_state = vyos.keepalived.get_old_state(args.group) - +exitcode = 0 if (old_state is None) or (old_state != args.state): - exitcode = 0 - # Run the script and save the new state # Change the process GID to the config owners group to avoid screwing up |