summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorViacheslav Hletenko <v.gletenko@vyos.io>2026-07-15 16:27:30 +0300
committerGitHub <noreply@github.com>2026-07-15 16:27:30 +0300
commita2ca9b1cf96db9fb9ed9fffe9c02248b0d59c7bd (patch)
treeff724bb1eb04005184618677fedfd61dc5fb1da3 /src
parentdc3d9bb55411af4359e5dfd731356af826a80738 (diff)
parentb14a010b07de95f36e9d0d420ea7f74fa062ad39 (diff)
downloadvyos-1x-a2ca9b1cf96db9fb9ed9fffe9c02248b0d59c7bd.tar.gz
vyos-1x-a2ca9b1cf96db9fb9ed9fffe9c02248b0d59c7bd.zip
Merge pull request #5318 from jestabro/config-manager
T9068: Add config manager module and refactor vyos-configd
Diffstat (limited to 'src')
-rwxr-xr-xsrc/services/vyos-configd92
1 files changed, 27 insertions, 65 deletions
diff --git a/src/services/vyos-configd b/src/services/vyos-configd
index 2f060dc82..52088c601 100755
--- a/src/services/vyos-configd
+++ b/src/services/vyos-configd
@@ -25,7 +25,6 @@ import typing
import logging
import signal
import traceback
-import importlib.util
import io
from contextlib import redirect_stdout
from enum import Enum
@@ -42,6 +41,7 @@ from vyos.config import Config
from vyos.frrender import FRRender
from vyos.frrender import get_frrender_dict
from vyos import ConfigError
+from vyos.configmanager import ConfigManager
CFG_GROUP = 'vyattacfg'
@@ -72,62 +72,13 @@ class Response(Enum):
ERROR_COMMIT_APPLY = 16
-vyos_conf_scripts_dir = directories['conf_mode']
-configd_include_file = os.path.join(directories['data'], 'configd-include.json')
+## config session vyshim env var
configd_env_set_file = os.path.join(directories['data'], 'vyos-configd-env-set')
configd_env_unset_file = os.path.join(directories['data'], 'vyos-configd-env-unset')
# sourced on entering config session
configd_env_file = '/etc/default/vyos-configd-env'
-def key_name_from_file_name(f):
- return os.path.splitext(f)[0]
-
-
-def module_name_from_key(k):
- return k.replace('-', '_')
-
-
-def path_from_file_name(f):
- return os.path.join(vyos_conf_scripts_dir, f)
-
-
-# opt-in to be run by daemon
-with open(configd_include_file) as f:
- try:
- include = json.load(f)
- except OSError as e:
- logger.critical(f'configd include file error: {e}')
- sys.exit(1)
- except json.JSONDecodeError as e:
- logger.critical(f'JSON load error: {e}')
- sys.exit(1)
-
-
-# import conf_mode scripts
-(_, _, filenames) = next(iter(os.walk(vyos_conf_scripts_dir)))
-filenames.sort()
-
-load_filenames = [f for f in filenames if f in include]
-imports = [key_name_from_file_name(f) for f in load_filenames]
-module_names = [module_name_from_key(k) for k in imports]
-paths = [path_from_file_name(f) for f in load_filenames]
-to_load = list(zip(module_names, paths))
-
-modules = []
-
-for x in to_load:
- spec = importlib.util.spec_from_file_location(x[0], x[1])
- module = importlib.util.module_from_spec(spec)
- spec.loader.exec_module(module)
- modules.append(module)
-
-conf_mode_scripts = dict(zip(imports, modules))
-
-exclude_set = {key_name_from_file_name(f) for f in filenames if f not in include}
-include_set = {key_name_from_file_name(f) for f in filenames if f in include}
-
-
def write_stdout_log(file_name, msg):
if boot_configuration_complete():
return
@@ -135,15 +86,16 @@ def write_stdout_log(file_name, msg):
f.write(msg)
-def run_script(script_name, config, args) -> tuple[Response, str]:
+def run_script(
+ config_manager: ConfigManager, script_name: str, args: list
+) -> tuple[Response, str]:
# pylint: disable=broad-exception-caught
- script = conf_mode_scripts[script_name]
- script.argv = args
+ config = config_manager.config
config.set_level([])
try:
- c = script.get_config(config)
- script.verify(c)
+ c = config_manager.get_config(script_name, args)
+ config_manager.verify(script_name, c)
except ConfigError as e:
logger.error(e)
return Response.ERROR_COMMIT, str(e)
@@ -153,8 +105,8 @@ def run_script(script_name, config, args) -> tuple[Response, str]:
return Response.ERROR_COMMIT, tb
try:
- script.generate(c)
- script.apply(c)
+ config_manager.generate(script_name, c)
+ config_manager.apply(script_name, c)
except ConfigError as e:
logger.error(e)
return Response.ERROR_COMMIT_APPLY, str(e)
@@ -166,7 +118,7 @@ def run_script(script_name, config, args) -> tuple[Response, str]:
return Response.SUCCESS, ''
-def initialization(socket):
+def initialization(config_manager: ConfigManager, socket):
# pylint: disable=broad-exception-caught,too-many-locals
# Reset config strings:
@@ -217,6 +169,7 @@ def initialization(socket):
running_config_text=active_string, session_config_text=session_string
)
except ConfigSourceError as e:
+ config_manager.set_config(None)
logger.debug(e)
return None
@@ -230,15 +183,21 @@ def initialization(socket):
scripts_called = []
setattr(config, 'scripts_called', scripts_called)
+ config_manager.set_config(config)
+
return config
-def process_node_data(config, data, _last: bool = False) -> tuple[Response, str]:
+def process_node_data(config_manager: ConfigManager, data) -> tuple[Response, str]:
+ # pylint: disable=too-many-locals
+ config = config_manager.config
if not config:
- out = 'Empty config'
+ out = 'Empty config: missing initialization'
logger.critical(out)
return Response.ERROR_DAEMON, out
+ include_list = list(config_manager.components)
+
script_name = None
os.environ['VYOS_TAGNODE_VALUE'] = ''
args = []
@@ -264,11 +223,11 @@ def process_node_data(config, data, _last: bool = False) -> tuple[Response, str]
scripts_called = getattr(config, 'scripts_called', [])
scripts_called.append(script_record)
- if script_name not in include_set:
+ if script_name not in include_list:
return Response.PASS, ''
with redirect_stdout(io.StringIO()) as o:
- result, err_out = run_script(script_name, config, args)
+ result, err_out = run_script(config_manager, script_name, args)
amb_out = o.getvalue()
o.close()
@@ -363,6 +322,9 @@ if __name__ == '__main__':
remove_if_file(configd_env_file)
os.symlink(configd_env_set_file, configd_env_file)
+ # init ConfigManager; caching off pending use
+ config_manager = ConfigManager(cache_config=False)
+
# We only need one long-lived instance of FRRender
frr = FRRender()
@@ -376,9 +338,9 @@ if __name__ == '__main__':
if message['type'] == 'init':
resp = 'init'
socket.send(resp.encode())
- config = initialization(socket)
+ config = initialization(config_manager, socket)
elif message['type'] == 'node':
- res, out = process_node_data(config, message['data'], message['last'])
+ res, out = process_node_data(config_manager, message['data'])
if message['last'] and config:
scripts_called = getattr(config, 'scripts_called', [])