From 7245a4817deba310153b6e7fa94768a94dc64f3b Mon Sep 17 00:00:00 2001 From: novirium Date: Fri, 3 Jan 2020 13:45:47 +0800 Subject: [PATCH] Config file logic --- shepherd/core.py | 86 ++++++++++++++++++++++++++++------------ tests/shepherd-test.toml | 0 2 files changed, 60 insertions(+), 26 deletions(-) create mode 100644 tests/shepherd-test.toml diff --git a/shepherd/core.py b/shepherd/core.py index 2d2fd3f..cf353d5 100644 --- a/shepherd/core.py +++ b/shepherd/core.py @@ -5,6 +5,7 @@ Core shepherd module, tying together main service functionality. import os from pathlib import Path +import glob from datetime import datetime import logging import pkg_resources @@ -20,10 +21,17 @@ from . import control @click.group(invoke_without_command=True) #help="Path to default config TOML file" @click.argument('default_config_path', required=False, type=click.Path()) +@click.option('-l', '--local-config', 'only_local_layers', is_flag=True, + help="Only use the local config layers (default and custom)") +@click.option('-d', '--default-config', 'only_default_layer', is_flag=True, + help="Only use the default config layer (ignore" + "custom and control layers)") @click.pass_context -def cli(ctx, default_config_path): +def cli(ctx, default_config_path, only_local_layers, only_default_layer): """ - Core service. Expects the default config to be set as an argument. + Core service. DEFAULT_CONFIG_PATH must point to a valid Shepherd config TOML file. If not + provided, the first filename in the current working directory beginning with "shepherd" and + ending with ".toml" will be used. """ version_text = pkg_resources.get_distribution("shepherd") logging.info(F"Initialising Shepherd Agent {version_text}") @@ -38,15 +46,35 @@ def cli(ctx, default_config_path): #args = argparser.parse_args() + if default_config_path is None: + default_config_path = sorted(glob.glob("./shepherd*.toml"))[:1] + if default_config_path: + default_config_path = default_config_path[0] + logging.info(F"No default config file provided, using {default_config_path}") + else: + raise Exception("No default config file provided, and no 'shepherd*.toml' could be" + " found in the current directory") + + layers_disabled = [] + if only_local_layers: + layers_disabled.append("control") + + if only_default_layer: + layers_disabled.append("control") + layers_disabled.append("custom") + confman = ConfigManager() - plugin_classes = compile_config_and_get_plugins(confman, default_config_path) + plugin_classes = compile_config_and_get_plugins(confman, default_config_path, layers_disabled) + plugin_configs = confman.get_config_bundles() + core_config = confman.get_config_bundle("shepherd") + del plugin_configs["shepherd"] - control.init_control(core_conf, plugin_configs) + # control.init_control(core_config, plugin_configs) - scheduler.init_scheduler(core_conf) + # scheduler.init_scheduler(core_config) plugin.init_plugins(plugin_classes, plugin_configs, core_config) - scheduler.restore_jobs() + # scheduler.restore_jobs() print(str(datetime.now())) @@ -60,7 +88,7 @@ def cli(ctx, default_config_path): pass -def compile_config_and_get_plugins(confman, default_config_path): +def compile_config_and_get_plugins(confman, default_config_path, layers_disabled): """ Run through the process of assembling the various config layers, falling back to working ones where necessary. Also gathers needed plugin classes in the process. @@ -95,14 +123,17 @@ def compile_config_and_get_plugins(confman, default_config_path): # ====Custom Local Config Layer==== # If this fails, maintain default config but continue on to Control layer - try: - plugin_classes = load_config_layer_and_plugins(confman, custom_config_path) - logging.info(F"Loaded custom config layer from {custom_config_path}") - except Exception as e: - logging.error( - F"Failed to load custom config layer from {custom_config_path}. Falling back" - " to default config.", exc_info=e) - confman.fallback() + if "custom" not in layers_disabled: + try: + plugin_classes = load_config_layer_and_plugins(confman, custom_config_path) + logging.info(F"Loaded custom config layer from {custom_config_path}") + except Exception as e: + logging.error( + F"Failed to load custom config layer from {custom_config_path}. Falling back" + " to default config.", exc_info=e) + confman.fallback() + else: + logging.info("Custom config layer disabled") # Freeze Shepherd Control related config. core_conf = confman.get_config_bundle("shepherd") @@ -115,18 +146,21 @@ def compile_config_and_get_plugins(confman, default_config_path): # ====Control Remote Config Layer==== # If this fails, maintain current local config. - try: - control_config = control.get_config(core_conf["root_dir"]) + if "control" not in layers_disabled: try: - plugin_classes = load_config_layer_and_plugins(confman, control_config) - logging.info(F"Loaded cached Shepherd Control config layer") - except Exception as e: - logging.error( - F"Failed to load cached Shepherd Control config layer. Falling back" - " to local config.", exc_info=e) - confman.fallback() - except Exception: - logging.warning("No cached Shepherd Control config layer available.") + control_config = control.get_config(core_conf["root_dir"]) + try: + plugin_classes = load_config_layer_and_plugins(confman, control_config) + logging.info(F"Loaded cached Shepherd Control config layer") + except Exception as e: + logging.error( + F"Failed to load cached Shepherd Control config layer. Falling back" + " to local config.", exc_info=e) + confman.fallback() + except Exception: + logging.warning("No cached Shepherd Control config layer available.") + else: + logging.info("Shepherd Control config layer disabled") logging.debug("Compiled config: %s", confman.root_config) confman.dump_to_file(core_conf["generated_config_path"]) diff --git a/tests/shepherd-test.toml b/tests/shepherd-test.toml new file mode 100644 index 0000000..e69de29