mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-11-05 11:37:44 +01:00
* seaweed-common: share the security.toml search path with the volume server * weed-worker: read jwt.filer_signing from security.toml and WEED_JWT_* like the Go worker * helm: give the worker-lance container security.toml and the extra environment * weed-worker: treat an empty signing key in the environment as unset Viper ignores an empty environment value, so the Go worker falls back to the security.toml key when WEED_JWT_FILER_SIGNING_KEY is blank. The Rust worker took the blank value and connected with no token. An empty --filer-signing-key / WEED_FILER_SIGNING_KEY also falls through to the security.toml lookup now. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * weed-worker: read a quoted expires_after_seconds like viper The Go worker reads jwt.filer_signing.expires_after_seconds with GetInt, which also accepts a quoted number. The Rust worker dropped a quoted value and minted tokens with no expiry. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * weed-worker: warn when security.toml cannot be read or parsed Viper logs a warning when an optional config file is broken. The Rust worker skipped it silently, so a typo looked like an install with no signing key. Log the path and the parse message, without the quoted line, which can hold a key. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * helm: keep POD_NAME and LANCE_NAMESPACE_URL out of worker-lance's extra environment A duplicate name renders after the chart's entry and wins, silently changing the Lance worker's --id or --namespace. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * weed-worker: list /usr/local/etc/seaweedfs in the security.toml search path Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * weed-worker: an explicit --filer-signing-key-expires-after-seconds wins The flag was silently ignored whenever the key was discovered, from WEED_JWT_FILER_SIGNING_KEY as well as from security.toml. Use it when given, else the expiry configured beside the discovered key, else zero. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * weed-worker: test where filer_signing looks for security.toml Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * weed-worker: read a float expires_after_seconds as viper's GetInt does Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * weed-worker: cap the minted exp so a huge expiry cannot overflow Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
80 lines
2.8 KiB
Rust
80 lines
2.8 KiB
Rust
//! Where a SeaweedFS process finds security.toml, the way `weed` does.
|
|
//!
|
|
//! Mirrors the search list in `weed/util/config.go`: the working directory,
|
|
//! `$HOME/.seaweedfs`, `/usr/local/etc/seaweedfs` and `/etc/seaweedfs`, first
|
|
//! existing file wins. The volume server and the workers each read the file
|
|
//! for different sections, but an operator mounts it in one place and expects
|
|
//! every binary to pick it up from there.
|
|
|
|
use std::ffi::OsString;
|
|
use std::path::{Path, PathBuf};
|
|
|
|
pub const SECURITY_CONFIG_FILE_NAME: &str = "security.toml";
|
|
|
|
/// The locations searched for security.toml, in order.
|
|
pub fn candidates(current_dir: Option<&Path>, home_dir: Option<&Path>) -> Vec<PathBuf> {
|
|
let mut candidates = Vec::new();
|
|
if let Some(dir) = current_dir {
|
|
candidates.push(dir.join(SECURITY_CONFIG_FILE_NAME));
|
|
}
|
|
if let Some(home) = home_dir {
|
|
candidates.push(home.join(".seaweedfs").join(SECURITY_CONFIG_FILE_NAME));
|
|
}
|
|
candidates.push(PathBuf::from("/usr/local/etc/seaweedfs").join(SECURITY_CONFIG_FILE_NAME));
|
|
candidates.push(PathBuf::from("/etc/seaweedfs").join(SECURITY_CONFIG_FILE_NAME));
|
|
candidates
|
|
}
|
|
|
|
/// The first candidate that is a file.
|
|
pub fn find(current_dir: Option<&Path>, home_dir: Option<&Path>) -> Option<PathBuf> {
|
|
candidates(current_dir, home_dir)
|
|
.into_iter()
|
|
.find(|candidate| candidate.is_file())
|
|
}
|
|
|
|
/// `$HOME`, or `%USERPROFILE%` where that is what the platform sets, read
|
|
/// through an injected lookup so tests need not touch the process environment.
|
|
pub fn home_dir(env: &dyn Fn(&str) -> Option<OsString>) -> Option<PathBuf> {
|
|
env("HOME")
|
|
.filter(|v| !v.is_empty())
|
|
.map(PathBuf::from)
|
|
.or_else(|| {
|
|
env("USERPROFILE")
|
|
.filter(|v| !v.is_empty())
|
|
.map(PathBuf::from)
|
|
})
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn search_order_matches_go() {
|
|
let found = candidates(Some(Path::new("/work")), Some(Path::new("/home/u")));
|
|
assert_eq!(
|
|
found,
|
|
vec![
|
|
PathBuf::from("/work/security.toml"),
|
|
PathBuf::from("/home/u/.seaweedfs/security.toml"),
|
|
PathBuf::from("/usr/local/etc/seaweedfs/security.toml"),
|
|
PathBuf::from("/etc/seaweedfs/security.toml"),
|
|
]
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn home_falls_back_to_userprofile() {
|
|
let env = |key: &str| match key {
|
|
"USERPROFILE" => Some(OsString::from("/users/u")),
|
|
_ => None,
|
|
};
|
|
assert_eq!(home_dir(&env), Some(PathBuf::from("/users/u")));
|
|
let empty_home = |key: &str| match key {
|
|
"HOME" => Some(OsString::new()),
|
|
_ => None,
|
|
};
|
|
assert_eq!(home_dir(&empty_home), None);
|
|
}
|
|
}
|