Standardize on ~/.config/shepherd/config.toml

This commit is contained in:
Albert Armea 2026-01-04 20:53:31 -05:00
parent 51b81c2a5b
commit 65292566f2
4 changed files with 44 additions and 6 deletions

View file

@ -86,8 +86,8 @@ max_run_seconds = 3600 # 1 hour
use shepherd_config::{load_config, parse_config, Policy};
use std::path::Path;
// Load from file
let policy = load_config("/etc/shepherdd/config.toml")?;
// Load from file (typically ~/.config/shepherd/config.toml)
let policy = load_config("config.toml")?;
// Parse from string
let toml_content = std::fs::read_to_string("config.toml")?;

View file

@ -115,6 +115,37 @@ pub fn socket_dir() -> PathBuf {
})
}
/// Configuration subdirectory name (uses "shepherd" not "shepherdd")
const CONFIG_APP_DIR: &str = "shepherd";
/// Configuration filename
const CONFIG_FILENAME: &str = "config.toml";
/// Get the default configuration file path.
///
/// Returns `$XDG_CONFIG_HOME/shepherd/config.toml` or `~/.config/shepherd/config.toml`
pub fn default_config_path() -> PathBuf {
// Try XDG_CONFIG_HOME first
if let Ok(config_home) = std::env::var("XDG_CONFIG_HOME") {
return PathBuf::from(config_home)
.join(CONFIG_APP_DIR)
.join(CONFIG_FILENAME);
}
// Fallback to ~/.config/shepherd/config.toml
if let Ok(home) = std::env::var("HOME") {
return PathBuf::from(home)
.join(".config")
.join(CONFIG_APP_DIR)
.join(CONFIG_FILENAME);
}
// Last resort (unlikely to be valid, but provides a fallback)
PathBuf::from("/etc")
.join(CONFIG_APP_DIR)
.join(CONFIG_FILENAME)
}
#[cfg(test)]
mod tests {
use super::*;
@ -145,4 +176,11 @@ mod tests {
let dir = socket_dir();
assert_eq!(socket.parent().unwrap(), dir);
}
#[test]
fn config_path_contains_shepherd() {
let path = default_config_path();
assert!(path.to_string_lossy().contains("shepherd"));
assert!(path.to_string_lossy().ends_with("config.toml"));
}
}

View file

@ -65,7 +65,7 @@ shepherdd --log-level debug
| Option | Default | Description |
|--------|---------|-------------|
| `-c, --config` | `/etc/shepherdd/config.toml` | Configuration file path |
| `-c, --config` | `~/.config/shepherd/config.toml` | Configuration file path |
| `-s, --socket` | From config | IPC socket path |
| `-d, --data-dir` | From config | Data directory |
| `-l, --log-level` | `info` | Log verbosity |

View file

@ -21,7 +21,7 @@ use shepherd_host_api::{HostAdapter, HostEvent, StopMode as HostStopMode, Volume
use shepherd_host_linux::{LinuxHost, LinuxVolumeController};
use shepherd_ipc::{IpcServer, ServerMessage};
use shepherd_store::{AuditEvent, AuditEventType, SqliteStore, Store};
use shepherd_util::{ClientId, MonotonicInstant, RateLimiter};
use shepherd_util::{default_config_path, ClientId, MonotonicInstant, RateLimiter};
use std::path::PathBuf;
use std::sync::Arc;
use std::time::Duration;
@ -35,8 +35,8 @@ use tracing_subscriber::EnvFilter;
#[command(name = "shepherdd")]
#[command(about = "Policy enforcement service for child-focused computing", long_about = None)]
struct Args {
/// Configuration file path
#[arg(short, long, default_value = "/etc/shepherdd/config.toml")]
/// Configuration file path (default: ~/.config/shepherd/config.toml)
#[arg(short, long, default_value_os_t = default_config_path())]
config: PathBuf,
/// Socket path override (or set SHEPHERD_SOCKET env var)