07c63032
wire up HTTP + SSH concurrent startup in main
a73x 2026-03-31 13:26
diff --git a/src/server/main.rs b/src/server/main.rs index dfe6648..6fadd41 100644 --- a/src/server/main.rs +++ b/src/server/main.rs @@ -1,8 +1,97 @@ use std::path::PathBuf; use clap::Parser; use tracing::info; mod config; mod http; mod repos; mod ssh; fn main() { println!("git-collab-server: not yet implemented"); #[derive(Parser)] #[command(name = "git-collab-server", about = "Minimal git hosting server")] struct Args { #[arg(short, long)] config: PathBuf, } #[tokio::main] async fn main() { tracing_subscriber::fmt::init(); let args = Args::parse(); let config = match config::ServerConfig::from_file(&args.config) { Ok(c) => c, Err(e) => { eprintln!("Failed to load config from {:?}: {}", args.config, e); std::process::exit(1); } }; if !config.repos_dir.exists() { eprintln!("repos_dir {:?} does not exist", config.repos_dir); std::process::exit(1); } let host_key_path = config.repos_dir.join(".server").join("host_key"); let host_key = match ssh::load_or_generate_host_key(&host_key_path) { Ok(k) => k, Err(e) => { eprintln!("Failed to load/generate SSH host key: {}", e); std::process::exit(1); } }; let fingerprint = match host_key.clone_public_key() { Ok(pub_key) => pub_key.fingerprint(), Err(e) => { eprintln!("Failed to get host key fingerprint: {}", e); std::process::exit(1); } }; info!("HTTP listening on {}", config.http_bind); info!("SSH listening on {}", config.ssh_bind); info!("Repos dir: {:?}", config.repos_dir); info!("Site title: {}", config.site_title); info!("SSH host key fingerprint: SHA256:{}", fingerprint); let app_state = http::AppState { repos_dir: config.repos_dir.clone(), site_title: config.site_title.clone(), }; let router = http::router(app_state); let ssh_config = ssh::session::SshServerConfig { repos_dir: config.repos_dir.clone(), authorized_keys_path: config.authorized_keys.clone(), }; let http_bind = config.http_bind; let ssh_bind = config.ssh_bind; let http_listener = match tokio::net::TcpListener::bind(http_bind).await { Ok(l) => l, Err(e) => { eprintln!("Failed to bind HTTP on {}: {}", http_bind, e); std::process::exit(1); } }; let http_fut = axum::serve(http_listener, router); let ssh_fut = ssh::serve(ssh_bind, host_key, ssh_config); tokio::select! { result = http_fut => { if let Err(e) = result { eprintln!("HTTP server error: {}", e); } } result = ssh_fut => { if let Err(e) = result { eprintln!("SSH server error: {}", e); } } } }