Skip to main content

olai_stack_runtime/
lib.rs

1//! Run trestle environments on Docker Compose.
2//!
3//! [`olai_stack_topology`] plans and renders an environment without touching Docker; this crate
4//! is the part that runs it. The CLI and the desktop app share it.
5//!
6//! - [`ComposeEngine`]: what the runtime asks of Compose (up, down, ls, ps, logs, events,
7//!   network removal). [`DockerCli`] runs the `docker` CLI; [`FakeEngine`] (feature `testing`)
8//!   is an in-memory stand-in for tests.
9//! - Typed [`ProjectStatus`], [`ServiceStatus`] / [`Health`] and [`EngineEvent`], parsed from the
10//!   CLI's JSON output (the test fixtures are captured from real engines, see
11//!   `docs/runtime.md`).
12//! - [`probe_host_ports`]: whether a plan's host ports are free before starting it.
13//! - [`managed_projects`] and [`remove_mesh_if_idle`]: matching what Docker runs against what
14//!   the caller manages.
15//! - [`Instances`]: runs the revisions of an [`olai_stack_state::Store`] as compose projects,
16//!   side by side, with the layered [`EffectiveEnv`] injected and credentials resolved by
17//!   [`SecretProvider`]s ([`EnvProvider`], and `KeychainProvider` behind feature `keychain`) and
18//!   [`Source`] overlays.
19//!
20//! Values that must not reach a file (credentials) go to Compose as process environment only:
21//! every lifecycle call takes the variables to add ([`UpOptions::env`]).
22//!
23//! ```no_run
24//! use olai_stack_runtime::{ComposeEngine, DockerCli, UpOptions};
25//!
26//! # async fn run() -> olai_stack_runtime::Result<()> {
27//! let docker = DockerCli::new();
28//! let opts = UpOptions { wait: true, ..UpOptions::default() };
29//! docker.up(std::path::Path::new("demo/dev"), &opts).await?;
30//! for project in docker.ls().await? {
31//!     println!("{}: {}", project.name, project.status);
32//! }
33//! # Ok(())
34//! # }
35//! ```
36
37#![cfg_attr(docsrs, feature(doc_cfg))]
38
39mod docker;
40mod effective;
41mod engine;
42mod error;
43mod events;
44#[cfg(feature = "testing")]
45mod fake;
46mod instances;
47mod logs;
48mod ports;
49mod reconcile;
50mod secrets;
51mod source;
52mod status;
53
54pub use docker::DockerCli;
55pub use effective::{
56    EffectiveEnv, EnvLayers, EnvValue, Layer, LayerValue, MASK, MaskedVar, Resolved,
57};
58pub use engine::{ComposeEngine, DownOptions, EngineStream, LogOptions, Progress, UpOptions};
59pub use error::{Error, Result};
60pub use events::{
61    EngineEvent, EventAction, EventFilter, PROJECT_LABEL, SERVICE_LABEL, parse_event,
62};
63#[cfg(feature = "testing")]
64#[cfg_attr(docsrs, doc(cfg(feature = "testing")))]
65pub use fake::{FakeCall, FakeEngine};
66pub use instances::{
67    INSTANCES_DIR, InstanceError, InstanceEvent, Instances, Materialized, PLACEMENT_KEYS,
68    ReconcileOptions, Reconciled, instance_project, parse_instance_project,
69};
70pub use logs::{LogLine, parse_log_line};
71pub use ports::{BusyPort, is_free, probe_host_ports};
72pub use reconcile::{ProjectMatch, managed_projects, remove_mesh_if_idle};
73#[cfg(feature = "keychain")]
74#[cfg_attr(docsrs, doc(cfg(feature = "keychain")))]
75pub use secrets::KeychainProvider;
76pub use secrets::{EnvProvider, SecretError, SecretProvider, SecretProviders, SecretValue};
77pub use source::{Overlay, Source, SourceCtx, SourceError, UserVars};
78pub use status::{Health, ProjectStatus, Published, ServiceStatus, State, parse_ls, parse_ps};