bffh/src/main.rs

124 lines
3.4 KiB
Rust
Raw Normal View History

2020-02-14 12:20:17 +01:00
#[macro_use]
extern crate slog;
#[macro_use]
extern crate capnp_rpc;
#[macro_use]
extern crate async_trait;
2020-02-14 12:20:17 +01:00
mod modules;
mod log;
mod api;
mod config;
mod error;
mod connection;
2020-09-14 10:37:51 +02:00
mod registries;
2020-10-22 13:00:58 +02:00
mod schema;
2020-10-23 16:35:10 +02:00
mod db;
2020-11-17 12:09:45 +01:00
mod machine;
2020-11-24 14:16:22 +01:00
mod builtin;
2020-11-30 15:05:25 +01:00
mod server;
2020-02-18 01:30:40 +01:00
use clap::{App, Arg};
2020-02-14 12:20:17 +01:00
2020-02-18 01:30:40 +01:00
use futures::prelude::*;
use futures::executor::{LocalPool, ThreadPool};
2020-02-18 13:06:25 +01:00
use futures::compat::Stream01CompatExt;
2020-02-18 01:30:40 +01:00
use futures::join;
use futures::task::LocalSpawn;
2020-02-18 01:30:40 +01:00
use std::io;
use std::io::Write;
use std::path::PathBuf;
use std::str::FromStr;
use std::sync::Arc;
use lmdb::Transaction;
2020-11-30 15:05:25 +01:00
use smol::net::TcpListener;
2020-02-18 01:30:40 +01:00
use error::Error;
use registries::Registries;
2020-02-18 01:30:40 +01:00
// Returning a `Result` from `main` allows us to use the `?` shorthand.
// In the case of an Err it will be printed using `fmt::Debug`
fn main() -> Result<(), Error> {
use clap::{crate_version, crate_description, crate_name};
// Argument parsing
// values for the name, description and version are pulled from `Cargo.toml`.
let matches = App::new(crate_name!())
.about(crate_description!())
.version(crate_version!())
.arg(Arg::with_name("config")
.help("Path to the config file to use")
.long("config")
.short("c")
.takes_value(true)
)
.arg(Arg::with_name("print default")
.help("Print a default config to stdout instead of running")
.long("print-default")
)
.arg(Arg::with_name("dump")
.help("Dump all databases into the given directory")
.long("dump")
.conflicts_with("load")
.takes_value(true)
)
.arg(Arg::with_name("load")
.help("Load databases from the given directory")
.long("load")
.conflicts_with("dump")
.takes_value(true)
)
2020-02-18 01:30:40 +01:00
.get_matches();
// Check for the --print-default option first because we don't need to do anything else in that
// case.
if matches.is_present("print default") {
2020-09-15 14:31:10 +02:00
let config = config::Settings::default();
2020-02-18 01:30:40 +01:00
let encoded = toml::to_vec(&config)?;
// Direct writing to fd 1 is faster but also prevents any print-formatting that could
// invalidate the generated TOML
let stdout = io::stdout();
let mut handle = stdout.lock();
handle.write_all(&encoded)?;
// Early return to exit.
return Ok(())
2020-11-30 15:05:25 +01:00
} else if matches.is_present("dump") {
} else if matches.is_present("load") {
} else {
2020-02-18 01:30:40 +01:00
}
2020-02-18 01:30:40 +01:00
// If no `config` option is given use a preset default.
2020-11-20 13:06:55 +01:00
let configpath = matches.value_of("config").unwrap_or("/etc/bffh/config.toml");
2020-02-18 01:30:40 +01:00
let config = config::read(&PathBuf::from_str(configpath).unwrap())?;
2020-02-18 01:30:40 +01:00
// Initialize the logging subsystem first to be able to better document the progress from now
// on.
// TODO: Now would be a really good time to close stdin/out and move logging to syslog
// Log is in an Arc so we can do very cheap clones in closures.
let log = Arc::new(log::init(&config));
info!(log, "Starting");
2020-02-14 12:20:17 +01:00
2020-11-30 15:05:25 +01:00
let db = db::Databases::new(&log, &config)?;
2020-02-18 13:06:25 +01:00
2020-11-30 15:05:25 +01:00
server::serve_api_connections(log, config, db)
2020-02-14 12:20:17 +01:00
}
2020-02-18 13:06:25 +01:00
/// The result of one iteration of the core loop
2020-11-30 15:05:25 +01:00
pub enum LoopResult {
2020-02-18 13:06:25 +01:00
/// Everything was fine, keep going
Continue,
/// Something happened that means we should shut down
Stop,
/// The Server is currently overloaded
Overloaded,
}