objectstore_server/
cli.rs1use std::path::PathBuf;
2use std::thread;
3use std::time::Duration;
4
5use anyhow::Result;
6use argh::FromArgs;
7
8use crate::config::Config;
9use crate::{healthcheck, observability, web};
10
11#[derive(Debug, FromArgs)]
13struct Args {
14 #[argh(option, short = 'c')]
16 pub config: Option<PathBuf>,
17
18 #[argh(subcommand)]
19 pub command: Command,
20}
21
22#[derive(Debug, FromArgs)]
23#[argh(subcommand)]
24enum Command {
25 Run(RunCommand),
26 Healthcheck(HealthcheckCommand),
27 Version(VersionCommand),
28 Sleep(SleepCommand),
29}
30
31#[derive(Debug, FromArgs)]
33#[argh(subcommand, name = "run")]
34struct RunCommand {}
35
36#[derive(Debug, FromArgs)]
41#[argh(subcommand, name = "healthcheck")]
42struct HealthcheckCommand {}
43
44#[derive(Default, Debug, FromArgs)]
46#[argh(subcommand, name = "version")]
47struct VersionCommand {}
48
49#[derive(Debug, FromArgs)]
51#[argh(subcommand, name = "sleep")]
52struct SleepCommand {
53 #[argh(positional)]
54 seconds: u64,
55}
56
57pub fn execute() -> Result<()> {
59 let args: Args = argh::from_env();
60
61 if let Command::Version(_) = args.command {
63 println!("{}", env!("OBJECTSTORE_RELEASE"));
64 return Ok(());
65 }
66
67 if let Command::Sleep(SleepCommand { seconds }) = args.command {
68 thread::sleep(Duration::from_secs(seconds));
69 return Ok(());
70 }
71
72 let config = Config::load(args.config.as_deref())?;
73
74 rustls::crypto::ring::default_provider()
76 .install_default()
77 .map_err(|_| anyhow::anyhow!("Failed to install rustls crypto provider"))?;
78
79 let _sentry_guard = observability::init_sentry(&config);
81
82 let runtime = tokio::runtime::Builder::new_multi_thread()
83 .thread_name("main-rt")
84 .enable_all()
85 .worker_threads(config.runtime.worker_threads)
86 .build()?;
87 let _runtime_guard = runtime.enter();
88
89 observability::init_tracing(&config);
90 tracing::debug!(?config);
91
92 let metrics_guard = observability::init_metrics(&config)?;
93
94 let result = runtime.block_on(async move {
95 match args.command {
96 Command::Run(RunCommand {}) => web::server(config).await,
97 Command::Healthcheck(HealthcheckCommand {}) => healthcheck::healthcheck(config).await,
98 Command::Version(VersionCommand {}) | Command::Sleep(SleepCommand { .. }) => {
99 unreachable!()
100 }
101 }
102 });
103
104 runtime.block_on(async {
106 if let Some(metrics_guard) = metrics_guard {
107 metrics_guard.flush(None).await.ok();
108 }
109 });
110
111 result
112}