|
|
|
@ -8,6 +8,8 @@ import sys
|
|
|
|
from pathlib import Path
|
|
|
|
from pathlib import Path
|
|
|
|
import glob
|
|
|
|
import glob
|
|
|
|
from datetime import datetime
|
|
|
|
from datetime import datetime
|
|
|
|
|
|
|
|
from types import SimpleNamespace
|
|
|
|
|
|
|
|
from pprint import pprint
|
|
|
|
import logging
|
|
|
|
import logging
|
|
|
|
import chromalog
|
|
|
|
import chromalog
|
|
|
|
import pkg_resources
|
|
|
|
import pkg_resources
|
|
|
|
@ -50,14 +52,19 @@ def cli(ctx, default_config_path, local_operation, only_default_layer):
|
|
|
|
default_config_path = sorted(glob.glob("./shepherd*.toml"))[:1]
|
|
|
|
default_config_path = sorted(glob.glob("./shepherd*.toml"))[:1]
|
|
|
|
if default_config_path:
|
|
|
|
if default_config_path:
|
|
|
|
default_config_path = default_config_path[0]
|
|
|
|
default_config_path = default_config_path[0]
|
|
|
|
log.info(F"No default config file provided, using {default_config_path}")
|
|
|
|
log.info(F"No default config file provided, found {default_config_path}")
|
|
|
|
|
|
|
|
with open(default_config_path, 'r+') as f:
|
|
|
|
|
|
|
|
content = f.read()
|
|
|
|
|
|
|
|
if "Compiled Shepherd config" in content:
|
|
|
|
|
|
|
|
log.warn("Default config file looks like it is full compiled config file"
|
|
|
|
|
|
|
|
" generated by Shepherd and picked up due to accidental name match")
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
log.error("No default config file provided, and no 'shepherd*.toml' could be"
|
|
|
|
log.error("No default config file provided, and no 'shepherd*.toml' could be"
|
|
|
|
" found in the current directory")
|
|
|
|
" found in the current directory")
|
|
|
|
sys.exit(1)
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
|
|
|
|
layers_disabled = []
|
|
|
|
layers_disabled = []
|
|
|
|
if local_operation:
|
|
|
|
if local_operation or (ctx.invoked_subcommand == "test"):
|
|
|
|
layers_disabled.append("control")
|
|
|
|
layers_disabled.append("control")
|
|
|
|
log.info("Running in local only mode")
|
|
|
|
log.info("Running in local only mode")
|
|
|
|
|
|
|
|
|
|
|
|
@ -184,24 +191,25 @@ def compile_config(confman, default_config_path, layers_disabled):
|
|
|
|
|
|
|
|
|
|
|
|
# ====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().resolve()
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
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):
|
|
|
|
log.error(F"Failed to load default config from {default_config_path}. {e.args[0]}")
|
|
|
|
log.error(
|
|
|
|
|
|
|
|
F"Failed to load default config from {default_config_path}. {chr(10).join(e.args)}")
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
log.error(F"Failed to load default config from {default_config_path}", exc_info=True)
|
|
|
|
log.error(F"Failed to load default config from {default_config_path}", exc_info=True)
|
|
|
|
sys.exit(1)
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
|
|
|
|
# Resolve and freeze local install paths that shouldn't be changed from default config
|
|
|
|
# Resolve and freeze local install paths that shouldn't be changed from default config
|
|
|
|
core_conf = confman.get_config_bundle("shepherd")
|
|
|
|
core_conf = confman.get_config_bundle("shepherd")
|
|
|
|
resolve_core_conf_paths(core_conf)
|
|
|
|
resolve_core_conf_paths(core_conf, default_config_path.parent)
|
|
|
|
confman.freeze_value("shepherd", "root_dir")
|
|
|
|
confman.freeze_value("shepherd", "root_dir")
|
|
|
|
confman.freeze_value("shepherd", "plugin_dir")
|
|
|
|
confman.freeze_value("shepherd", "plugin_dir")
|
|
|
|
confman.freeze_value("shepherd", "custom_config_path")
|
|
|
|
confman.freeze_value("shepherd", "custom_config_path")
|
|
|
|
confman.freeze_value("shepherd", "generated_config_path")
|
|
|
|
confman.freeze_value("shepherd", "compiled_config_path")
|
|
|
|
|
|
|
|
|
|
|
|
# Pull out custom config path and save current good config
|
|
|
|
# Pull out custom config path and save current good config
|
|
|
|
custom_config_path = core_conf["custom_config_path"]
|
|
|
|
custom_config_path = core_conf["custom_config_path"]
|
|
|
|
@ -232,7 +240,7 @@ def compile_config(confman, default_config_path, layers_disabled):
|
|
|
|
|
|
|
|
|
|
|
|
# Freeze Shepherd Control related config.
|
|
|
|
# Freeze Shepherd Control related config.
|
|
|
|
core_conf = confman.get_config_bundle("shepherd")
|
|
|
|
core_conf = confman.get_config_bundle("shepherd")
|
|
|
|
resolve_core_conf_paths(core_conf)
|
|
|
|
resolve_core_conf_paths(core_conf, default_config_path.parent)
|
|
|
|
confman.freeze_value("shepherd", "control_server")
|
|
|
|
confman.freeze_value("shepherd", "control_server")
|
|
|
|
confman.freeze_value("shepherd", "control_api_key")
|
|
|
|
confman.freeze_value("shepherd", "control_api_key")
|
|
|
|
|
|
|
|
|
|
|
|
@ -262,7 +270,10 @@ def compile_config(confman, default_config_path, layers_disabled):
|
|
|
|
log.info("Shepherd Control config layer disabled")
|
|
|
|
log.info("Shepherd Control config layer 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"])
|
|
|
|
if core_conf["compiled_config_path"]:
|
|
|
|
|
|
|
|
message = F"Compiled Shepherd config at {datetime.now()}"
|
|
|
|
|
|
|
|
confman.dump_to_file(core_conf["compiled_config_path"], message=message)
|
|
|
|
|
|
|
|
log.info(F"Saved compiled config to {core_conf['compiled_config_path']}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Relative pathnames here are all relative to "root_dir"
|
|
|
|
# Relative pathnames here are all relative to "root_dir"
|
|
|
|
@ -283,7 +294,7 @@ def core_confspec():
|
|
|
|
" working files.")),
|
|
|
|
" working files.")),
|
|
|
|
("custom_config_path", StringSpec(optional=True, helptext="Path to custom config"
|
|
|
|
("custom_config_path", StringSpec(optional=True, helptext="Path to custom config"
|
|
|
|
" layer TOML file.")),
|
|
|
|
" layer TOML file.")),
|
|
|
|
("generated_config_path", StringSpec(default="shepherd-generated.toml", optional=True,
|
|
|
|
("compiled_config_path", StringSpec(default="compiled-config.toml", optional=True,
|
|
|
|
helptext="Path to custom file Shepherd will generate"
|
|
|
|
helptext="Path to custom file Shepherd will generate"
|
|
|
|
" to show compiled config that was used and any"
|
|
|
|
" to show compiled config that was used and any"
|
|
|
|
" errors in validation."))
|
|
|
|
" errors in validation."))
|
|
|
|
@ -295,7 +306,7 @@ def core_confspec():
|
|
|
|
return confspec
|
|
|
|
return confspec
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def resolve_core_conf_paths(core_conf):
|
|
|
|
def resolve_core_conf_paths(core_conf, relative_dir):
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
Set the cwd to ``root_dir`` and resolve other core config paths relative to that.
|
|
|
|
Set the cwd to ``root_dir`` and resolve other core config paths relative to that.
|
|
|
|
``root_dir`` itself will resolve relative to ``relative_dir``, intended to be the config
|
|
|
|
``root_dir`` itself will resolve relative to ``relative_dir``, intended to be the config
|
|
|
|
@ -316,8 +327,9 @@ def resolve_core_conf_paths(core_conf):
|
|
|
|
if core_conf["custom_config_path"]:
|
|
|
|
if core_conf["custom_config_path"]:
|
|
|
|
core_conf["custom_config_path"] = str(
|
|
|
|
core_conf["custom_config_path"] = str(
|
|
|
|
Path(core_conf["custom_config_path"]).expanduser().resolve())
|
|
|
|
Path(core_conf["custom_config_path"]).expanduser().resolve())
|
|
|
|
core_conf["generated_config_path"] = str(
|
|
|
|
if core_conf["compiled_config_path"]:
|
|
|
|
Path(core_conf["generated_config_path"]).expanduser().resolve())
|
|
|
|
core_conf["compiled_config_path"] = str(
|
|
|
|
|
|
|
|
Path(core_conf["compiled_config_path"]).expanduser().resolve())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def load_config_layer_and_plugins(confman: ConfigManager, config_source):
|
|
|
|
def load_config_layer_and_plugins(confman: ConfigManager, config_source):
|
|
|
|
|