aboutsummaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs84
1 files changed, 63 insertions, 21 deletions
diff --git a/src/main.rs b/src/main.rs
index 711717d7..4448d535 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,33 +1,73 @@
mod error;
mod data;
mod proto;
+mod membership;
mod rpc;
mod api;
+use std::io::{Read, Write};
+use std::sync::Arc;
+use std::net::SocketAddr;
+use std::path::PathBuf;
use structopt::StructOpt;
use futures::channel::oneshot;
-use tokio::sync::Mutex;
-use hyper::client::Client;
-
-use data::*;
+use serde::Deserialize;
+use rand::Rng;
+use data::UUID;
+use error::Error;
+use membership::System;
#[derive(StructOpt, Debug)]
#[structopt(name = "garage")]
pub struct Opt {
- #[structopt(long = "api-port", default_value = "3900")]
- api_port: u16,
+ #[structopt(short = "c", long = "config", default_value = "./config.toml")]
+ config_file: PathBuf,
+}
- #[structopt(long = "rpc-port", default_value = "3901")]
+#[derive(Deserialize, Debug)]
+pub struct Config {
+ metadata_dir: PathBuf,
+ data_dir: PathBuf,
+
+ api_port: u16,
rpc_port: u16,
+
+ bootstrap_peers: Vec<SocketAddr>,
}
-pub struct System {
- pub opt: Opt,
+fn read_config(config_file: PathBuf) -> Result<Config, Error> {
+ let mut file = std::fs::OpenOptions::new()
+ .read(true)
+ .open(config_file.as_path())?;
+
+ let mut config = String::new();
+ file.read_to_string(&mut config)?;
- pub rpc_client: Client<hyper::client::HttpConnector, hyper::Body>,
+ Ok(toml::from_str(&config)?)
+}
- pub network_members: Mutex<NetworkMembers>,
+fn gen_node_id(metadata_dir: &PathBuf) -> Result<UUID, Error> {
+ let mut id_file = metadata_dir.clone();
+ id_file.push("node_id");
+ if id_file.as_path().exists() {
+ let mut f = std::fs::File::open(id_file.as_path())?;
+ let mut d = vec![];
+ f.read_to_end(&mut d)?;
+ if d.len() != 32 {
+ return Err(Error::Message(format!("Corrupt node_id file")))
+ }
+
+ let mut id = [0u8; 32];
+ id.copy_from_slice(&d[..]);
+ Ok(id)
+ } else {
+ let id = rand::thread_rng().gen::<UUID>();
+
+ let mut f = std::fs::File::create(id_file.as_path())?;
+ f.write_all(&id[..])?;
+ Ok(id)
+ }
}
async fn shutdown_signal(chans: Vec<oneshot::Sender<()>>) {
@@ -47,22 +87,23 @@ async fn wait_from(chan: oneshot::Receiver<()>) -> () {
#[tokio::main]
async fn main() {
let opt = Opt::from_args();
- let rpc_port = opt.rpc_port;
- let api_port = opt.api_port;
+ let config = read_config(opt.config_file)
+ .expect("Unable to read config file");
+
+ let id = gen_node_id(&config.metadata_dir)
+ .expect("Unable to read or generate node ID");
+ println!("Node ID: {}", hex::encode(id));
- let sys = System{
- opt,
- rpc_client: Client::new(),
- network_members: Mutex::new(NetworkMembers::default()),
- };
+ let sys = Arc::new(System::new(config, id));
let (tx1, rx1) = oneshot::channel();
let (tx2, rx2) = oneshot::channel();
- tokio::spawn(shutdown_signal(vec![tx1, tx2]));
+ let rpc_server = rpc::run_rpc_server(sys.clone(), wait_from(rx1));
+ let api_server = api::run_api_server(sys.clone(), wait_from(rx2));
- let rpc_server = rpc::run_rpc_server(&sys, rpc_port, wait_from(rx1));
- let api_server = api::run_api_server(&sys, api_port, wait_from(rx2));
+ tokio::spawn(shutdown_signal(vec![tx1, tx2]));
+ tokio::spawn(membership::bootstrap(sys));
let (e1, e2) = futures::join![rpc_server, api_server];
@@ -74,3 +115,4 @@ async fn main() {
eprintln!("API server error: {}", e)
}
}
+