fix: read secrets from legacy data dir
This commit is contained in:
parent
5d1950647e
commit
6114cc9018
|
|
@ -5,6 +5,9 @@
|
||||||
//! - **`config_dir`** — 人が手で書く / 編集する設定。`profiles.toml`,
|
//! - **`config_dir`** — 人が手で書く / 編集する設定。`profiles.toml`,
|
||||||
//! `providers.toml`, `models.toml`, `prompts/`, `prompts.toml` 等
|
//! `providers.toml`, `models.toml`, `prompts/`, `prompts.toml` 等
|
||||||
//! - **`data_dir`** — プログラムが書く永続データ。`sessions/` 等
|
//! - **`data_dir`** — プログラムが書く永続データ。`sessions/` 等
|
||||||
|
//! - **`secret_data_dir`** — local secret store の読み書き base。既存
|
||||||
|
//! secret store は path-derived key を使うため、通常 data とは別に
|
||||||
|
//! legacy `$HOME/.yoi` を既定にする
|
||||||
//! - **`runtime_dir`** — 再起動で消えてよいランタイム状態。socket,
|
//! - **`runtime_dir`** — 再起動で消えてよいランタイム状態。socket,
|
||||||
//! `workers.json`, `pid` ファイル等
|
//! `workers.json`, `pid` ファイル等
|
||||||
//!
|
//!
|
||||||
|
|
@ -14,6 +17,7 @@
|
||||||
//! |---|---|---|---|---|
|
//! |---|---|---|---|---|
|
||||||
//! | config | `YOI_CONFIG_DIR` | `$YOI_HOME/config` | `$XDG_CONFIG_HOME/yoi` | `$HOME/.config/yoi` |
|
//! | config | `YOI_CONFIG_DIR` | `$YOI_HOME/config` | `$XDG_CONFIG_HOME/yoi` | `$HOME/.config/yoi` |
|
||||||
//! | data | `YOI_DATA_DIR` | `$YOI_HOME` | `$XDG_DATA_HOME/yoi` | `$HOME/.local/share/yoi` |
|
//! | data | `YOI_DATA_DIR` | `$YOI_HOME` | `$XDG_DATA_HOME/yoi` | `$HOME/.local/share/yoi` |
|
||||||
|
//! | secrets | `YOI_DATA_DIR` | `$YOI_HOME` | — | `$HOME/.yoi` |
|
||||||
//! | runtime | `YOI_RUNTIME_DIR` | `$YOI_HOME/run` | `$XDG_RUNTIME_DIR/yoi` | `$HOME/.yoi/run` |
|
//! | runtime | `YOI_RUNTIME_DIR` | `$YOI_HOME/run` | `$XDG_RUNTIME_DIR/yoi` | `$HOME/.yoi/run` |
|
||||||
//!
|
//!
|
||||||
//! `YOI_HOME=$X` のとき config は `$X/config`、data は `$X` 直下、
|
//! `YOI_HOME=$X` のとき config は `$X/config`、data は `$X` 直下、
|
||||||
|
|
@ -47,6 +51,19 @@ pub fn data_dir() -> Option<PathBuf> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Secret store 用の data directory。
|
||||||
|
///
|
||||||
|
/// SecretStore は base path から復号 key を導出するため、通常 data dir の
|
||||||
|
/// XDG fallback には追従させず、明示 override が無い場合は legacy
|
||||||
|
/// `$HOME/.yoi` を読み書きする。
|
||||||
|
pub fn secret_data_dir() -> Option<PathBuf> {
|
||||||
|
resolve_secret_data_dir_from_parts(
|
||||||
|
env_path("YOI_DATA_DIR"),
|
||||||
|
env_path("YOI_HOME"),
|
||||||
|
env_path("HOME"),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/// ランタイムディレクトリ。socket, `workers.json`, Worker ごとの `pid` /
|
/// ランタイムディレクトリ。socket, `workers.json`, Worker ごとの `pid` /
|
||||||
/// `status.json` 等が置かれる。再起動で消えて構わない。
|
/// `status.json` 等が置かれる。再起動で消えて構わない。
|
||||||
pub fn runtime_dir() -> Option<PathBuf> {
|
pub fn runtime_dir() -> Option<PathBuf> {
|
||||||
|
|
@ -147,6 +164,20 @@ fn resolve_data_dir_from_parts(
|
||||||
Some(home?.join(".local").join("share").join("yoi"))
|
Some(home?.join(".local").join("share").join("yoi"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn resolve_secret_data_dir_from_parts(
|
||||||
|
yoi_data_dir: Option<PathBuf>,
|
||||||
|
yoi_home: Option<PathBuf>,
|
||||||
|
home: Option<PathBuf>,
|
||||||
|
) -> Option<PathBuf> {
|
||||||
|
if let Some(p) = yoi_data_dir {
|
||||||
|
return Some(p);
|
||||||
|
}
|
||||||
|
if let Some(p) = yoi_home {
|
||||||
|
return Some(p);
|
||||||
|
}
|
||||||
|
Some(home?.join(".yoi"))
|
||||||
|
}
|
||||||
|
|
||||||
fn resolve_runtime_dir_from_parts(
|
fn resolve_runtime_dir_from_parts(
|
||||||
yoi_runtime_dir: Option<PathBuf>,
|
yoi_runtime_dir: Option<PathBuf>,
|
||||||
yoi_home: Option<PathBuf>,
|
yoi_home: Option<PathBuf>,
|
||||||
|
|
@ -322,6 +353,40 @@ mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn secret_data_dir_falls_back_to_home_dot_yoi() {
|
||||||
|
assert_eq!(
|
||||||
|
resolve_secret_data_dir_from_parts(None, None, Some(PathBuf::from("/h"))).unwrap(),
|
||||||
|
PathBuf::from("/h/.yoi")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn secret_data_dir_yoi_home_wins() {
|
||||||
|
assert_eq!(
|
||||||
|
resolve_secret_data_dir_from_parts(
|
||||||
|
None,
|
||||||
|
Some(PathBuf::from("/sand")),
|
||||||
|
Some(PathBuf::from("/h"))
|
||||||
|
)
|
||||||
|
.unwrap(),
|
||||||
|
PathBuf::from("/sand")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn secret_data_dir_explicit_wins_over_yoi_home() {
|
||||||
|
assert_eq!(
|
||||||
|
resolve_secret_data_dir_from_parts(
|
||||||
|
Some(PathBuf::from("/explicit-data")),
|
||||||
|
Some(PathBuf::from("/sand")),
|
||||||
|
Some(PathBuf::from("/h")),
|
||||||
|
)
|
||||||
|
.unwrap(),
|
||||||
|
PathBuf::from("/explicit-data")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn runtime_dir_prefers_xdg_runtime_dir() {
|
fn runtime_dir_prefers_xdg_runtime_dir() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ impl WebTools {
|
||||||
.user_agent("yoi-web-tools/0.1")
|
.user_agent("yoi-web-tools/0.1")
|
||||||
.build()
|
.build()
|
||||||
.expect("static reqwest client configuration is valid");
|
.expect("static reqwest client configuration is valid");
|
||||||
let secret_store = manifest::paths::data_dir().map(SecretStore::new);
|
let secret_store = manifest::paths::secret_data_dir().map(SecretStore::new);
|
||||||
Self {
|
Self {
|
||||||
config,
|
config,
|
||||||
client,
|
client,
|
||||||
|
|
|
||||||
|
|
@ -218,10 +218,10 @@ impl std::fmt::Debug for Action {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn launch() -> ExitCode {
|
pub async fn launch() -> ExitCode {
|
||||||
let data_dir = match manifest::paths::data_dir() {
|
let data_dir = match manifest::paths::secret_data_dir() {
|
||||||
Some(path) => path,
|
Some(path) => path,
|
||||||
None => {
|
None => {
|
||||||
eprintln!("yoi keys: could not determine yoi data directory");
|
eprintln!("yoi keys: could not determine yoi secret data directory");
|
||||||
return ExitCode::FAILURE;
|
return ExitCode::FAILURE;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -70,11 +70,11 @@ struct DefaultSecretResolver;
|
||||||
|
|
||||||
impl SecretResolver for DefaultSecretResolver {
|
impl SecretResolver for DefaultSecretResolver {
|
||||||
fn get_secret(&self, id: &str) -> Result<SecretValue, secrets::Error> {
|
fn get_secret(&self, id: &str) -> Result<SecretValue, secrets::Error> {
|
||||||
let data_dir = manifest::paths::data_dir().ok_or_else(|| secrets::Error::Read {
|
let data_dir = manifest::paths::secret_data_dir().ok_or_else(|| secrets::Error::Read {
|
||||||
path: std::path::PathBuf::from("<data_dir>"),
|
path: std::path::PathBuf::from("<secret_data_dir>"),
|
||||||
source: std::io::Error::new(
|
source: std::io::Error::new(
|
||||||
std::io::ErrorKind::NotFound,
|
std::io::ErrorKind::NotFound,
|
||||||
"could not determine yoi data directory",
|
"could not determine yoi secret data directory",
|
||||||
),
|
),
|
||||||
})?;
|
})?;
|
||||||
SecretStore::new(data_dir).get(id)
|
SecretStore::new(data_dir).get(id)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user