1use gonzalo_core::{BlobStore, Store};
22use gonzalo_server::{Auth, Service, StoreConfig, serve_grpc, serve_http};
23use gonzalo_store_fs::FsStore;
24use gonzalo_store_s3::S3Store;
25use std::sync::Arc;
26
27#[tokio::main]
28async fn main() -> Result<(), Box<dyn std::error::Error>> {
29 let http_addr = std::env::var("GONZALO_HTTP_ADDR").unwrap_or_else(|_| "127.0.0.1:8080".into());
30 let grpc_addr = std::env::var("GONZALO_GRPC_ADDR").unwrap_or_else(|_| "127.0.0.1:50051".into());
31
32 let auth = Arc::new(Auth::from_env(
34 |k| std::env::var(k).ok(),
35 |path| std::fs::read_to_string(path).map_err(|e| e.to_string()),
36 )?);
37 let auth_on = !matches!(*auth, Auth::Disabled);
38
39 let config = StoreConfig::from_env(|k| std::env::var(k).ok())?;
43 let (store, blobs, graph_root): (
44 Arc<dyn Store>,
45 Arc<dyn BlobStore>,
46 Option<std::path::PathBuf>,
47 ) = match &config {
48 StoreConfig::Fs { root } => {
49 let fs = Arc::new(FsStore::new(root));
52 let graphs = std::path::Path::new(root).join("graphs");
53 (fs.clone(), fs, Some(graphs))
54 }
55 StoreConfig::S3 {
56 bucket,
57 endpoint,
58 region,
59 } => {
60 let s3 =
63 Arc::new(S3Store::connect(bucket.clone(), endpoint.clone(), region.clone()).await);
64 (s3.clone(), s3, None)
65 }
66 };
67 let mut service = Service::new(store, blobs);
68 let max_blob_size = match std::env::var("GONZALO_MAX_BLOB_SIZE") {
71 Ok(v) if !v.is_empty() => v
72 .parse::<usize>()
73 .map_err(|e| format!("GONZALO_MAX_BLOB_SIZE must be a byte count: {e}"))?,
74 _ => gonzalo_proto::DEFAULT_MAX_BLOB_SIZE,
75 };
76 service = service.with_max_blob_size(max_blob_size);
77 if let Some(graph_root) = graph_root {
78 service = service.with_graph_root(graph_root);
79 }
80
81 let substrate = match &config {
82 StoreConfig::Fs { root } => format!("fs({root})"),
83 StoreConfig::S3 { bucket, .. } => format!("s3({bucket})"),
84 };
85 let http_listener = tokio::net::TcpListener::bind(&http_addr).await?;
86 let grpc_listener = tokio::net::TcpListener::bind(&grpc_addr).await?;
87 eprintln!(
88 "gonzalod: store {substrate}, HTTP on {http_addr}, gRPC on {grpc_addr}, auth {}",
89 if auth_on { "on" } else { "off" }
90 );
91
92 let http = tokio::spawn(serve_http(http_listener, service.clone(), auth.clone()));
93 let grpc = tokio::spawn(serve_grpc(grpc_listener, service, auth));
94
95 tokio::select! {
96 r = http => { r??; }
97 r = grpc => { r??; }
98 _ = tokio::signal::ctrl_c() => { eprintln!("gonzalod: shutting down"); }
99 }
100 Ok(())
101}