|
|
|
|
@ -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"])
|
|
|
|
|
|