daemon: introduce the DaemonHandle, which for now only creates a datadir
This code was mainly taken and adapted from revaultd at commit 7cd856d5a345319cebc815aa61f3b66cebb48b86.
This commit is contained in:
parent
1b35196448
commit
989a2cf8fd
67
Cargo.lock
generated
67
Cargo.lock
generated
@ -2,6 +2,36 @@
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
version = "0.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b"
|
||||
dependencies = [
|
||||
"gimli",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "adler"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.66"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cab84319d616cfb654d03394f38ab7e6f0919e181b1b57e1fd15e7fb4077d9a7"
|
||||
dependencies = [
|
||||
"addr2line",
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"miniz_oxide",
|
||||
"object",
|
||||
"rustc-demangle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bech32"
|
||||
version = "0.8.1"
|
||||
@ -87,6 +117,12 @@ dependencies = [
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.26.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d"
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.2"
|
||||
@ -108,10 +144,17 @@ dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
|
||||
[[package]]
|
||||
name = "minisafed"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"dirs",
|
||||
"fern",
|
||||
"log",
|
||||
@ -131,6 +174,24 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc"
|
||||
dependencies = [
|
||||
"adler",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.29.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.40"
|
||||
@ -169,6 +230,12 @@ dependencies = [
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.10"
|
||||
|
||||
@ -32,3 +32,8 @@ serde_json = { version = "1.0", features = ["raw_value"] }
|
||||
# Logging stuff
|
||||
log = "0.4"
|
||||
fern = "0.6"
|
||||
|
||||
# In order to have a backtrace on panic, because the
|
||||
# stdlib does not have a programmatic interface yet
|
||||
# to work with our custom panic hook.
|
||||
backtrace = "0.3"
|
||||
|
||||
@ -5,7 +5,7 @@ use std::{
|
||||
process, time,
|
||||
};
|
||||
|
||||
use minisafed::config::Config;
|
||||
use minisafed::{config::Config, DaemonHandle};
|
||||
|
||||
fn parse_args(args: Vec<String>) -> Option<PathBuf> {
|
||||
if args.len() == 1 {
|
||||
@ -58,6 +58,11 @@ fn main() {
|
||||
process::exit(1);
|
||||
});
|
||||
|
||||
let _ = DaemonHandle::start(config).unwrap_or_else(|e| {
|
||||
// The panic hook will log::error
|
||||
panic!("Starting Minisafe daemon: {}", e);
|
||||
});
|
||||
|
||||
// We are always logging to stdout, should it be then piped to the log file (if self) or
|
||||
// not. So just make sure that all messages were actually written.
|
||||
io::stdout().flush().expect("Flushing stdout");
|
||||
|
||||
115
src/lib.rs
115
src/lib.rs
@ -1 +1,116 @@
|
||||
pub mod config;
|
||||
|
||||
use crate::config::{config_folder_path, Config};
|
||||
|
||||
use std::{error, fmt, fs, io, panic, path, process};
|
||||
|
||||
// A panic in any thread should stop the main thread, and print the panic.
|
||||
fn setup_panic_hook() {
|
||||
panic::set_hook(Box::new(move |panic_info| {
|
||||
let file = panic_info
|
||||
.location()
|
||||
.map(|l| l.file())
|
||||
.unwrap_or_else(|| "'unknown'");
|
||||
let line = panic_info
|
||||
.location()
|
||||
.map(|l| l.line().to_string())
|
||||
.unwrap_or_else(|| "'unknown'".to_string());
|
||||
|
||||
let bt = backtrace::Backtrace::new();
|
||||
let info = panic_info
|
||||
.payload()
|
||||
.downcast_ref::<&str>()
|
||||
.map(|s| s.to_string())
|
||||
.or_else(|| panic_info.payload().downcast_ref::<String>().cloned());
|
||||
log::error!(
|
||||
"panic occurred at line {} of file {}: {:?}\n{:?}",
|
||||
line,
|
||||
file,
|
||||
info,
|
||||
bt
|
||||
);
|
||||
|
||||
process::exit(1);
|
||||
}));
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum StartupError {
|
||||
Io(io::Error),
|
||||
DefaultDataDirNotFound,
|
||||
DatadirCreation(path::PathBuf, io::Error),
|
||||
}
|
||||
|
||||
impl fmt::Display for StartupError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Self::Io(e) => write!(f, "{}", e),
|
||||
Self::DefaultDataDirNotFound => write!(
|
||||
f,
|
||||
"Not data directory was specified and a default path could not be determined for this platform."
|
||||
),
|
||||
Self::DatadirCreation(dir_path, e) => write!(
|
||||
f,
|
||||
"Could not create data directory at '{}': '{}'", dir_path.display(), e
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl error::Error for StartupError {}
|
||||
|
||||
impl From<io::Error> for StartupError {
|
||||
fn from(e: io::Error) -> Self {
|
||||
Self::Io(e)
|
||||
}
|
||||
}
|
||||
|
||||
fn create_datadir(datadir_path: &path::Path) -> Result<(), StartupError> {
|
||||
#[cfg(unix)]
|
||||
return {
|
||||
use fs::DirBuilder;
|
||||
use std::os::unix::fs::DirBuilderExt;
|
||||
|
||||
let mut builder = DirBuilder::new();
|
||||
builder
|
||||
.mode(0o700)
|
||||
.recursive(true)
|
||||
.create(datadir_path)
|
||||
.map_err(|e| StartupError::DatadirCreation(datadir_path.to_path_buf(), e))
|
||||
};
|
||||
|
||||
// TODO: permissions on Windows..
|
||||
#[cfg(not(unix))]
|
||||
return {
|
||||
fs::create_dir_all(datadir_path)
|
||||
.map_err(|e| StartupError::DatadirCreation(datadir_path.to_path_buf(), e))
|
||||
};
|
||||
}
|
||||
|
||||
pub struct DaemonHandle {}
|
||||
|
||||
impl DaemonHandle {
|
||||
/// This starts the Minisafe daemon. Call `shutdown` to shut it down.
|
||||
///
|
||||
/// **Note**: we internally use threads, and set a panic hook. A downstream application must
|
||||
/// not overwrite this panic hook.
|
||||
pub fn start(config: Config) -> Result<Self, StartupError> {
|
||||
setup_panic_hook();
|
||||
|
||||
// First, check the data directory
|
||||
let mut data_dir = config
|
||||
.data_dir
|
||||
.unwrap_or(config_folder_path().ok_or(StartupError::DefaultDataDirNotFound)?);
|
||||
data_dir.push(config.bitcoind_config.network.to_string());
|
||||
if !data_dir.as_path().exists() {
|
||||
create_datadir(&data_dir)?;
|
||||
log::info!("Created a new data directory at '{}'", data_dir.display());
|
||||
}
|
||||
|
||||
Ok(Self {})
|
||||
}
|
||||
|
||||
// NOTE: this moves out the data as it should not be reused after shutdown
|
||||
/// Shut down the Minisafe daemon.
|
||||
pub fn shutdown(self) {}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user