Reverts the NUMA_DATA_DIR env var added in the previous commit and replaces it with a [server] data_dir TOML field. Numa already has a well-developed config system; adding a parallel env-var mechanism for a single knob was wrong. The principle: TOML is for application behavior configuration. Env vars are for bootstrap values (HOME, SUDO_USER to discover paths before config loads) and standard ecosystem conventions (RUST_LOG). data_dir is neither — it's an app knob, so it belongs in the TOML. Changes: - lib.rs::data_dir() reverts to the platform-specific fallback only - config.rs adds `data_dir: Option<PathBuf>` to ServerConfig - main.rs resolves config.server.data_dir with fallback to numa::data_dir() and passes it to build_tls_config, then stores the resolved path on ctx.data_dir for downstream consumers - tls.rs::build_tls_config takes `data_dir: &Path` as an explicit parameter instead of calling crate::data_dir() behind the caller's back. regenerate_tls and dot.rs self_signed_tls now pass &ctx.data_dir, honoring whatever path the config resolved to - tests/integration.sh Suite 6 uses `data_dir = "$NUMA_DATA"` in its test TOML instead of the NUMA_DATA_DIR env var prefix - numa.toml gains a commented-out data_dir example No behavior change for existing production deployments (the default path is unchanged). Test harness is now fully config-driven, and containerized deploys can override data_dir via mount+config without needing env var injection. 127/127 unit tests pass, Suite 6 passes end-to-end. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
87 lines
2.3 KiB
Rust
87 lines
2.3 KiB
Rust
pub mod api;
|
|
pub mod blocklist;
|
|
pub mod buffer;
|
|
pub mod cache;
|
|
pub mod config;
|
|
pub mod ctx;
|
|
pub mod dnssec;
|
|
pub mod dot;
|
|
pub mod forward;
|
|
pub mod header;
|
|
pub mod lan;
|
|
pub mod override_store;
|
|
pub mod packet;
|
|
pub mod proxy;
|
|
pub mod query_log;
|
|
pub mod question;
|
|
pub mod record;
|
|
pub mod recursive;
|
|
pub mod service_store;
|
|
pub mod srtt;
|
|
pub mod stats;
|
|
pub mod system_dns;
|
|
pub mod tls;
|
|
|
|
pub type Error = Box<dyn std::error::Error + Send + Sync>;
|
|
pub type Result<T> = std::result::Result<T, Error>;
|
|
|
|
/// Shared config directory for persistent data (services.json, etc).
|
|
/// Unix: ~/.config/numa/ (or /usr/local/var/numa/ when running as root daemon)
|
|
/// Windows: %APPDATA%\numa
|
|
pub fn config_dir() -> std::path::PathBuf {
|
|
#[cfg(windows)]
|
|
{
|
|
std::path::PathBuf::from(
|
|
std::env::var("APPDATA").unwrap_or_else(|_| "C:\\ProgramData".into()),
|
|
)
|
|
.join("numa")
|
|
}
|
|
#[cfg(not(windows))]
|
|
{
|
|
config_dir_unix()
|
|
}
|
|
}
|
|
|
|
#[cfg(not(windows))]
|
|
fn config_dir_unix() -> std::path::PathBuf {
|
|
// When run via sudo, SUDO_USER has the real user
|
|
if let Ok(user) = std::env::var("SUDO_USER") {
|
|
let home = if cfg!(target_os = "macos") {
|
|
format!("/Users/{}", user)
|
|
} else {
|
|
format!("/home/{}", user)
|
|
};
|
|
return std::path::PathBuf::from(home).join(".config").join("numa");
|
|
}
|
|
|
|
// Normal user (not root)
|
|
if let Ok(home) = std::env::var("HOME") {
|
|
let path = std::path::PathBuf::from(&home);
|
|
if !home.starts_with("/var/root") && !home.starts_with("/root") {
|
|
return path.join(".config").join("numa");
|
|
}
|
|
}
|
|
|
|
// Running as root daemon (launchd/systemd) — use system-wide path
|
|
std::path::PathBuf::from("/usr/local/var/numa")
|
|
}
|
|
|
|
/// Default system-wide data directory for TLS certs. Overridable via
|
|
/// `[server] data_dir = "..."` in numa.toml — this function only provides
|
|
/// the fallback when the config doesn't set it.
|
|
/// Unix: /usr/local/var/numa
|
|
/// Windows: %PROGRAMDATA%\numa
|
|
pub fn data_dir() -> std::path::PathBuf {
|
|
#[cfg(windows)]
|
|
{
|
|
std::path::PathBuf::from(
|
|
std::env::var("PROGRAMDATA").unwrap_or_else(|_| "C:\\ProgramData".into()),
|
|
)
|
|
.join("numa")
|
|
}
|
|
#[cfg(not(windows))]
|
|
{
|
|
std::path::PathBuf::from("/usr/local/var/numa")
|
|
}
|
|
}
|