refactor(config): require explicit BZOD data directory
Rust CI / Test & Quality Checks (push) Canceled after 0s
Rust CI / Build Docker Image (push) Canceled after 0s

This commit is contained in:
thakares committed 2026-08-27 15:06:05 +05:30
1 parent d398341f01
commit c2e138f823
55 files changed
+471 -119

No files matched your search

+3 -1
View File
@@ -1,7 +1,9 @@
# BZOD Platform Configuration # BZOD Platform Configuration
HOST=0.0.0.0 HOST=0.0.0.0
PORT=8080 PORT=8080
DATA_DIR=./data # Physical BZOD data root.
# REQUIRED: Set this explicitly; there is no implicit ./data fallback.
NX9_BZOD_DATA_DIR=/var/lib/bzod/data
# Security Settings # Security Settings
COOKIE_SECURE=false COOKIE_SECURE=false
+1 -1
View File
@@ -73,7 +73,7 @@ RUN mkdir -p \
/usr/local/bin/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
# Runtime configuration # Runtime configuration
ENV DATA_DIR=/app/data \ ENV NX9_BZOD_DATA_DIR=/app/data \
CONFIG_DIR=/app/config \ CONFIG_DIR=/app/config \
IMAGES_DIR=/app/images \ IMAGES_DIR=/app/images \
PORT=8654 \ PORT=8654 \
+29 -5
View File
@@ -168,9 +168,10 @@ services:
- "8654:8654" - "8654:8654"
volumes: volumes:
- ./data:/app/data - /var/lib/bzod/data:/app/data
environment: environment:
- NX9_BZOD_DATA_DIR=/app/data
- RUST_LOG=info - RUST_LOG=info
``` ```
@@ -182,6 +183,28 @@ docker compose up -d
--- ---
# Data Directory & Configuration Precedence
BZOD requires an explicit physical data root. There is **no implicit `./data` fallback**.
Precedence:
1. **CLI `--data-dir`** (Highest)
2. **`NX9_BZOD_DATA_DIR`** environment variable
3. **`config.toml` / `bzod.toml` `data_dir`** setting
4. **Configuration Error** if no data directory is configured.
Examples:
```bash
# Via environment variable
NX9_BZOD_DATA_DIR=/var/lib/bzod/data bzod serve
# Via CLI argument
bzod migrate --data-dir=/var/lib/bzod/data --dry-run
```
---
# Native Installation # Native Installation
Download the latest release. Download the latest release.
@@ -202,16 +225,16 @@ bzod --help
# Initialize # Initialize
Create the administrator. Create the administrator (specifying `--data-dir` or `NX9_BZOD_DATA_DIR`):
```bash ```bash
bzod create-admin NX9_BZOD_DATA_DIR=/var/lib/bzod/data bzod create-admin
``` ```
Start the server. Start the server:
```bash ```bash
bzod serve NX9_BZOD_DATA_DIR=/var/lib/bzod/data bzod serve
``` ```
Default server: Default server:
@@ -234,6 +257,7 @@ After=network.target
[Service] [Service]
Environment=NX9_BZOD_DATA_DIR=/var/lib/bzod/data
ExecStart=/usr/local/bin/bzod serve ExecStart=/usr/local/bin/bzod serve
Restart=always Restart=always
+2 -2
View File
@@ -180,7 +180,7 @@ BZOD_IMAGE=${BZOD_IMAGE}
HOST=0.0.0.0 HOST=0.0.0.0
PORT=8654 PORT=8654
DATA_DIR=/app/data NX9_BZOD_DATA_DIR=/app/data
CONFIG_DIR=/app/config CONFIG_DIR=/app/config
IMAGES_DIR=/app/images IMAGES_DIR=/app/images
@@ -238,7 +238,7 @@ services:
HOST: "${HOST:-0.0.0.0}" HOST: "${HOST:-0.0.0.0}"
PORT: "${PORT:-8654}" PORT: "${PORT:-8654}"
DATA_DIR: "/app/data" NX9_BZOD_DATA_DIR: "/app/data"
CONFIG_DIR: "/app/config" CONFIG_DIR: "/app/config"
IMAGES_DIR: "/app/images" IMAGES_DIR: "/app/images"
+1 -1
View File
@@ -18,7 +18,7 @@ services:
- ADMIN_USERNAME=${ADMIN_USERNAME} - ADMIN_USERNAME=${ADMIN_USERNAME}
- CONFIG_DIR=/app/config - CONFIG_DIR=/app/config
- COOKIE_SECURE=false - COOKIE_SECURE=false
- DATA_DIR=/app/data - NX9_BZOD_DATA_DIR=/app/data
- HOST=0.0.0.0 - HOST=0.0.0.0
- IMAGES_DIR=/app/images - IMAGES_DIR=/app/images
- PORT=8654 - PORT=8654
+24
View File
@@ -284,3 +284,27 @@ bzod doctor
* SECURITY.md * SECURITY.md
* API.md * API.md
* ARCHITECTURE.md * ARCHITECTURE.md
---
# Data Directory Configuration
BZOD requires an explicit physical data directory root. There is **no implicit `./data` fallback**.
### Configuration Precedence
1. **CLI `--data-dir`** (Highest priority)
```bash
bzod serve --data-dir /var/lib/bzod/data
bzod migrate --data-dir=/var/lib/bzod/data --dry-run
```
2. **Environment Variable `NX9_BZOD_DATA_DIR`**
```bash
export NX9_BZOD_DATA_DIR=/var/lib/bzod/data
bzod serve
```
3. **Configuration File (`bzod.toml` / `config.toml`)**
```toml
data_dir = "/var/lib/bzod/data"
```
4. **Error**: If no data directory is provided via CLI, `NX9_BZOD_DATA_DIR`, or config file, BZOD terminates with an actionable error.
+3 -3
View File
@@ -100,7 +100,7 @@ services:
environment: environment:
HOST: 0.0.0.0 HOST: 0.0.0.0
PORT: 8654 PORT: 8654
DATA_DIR: /app/data NX9_BZOD_DATA_DIR: /app/data
COOKIE_SECURE: "false" COOKIE_SECURE: "false"
healthcheck: healthcheck:
@@ -205,10 +205,10 @@ BZOD Docker Container
# Environment Variables # Environment Variables
| Variable | Description | Default | | Variable | Description | Default |
| ------------- | ------------------ | --------- | | ----------------- | ------------------ | ------------- |
| HOST | Bind address | 0.0.0.0 | | HOST | Bind address | 0.0.0.0 |
| PORT | Listen port | 8654 | | PORT | Listen port | 8654 |
| DATA_DIR | Database directory | /app/data | | NX9_BZOD_DATA_DIR | Database directory | (required) |
| COOKIE_SECURE | Secure cookies | false | | COOKIE_SECURE | Secure cookies | false |
| RUST_LOG | Logging level | info | | RUST_LOG | Logging level | info |
+31
View File
@@ -213,3 +213,34 @@ pub enum RepairCommands {
data_dir: Option<String>, data_dir: Option<String>,
}, },
} }
impl Commands {
pub fn data_dir(&self) -> Option<&str> {
match self {
Commands::Serve { data_dir, .. } => data_dir.as_deref(),
Commands::Backup { data_dir, .. } => data_dir.as_deref(),
Commands::Restore { data_dir, .. } => data_dir.as_deref(),
Commands::Migrate { data_dir, .. } => data_dir.as_deref(),
Commands::Stats { data_dir, .. } => data_dir.as_deref(),
Commands::Validate { data_dir, .. } => data_dir.as_deref(),
Commands::AuditDestinations { data_dir, .. } => data_dir.as_deref(),
Commands::CreateAdmin { data_dir, .. } => data_dir.as_deref(),
Commands::InitAdmin { data_dir, .. } => data_dir.as_deref(),
Commands::Doctor { data_dir, .. } => data_dir.as_deref(),
Commands::Shorten { data_dir, .. } => data_dir.as_deref(),
Commands::Expand { data_dir, .. } => data_dir.as_deref(),
Commands::CreateUser { data_dir, .. } => data_dir.as_deref(),
Commands::DeleteUser { data_dir, .. } => data_dir.as_deref(),
Commands::DisableUser { data_dir, .. } => data_dir.as_deref(),
Commands::EnableUser { data_dir, .. } => data_dir.as_deref(),
Commands::ResetPassword { data_dir, .. } => data_dir.as_deref(),
Commands::ListUsers { data_dir, .. } => data_dir.as_deref(),
Commands::BackupUser { data_dir, .. } => data_dir.as_deref(),
Commands::RestoreUser { data_dir, .. } => data_dir.as_deref(),
Commands::AdminMigrate { data_dir, .. } => data_dir.as_deref(),
Commands::Repair { command } => match command {
RepairCommands::Registry { data_dir, .. } => data_dir.as_deref(),
},
}
}
}
+1 -2
View File
@@ -277,8 +277,7 @@ pub fn perform_restore(
} }
// 5. Run validation on the normalized temp_dir // 5. Run validation on the normalized temp_dir
let mut temp_config = Config::load(); let temp_config = Config::load_with_cli(Some(&temp_dir))?;
temp_config.data_dir = temp_dir.clone();
// Namespace audit // Namespace audit
match crate::db::users::audit_slug_namespace(&temp_config) { match crate::db::users::audit_slug_namespace(&temp_config) {
+101 -15
View File
@@ -3,6 +3,45 @@ use std::env;
use std::fs; use std::fs;
use std::path::PathBuf; use std::path::PathBuf;
pub const NX9_BZOD_DATA_DIR_ENV: &str = "NX9_BZOD_DATA_DIR";
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ConfigError {
MissingDataDir,
InvalidConfig(String),
}
impl std::fmt::Display for ConfigError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::MissingDataDir => write!(
f,
"data directory is not configured; set NX9_BZOD_DATA_DIR or use --data-dir=<path>"
),
Self::InvalidConfig(msg) => write!(f, "configuration error: {msg}"),
}
}
}
impl std::error::Error for ConfigError {}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DataDirSource {
Cli,
Env,
ConfigFile,
}
impl std::fmt::Display for DataDirSource {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Cli => write!(f, "CLI"),
Self::Env => write!(f, "NX9_BZOD_DATA_DIR"),
Self::ConfigFile => write!(f, "config.toml"),
}
}
}
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Config { pub struct Config {
pub host: String, pub host: String,
@@ -45,11 +84,23 @@ struct TomlBackupConfig {
} }
impl Config { impl Config {
pub fn load() -> Self { pub fn load() -> Result<Self, ConfigError> {
// 1. Built-in defaults Self::load_with_cli(None::<&std::path::Path>)
}
pub fn load_with_cli<P: AsRef<std::path::Path>>(
cli_data_dir: Option<P>,
) -> Result<Self, ConfigError> {
Self::load_from_sources(cli_data_dir, true)
}
pub fn load_from_sources<P: AsRef<std::path::Path>>(
cli_data_dir: Option<P>,
load_dotenv: bool,
) -> Result<Self, ConfigError> {
// 1. Built-in defaults (no implicit data_dir default)
let mut host = "0.0.0.0".to_string(); let mut host = "0.0.0.0".to_string();
let mut port = 8080u16; let mut port = 8080u16;
let mut data_dir = PathBuf::from("./data");
let mut admin_username = "admin".to_string(); let mut admin_username = "admin".to_string();
let mut bootstrap_password_sha256 = "".to_string(); let mut bootstrap_password_sha256 = "".to_string();
let mut session_secret = let mut session_secret =
@@ -63,12 +114,18 @@ impl Config {
let mut backup_dir = PathBuf::from("./backups"); let mut backup_dir = PathBuf::from("./backups");
let mut base_url = None; let mut base_url = None;
// 2. Load bzod.toml if it exists let mut resolved_data_dir: Option<PathBuf> = None;
let mut toml_path = "bzod.toml".to_string(); let mut data_dir_source: Option<DataDirSource> = None;
if fs::metadata("bzod.toml").is_err() && fs::metadata("config/bzod.toml").is_ok() {
toml_path = "config/bzod.toml".to_string(); // 2. Load bzod.toml / config.toml if it exists
} let possible_tomls = [
if let Ok(toml_content) = fs::read_to_string(&toml_path) { "bzod.toml",
"config/bzod.toml",
"config.toml",
"config/config.toml",
];
for toml_path in possible_tomls {
if let Ok(toml_content) = fs::read_to_string(toml_path) {
if let Ok(toml_config) = toml::from_str::<TomlConfig>(&toml_content) { if let Ok(toml_config) = toml::from_str::<TomlConfig>(&toml_content) {
if let Some(h) = toml_config.host { if let Some(h) = toml_config.host {
host = h; host = h;
@@ -77,7 +134,10 @@ impl Config {
port = p; port = p;
} }
if let Some(d) = toml_config.data_dir { if let Some(d) = toml_config.data_dir {
data_dir = PathBuf::from(d); if !d.trim().is_empty() {
resolved_data_dir = Some(PathBuf::from(d));
data_dir_source = Some(DataDirSource::ConfigFile);
}
} }
if let Some(u) = toml_config.admin_username { if let Some(u) = toml_config.admin_username {
admin_username = u; admin_username = u;
@@ -118,16 +178,20 @@ impl Config {
if let Some(bu) = toml_config.base_url { if let Some(bu) = toml_config.base_url {
base_url = Some(bu); base_url = Some(bu);
} }
break;
}
} }
} }
// 3. Load .env if present // 3. Load .env if present
if load_dotenv {
let _ = dotenvy::dotenv(); let _ = dotenvy::dotenv();
if fs::metadata("config/.env").is_ok() { if fs::metadata("config/.env").is_ok() {
let _ = dotenvy::from_path("config/.env"); let _ = dotenvy::from_path("config/.env");
} }
}
// 4. Load from Environment Variables (taking highest precedence) // 4. Load from Environment Variables (taking precedence over config file)
if let Ok(h) = env::var("HOST") { if let Ok(h) = env::var("HOST") {
host = h; host = h;
} }
@@ -136,8 +200,11 @@ impl Config {
port = p; port = p;
} }
} }
if let Ok(d_str) = env::var("DATA_DIR") { if let Ok(d_str) = env::var(NX9_BZOD_DATA_DIR_ENV) {
data_dir = PathBuf::from(d_str); if !d_str.trim().is_empty() {
resolved_data_dir = Some(PathBuf::from(d_str));
data_dir_source = Some(DataDirSource::Env);
}
} }
if let Ok(u) = env::var("ADMIN_USERNAME") { if let Ok(u) = env::var("ADMIN_USERNAME") {
admin_username = u; admin_username = u;
@@ -187,7 +254,26 @@ impl Config {
base_url = Some(bu); base_url = Some(bu);
} }
Self { // 5. CLI override (highest precedence)
if let Some(cli_dir) = cli_data_dir {
let path_ref = cli_dir.as_ref();
if !path_ref.as_os_str().is_empty() {
resolved_data_dir = Some(path_ref.to_path_buf());
data_dir_source = Some(DataDirSource::Cli);
}
}
let data_dir = match resolved_data_dir {
Some(dir) => dir,
None => return Err(ConfigError::MissingDataDir),
};
if let Some(source) = data_dir_source {
tracing::info!("Data directory: {}", data_dir.display());
tracing::info!("Data directory source: {}", source);
}
Ok(Self {
host, host,
port, port,
data_dir, data_dir,
@@ -202,6 +288,6 @@ impl Config {
backup_interval_mins, backup_interval_mins,
backup_dir, backup_dir,
base_url, base_url,
} })
} }
} }
+2 -3
View File
@@ -392,12 +392,11 @@ mod db_init_tests {
#[test] #[test]
fn test_db_init() { fn test_db_init() {
let temp_dir = PathBuf::from("./temp_test_db_dir"); let temp_dir = std::env::temp_dir().join(format!("test_db_init_{}", uuid::Uuid::new_v4()));
if temp_dir.exists() { if temp_dir.exists() {
let _ = std::fs::remove_dir_all(&temp_dir); let _ = std::fs::remove_dir_all(&temp_dir);
} }
let mut config = Config::load(); let config = Config::load_with_cli(Some(&temp_dir)).unwrap();
config.data_dir = temp_dir.clone();
let db = Db::init(&config); let db = Db::init(&config);
// Cleanup // Cleanup
+1 -1
View File
@@ -10,7 +10,7 @@
//! └── extensions/<extension>/<extension>.db //! └── extensions/<extension>/<extension>.db
//! ``` //! ```
//! //!
//! `<data_dir>` is `Config.data_dir` (env `DATA_DIR`, default `./data`). //! `<data_dir>` is `Config.data_dir` (CLI `--data-dir`, env `NX9_BZOD_DATA_DIR`, or config file).
//! It is not renamed to `database/`. Production Docker, CasaOS, and //! It is not renamed to `database/`. Production Docker, CasaOS, and
//! `deploy.sh` bind this physical root. //! `deploy.sh` bind this physical root.
+7 -1
View File
@@ -13,7 +13,13 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
.init(); .init();
let cli = Cli::parse(); let cli = Cli::parse();
let config = Config::load(); let config = match Config::load_with_cli(cli.command.data_dir()) {
Ok(config) => config,
Err(err) => {
eprintln!("Error: {err}");
std::process::exit(1);
}
};
match cli.command { match cli.command {
Commands::Serve { Commands::Serve {
+1 -2
View File
@@ -4,8 +4,7 @@ use std::fs;
use std::path::PathBuf; use std::path::PathBuf;
fn create_temp_config(temp_dir: PathBuf) -> Config { fn create_temp_config(temp_dir: PathBuf) -> Config {
let mut config = Config::load(); let mut config = Config::load_with_cli(Some(&temp_dir)).unwrap();
config.data_dir = temp_dir.clone();
config.backup_dir = temp_dir.clone(); config.backup_dir = temp_dir.clone();
config.base_url = Some("http://bzo.in".to_string()); config.base_url = Some("http://bzo.in".to_string());
config config
+2 -3
View File
@@ -19,10 +19,9 @@ use bzod::web::admin::{
}; };
fn create_temp_config(temp_dir: PathBuf) -> Config { fn create_temp_config(temp_dir: PathBuf) -> Config {
let mut config = Config::load(); let mut config = Config::load_with_cli(Some(&temp_dir)).unwrap();
config.data_dir = temp_dir.clone();
config.backup_dir = temp_dir.clone(); config.backup_dir = temp_dir.clone();
config.base_url = Some("http://localhost:8080".to_string()); config.base_url = Some("http://bzo.in".to_string());
config config
} }
+1 -2
View File
@@ -18,8 +18,7 @@ fn compute_sha256(value: &str) -> String {
} }
fn create_temp_config(temp_dir: PathBuf) -> Config { fn create_temp_config(temp_dir: PathBuf) -> Config {
let mut config = Config::load(); let mut config = Config::load_with_cli(Some(&temp_dir)).unwrap();
config.data_dir = temp_dir.clone();
config.backup_dir = temp_dir.clone(); config.backup_dir = temp_dir.clone();
config.admin_username = "admin".to_string(); config.admin_username = "admin".to_string();
config.base_url = Some("http://localhost:8080".to_string()); config.base_url = Some("http://localhost:8080".to_string());
+1 -2
View File
@@ -21,8 +21,7 @@ use bzod::db::Db;
use bzod::web::admin::{dashboard_get, login_post, LoginForm}; use bzod::web::admin::{dashboard_get, login_post, LoginForm};
fn create_temp_config(temp_dir: PathBuf) -> Config { fn create_temp_config(temp_dir: PathBuf) -> Config {
let mut config = Config::load(); let mut config = Config::load_with_cli(Some(&temp_dir)).unwrap();
config.data_dir = temp_dir.clone();
config.backup_dir = temp_dir.clone(); config.backup_dir = temp_dir.clone();
config.admin_username = "admin".to_string(); config.admin_username = "admin".to_string();
config.base_url = Some("http://localhost:8080".to_string()); config.base_url = Some("http://localhost:8080".to_string());
+1 -2
View File
@@ -7,8 +7,7 @@ use std::fs;
use std::path::PathBuf; use std::path::PathBuf;
fn create_temp_config(temp_dir: PathBuf) -> Config { fn create_temp_config(temp_dir: PathBuf) -> Config {
let mut config = Config::load(); let mut config = Config::load_with_cli(Some(&temp_dir)).unwrap();
config.data_dir = temp_dir.clone();
config.backup_dir = temp_dir.clone(); config.backup_dir = temp_dir.clone();
config.base_url = Some("http://bzo.in".to_string()); config.base_url = Some("http://bzo.in".to_string());
config config
+2 -4
View File
@@ -7,8 +7,7 @@ use tar::Archive;
use zstd::Decoder; use zstd::Decoder;
fn create_temp_config(temp_dir: PathBuf) -> Config { fn create_temp_config(temp_dir: PathBuf) -> Config {
let mut config = Config::load(); let mut config = Config::load_with_cli(Some(&temp_dir)).unwrap();
config.data_dir = temp_dir.clone();
config.backup_dir = temp_dir.clone(); config.backup_dir = temp_dir.clone();
config.base_url = Some("http://bzo.in".to_string()); config.base_url = Some("http://bzo.in".to_string());
config config
@@ -200,8 +199,7 @@ async fn test_restore_slug_collision_rejection() {
)); ));
fs::create_dir_all(&temp_dir).unwrap(); fs::create_dir_all(&temp_dir).unwrap();
let mut config = Config::load(); let mut config = Config::load_with_cli(Some(&temp_dir)).unwrap();
config.data_dir = temp_dir.clone();
config.backup_dir = temp_dir.join("backups"); config.backup_dir = temp_dir.join("backups");
fs::create_dir_all(&config.backup_dir).unwrap(); fs::create_dir_all(&config.backup_dir).unwrap();
+1 -2
View File
@@ -18,8 +18,7 @@ fn compute_sha256(value: &str) -> String {
} }
fn create_temp_config(temp_dir: PathBuf) -> Config { fn create_temp_config(temp_dir: PathBuf) -> Config {
let mut config = Config::load(); let mut config = Config::load_with_cli(Some(&temp_dir)).unwrap();
config.data_dir = temp_dir.clone();
config.backup_dir = temp_dir.clone(); config.backup_dir = temp_dir.clone();
config.admin_username = "admin".to_string(); config.admin_username = "admin".to_string();
config.base_url = Some("http://localhost:8080".to_string()); config.base_url = Some("http://localhost:8080".to_string());
+1 -2
View File
@@ -6,8 +6,7 @@ use std::sync::Arc;
use tokio::sync::Barrier; use tokio::sync::Barrier;
fn create_temp_config(temp_dir: PathBuf) -> Config { fn create_temp_config(temp_dir: PathBuf) -> Config {
let mut config = Config::load(); let mut config = Config::load_with_cli(Some(&temp_dir)).unwrap();
config.data_dir = temp_dir.clone();
config.backup_dir = temp_dir.clone(); config.backup_dir = temp_dir.clone();
config.base_url = Some("http://bzo.in".to_string()); config.base_url = Some("http://bzo.in".to_string());
config config
+222
View File
@@ -0,0 +1,222 @@
use bzod::config::{Config, ConfigError, NX9_BZOD_DATA_DIR_ENV};
use bzod::db::topology::Topology;
use bzod::identity::TenantId;
use std::env;
use std::fs;
use std::path::{Path, PathBuf};
use std::sync::Mutex;
// Global lock to prevent race conditions during env-var testing
static ENV_LOCK: Mutex<()> = Mutex::new(());
struct EnvGuard {
key: &'static str,
original_val: Option<String>,
}
impl EnvGuard {
fn set(key: &'static str, val: &str) -> Self {
let original_val = env::var(key).ok();
env::set_var(key, val);
Self { key, original_val }
}
fn unset(key: &'static str) -> Self {
let original_val = env::var(key).ok();
env::remove_var(key);
Self { key, original_val }
}
}
impl Drop for EnvGuard {
fn drop(&mut self) {
if let Some(ref val) = self.original_val {
env::set_var(self.key, val);
} else {
env::remove_var(self.key);
}
}
}
#[test]
fn test_no_configuration_returns_missing_data_dir_error() {
let _lock = ENV_LOCK.lock().unwrap();
let _guard = EnvGuard::unset(NX9_BZOD_DATA_DIR_ENV);
// Call load_from_sources with no CLI and load_dotenv=false in an isolated context
let res = Config::load_from_sources(None::<&Path>, false);
assert!(
res.is_err(),
"Expected error when no data directory is configured"
);
match res.err().unwrap() {
ConfigError::MissingDataDir => {}
other => panic!("Expected ConfigError::MissingDataDir, got {:?}", other),
}
}
#[test]
fn test_environment_variable_resolves_data_dir() {
let _lock = ENV_LOCK.lock().unwrap();
let test_path = "/tmp/nx9-env-test-data";
let _guard = EnvGuard::set(NX9_BZOD_DATA_DIR_ENV, test_path);
let config = Config::load_from_sources(None::<&Path>, false)
.expect("Config should load with NX9_BZOD_DATA_DIR set");
assert_eq!(config.data_dir, PathBuf::from(test_path));
}
#[test]
fn test_config_file_resolves_data_dir() {
let _lock = ENV_LOCK.lock().unwrap();
let _guard = EnvGuard::unset(NX9_BZOD_DATA_DIR_ENV);
let temp_dir = std::env::temp_dir().join(format!("bzod_cfg_test_{}", uuid::Uuid::new_v4()));
fs::create_dir_all(&temp_dir).unwrap();
let toml_file = temp_dir.join("bzod.toml");
let target_data_dir = "/tmp/config-file-data";
fs::write(&toml_file, format!("data_dir = \"{}\"\n", target_data_dir)).unwrap();
// Change current directory temporarily for config file reading
let original_cwd = env::current_dir().unwrap();
env::set_current_dir(&temp_dir).unwrap();
let config_res = Config::load_from_sources(None::<&Path>, false);
// Restore cwd
env::set_current_dir(original_cwd).unwrap();
let _ = fs::remove_dir_all(&temp_dir);
let config = config_res.expect("Config should load from bzod.toml");
assert_eq!(config.data_dir, PathBuf::from(target_data_dir));
}
#[test]
fn test_environment_overrides_config_file() {
let _lock = ENV_LOCK.lock().unwrap();
let env_data_dir = "/tmp/env-override-data";
let _guard = EnvGuard::set(NX9_BZOD_DATA_DIR_ENV, env_data_dir);
let temp_dir = std::env::temp_dir().join(format!("bzod_cfg_test_{}", uuid::Uuid::new_v4()));
fs::create_dir_all(&temp_dir).unwrap();
let toml_file = temp_dir.join("bzod.toml");
let config_data_dir = "/tmp/config-file-data";
fs::write(&toml_file, format!("data_dir = \"{}\"\n", config_data_dir)).unwrap();
let original_cwd = env::current_dir().unwrap();
env::set_current_dir(&temp_dir).unwrap();
let config_res = Config::load_from_sources(None::<&Path>, false);
env::set_current_dir(original_cwd).unwrap();
let _ = fs::remove_dir_all(&temp_dir);
let config = config_res.expect("Config should load");
assert_eq!(config.data_dir, PathBuf::from(env_data_dir));
}
#[test]
fn test_cli_overrides_environment() {
let _lock = ENV_LOCK.lock().unwrap();
let env_data_dir = "/tmp/env-data";
let _guard = EnvGuard::set(NX9_BZOD_DATA_DIR_ENV, env_data_dir);
let cli_data_dir = "/tmp/cli-override-data";
let config = Config::load_from_sources(Some(cli_data_dir), false)
.expect("Config should load with CLI override");
assert_eq!(config.data_dir, PathBuf::from(cli_data_dir));
}
#[test]
fn test_cli_overrides_config_file() {
let _lock = ENV_LOCK.lock().unwrap();
let _guard = EnvGuard::unset(NX9_BZOD_DATA_DIR_ENV);
let temp_dir = std::env::temp_dir().join(format!("bzod_cfg_test_{}", uuid::Uuid::new_v4()));
fs::create_dir_all(&temp_dir).unwrap();
let toml_file = temp_dir.join("bzod.toml");
let config_data_dir = "/tmp/config-file-data";
fs::write(&toml_file, format!("data_dir = \"{}\"\n", config_data_dir)).unwrap();
let original_cwd = env::current_dir().unwrap();
env::set_current_dir(&temp_dir).unwrap();
let cli_data_dir = "/tmp/cli-data-highest";
let config_res = Config::load_from_sources(Some(cli_data_dir), false);
env::set_current_dir(original_cwd).unwrap();
let _ = fs::remove_dir_all(&temp_dir);
let config = config_res.expect("Config should load with CLI override");
assert_eq!(config.data_dir, PathBuf::from(cli_data_dir));
}
#[test]
fn test_relative_path_semantics_preserved() {
let _lock = ENV_LOCK.lock().unwrap();
let relative_path = "custom_relative/data";
let config = Config::load_from_sources(Some(relative_path), false)
.expect("Relative path in CLI should be accepted as-is without forced canonicalization");
assert_eq!(config.data_dir, PathBuf::from(relative_path));
}
#[test]
fn test_topology_resolves_all_databases_relative_to_configured_root() {
let custom_root = PathBuf::from("/var/lib/bzod/custom_root");
let topology = Topology::new(&custom_root);
assert_eq!(topology.root(), &custom_root);
assert_eq!(topology.admin_dir(), custom_root.join("admin"));
assert_eq!(topology.slugs_dir(), custom_root.join("slugs"));
assert_eq!(topology.users_dir(), custom_root.join("users"));
// Core databases
assert_eq!(topology.admin_db(), custom_root.join("admin/admin.db"));
assert_eq!(topology.system_db(), custom_root.join("admin/system.db"));
assert_eq!(
topology.users_registry_db(),
custom_root.join("admin/users.db")
);
assert_eq!(
topology.global_urls_db(),
custom_root.join("slugs/global_urls.db")
);
assert_eq!(
topology.global_landing_pages_db(),
custom_root.join("slugs/global_landing_pages.db")
);
assert_eq!(
topology.reserved_db(),
custom_root.join("slugs/reserved.db")
);
// Tenant databases
let tenant_id = TenantId::parse("a1b2c3d4e5f6").unwrap();
assert_eq!(
topology.tenant_dir(tenant_id),
custom_root.join("users/a1b2c3d4e5f6")
);
assert_eq!(
topology.tenant_content_db(tenant_id),
custom_root.join("users/a1b2c3d4e5f6/content.db")
);
assert_eq!(
topology.tenant_analytics_db(tenant_id),
custom_root.join("users/a1b2c3d4e5f6/analytics.db")
);
assert_eq!(
topology.tenant_profile_db(tenant_id),
custom_root.join("users/a1b2c3d4e5f6/profile.db")
);
assert_eq!(
topology.extension_db("a1b2c3d4e5f6", "cv").unwrap(),
custom_root.join("users/a1b2c3d4e5f6/extensions/cv/cv.db")
);
}
+1 -2
View File
@@ -4,8 +4,7 @@ use std::fs;
use std::path::PathBuf; use std::path::PathBuf;
fn create_temp_config(temp_dir: PathBuf) -> Config { fn create_temp_config(temp_dir: PathBuf) -> Config {
let mut config = Config::load(); let mut config = Config::load_with_cli(Some(&temp_dir)).unwrap();
config.data_dir = temp_dir.clone();
config.backup_dir = temp_dir.clone(); config.backup_dir = temp_dir.clone();
config.base_url = Some("http://bzo.in".to_string()); config.base_url = Some("http://bzo.in".to_string());
config config
+1 -2
View File
@@ -18,8 +18,7 @@ fn compute_sha256(value: &str) -> String {
} }
fn create_temp_config(temp_dir: PathBuf) -> Config { fn create_temp_config(temp_dir: PathBuf) -> Config {
let mut config = Config::load(); let mut config = Config::load_with_cli(Some(&temp_dir)).unwrap();
config.data_dir = temp_dir.clone();
config.backup_dir = temp_dir.clone(); config.backup_dir = temp_dir.clone();
config.admin_username = "admin".to_string(); config.admin_username = "admin".to_string();
config.base_url = Some("http://localhost:8080".to_string()); config.base_url = Some("http://localhost:8080".to_string());
+1 -2
View File
@@ -5,8 +5,7 @@ use std::fs;
use std::path::PathBuf; use std::path::PathBuf;
fn create_temp_config(temp_dir: PathBuf) -> Config { fn create_temp_config(temp_dir: PathBuf) -> Config {
let mut config = Config::load(); let mut config = Config::load_with_cli(Some(&temp_dir)).unwrap();
config.data_dir = temp_dir.clone();
config.backup_dir = temp_dir.clone(); config.backup_dir = temp_dir.clone();
config.base_url = Some("http://bzo.in".to_string()); config.base_url = Some("http://bzo.in".to_string());
config config
+1 -2
View File
@@ -4,8 +4,7 @@ use std::fs;
use std::path::PathBuf; use std::path::PathBuf;
fn create_temp_config(temp_dir: PathBuf) -> Config { fn create_temp_config(temp_dir: PathBuf) -> Config {
let mut config = Config::load(); let mut config = Config::load_with_cli(Some(&temp_dir)).unwrap();
config.data_dir = temp_dir.clone();
config.backup_dir = temp_dir.clone(); config.backup_dir = temp_dir.clone();
config.base_url = Some("http://bzo.in".to_string()); config.base_url = Some("http://bzo.in".to_string());
config config
+1 -2
View File
@@ -21,8 +21,7 @@ use std::path::PathBuf;
use tar::Builder; use tar::Builder;
fn create_temp_config(temp_dir: PathBuf) -> Config { fn create_temp_config(temp_dir: PathBuf) -> Config {
let mut config = Config::load(); let mut config = Config::load_with_cli(Some(&temp_dir)).unwrap();
config.data_dir = temp_dir.clone();
config.backup_dir = temp_dir.clone(); config.backup_dir = temp_dir.clone();
config.base_url = Some("http://bzo.in".to_string()); config.base_url = Some("http://bzo.in".to_string());
config config
+1 -2
View File
@@ -4,8 +4,7 @@ use std::fs;
use std::path::PathBuf; use std::path::PathBuf;
fn create_temp_config(temp_dir: PathBuf) -> Config { fn create_temp_config(temp_dir: PathBuf) -> Config {
let mut config = Config::load(); let mut config = Config::load_with_cli(Some(&temp_dir)).unwrap();
config.data_dir = temp_dir.clone();
config.backup_dir = temp_dir.clone(); config.backup_dir = temp_dir.clone();
config.base_url = Some("http://bzo.in".to_string()); config.base_url = Some("http://bzo.in".to_string());
config config
+1 -2
View File
@@ -6,8 +6,7 @@ use std::path::PathBuf;
use uuid::Uuid; use uuid::Uuid;
fn create_temp_config(temp_dir: PathBuf) -> Config { fn create_temp_config(temp_dir: PathBuf) -> Config {
let mut config = Config::load(); let mut config = Config::load_with_cli(Some(&temp_dir)).unwrap();
config.data_dir = temp_dir.clone();
config.backup_dir = temp_dir.clone(); config.backup_dir = temp_dir.clone();
config.base_url = Some("http://bzo.in".to_string()); config.base_url = Some("http://bzo.in".to_string());
config config
+1 -2
View File
@@ -34,8 +34,7 @@ fn test_custom_slug_validation() {
} }
fn create_temp_config(temp_dir: PathBuf) -> Config { fn create_temp_config(temp_dir: PathBuf) -> Config {
let mut config = Config::load(); let mut config = Config::load_with_cli(Some(&temp_dir)).unwrap();
config.data_dir = temp_dir.clone();
config.backup_dir = temp_dir.clone(); config.backup_dir = temp_dir.clone();
config.base_url = Some("http://bzo.in".to_string()); config.base_url = Some("http://bzo.in".to_string());
config config
+1 -2
View File
@@ -18,8 +18,7 @@ fn compute_sha256(value: &str) -> String {
} }
fn create_temp_config(temp_dir: PathBuf) -> Config { fn create_temp_config(temp_dir: PathBuf) -> Config {
let mut config = Config::load(); let mut config = Config::load_with_cli(Some(&temp_dir)).unwrap();
config.data_dir = temp_dir.clone();
config.backup_dir = temp_dir.clone(); config.backup_dir = temp_dir.clone();
config.admin_username = "admin".to_string(); config.admin_username = "admin".to_string();
config.base_url = Some("http://localhost:8080".to_string()); config.base_url = Some("http://localhost:8080".to_string());
+1 -2
View File
@@ -18,8 +18,7 @@ fn compute_sha256(value: &str) -> String {
} }
fn create_temp_config(temp_dir: PathBuf) -> Config { fn create_temp_config(temp_dir: PathBuf) -> Config {
let mut config = Config::load(); let mut config = Config::load_with_cli(Some(&temp_dir)).unwrap();
config.data_dir = temp_dir.clone();
config.backup_dir = temp_dir.clone(); config.backup_dir = temp_dir.clone();
config.admin_username = "admin".to_string(); config.admin_username = "admin".to_string();
config.base_url = Some("http://localhost:8080".to_string()); config.base_url = Some("http://localhost:8080".to_string());
+1 -2
View File
@@ -4,8 +4,7 @@ use std::fs;
use std::path::PathBuf; use std::path::PathBuf;
fn create_temp_config(temp_dir: PathBuf) -> Config { fn create_temp_config(temp_dir: PathBuf) -> Config {
let mut config = Config::load(); let mut config = Config::load_with_cli(Some(&temp_dir)).unwrap();
config.data_dir = temp_dir.clone();
config.backup_dir = temp_dir.clone(); config.backup_dir = temp_dir.clone();
config.base_url = Some("http://bzo.in".to_string()); config.base_url = Some("http://bzo.in".to_string());
config config
+1 -2
View File
@@ -29,8 +29,7 @@ fn compute_sha256(value: &str) -> String {
} }
fn create_temp_config(temp_dir: PathBuf) -> Config { fn create_temp_config(temp_dir: PathBuf) -> Config {
let mut config = Config::load(); let mut config = Config::load_with_cli(Some(&temp_dir)).unwrap();
config.data_dir = temp_dir.clone();
config.backup_dir = temp_dir.clone(); config.backup_dir = temp_dir.clone();
config.admin_username = "admin".to_string(); config.admin_username = "admin".to_string();
config.base_url = Some("http://localhost:8080".to_string()); config.base_url = Some("http://localhost:8080".to_string());
+1 -2
View File
@@ -5,8 +5,7 @@ use std::fs;
use std::path::PathBuf; use std::path::PathBuf;
fn create_temp_config(temp_dir: PathBuf) -> Config { fn create_temp_config(temp_dir: PathBuf) -> Config {
let mut config = Config::load(); let mut config = Config::load_with_cli(Some(&temp_dir)).unwrap();
config.data_dir = temp_dir.clone();
config.backup_dir = temp_dir.clone(); config.backup_dir = temp_dir.clone();
config.base_url = Some("http://bzo.in".to_string()); config.base_url = Some("http://bzo.in".to_string());
config config
+1 -2
View File
@@ -11,8 +11,7 @@ use std::path::PathBuf;
use std::time::Instant; use std::time::Instant;
fn create_temp_config(temp_dir: PathBuf) -> Config { fn create_temp_config(temp_dir: PathBuf) -> Config {
let mut config = Config::load(); let mut config = Config::load_with_cli(Some(&temp_dir)).unwrap();
config.data_dir = temp_dir.clone();
config.backup_dir = temp_dir.clone(); config.backup_dir = temp_dir.clone();
config.base_url = Some("http://bzo.in".to_string()); config.base_url = Some("http://bzo.in".to_string());
config config
+1 -2
View File
@@ -4,8 +4,7 @@ use std::fs;
use std::path::PathBuf; use std::path::PathBuf;
fn create_temp_config(temp_dir: PathBuf) -> Config { fn create_temp_config(temp_dir: PathBuf) -> Config {
let mut config = Config::load(); let mut config = Config::load_with_cli(Some(&temp_dir)).unwrap();
config.data_dir = temp_dir.clone();
config.backup_dir = temp_dir.clone(); config.backup_dir = temp_dir.clone();
config.base_url = Some("http://bzo.in".to_string()); config.base_url = Some("http://bzo.in".to_string());
config config
+1 -2
View File
@@ -6,8 +6,7 @@ use std::fs;
use std::path::PathBuf; use std::path::PathBuf;
fn create_temp_config(temp_dir: PathBuf) -> Config { fn create_temp_config(temp_dir: PathBuf) -> Config {
let mut config = Config::load(); let mut config = Config::load_with_cli(Some(&temp_dir)).unwrap();
config.data_dir = temp_dir.clone();
config.backup_dir = temp_dir.clone(); config.backup_dir = temp_dir.clone();
config.base_url = Some("http://bzo.in".to_string()); config.base_url = Some("http://bzo.in".to_string());
config config
+1 -2
View File
@@ -5,8 +5,7 @@ use std::fs;
use std::path::PathBuf; use std::path::PathBuf;
fn create_temp_config(temp_dir: PathBuf) -> Config { fn create_temp_config(temp_dir: PathBuf) -> Config {
let mut config = Config::load(); let mut config = Config::load_with_cli(Some(&temp_dir)).unwrap();
config.data_dir = temp_dir.clone();
config.backup_dir = temp_dir.clone(); config.backup_dir = temp_dir.clone();
config.base_url = Some("http://bzo.in".to_string()); config.base_url = Some("http://bzo.in".to_string());
config config
+1 -2
View File
@@ -4,8 +4,7 @@ use std::fs;
use std::path::PathBuf; use std::path::PathBuf;
fn create_temp_config(temp_dir: PathBuf) -> Config { fn create_temp_config(temp_dir: PathBuf) -> Config {
let mut config = Config::load(); let mut config = Config::load_with_cli(Some(&temp_dir)).unwrap();
config.data_dir = temp_dir.clone();
config.backup_dir = temp_dir.clone(); config.backup_dir = temp_dir.clone();
config.base_url = Some("http://bzo.in".to_string()); config.base_url = Some("http://bzo.in".to_string());
config config
+1 -2
View File
@@ -4,8 +4,7 @@ use std::fs;
use std::path::PathBuf; use std::path::PathBuf;
fn create_temp_config(temp_dir: PathBuf) -> Config { fn create_temp_config(temp_dir: PathBuf) -> Config {
let mut config = Config::load(); let mut config = Config::load_with_cli(Some(&temp_dir)).unwrap();
config.data_dir = temp_dir.clone();
config.backup_dir = temp_dir.clone(); config.backup_dir = temp_dir.clone();
config.base_url = Some("http://bzo.in".to_string()); config.base_url = Some("http://bzo.in".to_string());
config config
+1 -2
View File
@@ -19,8 +19,7 @@ fn compute_sha256(value: &str) -> String {
} }
fn create_temp_config(temp_dir: PathBuf) -> Config { fn create_temp_config(temp_dir: PathBuf) -> Config {
let mut config = Config::load(); let mut config = Config::load_with_cli(Some(&temp_dir)).unwrap();
config.data_dir = temp_dir.clone();
config.backup_dir = temp_dir.clone(); config.backup_dir = temp_dir.clone();
config.admin_username = "admin".to_string(); config.admin_username = "admin".to_string();
config.base_url = Some("http://localhost:8080".to_string()); config.base_url = Some("http://localhost:8080".to_string());
+1 -2
View File
@@ -4,8 +4,7 @@ use std::fs;
use std::path::PathBuf; use std::path::PathBuf;
fn create_temp_config(temp_dir: PathBuf) -> Config { fn create_temp_config(temp_dir: PathBuf) -> Config {
let mut config = Config::load(); let mut config = Config::load_with_cli(Some(&temp_dir)).unwrap();
config.data_dir = temp_dir.clone();
config.backup_dir = temp_dir.clone(); config.backup_dir = temp_dir.clone();
config.base_url = Some("http://bzo.in".to_string()); config.base_url = Some("http://bzo.in".to_string());
config config
+1 -2
View File
@@ -4,8 +4,7 @@ use std::fs;
use std::path::PathBuf; use std::path::PathBuf;
fn create_temp_config(temp_dir: PathBuf) -> Config { fn create_temp_config(temp_dir: PathBuf) -> Config {
let mut config = Config::load(); let mut config = Config::load_with_cli(Some(&temp_dir)).unwrap();
config.data_dir = temp_dir.clone();
config.backup_dir = temp_dir.clone(); config.backup_dir = temp_dir.clone();
config.base_url = Some("http://bzo.in".to_string()); config.base_url = Some("http://bzo.in".to_string());
config config
+1 -2
View File
@@ -4,8 +4,7 @@ use std::fs;
use std::path::PathBuf; use std::path::PathBuf;
fn create_temp_config(temp_dir: PathBuf) -> Config { fn create_temp_config(temp_dir: PathBuf) -> Config {
let mut config = Config::load(); let mut config = Config::load_with_cli(Some(&temp_dir)).unwrap();
config.data_dir = temp_dir.clone();
config.backup_dir = temp_dir.clone(); config.backup_dir = temp_dir.clone();
config.base_url = Some("http://bzo.in".to_string()); config.base_url = Some("http://bzo.in".to_string());
config config
+1 -2
View File
@@ -50,8 +50,7 @@ impl TestHarness {
let temp_dir = let temp_dir =
std::env::temp_dir().join(format!("bzod_admin_boundary_{}", uuid::Uuid::new_v4())); std::env::temp_dir().join(format!("bzod_admin_boundary_{}", uuid::Uuid::new_v4()));
fs::create_dir_all(&temp_dir).unwrap(); fs::create_dir_all(&temp_dir).unwrap();
let mut config = Config::load(); let mut config = Config::load_with_cli(Some(&temp_dir)).unwrap();
config.data_dir = temp_dir.clone();
config.backup_dir = temp_dir.join("backups"); config.backup_dir = temp_dir.join("backups");
config.base_url = Some("http://localhost:8080".to_string()); config.base_url = Some("http://localhost:8080".to_string());
+1 -2
View File
@@ -13,8 +13,7 @@ use bzod::state::AppState;
use bzod::web::create_router; use bzod::web::create_router;
fn create_temp_config(temp_dir: PathBuf) -> Config { fn create_temp_config(temp_dir: PathBuf) -> Config {
let mut config = Config::load(); let mut config = Config::load_with_cli(Some(&temp_dir)).unwrap();
config.data_dir = temp_dir.clone();
config.backup_dir = temp_dir.join("backups"); config.backup_dir = temp_dir.join("backups");
config.base_url = Some("http://localhost:8080".to_string()); config.base_url = Some("http://localhost:8080".to_string());
config config
+1 -2
View File
@@ -55,8 +55,7 @@ impl TestHarness {
let temp_dir = let temp_dir =
std::env::temp_dir().join(format!("bzod_user_boundary_{}", uuid::Uuid::new_v4())); std::env::temp_dir().join(format!("bzod_user_boundary_{}", uuid::Uuid::new_v4()));
fs::create_dir_all(&temp_dir).unwrap(); fs::create_dir_all(&temp_dir).unwrap();
let mut config = Config::load(); let mut config = Config::load_with_cli(Some(&temp_dir)).unwrap();
config.data_dir = temp_dir.clone();
config.backup_dir = temp_dir.join("backups"); config.backup_dir = temp_dir.join("backups");
config.base_url = Some("http://localhost:8080".to_string()); config.base_url = Some("http://localhost:8080".to_string());
+1 -2
View File
@@ -12,8 +12,7 @@ use std::path::PathBuf;
fn temp_config() -> (PathBuf, Config) { fn temp_config() -> (PathBuf, Config) {
let temp_dir = std::env::temp_dir().join(format!("bzod_v08_topology_{}", uuid::Uuid::new_v4())); let temp_dir = std::env::temp_dir().join(format!("bzod_v08_topology_{}", uuid::Uuid::new_v4()));
fs::create_dir_all(&temp_dir).unwrap(); fs::create_dir_all(&temp_dir).unwrap();
let mut config = Config::load(); let mut config = Config::load_with_cli(Some(&temp_dir)).unwrap();
config.data_dir = temp_dir.clone();
config.backup_dir = temp_dir.join("backups"); config.backup_dir = temp_dir.join("backups");
(temp_dir, config) (temp_dir, config)
} }
+1 -2
View File
@@ -25,8 +25,7 @@ fn temp_config() -> (PathBuf, Config) {
let temp_dir = let temp_dir =
std::env::temp_dir().join(format!("bzod_v08_id_migrate_{}", uuid::Uuid::new_v4())); std::env::temp_dir().join(format!("bzod_v08_id_migrate_{}", uuid::Uuid::new_v4()));
fs::create_dir_all(&temp_dir).unwrap(); fs::create_dir_all(&temp_dir).unwrap();
let mut config = Config::load(); let mut config = Config::load_with_cli(Some(&temp_dir)).unwrap();
config.data_dir = temp_dir.clone();
config.backup_dir = temp_dir.join("backups"); config.backup_dir = temp_dir.join("backups");
(temp_dir, config) (temp_dir, config)
} }
+1 -2
View File
@@ -20,8 +20,7 @@ use uuid::Uuid;
fn create_test_config() -> (PathBuf, Config) { fn create_test_config() -> (PathBuf, Config) {
let temp_dir = std::env::temp_dir().join(format!("bzod_p6a_test_{}", Uuid::new_v4())); let temp_dir = std::env::temp_dir().join(format!("bzod_p6a_test_{}", Uuid::new_v4()));
fs::create_dir_all(&temp_dir).unwrap(); fs::create_dir_all(&temp_dir).unwrap();
let mut config = Config::load(); let mut config = Config::load_with_cli(Some(&temp_dir)).unwrap();
config.data_dir = temp_dir.clone();
config.backup_dir = temp_dir.join("backups"); config.backup_dir = temp_dir.join("backups");
config.base_url = Some("http://localhost:8080".to_string()); config.base_url = Some("http://localhost:8080".to_string());
(temp_dir, config) (temp_dir, config)
+1 -2
View File
@@ -25,8 +25,7 @@ fn temp_config() -> (PathBuf, Config) {
let temp_dir = let temp_dir =
std::env::temp_dir().join(format!("bzod_v08_slug_migrate_{}", uuid::Uuid::new_v4())); std::env::temp_dir().join(format!("bzod_v08_slug_migrate_{}", uuid::Uuid::new_v4()));
fs::create_dir_all(&temp_dir).unwrap(); fs::create_dir_all(&temp_dir).unwrap();
let mut config = Config::load(); let mut config = Config::load_with_cli(Some(&temp_dir)).unwrap();
config.data_dir = temp_dir.clone();
config.backup_dir = temp_dir.join("backups"); config.backup_dir = temp_dir.join("backups");
(temp_dir, config) (temp_dir, config)
} }
+1 -2
View File
@@ -15,8 +15,7 @@ use std::time::Instant;
fn temp_config() -> (PathBuf, Config) { fn temp_config() -> (PathBuf, Config) {
let temp_dir = std::env::temp_dir().join(format!("bzod_v08_boundary_{}", uuid::Uuid::new_v4())); let temp_dir = std::env::temp_dir().join(format!("bzod_v08_boundary_{}", uuid::Uuid::new_v4()));
fs::create_dir_all(&temp_dir).unwrap(); fs::create_dir_all(&temp_dir).unwrap();
let mut config = Config::load(); let mut config = Config::load_with_cli(Some(&temp_dir)).unwrap();
config.data_dir = temp_dir.clone();
config.backup_dir = temp_dir.join("backups"); config.backup_dir = temp_dir.join("backups");
(temp_dir, config) (temp_dir, config)
} }
+1 -2
View File
@@ -4,8 +4,7 @@ use std::fs;
use std::path::PathBuf; use std::path::PathBuf;
fn create_temp_config(temp_dir: PathBuf) -> Config { fn create_temp_config(temp_dir: PathBuf) -> Config {
let mut config = Config::load(); let mut config = Config::load_with_cli(Some(&temp_dir)).unwrap();
config.data_dir = temp_dir.clone();
config.backup_dir = temp_dir.clone(); config.backup_dir = temp_dir.clone();
config.base_url = Some("http://bzo.in".to_string()); config.base_url = Some("http://bzo.in".to_string());
config config
+1 -1
View File
@@ -121,7 +121,7 @@ if [ ! -f "${ENV_FILE}" ]; then
cat <<EOF > "${ENV_FILE}" cat <<EOF > "${ENV_FILE}"
HOST=0.0.0.0 HOST=0.0.0.0
PORT=8654 PORT=8654
DATA_DIR=${DATA_DIR} NX9_BZOD_DATA_DIR=${DATA_DIR}
COOKIE_SECURE=true COOKIE_SECURE=true
RUST_LOG=info RUST_LOG=info
SESSION_SECRET=$(openssl rand -hex 32) SESSION_SECRET=$(openssl rand -hex 32)