|
|
|
@ -66,15 +66,16 @@ def cli(ctx, default_config_path, local_operation, only_default_layer):
|
|
|
|
|
|
|
|
|
|
|
|
confman = ConfigManager()
|
|
|
|
confman = ConfigManager()
|
|
|
|
|
|
|
|
|
|
|
|
plugin_classes = compile_config_and_get_plugins(confman, default_config_path, layers_disabled)
|
|
|
|
compile_config(confman, default_config_path, layers_disabled)
|
|
|
|
|
|
|
|
|
|
|
|
plugin_configs = confman.get_config_bundles()
|
|
|
|
plugin_configs = confman.get_config_bundles()
|
|
|
|
core_config = confman.get_config_bundle("shepherd")
|
|
|
|
|
|
|
|
del plugin_configs["shepherd"]
|
|
|
|
del plugin_configs["shepherd"]
|
|
|
|
|
|
|
|
core_config = confman.get_config_bundle("shepherd")
|
|
|
|
|
|
|
|
|
|
|
|
# control.init_control(core_config, plugin_configs)
|
|
|
|
# control.init_control(core_config, plugin_configs)
|
|
|
|
|
|
|
|
|
|
|
|
scheduler.init_scheduler(core_config)
|
|
|
|
scheduler.init_scheduler(core_config)
|
|
|
|
plugin.init_plugins(plugin_classes, plugin_configs, core_config)
|
|
|
|
plugin.init_plugins(plugin_configs, core_config)
|
|
|
|
# scheduler.restore_jobs()
|
|
|
|
# scheduler.restore_jobs()
|
|
|
|
|
|
|
|
|
|
|
|
print(str(datetime.now()))
|
|
|
|
print(str(datetime.now()))
|
|
|
|
@ -119,14 +120,14 @@ def template(ctx, plugin_name, include_all, config_path, plugin_dir):
|
|
|
|
confspec = ConfigSpecification()
|
|
|
|
confspec = ConfigSpecification()
|
|
|
|
if (not plugin_name) or (plugin_name == "shepherd"):
|
|
|
|
if (not plugin_name) or (plugin_name == "shepherd"):
|
|
|
|
plugin_name = "shepherd"
|
|
|
|
plugin_name = "shepherd"
|
|
|
|
specify_core_config(confspec)
|
|
|
|
confspec = core_confspec()
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
plugin_class = plugin.find_plugins([plugin_name], plugin_dir)[plugin_name]
|
|
|
|
plugin_interface = plugin.load_plugin(plugin_name, plugin_dir)
|
|
|
|
except plugin.PluginLoadError as e:
|
|
|
|
except plugin.PluginLoadError as e:
|
|
|
|
log.error(e.args[0])
|
|
|
|
log.error(e.args[0])
|
|
|
|
sys.exit(1)
|
|
|
|
sys.exit(1)
|
|
|
|
plugin_class.specify_config(confspec)
|
|
|
|
confspec = plugin_interface.confspec
|
|
|
|
|
|
|
|
|
|
|
|
template_dict = confspec.get_template(include_all)
|
|
|
|
template_dict = confspec.get_template(include_all)
|
|
|
|
template_toml = toml.dumps({plugin_name: template_dict})
|
|
|
|
template_toml = toml.dumps({plugin_name: template_dict})
|
|
|
|
@ -169,22 +170,19 @@ def template(ctx, plugin_name, include_all, config_path, plugin_dir):
|
|
|
|
f.write(template_toml)
|
|
|
|
f.write(template_toml)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def compile_config_and_get_plugins(confman, default_config_path, layers_disabled):
|
|
|
|
def compile_config(confman, default_config_path, layers_disabled):
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
Run through the process of assembling the various config layers, falling back to working
|
|
|
|
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.
|
|
|
|
ones where necessary. As part of this, loads in the required plugins.
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
# Create core confspec and populate it
|
|
|
|
confman.add_confspec("shepherd", core_confspec())
|
|
|
|
core_confspec = ConfigSpecification()
|
|
|
|
|
|
|
|
specify_core_config(core_confspec)
|
|
|
|
|
|
|
|
confman.add_confspec("shepherd", core_confspec)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# ====Default Local Config Layer====
|
|
|
|
# ====Default Local Config Layer====
|
|
|
|
# This must validate to continue.
|
|
|
|
# This must validate to continue.
|
|
|
|
default_config_path = Path(default_config_path).expanduser()
|
|
|
|
default_config_path = Path(default_config_path).expanduser()
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
plugin_classes = load_config_layer_and_plugins(confman, default_config_path)
|
|
|
|
load_config_layer_and_plugins(confman, default_config_path)
|
|
|
|
log.info(F"Loaded default config layer from {default_config_path}")
|
|
|
|
log.info(F"Loaded default config layer from {default_config_path}")
|
|
|
|
except Exception as e:
|
|
|
|
except Exception as e:
|
|
|
|
if isinstance(e, InvalidConfigError):
|
|
|
|
if isinstance(e, InvalidConfigError):
|
|
|
|
@ -209,7 +207,7 @@ def compile_config_and_get_plugins(confman, default_config_path, layers_disabled
|
|
|
|
# If this fails, maintain default config but continue on to Control layer
|
|
|
|
# If this fails, maintain default config but continue on to Control layer
|
|
|
|
if "custom" not in layers_disabled:
|
|
|
|
if "custom" not in layers_disabled:
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
plugin_classes = load_config_layer_and_plugins(confman, custom_config_path)
|
|
|
|
load_config_layer_and_plugins(confman, custom_config_path)
|
|
|
|
log.info(F"Loaded custom config layer from {custom_config_path}")
|
|
|
|
log.info(F"Loaded custom config layer from {custom_config_path}")
|
|
|
|
except Exception as e:
|
|
|
|
except Exception as e:
|
|
|
|
if isinstance(e, InvalidConfigError):
|
|
|
|
if isinstance(e, InvalidConfigError):
|
|
|
|
@ -239,7 +237,7 @@ def compile_config_and_get_plugins(confman, default_config_path, layers_disabled
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
control_config = control.get_config(core_conf["root_dir"])
|
|
|
|
control_config = control.get_config(core_conf["root_dir"])
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
plugin_classes = load_config_layer_and_plugins(confman, control_config)
|
|
|
|
load_config_layer_and_plugins(confman, control_config)
|
|
|
|
log.info(F"Loaded cached Shepherd Control config layer")
|
|
|
|
log.info(F"Loaded cached Shepherd Control config layer")
|
|
|
|
except Exception as e:
|
|
|
|
except Exception as e:
|
|
|
|
if isinstance(e, InvalidConfigError):
|
|
|
|
if isinstance(e, InvalidConfigError):
|
|
|
|
@ -258,15 +256,13 @@ def compile_config_and_get_plugins(confman, default_config_path, layers_disabled
|
|
|
|
log.debug("Compiled config: %s", confman.root_config)
|
|
|
|
log.debug("Compiled config: %s", confman.root_config)
|
|
|
|
confman.dump_to_file(core_conf["generated_config_path"])
|
|
|
|
confman.dump_to_file(core_conf["generated_config_path"])
|
|
|
|
|
|
|
|
|
|
|
|
return plugin_classes
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Relative pathnames here are all relative to "root_dir"
|
|
|
|
# Relative pathnames here are all relative to "root_dir"
|
|
|
|
def specify_core_config(confspec):
|
|
|
|
def core_confspec():
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
Defines the config specification by populating the ConfigSpecification passed in
|
|
|
|
Returns the core config specification
|
|
|
|
``confspec`` - the same pattern plugins use
|
|
|
|
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
|
|
|
|
confspec = ConfigSpecification()
|
|
|
|
confspec.add_specs([
|
|
|
|
confspec.add_specs([
|
|
|
|
("name", StringSpec(helptext="Identifying name for this device")),
|
|
|
|
("name", StringSpec(helptext="Identifying name for this device")),
|
|
|
|
("hostname", StringSpec(default="", optional=True, helptext="If set, changes the system"
|
|
|
|
("hostname", StringSpec(default="", optional=True, helptext="If set, changes the system"
|
|
|
|
@ -288,6 +284,8 @@ def specify_core_config(confspec):
|
|
|
|
confspec.add_spec("control_server", StringSpec())
|
|
|
|
confspec.add_spec("control_server", StringSpec())
|
|
|
|
confspec.add_spec("control_api_key", StringSpec())
|
|
|
|
confspec.add_spec("control_api_key", StringSpec())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return confspec
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def resolve_core_conf_paths(core_conf):
|
|
|
|
def resolve_core_conf_paths(core_conf):
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
@ -303,7 +301,7 @@ def resolve_core_conf_paths(core_conf):
|
|
|
|
Path(core_conf["generated_config_path"]).expanduser().resolve())
|
|
|
|
Path(core_conf["generated_config_path"]).expanduser().resolve())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def load_config_layer_and_plugins(confman, config_source):
|
|
|
|
def load_config_layer_and_plugins(confman: ConfigManager, config_source):
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
Load a config layer, find the necessary plugin classes, then validate it.
|
|
|
|
Load a config layer, find the necessary plugin classes, then validate it.
|
|
|
|
If this succeeds, the returned dict of plugin classes will directly match
|
|
|
|
If this succeeds, the returned dict of plugin classes will directly match
|
|
|
|
@ -321,13 +319,9 @@ def load_config_layer_and_plugins(confman, config_source):
|
|
|
|
plugin_names.remove("shepherd")
|
|
|
|
plugin_names.remove("shepherd")
|
|
|
|
|
|
|
|
|
|
|
|
# Load plugins to get their config specifications
|
|
|
|
# Load plugins to get their config specifications
|
|
|
|
plugin_classes = plugin.find_plugins(plugin_names, plugin_dir)
|
|
|
|
plugin_interfaces = plugin.load_plugins(plugin_names, plugin_dir)
|
|
|
|
for plugin_name, plugin_class in plugin_classes.items():
|
|
|
|
for plugin_name, plugin_interface in plugin_interfaces.items():
|
|
|
|
new_conf_spec = ConfigSpecification()
|
|
|
|
confman.add_confspec(plugin_name, plugin_interface.confspec)
|
|
|
|
plugin_class.specify_config(new_conf_spec)
|
|
|
|
|
|
|
|
confman.add_confspec(plugin_name, new_conf_spec)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Validate all plugin configs
|
|
|
|
# Validate all plugin configs
|
|
|
|
confman.validate_bundles()
|
|
|
|
confman.validate_bundles()
|
|
|
|
|
|
|
|
|
|
|
|
return plugin_classes
|
|
|
|
|
|
|
|
|