summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniil Baturin <daniil@vyos.io>2021-07-04 14:10:22 -0500
committerDaniil Baturin <daniil@vyos.io>2021-07-04 14:10:22 -0500
commite0a754a0a608e1eb9021cf847b83e72165219de2 (patch)
tree65de100f699b68eb9f9eb08122a2720b594368c8
parent2680712b741631a97be38bff7c0725e4aee79646 (diff)
downloadvyos-1x-e0a754a0a608e1eb9021cf847b83e72165219de2.tar.gz
vyos-1x-e0a754a0a608e1eb9021cf847b83e72165219de2.zip
T3663: prerequisites for inotify-based watching implementations.
-rw-r--r--debian/control1
-rw-r--r--python/vyos/util.py33
2 files changed, 34 insertions, 0 deletions
diff --git a/debian/control b/debian/control
index aed1a3b2d..5a434bfc6 100644
--- a/debian/control
+++ b/debian/control
@@ -24,6 +24,7 @@ Build-Depends:
python3-setuptools,
python3-sphinx,
python3-xmltodict,
+ python3-inotify,
quilt,
whois
Standards-Version: 3.9.6
diff --git a/python/vyos/util.py b/python/vyos/util.py
index cf90dc74f..630fb1dcc 100644
--- a/python/vyos/util.py
+++ b/python/vyos/util.py
@@ -16,6 +16,9 @@
import os
import re
import sys
+import time
+
+import inotify.adapters
#
# NOTE: Do not import full classes here, move your import to the function
@@ -506,6 +509,36 @@ def file_is_persistent(path):
absolute = os.path.abspath(os.path.dirname(path))
return re.match(location,absolute)
+def wait_for_inotify(file_path, 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))
+
+ time_start = time.time()
+
+ i = inotify.adapters.Inotify()
+ i.add_watch(os.path.dirname(file_path))
+
+ for event in i.event_gen(yield_nones=True):
+ if (timeout is not None) and ((time.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, 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', timeout=timeout, sleep_interval=sleep_interval)
def commit_in_progress():
""" Not to be used in normal op mode scripts! """