- Revamped README.md to enhance clarity and detail on features, installation, and system requirements for Archipelago. - Added macOS-specific configuration in `config.rs` to detect when running from a macOS app bundle, adjusting data directory paths accordingly. - Introduced a new production build script in `package.json` for optimized deployment of the Neode UI.
156 lines
5.0 KiB
Rust
156 lines
5.0 KiB
Rust
use anyhow::{Context, Result};
|
|
use serde::{Deserialize, Serialize};
|
|
use std::path::{Path, PathBuf};
|
|
use tokio::fs;
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub enum ContainerRuntime {
|
|
Podman,
|
|
Docker,
|
|
Auto,
|
|
}
|
|
|
|
impl ContainerRuntime {
|
|
pub fn from_str(s: &str) -> Self {
|
|
match s.to_lowercase().as_str() {
|
|
"podman" => ContainerRuntime::Podman,
|
|
"docker" => ContainerRuntime::Docker,
|
|
"auto" | _ => ContainerRuntime::Auto,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub enum BitcoinSimulation {
|
|
Mock,
|
|
Testnet,
|
|
Mainnet,
|
|
None,
|
|
}
|
|
|
|
impl BitcoinSimulation {
|
|
pub fn from_str(s: &str) -> Self {
|
|
match s.to_lowercase().as_str() {
|
|
"mock" => BitcoinSimulation::Mock,
|
|
"testnet" => BitcoinSimulation::Testnet,
|
|
"mainnet" => BitcoinSimulation::Mainnet,
|
|
"none" | _ => BitcoinSimulation::None,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct Config {
|
|
pub data_dir: PathBuf,
|
|
pub bind_host: String,
|
|
pub bind_port: u16,
|
|
pub log_level: String,
|
|
// Dev mode configuration
|
|
pub dev_mode: bool,
|
|
pub container_runtime: ContainerRuntime,
|
|
pub port_offset: u16,
|
|
pub bitcoin_simulation: BitcoinSimulation,
|
|
pub dev_data_dir: PathBuf,
|
|
}
|
|
|
|
impl Config {
|
|
pub async fn load() -> Result<Self> {
|
|
// Default configuration
|
|
let mut config = Self::default();
|
|
|
|
// Detect if running from macOS app bundle
|
|
if let Ok(exe_path) = std::env::current_exe() {
|
|
if let Some(exe_str) = exe_path.to_str() {
|
|
if exe_str.contains(".app/Contents/MacOS") {
|
|
// Running from macOS bundle - use user's Library directory
|
|
if let Some(home) = std::env::var_os("HOME") {
|
|
let app_support = PathBuf::from(home)
|
|
.join("Library/Application Support/Archipelago");
|
|
config.data_dir = app_support.join("data");
|
|
config.dev_data_dir = app_support.join("data");
|
|
tracing::info!("🍎 Detected macOS bundle, using: {}", app_support.display());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Try to load from config file
|
|
let config_path = Path::new("/etc/archipelago/config.toml");
|
|
if config_path.exists() {
|
|
let content = fs::read_to_string(config_path).await
|
|
.context("Failed to read config file")?;
|
|
let file_config: Config = toml::de::from_str(&content)
|
|
.context("Failed to parse config file")?;
|
|
config = file_config;
|
|
}
|
|
|
|
// Override with environment variables
|
|
if let Ok(data_dir) = std::env::var("ARCHIPELAGO_DATA_DIR") {
|
|
config.data_dir = PathBuf::from(data_dir);
|
|
}
|
|
|
|
if let Ok(bind) = std::env::var("ARCHIPELAGO_BIND") {
|
|
let parts: Vec<&str> = bind.split(':').collect();
|
|
if parts.len() == 2 {
|
|
config.bind_host = parts[0].to_string();
|
|
config.bind_port = parts[1].parse()
|
|
.context("Invalid port in ARCHIPELAGO_BIND")?;
|
|
}
|
|
}
|
|
|
|
if let Ok(level) = std::env::var("ARCHIPELAGO_LOG_LEVEL") {
|
|
config.log_level = level;
|
|
}
|
|
|
|
// Dev mode configuration
|
|
if let Ok(dev_mode) = std::env::var("ARCHIPELAGO_DEV_MODE") {
|
|
config.dev_mode = dev_mode.parse().unwrap_or(false);
|
|
}
|
|
|
|
if let Ok(runtime) = std::env::var("ARCHIPELAGO_CONTAINER_RUNTIME") {
|
|
config.container_runtime = ContainerRuntime::from_str(&runtime);
|
|
}
|
|
|
|
if let Ok(offset) = std::env::var("ARCHIPELAGO_PORT_OFFSET") {
|
|
config.port_offset = offset.parse()
|
|
.context("Invalid port offset in ARCHIPELAGO_PORT_OFFSET")?;
|
|
}
|
|
|
|
if let Ok(sim) = std::env::var("ARCHIPELAGO_BITCOIN_SIMULATION") {
|
|
config.bitcoin_simulation = BitcoinSimulation::from_str(&sim);
|
|
}
|
|
|
|
if let Ok(dev_data_dir) = std::env::var("ARCHIPELAGO_DEV_DATA_DIR") {
|
|
config.dev_data_dir = PathBuf::from(dev_data_dir);
|
|
}
|
|
|
|
// Ensure data directory exists
|
|
fs::create_dir_all(&config.data_dir).await
|
|
.context("Failed to create data directory")?;
|
|
|
|
// Ensure dev data directory exists if in dev mode
|
|
if config.dev_mode {
|
|
fs::create_dir_all(&config.dev_data_dir).await
|
|
.context("Failed to create dev data directory")?;
|
|
}
|
|
|
|
Ok(config)
|
|
}
|
|
}
|
|
|
|
impl Default for Config {
|
|
fn default() -> Self {
|
|
Self {
|
|
data_dir: PathBuf::from("/var/lib/archipelago"),
|
|
bind_host: "127.0.0.1".to_string(),
|
|
bind_port: 5959,
|
|
log_level: "info".to_string(),
|
|
dev_mode: false,
|
|
container_runtime: ContainerRuntime::Auto,
|
|
port_offset: 10000,
|
|
bitcoin_simulation: BitcoinSimulation::Mock,
|
|
dev_data_dir: PathBuf::from("/tmp/archipelago-dev"),
|
|
}
|
|
}
|
|
}
|