2020-02-14 12:20:17 +01:00
|
|
|
#[macro_use]
|
|
|
|
extern crate slog;
|
|
|
|
|
2020-02-16 16:02:03 +01:00
|
|
|
#[macro_use]
|
|
|
|
extern crate capnp_rpc;
|
|
|
|
|
2020-09-15 11:38:15 +02:00
|
|
|
#[macro_use]
|
|
|
|
extern crate async_trait;
|
|
|
|
|
2020-02-14 12:20:17 +01:00
|
|
|
mod modules;
|
|
|
|
mod log;
|
|
|
|
mod api;
|
|
|
|
mod config;
|
|
|
|
mod error;
|
2020-05-10 17:23:43 +02:00
|
|
|
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-16 16:02:03 +01:00
|
|
|
|
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;
|
2020-09-07 09:45:55 +02:00
|
|
|
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;
|
|
|
|
|
2020-09-11 09:57:03 +02:00
|
|
|
use lmdb::Transaction;
|
2020-11-30 15:05:25 +01:00
|
|
|
use smol::net::TcpListener;
|
2020-09-11 09:57:03 +02:00
|
|
|
|
2020-02-18 01:30:40 +01:00
|
|
|
use error::Error;
|
|
|
|
|
2020-09-15 11:38:15 +02:00
|
|
|
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`
|
2020-11-30 16:12:40 +01:00
|
|
|
fn maybe() -> Result<i32, Error> {
|
2020-02-18 01:30:40 +01:00
|
|
|
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")
|
|
|
|
)
|
2020-09-11 09:57:03 +02:00
|
|
|
.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.
|
2020-11-30 16:12:40 +01:00
|
|
|
return Ok(0)
|
2020-02-18 01:30:40 +01:00
|
|
|
}
|
2020-02-16 16:02:03 +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())?;
|
|
|
|
// 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-02-18 13:06:25 +01:00
|
|
|
|
2020-11-30 16:12:40 +01:00
|
|
|
if matches.is_present("dump") {
|
|
|
|
error!(log, "Dumping is currently not implemented");
|
|
|
|
Ok(-2)
|
|
|
|
} else if matches.is_present("load") {
|
|
|
|
error!(log, "Loading is currently not implemented");
|
|
|
|
Ok(-2)
|
|
|
|
} else {
|
|
|
|
let db = match db::Databases::new(&log, &config) {
|
|
|
|
Err(e) => {
|
|
|
|
error!(log, "{}", e);
|
|
|
|
return Ok(-1);
|
|
|
|
},
|
|
|
|
Ok(ok) => ok
|
|
|
|
};
|
|
|
|
|
|
|
|
match server::serve_api_connections(log.clone(), config, db) {
|
|
|
|
Err(e) => {
|
|
|
|
error!(log, "{}", e);
|
|
|
|
Ok(-1)
|
|
|
|
},
|
|
|
|
ok => Ok(0)
|
|
|
|
}
|
|
|
|
}
|
2020-02-14 12:20:17 +01:00
|
|
|
}
|
2020-02-18 13:06:25 +01:00
|
|
|
|
2020-11-30 16:12:40 +01:00
|
|
|
fn main() {
|
|
|
|
match maybe() {
|
|
|
|
Ok(i) => std::process::exit(i),
|
|
|
|
Err(e) => {
|
|
|
|
println!("{}", e);
|
|
|
|
std::process::exit(-1);
|
|
|
|
}
|
|
|
|
}
|
2020-02-18 13:06:25 +01:00
|
|
|
}
|