()
| 195 | } |
| 196 | |
| 197 | fn main() -> Result<()> { |
| 198 | // Handle `copy-self <DEST>` before clap so it works without any of the |
| 199 | // sandbox flags. Kubernetes init containers invoke this path to seed an |
| 200 | // emptyDir volume that the agent container then executes from. |
| 201 | let raw_args: Vec<String> = std::env::args().collect(); |
| 202 | if raw_args.get(1).map(String::as_str) == Some(COPY_SELF_SUBCOMMAND) { |
| 203 | let dest = raw_args.get(2).ok_or_else(|| { |
| 204 | miette::miette!("usage: openshell-sandbox {COPY_SELF_SUBCOMMAND} <DEST>") |
| 205 | })?; |
| 206 | return copy_self(dest); |
| 207 | } |
| 208 | |
| 209 | // Handle `debug-rpc <subcommand> [args]` before clap. Uses a small |
| 210 | // dedicated runtime so we don't pay the supervisor's full startup cost. |
| 211 | if raw_args.get(1).map(String::as_str) == Some(DEBUG_RPC_SUBCOMMAND) { |
| 212 | let runtime = tokio::runtime::Builder::new_current_thread() |
| 213 | .enable_all() |
| 214 | .build() |
| 215 | .into_diagnostic()?; |
| 216 | return runtime.block_on(async move { |
| 217 | let _ = rustls::crypto::ring::default_provider().install_default(); |
| 218 | let exit = openshell_supervisor_process::debug_rpc::run(&raw_args[2..]).await?; |
| 219 | std::process::exit(exit); |
| 220 | }); |
| 221 | } |
| 222 | |
| 223 | let args = Args::parse(); |
| 224 | |
| 225 | // Try to open a rolling log file; fall back to stderr-only logging if it fails |
| 226 | // (e.g., /var/log is not writable in custom workload images). |
| 227 | // Rotates daily, keeps the 3 most recent files to bound disk usage. |
| 228 | let file_logging = tracing_appender::rolling::RollingFileAppender::builder() |
| 229 | .rotation(tracing_appender::rolling::Rotation::DAILY) |
| 230 | .filename_prefix("openshell") |
| 231 | .filename_suffix("log") |
| 232 | .max_log_files(3) |
| 233 | .build("/var/log") |
| 234 | .ok() |
| 235 | .map(|roller| { |
| 236 | let (writer, guard) = tracing_appender::non_blocking(roller); |
| 237 | (writer, guard) |
| 238 | }); |
| 239 | |
| 240 | let console_filter = |
| 241 | EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new(&args.log_level)); |
| 242 | |
| 243 | let runtime = tokio::runtime::Builder::new_multi_thread() |
| 244 | .enable_all() |
| 245 | .build() |
| 246 | .into_diagnostic()?; |
| 247 | |
| 248 | let exit_code = runtime.block_on(async move { |
| 249 | // Install rustls crypto provider before any TLS connections (including log push). |
| 250 | let _ = rustls::crypto::ring::default_provider().install_default(); |
| 251 | |
| 252 | // Set up optional log push layer (gRPC mode only). |
| 253 | let log_push_state = if let (Some(sandbox_id), Some(endpoint)) = |
| 254 | (&args.sandbox_id, &args.openshell_endpoint) |
nothing calls this directly
no test coverage detected