summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--interface-definitions/vrrp.xml14
-rw-r--r--python/vyos/keepalived.py9
-rwxr-xr-xsrc/conf_mode/vrrp.py21
-rwxr-xr-xsrc/op_mode/vrrp.py3
-rwxr-xr-xsrc/system/vrrp-script-wrapper.py10
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