|  |  | @ -207,9 +207,16 @@ def compile_config(confman, default_config_path, layers_disabled): | 
			
		
	
		
		
			
				
					
					|  |  |  |     custom_config_path = core_conf["custom_config_path"] |  |  |  |     custom_config_path = core_conf["custom_config_path"] | 
			
		
	
		
		
			
				
					
					|  |  |  |     confman.save_fallback() |  |  |  |     confman.save_fallback() | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if not core_conf["plugin_dir"]: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         log.warn("Custom plugin path is empty, won't load custom plugins") | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     # ====Custom Local Config Layer==== |  |  |  |     # ====Custom Local Config Layer==== | 
			
		
	
		
		
			
				
					
					|  |  |  |     # 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" in layers_disabled: | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         log.info("Custom config layer disabled") | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     elif not custom_config_path: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         log.warning("Custom config path is empty, skipping custom config layer") | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     else: | 
			
		
	
		
		
			
				
					
					|  |  |  |         try: |  |  |  |         try: | 
			
		
	
		
		
			
				
					
					|  |  |  |             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}") | 
			
		
	
	
		
		
			
				
					|  |  | @ -223,9 +230,6 @@ def compile_config(confman, default_config_path, layers_disabled): | 
			
		
	
		
		
			
				
					
					|  |  |  |             log.warning("Falling back to default config.") |  |  |  |             log.warning("Falling back to default config.") | 
			
		
	
		
		
			
				
					
					|  |  |  |             confman.fallback() |  |  |  |             confman.fallback() | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     else: |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         log.info("Custom config layer 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) | 
			
		
	
	
		
		
			
				
					|  |  | @ -271,10 +275,10 @@ def core_confspec(): | 
			
		
	
		
		
			
				
					
					|  |  |  |         ("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" | 
			
		
	
		
		
			
				
					
					|  |  |  |                                 " hostname")), |  |  |  |                                 " hostname")), | 
			
		
	
		
		
			
				
					
					|  |  |  |         ("plugin_dir", StringSpec(default="~/shepherd-plugins", optional=True, |  |  |  |         ("plugin_dir", StringSpec(default="./shepherd-plugins", optional=True, | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                                   helptext="Optional directory for Shepherd to look for" |  |  |  |                                   helptext="Optional directory for Shepherd to look for" | 
			
		
	
		
		
			
				
					
					|  |  |  |                                   " plugins in.")), |  |  |  |                                   " plugins in.")), | 
			
		
	
		
		
			
				
					
					|  |  |  |         ("root_dir", StringSpec(default="~/shepherd", optional=True, |  |  |  |         ("root_dir", StringSpec(default="./shepherd", optional=False, | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                                 helptext="Operating directory for shepherd to place" |  |  |  |                                 helptext="Operating directory for shepherd to place" | 
			
		
	
		
		
			
				
					
					|  |  |  |                                 " 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" | 
			
		
	
	
		
		
			
				
					|  |  | @ -294,11 +298,22 @@ def core_confspec(): | 
			
		
	
		
		
			
				
					
					|  |  |  | def resolve_core_conf_paths(core_conf): |  |  |  | def resolve_core_conf_paths(core_conf): | 
			
		
	
		
		
			
				
					
					|  |  |  |     """ |  |  |  |     """ | 
			
		
	
		
		
			
				
					
					|  |  |  |     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. | 
			
		
	
		
		
			
				
					
					|  |  |  |     Also expands out any "~" user characters. |  |  |  |     ``root_dir`` itself will resolve relative to ``relative_dir``, intended to be the config | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     file directory. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     Also expands out any "~" user characters. If paths are empty, leaves them as is, rather than | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      the default pathlib behaviour of resolving to the current directory | 
			
		
	
		
		
			
				
					
					|  |  |  |     """ |  |  |  |     """ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     os.chdir(relative_dir) | 
			
		
	
		
		
			
				
					
					|  |  |  |     core_conf["root_dir"] = str(Path(core_conf["root_dir"]).expanduser().resolve()) |  |  |  |     core_conf["root_dir"] = str(Path(core_conf["root_dir"]).expanduser().resolve()) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     try: | 
			
		
	
		
		
			
				
					
					|  |  |  |     os.chdir(core_conf["root_dir"]) |  |  |  |     os.chdir(core_conf["root_dir"]) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     except FileNotFoundError: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         raise FileNotFoundError(F"Shepherd root operating directory '{core_conf['root_dir']}'" | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                 F" does not exist") | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if core_conf["plugin_dir"]: | 
			
		
	
		
		
			
				
					
					|  |  |  |     core_conf["plugin_dir"] = str(Path(core_conf["plugin_dir"]).expanduser().resolve()) |  |  |  |     core_conf["plugin_dir"] = str(Path(core_conf["plugin_dir"]).expanduser().resolve()) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     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( |  |  |  |     core_conf["generated_config_path"] = str( | 
			
		
	
	
		
		
			
				
					|  |  | 
 |