summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--python/vyos/config.py3
-rw-r--r--python/vyos/defaults.py4
-rw-r--r--python/vyos/util.py47
-rwxr-xr-xsrc/conf_mode/dns_forwarding.py8
-rwxr-xr-xsrc/conf_mode/host_name.py14
5 files changed, 70 insertions, 6 deletions
diff --git a/python/vyos/config.py b/python/vyos/config.py
index bcf04225b..7483e3552 100644
--- a/python/vyos/config.py
+++ b/python/vyos/config.py
@@ -383,7 +383,8 @@ class Config(object):
else:
try:
out = self._run(self._make_command('returnEffectiveValues', full_path))
- return out
+ values = re.findall(r"\'(.*?)\'", out)
+ return values
except VyOSError:
return(default)
diff --git a/python/vyos/defaults.py b/python/vyos/defaults.py
index 36185f16a..c46723626 100644
--- a/python/vyos/defaults.py
+++ b/python/vyos/defaults.py
@@ -19,3 +19,7 @@ directories = {
}
cfg_group = 'vyattacfg'
+
+cfg_vintage = 'vyatta'
+
+commit_lock = '/opt/vyatta/config/.lock'
diff --git a/python/vyos/util.py b/python/vyos/util.py
index 8b5342575..6ab606983 100644
--- a/python/vyos/util.py
+++ b/python/vyos/util.py
@@ -1,4 +1,4 @@
-# Copyright 2018 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright 2019 VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -16,6 +16,9 @@
import os
import re
import grp
+import time
+import subprocess
+
import psutil
import vyos.defaults
@@ -131,3 +134,45 @@ def file_is_persistent(path):
return (False, warning)
else:
return (True, None)
+
+def commit_in_progress():
+ """ Not to be used in normal op mode scripts! """
+
+ # The CStore backend locks the config by opening a file
+ # The file is not removed after commit, so just checking
+ # if it exists is insufficient, we need to know if it's open by anyone
+
+ # There are two ways to check if any other process keeps a file open.
+ # The first one is to try opening it and see if the OS objects.
+ # That's faster but prone to race conditions and can be intrusive.
+ # The other one is to actually check if any process keeps it open.
+ # It's non-intrusive but needs root permissions, else you can't check
+ # processes of other users.
+ #
+ # Since this will be used in scripts that modify the config outside of the CLI
+ # framework, those knowingly have root permissions.
+ # For everything else, we add a safeguard.
+ id = subprocess.check_output(['/usr/bin/id', '-u']).decode().strip()
+ if id != '0':
+ raise OSError("This functions needs root permissions to return correct results")
+
+ for proc in psutil.process_iter():
+ try:
+ files = proc.open_files()
+ if files:
+ for f in files:
+ if f.path == vyos.defaults.commit_lock:
+ return True
+ except psutil.NoSuchProcess as err:
+ # Process died before we could examine it
+ pass
+ # Default case
+ return False
+
+def wait_for_commit_lock():
+ """ Not to be used in normal op mode scripts! """
+
+ # Very synchronous approach to multiprocessing
+ while commit_in_progress():
+ time.sleep(1)
+
diff --git a/src/conf_mode/dns_forwarding.py b/src/conf_mode/dns_forwarding.py
index c7e362d07..aab389074 100755
--- a/src/conf_mode/dns_forwarding.py
+++ b/src/conf_mode/dns_forwarding.py
@@ -23,6 +23,8 @@ import argparse
import jinja2
import netifaces
+import vyos.util
+
from vyos.config import Config
from vyos import ConfigError
@@ -265,6 +267,12 @@ def apply(dns):
if __name__ == '__main__':
args = parser.parse_args()
+
+ if args.dhclient:
+ # There's a big chance it was triggered by a commit still in progress
+ # so we need to wait until the new values are in the running config
+ vyos.util.wait_for_commit_lock()
+
try:
c = get_config(args)
verify(c)
diff --git a/src/conf_mode/host_name.py b/src/conf_mode/host_name.py
index c5268df2a..5055faa65 100755
--- a/src/conf_mode/host_name.py
+++ b/src/conf_mode/host_name.py
@@ -28,6 +28,8 @@ import glob
import argparse
import jinja2
+import vyos.util
+
from vyos.config import Config
from vyos import ConfigError
@@ -117,10 +119,7 @@ def get_config(arguments):
hosts['domain_search'].append(search)
if conf.exists("system name-server"):
- if not isinstance(conf.return_values("system name-server"), list):
- hosts['nameserver'] = conf.return_values("system name-server").replace("'", "").split()
- else:
- hosts['nameserver'] = conf.return_values("system name-server")
+ hosts['nameserver'] = conf.return_values("system name-server")
hosts['no_dhcp_ns'] = conf.exists('system disable-dhcp-nameservers')
@@ -213,6 +212,13 @@ def apply(config):
if __name__ == '__main__':
args = parser.parse_args()
+
+ if args.dhclient:
+ # There's a big chance it was triggered by a commit still in progress
+ # so we need to wait until the new values are in the running config
+ vyos.util.wait_for_commit_lock()
+
+
try:
c = get_config(args)
verify(c)