diff options
author | Alex Auvolat <alex@adnab.me> | 2020-04-06 19:55:39 +0200 |
---|---|---|
committer | Alex Auvolat <alex@adnab.me> | 2020-04-06 19:55:39 +0200 |
commit | 1a5e6e39af19d572a9de7f54e66bef911bdbbf2f (patch) | |
tree | 201638e94ede125b654691953d33aeb37fa9e2f7 /src/main.rs | |
parent | 7102db1d544bec663a8492b24c455168d0b83f08 (diff) | |
download | garage-1a5e6e39af19d572a9de7f54e66bef911bdbbf2f.tar.gz garage-1a5e6e39af19d572a9de7f54e66bef911bdbbf2f.zip |
Some more basic work
Diffstat (limited to 'src/main.rs')
-rw-r--r-- | src/main.rs | 84 |
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) } } + |