summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniil Baturin <daniil@vyos.io>2021-07-08 08:43:53 -0500
committerDaniil Baturin <daniil@vyos.io>2021-07-08 08:45:03 -0500
commit859afacfeafcd56cecc065b463e75639b3e72d7e (patch)
tree02ee55194e9c03d481367cfa1b2d8f94bb32540f
parentae59f14144ee158f46dbd5716b2c94d14deae829 (diff)
downloadvyos-1x-859afacfeafcd56cecc065b463e75639b3e72d7e.tar.gz
vyos-1x-859afacfeafcd56cecc065b463e75639b3e72d7e.zip
T3663: use inotify-based waiting for keepalived in `show vrrp`
-rw-r--r--python/vyos/util.py37
-rwxr-xr-xsrc/op_mode/vrrp.py17
2 files changed, 46 insertions, 8 deletions
diff --git a/python/vyos/util.py b/python/vyos/util.py
index cc7ce5b40..3ffd025b9 100644
--- a/python/vyos/util.py
+++ b/python/vyos/util.py
@@ -136,6 +136,43 @@ def file_is_persistent(path):
else:
return (True, None)
+def wait_for_inotify(file_path, pre_hook=None, event_type=None, timeout=None, sleep_interval=0.1):
+ """ Waits for an inotify event to occur """
+ if not os.path.dirname(file_path):
+ raise ValueError(
+ "File path {} does not have a directory part (required for inotify watching)".format(file_path))
+ if not os.path.basename(file_path):
+ raise ValueError(
+ "File path {} does not have a file part, do not know what to watch for".format(file_path))
+
+ from inotify.adapters import Inotify
+ from time import time
+
+ time_start = time()
+
+ i = Inotify()
+ i.add_watch(os.path.dirname(file_path))
+
+ if pre_hook:
+ pre_hook()
+
+ for event in i.event_gen(yield_nones=True):
+ if (timeout is not None) and ((time() - time_start) > timeout):
+ # If the function didn't return until this point,
+ # the file failed to have been written to and closed within the timeout
+ raise OSError("Waiting for file {} to be written has failed".format(file_path))
+
+ if event is not None:
+ (_, type_names, path, filename) = event
+ if filename == os.path.basename(file_path):
+ if event_type in type_names:
+ return
+
+def wait_for_file_write_complete(file_path, pre_hook=None, timeout=None, sleep_interval=0.1):
+ """ Waits for a process to close a file after opening it in write mode. """
+ wait_for_inotify(file_path,
+ event_type='IN_CLOSE_WRITE', pre_hook=pre_hook, timeout=timeout, sleep_interval=sleep_interval)
+
def commit_in_progress():
""" Not to be used in normal op mode scripts! """
diff --git a/src/op_mode/vrrp.py b/src/op_mode/vrrp.py
index 8d1369823..7a1146b9e 100755
--- a/src/op_mode/vrrp.py
+++ b/src/op_mode/vrrp.py
@@ -27,10 +27,9 @@ import vyos.util
def print_summary():
try:
- vyos.keepalived.force_json_dump()
- # Wait for keepalived to produce the data
- # Replace with inotify or similar if it proves problematic
- time.sleep(0.2)
+ json_data = vyos.util.wait_for_file_write_complete(vyos.keepalived.json_file,
+ pre_hook=(lambda: vyos.keepalived.force_json_dump()),
+ timeout=30)
json_data = vyos.keepalived.get_json_data()
vyos.keepalived.remove_vrrp_data("json")
except:
@@ -60,8 +59,9 @@ def print_summary():
def print_statistics():
try:
- vyos.keepalived.force_stats_dump()
- time.sleep(0.2)
+ json_data = vyos.util.wait_for_file_write_complete(vyos.keepalived.stats_file,
+ pre_hook=(lambda: vyos.keepalived.force_stats_dump()),
+ timeout=30)
output = vyos.keepalived.get_statistics()
print(output)
vyos.keepalived.remove_vrrp_data("stats")
@@ -71,8 +71,9 @@ def print_statistics():
def print_state_data():
try:
- vyos.keepalived.force_state_data_dump()
- time.sleep(0.2)
+ json_data = vyos.util.wait_for_file_write_complete(vyos.keepalived.state_file,
+ pre_hook=(lambda: vyos.keepalived.force_state_data_dump()),
+ timeout=30)
output = vyos.keepalived.get_state_data()
print(output)
vyos.keepalived.remove_vrrp_data("state")