2020-04-24 10:10:01 +00:00
|
|
|
use std::path::PathBuf;
|
|
|
|
|
|
|
|
use tokio::sync::watch;
|
|
|
|
|
2022-06-08 08:01:44 +00:00
|
|
|
use garage_db as db;
|
|
|
|
|
2020-04-24 10:10:01 +00:00
|
|
|
use garage_util::background::*;
|
|
|
|
use garage_util::config::*;
|
|
|
|
use garage_util::error::Error;
|
|
|
|
|
2022-05-24 10:16:39 +00:00
|
|
|
use garage_api::admin::api_server::AdminApiServer;
|
2022-05-10 11:16:57 +00:00
|
|
|
use garage_api::s3::api_server::S3ApiServer;
|
2020-07-07 11:59:22 +00:00
|
|
|
use garage_model::garage::Garage;
|
2021-03-26 21:05:16 +00:00
|
|
|
use garage_web::run_web_server;
|
2020-04-24 10:10:01 +00:00
|
|
|
|
2022-05-10 11:16:57 +00:00
|
|
|
#[cfg(feature = "k2v")]
|
|
|
|
use garage_api::k2v::api_server::K2VApiServer;
|
|
|
|
|
2021-10-19 14:16:10 +00:00
|
|
|
use crate::admin::*;
|
2022-05-24 10:16:39 +00:00
|
|
|
use crate::tracing_setup::*;
|
2020-04-24 10:10:01 +00:00
|
|
|
|
2021-04-23 20:41:24 +00:00
|
|
|
async fn wait_from(mut chan: watch::Receiver<bool>) {
|
2021-03-15 21:36:41 +00:00
|
|
|
while !*chan.borrow() {
|
|
|
|
if chan.changed().await.is_err() {
|
2020-04-24 10:10:01 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn run_server(config_file: PathBuf) -> Result<(), Error> {
|
|
|
|
info!("Loading configuration...");
|
|
|
|
let config = read_config(config_file).expect("Unable to read config file");
|
|
|
|
|
|
|
|
info!("Opening database...");
|
|
|
|
let mut db_path = config.metadata_dir.clone();
|
2022-06-08 08:01:44 +00:00
|
|
|
std::fs::create_dir_all(&db_path).expect("Unable to create Garage meta data directory");
|
|
|
|
let db = match config.db_engine.as_str() {
|
|
|
|
"sled" => {
|
|
|
|
db_path.push("db");
|
|
|
|
info!("Opening Sled database at: {}", db_path.display());
|
|
|
|
let db = db::sled_adapter::sled::Config::default()
|
|
|
|
.path(&db_path)
|
|
|
|
.cache_capacity(config.sled_cache_capacity)
|
|
|
|
.flush_every_ms(Some(config.sled_flush_every_ms))
|
|
|
|
.open()
|
|
|
|
.expect("Unable to open sled DB");
|
|
|
|
db::sled_adapter::SledDb::init(db)
|
|
|
|
}
|
|
|
|
"sqlite" | "sqlite3" | "rusqlite" => {
|
|
|
|
db_path.push("db.sqlite");
|
|
|
|
info!("Opening Sqlite database at: {}", db_path.display());
|
|
|
|
let db = db::sqlite_adapter::rusqlite::Connection::open(db_path)
|
|
|
|
.expect("Unable to open sqlite DB");
|
|
|
|
db::sqlite_adapter::SqliteDb::init(db)
|
|
|
|
}
|
|
|
|
"lmdb" | "heed" => {
|
|
|
|
db_path.push("db.lmdb");
|
|
|
|
info!("Opening LMDB database at: {}", db_path.display());
|
|
|
|
std::fs::create_dir_all(&db_path).expect("Unable to create LMDB data directory");
|
|
|
|
let map_size = if u32::MAX as usize == usize::MAX {
|
|
|
|
warn!("LMDB is not recommended on 32-bit systems, database size will be limited");
|
|
|
|
1usize << 30 // 1GB for 32-bit systems
|
|
|
|
} else {
|
|
|
|
1usize << 40 // 1TB for 64-bit systems
|
|
|
|
};
|
|
|
|
|
|
|
|
let db = db::lmdb_adapter::heed::EnvOpenOptions::new()
|
|
|
|
.max_dbs(100)
|
|
|
|
.map_size(map_size)
|
|
|
|
.open(&db_path)
|
|
|
|
.expect("Unable to open LMDB DB");
|
|
|
|
db::lmdb_adapter::LmdbDb::init(db)
|
|
|
|
}
|
|
|
|
e => {
|
|
|
|
return Err(Error::Message(format!(
|
|
|
|
"Unsupported DB engine: {} (options: sled, sqlite, lmdb)",
|
|
|
|
e
|
|
|
|
)));
|
|
|
|
}
|
|
|
|
};
|
2020-04-24 10:10:01 +00:00
|
|
|
|
|
|
|
info!("Initializing background runner...");
|
2021-10-14 09:50:12 +00:00
|
|
|
let watch_cancel = netapp::util::watch_ctrl_c();
|
2021-03-15 22:14:12 +00:00
|
|
|
let (background, await_background_done) = BackgroundRunner::new(16, watch_cancel.clone());
|
2020-04-24 10:10:01 +00:00
|
|
|
|
2021-03-12 17:12:31 +00:00
|
|
|
info!("Initializing Garage main data store...");
|
2021-10-14 09:50:12 +00:00
|
|
|
let garage = Garage::new(config.clone(), db, background);
|
|
|
|
|
2022-02-17 22:28:23 +00:00
|
|
|
info!("Initialize tracing...");
|
2022-02-22 14:25:13 +00:00
|
|
|
if let Some(export_to) = config.admin.trace_sink {
|
2022-02-17 22:28:23 +00:00
|
|
|
init_tracing(&export_to, garage.system.id)?;
|
|
|
|
}
|
|
|
|
|
2022-05-24 10:16:39 +00:00
|
|
|
info!("Initialize Admin API server and metrics collector...");
|
|
|
|
let admin_server = AdminApiServer::new(garage.clone());
|
|
|
|
|
2021-10-14 09:50:12 +00:00
|
|
|
let run_system = tokio::spawn(garage.system.clone().run(watch_cancel.clone()));
|
2020-04-24 10:10:01 +00:00
|
|
|
|
2021-09-28 06:57:20 +00:00
|
|
|
info!("Create admin RPC handler...");
|
2021-10-14 09:50:12 +00:00
|
|
|
AdminRpcHandler::new(garage.clone());
|
|
|
|
|
2022-05-10 11:16:57 +00:00
|
|
|
info!("Initializing S3 API server...");
|
|
|
|
let s3_api_server = tokio::spawn(S3ApiServer::run(
|
2021-10-14 09:50:12 +00:00
|
|
|
garage.clone(),
|
|
|
|
wait_from(watch_cancel.clone()),
|
|
|
|
));
|
|
|
|
|
2022-05-10 11:16:57 +00:00
|
|
|
#[cfg(feature = "k2v")]
|
|
|
|
let k2v_api_server = {
|
|
|
|
info!("Initializing K2V API server...");
|
|
|
|
tokio::spawn(K2VApiServer::run(
|
|
|
|
garage.clone(),
|
|
|
|
wait_from(watch_cancel.clone()),
|
|
|
|
))
|
|
|
|
};
|
|
|
|
|
2021-10-14 09:50:12 +00:00
|
|
|
info!("Initializing web server...");
|
|
|
|
let web_server = tokio::spawn(run_web_server(
|
|
|
|
garage.clone(),
|
|
|
|
wait_from(watch_cancel.clone()),
|
|
|
|
));
|
|
|
|
|
2022-05-24 10:16:39 +00:00
|
|
|
info!("Launching Admin API server...");
|
|
|
|
let admin_server = tokio::spawn(admin_server.run(wait_from(watch_cancel.clone())));
|
2021-09-28 06:57:20 +00:00
|
|
|
|
2021-10-14 09:50:12 +00:00
|
|
|
// Stuff runs
|
|
|
|
|
|
|
|
// When a cancel signal is sent, stuff stops
|
2022-05-10 11:16:57 +00:00
|
|
|
if let Err(e) = s3_api_server.await? {
|
|
|
|
warn!("S3 API server exited with error: {}", e);
|
2022-05-24 10:16:39 +00:00
|
|
|
} else {
|
|
|
|
info!("S3 API server exited without error.");
|
2022-05-10 11:16:57 +00:00
|
|
|
}
|
|
|
|
#[cfg(feature = "k2v")]
|
|
|
|
if let Err(e) = k2v_api_server.await? {
|
|
|
|
warn!("K2V API server exited with error: {}", e);
|
2022-05-24 10:16:39 +00:00
|
|
|
} else {
|
|
|
|
info!("K2V API server exited without error.");
|
2021-10-14 09:50:12 +00:00
|
|
|
}
|
|
|
|
if let Err(e) = web_server.await? {
|
|
|
|
warn!("Web server exited with error: {}", e);
|
2022-05-24 10:16:39 +00:00
|
|
|
} else {
|
|
|
|
info!("Web server exited without error.");
|
2021-10-14 09:50:12 +00:00
|
|
|
}
|
2022-05-24 10:16:39 +00:00
|
|
|
if let Err(e) = admin_server.await? {
|
|
|
|
warn!("Admin web server exited with error: {}", e);
|
|
|
|
} else {
|
|
|
|
info!("Admin API server exited without error.");
|
2021-09-28 06:57:20 +00:00
|
|
|
}
|
2021-10-14 09:50:12 +00:00
|
|
|
|
|
|
|
// Remove RPC handlers for system to break reference cycles
|
|
|
|
garage.system.netapp.drop_all_handlers();
|
2022-05-24 10:16:39 +00:00
|
|
|
opentelemetry::global::shutdown_tracer_provider();
|
2021-10-14 09:50:12 +00:00
|
|
|
|
2021-10-15 09:05:09 +00:00
|
|
|
// Await for netapp RPC system to end
|
2021-10-14 09:50:12 +00:00
|
|
|
run_system.await?;
|
2022-05-24 10:16:39 +00:00
|
|
|
info!("Netapp exited");
|
2021-10-15 09:05:09 +00:00
|
|
|
|
2022-03-15 11:04:12 +00:00
|
|
|
// Drop all references so that stuff can terminate properly
|
2021-10-15 09:05:09 +00:00
|
|
|
drop(garage);
|
|
|
|
|
|
|
|
// Await for all background tasks to end
|
2021-10-14 09:50:12 +00:00
|
|
|
await_background_done.await?;
|
2020-04-24 10:10:01 +00:00
|
|
|
|
|
|
|
info!("Cleaning up...");
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|