Files
boxmaker/crates/memoryd/src/main.rs
T

74 lines
2.5 KiB
Rust

//! `memoryd serve --config <path>`.
use std::ffi::OsString;
use std::path::PathBuf;
use std::process::ExitCode;
use std::sync::Arc;
use bxcore::instance;
use memoryd::config::{Config, ConfigError};
use memoryd::honcho::config::RUNBOOK as HONCHO_INVALID;
use memoryd::serve;
const USAGE: &str = "usage: memoryd serve --config <path>";
const START_FAILED: &str = "see docs/runbook.md#memoryd-start-failed";
fn main() -> ExitCode {
let args: Vec<OsString> = std::env::args_os().skip(1).collect();
let Some(path) = parse(&args) else {
eprintln!("{USAGE}");
return ExitCode::from(2);
};
let config = match Config::load(&path) {
Ok(config) => config,
Err(e) => {
let pointer = match &e {
ConfigError::Read(..) | ConfigError::Parse(..) => START_FAILED,
ConfigError::Honcho(..) => HONCHO_INVALID,
};
eprintln!("memoryd: {e}\n{pointer}");
return ExitCode::from(1);
}
};
// One memoryd per home (M5b spec, section 9a). The lock comes before anything under the home
// is made or bound, so a second copy never takes the sockets of the one that runs. Held until
// the process ends.
let lock_path = config.paths.home.join("run/memoryd.lock");
let _instance = match instance::lock(&lock_path) {
Ok(held) => held,
Err(e) => {
eprintln!("{}", e.line("memoryd", &lock_path));
return ExitCode::from(1);
}
};
let log: serve::Log = Arc::new(|line: &str| eprintln!("{line}"));
let running = match serve::start(config, log) {
Ok(running) => running,
// The ledger's and a key's lines name their own pointers.
Err(e @ (serve::StartError::Ledger(_) | serve::StartError::Secret(_))) => {
eprintln!("memoryd: {e}");
return ExitCode::from(1);
}
Err(e) => {
eprintln!("memoryd: {e}\n{START_FAILED}");
return ExitCode::from(1);
}
};
eprintln!("memoryd: serving");
match running.run() {
Ok(()) => ExitCode::SUCCESS,
Err(e) => {
eprintln!("memoryd: stopped serving: {e}\n{START_FAILED}");
ExitCode::from(1)
}
}
}
/// The config path of `serve --config <path>`, or `None` for any other list.
fn parse(args: &[OsString]) -> Option<PathBuf> {
match args {
[serve, flag, path] if serve == "serve" && flag == "--config" => Some(PathBuf::from(path)),
_ => None,
}
}