domani/src/main.rs

97 lines
3.1 KiB
Rust
Raw Normal View History

use clap::Parser;
use futures::stream::StreamExt;
use signal_hook::consts::signal;
use signal_hook_tokio::Signals;
use tokio::sync::oneshot;
use std::net::SocketAddr;
use std::path;
use std::str::FromStr;
#[derive(Parser, Debug)]
#[command(version)]
2023-05-13 14:39:54 +00:00
#[command(about = "A domiply to another dimension")]
struct Cli {
2023-05-13 14:39:54 +00:00
#[arg(long, default_value_t = SocketAddr::from_str("127.0.0.1:3030").unwrap(), env = "DOMIPLY_HTTP_LISTEN_ADDR")]
http_listen_addr: SocketAddr,
2023-05-13 14:39:54 +00:00
#[arg(long, required = true, env = "DOMIPLY_PASSPHRASE")]
passphrase: String,
2023-05-13 14:39:54 +00:00
#[arg(long, required = true, env = "DOMIPLY_ORIGIN_STORE_GIT_DIR_PATH")]
origin_store_git_dir_path: path::PathBuf,
2023-05-13 14:39:54 +00:00
#[arg(long, required = true, env = "DOMIPLY_DOMAIN_CHECKER_TARGET_CNAME")]
domain_checker_target_cname: domiply::domain::Name,
2023-05-13 14:39:54 +00:00
#[arg(long, default_value_t = String::from("1.1.1.1:53"), env = "DOMIPLY_DOMAIN_CHECKER_RESOLVER_ADDR")]
domain_checker_resolver_addr: String,
2023-05-13 14:39:54 +00:00
#[arg(long, required = true, env = "DOMIPLY_DOMAIN_CONFIG_STORE_DIR_PATH")]
domain_config_store_dir_path: path::PathBuf,
}
fn main() {
let config = Cli::parse();
let tokio_runtime = std::sync::Arc::new(
tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.unwrap(),
);
let (stop_ch_tx, stop_ch_rx) = tokio_runtime.block_on(async { oneshot::channel() });
// set up signal handling, stop_ch_rx will be used to signal that the stop signal has been
// received
tokio_runtime.spawn(async move {
let mut signals = Signals::new(&[signal::SIGTERM, signal::SIGINT, signal::SIGQUIT])
.expect("initialized signals");
if let Some(_) = signals.next().await {
println!("Gracefully shutting down...");
let _ = stop_ch_tx.send(());
}
if let Some(_) = signals.next().await {
println!("Forcefully shutting down");
std::process::exit(1);
};
});
2023-05-13 14:39:54 +00:00
let origin_store = domiply::origin::store::git::new(config.origin_store_git_dir_path)
.expect("git origin store initialized");
2023-05-13 14:39:54 +00:00
let domain_checker = domiply::domain::checker::new(
tokio_runtime.clone(),
config.domain_checker_target_cname.clone(),
&config.domain_checker_resolver_addr,
)
.expect("domain checker initialized");
2023-05-13 14:39:54 +00:00
let domain_config_store = domiply::domain::config::new(&config.domain_config_store_dir_path)
.expect("domain config store initialized");
2023-05-13 14:39:54 +00:00
let manager = domiply::domain::manager::new(origin_store, domain_config_store, domain_checker);
2023-05-13 14:39:54 +00:00
let service = domiply::service::new(
manager,
config.domain_checker_target_cname,
config.passphrase,
)
.expect("service initialized");
tokio_runtime.block_on(async {
let (addr, server) =
warp::serve(service).bind_with_graceful_shutdown(config.http_listen_addr, async {
stop_ch_rx.await.ok();
});
println!("Listening on {addr}");
server.await;
});
println!("Graceful shutdown complete");
}