| 1 |
use anyhow::Result; |
| 2 |
use std::net::SocketAddr; |
| 3 |
use std::path::Path; |
| 4 |
use std::sync::Arc; |
| 5 |
|
| 6 |
mod backup; |
| 7 |
mod build; |
| 8 |
mod config; |
| 9 |
mod db; |
| 10 |
mod deploy; |
| 11 |
mod error; |
| 12 |
mod gates; |
| 13 |
mod git; |
| 14 |
mod metrics; |
| 15 |
mod routes; |
| 16 |
mod state; |
| 17 |
mod sync; |
| 18 |
mod topology; |
| 19 |
|
| 20 |
#[tokio::main] |
| 21 |
async fn main() -> Result<()> { |
| 22 |
tracing_subscriber::fmt() |
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
.with_writer(std::io::stderr) |
| 27 |
.with_env_filter( |
| 28 |
tracing_subscriber::EnvFilter::try_from_default_env() |
| 29 |
|
| 30 |
|
| 31 |
.unwrap_or_else(|_| "sandod=info,tower_http=info".into()), |
| 32 |
) |
| 33 |
.init(); |
| 34 |
|
| 35 |
let cfg = Arc::new(config::Config::load()?); |
| 36 |
let topo = Arc::new(topology::Topology::load(&cfg.topology_path)?); |
| 37 |
tokio::fs::create_dir_all(&cfg.workdir).await?; |
| 38 |
tokio::fs::create_dir_all(&cfg.release_root).await?; |
| 39 |
git::ensure_bare_repo(Path::new(&topo.repo.bare_path)).await?; |
| 40 |
let pool = db::connect(&cfg.db_path).await?; |
| 41 |
db::migrate(&pool).await?; |
| 42 |
sync::sync(&pool, &*topo).await?; |
| 43 |
tracing::info!(tiers = topo.tiers.len(), bare = %topo.repo.bare_path, "topology synced"); |
| 44 |
|
| 45 |
let prom = metrics::init(); |
| 46 |
let addr: SocketAddr = cfg.listen.parse()?; |
| 47 |
let app_state = state::AppState { pool, topo, cfg, prom }; |
| 48 |
let app = routes::router(app_state); |
| 49 |
tracing::info!(%addr, "sando daemon listening"); |
| 50 |
let listener = tokio::net::TcpListener::bind(addr).await?; |
| 51 |
axum::serve(listener, app).await?; |
| 52 |
Ok(()) |
| 53 |
} |
| 54 |
|