//! Orchestrator trait — the shared surface the RPC layer talks to. //! //! Step 4 of the rust-orchestrator migration. Unifies the container lifecycle //! surface of `DevContainerOrchestrator` and `ProdContainerOrchestrator` so //! `RpcHandler` can hold `Arc` and stop caring //! which mode it is in. //! //! The trait takes `app_id: &str` everywhere (never a manifest path). Dev and //! Prod both resolve app_id → manifest internally. The legacy //! `container-install { manifest_path }` RPC shape is preserved as a concrete //! `install_container_from_path` method on `DevContainerOrchestrator` only, //! since that ad-hoc workflow is a dev convenience and has no prod meaning. //! //! See `docs/rust-orchestrator-migration.md`. use anyhow::Result; use archipelago_container::ContainerStatus; use async_trait::async_trait; /// Lifecycle + query operations every orchestrator exposes to the RPC layer. #[async_trait] pub trait ContainerOrchestrator: Send + Sync { /// Build-or-pull the image, create the container, and start it. Returns the /// podman container name that was created. Assumes the app_id corresponds /// to a manifest the orchestrator already knows about. async fn install(&self, app_id: &str) -> Result; /// Start an already-created container. async fn start(&self, app_id: &str) -> Result<()>; /// Stop a running container. No-op on Prod if already stopped. async fn stop(&self, app_id: &str) -> Result<()>; /// Stop-then-start. Best-effort: ignores stop failure. async fn restart(&self, app_id: &str) -> Result<()>; /// Remove the container. `preserve_data = true` keeps the volumes; `false` /// is honored on a best-effort basis (Dev cleans, Prod leaves the volume /// management to the data layer). async fn remove(&self, app_id: &str, preserve_data: bool) -> Result<()>; /// Pull/rebuild the image and recreate the container from scratch. async fn upgrade(&self, app_id: &str) -> Result<()>; /// Current state of a single container. async fn status(&self, app_id: &str) -> Result; /// All containers this orchestrator knows about. async fn list(&self) -> Result>; /// Tail the container's stdout+stderr. async fn logs(&self, app_id: &str, lines: u32) -> Result>; /// Coarse health summary: "healthy", "unhealthy", "starting", "paused", "unknown". async fn health(&self, app_id: &str) -> Result; }