Skip to main content

olai_stack_state/
lib.rs

1//! The shared trestle state store.
2//!
3//! One SQLite database under the [trestle home](trestle_home) (`$TRESTLE_HOME`, else the
4//! platform data directory), shared by the `trestle` CLI and the desktop app. It holds:
5//!
6//! - [`Workspace`]s: sets of environments sharing a host, with their [`VarSet`]s.
7//! - [`Environment`]s: an editable [`Draft`] (the placement-free `env.toml`, the
8//!   `module.yaml` texts it lists, vars) and a head.
9//! - [`Revision`]s: numbered, immutable snapshots of a draft with a digest. Nothing in the
10//!   API changes one, and the database refuses an update.
11//! - [`Instance`]s: a revision to run, whether it should run, overrides and the overlay
12//!   [sources](SourceBinding) it takes.
13//! - [`SlotLease`]s: host-wide, so two instances never share a slot whatever their
14//!   workspace (slots per workspace clashed across workspaces).
15//!
16//! Secrets are stored as [`SecretRef`]s only; their values stay with their provider.
17//!
18//! Several processes use the store at once: writes are serialized (a writer waits for
19//! another's), and a [`Watcher`] notices commits made elsewhere. A store with a newer schema
20//! than this crate knows is refused ([`Error::UnsupportedVersion`]).
21//!
22//! `trestle-workspace.toml` and environment directories stay as an exchange format:
23//! [`Store::import_workspace`] drops placement (the store leases slots itself), and
24//! [`Store::export_instances`] and [`Store::export_workspace`] write slots, so the exported
25//! directory runs with `docker compose up` like any workspace.
26//!
27//! ```no_run
28//! use olai_stack_state::{Draft, Store};
29//! use olai_stack_topology::{EnvManifest, PlanCtx, Selection};
30//!
31//! # fn run() -> olai_stack_state::Result<()> {
32//! let store = Store::open_default()?;
33//! let ws = store.create_workspace("demo", false)?;
34//! let manifest = EnvManifest::new(Selection::modules(["unity-catalog"]), PlanCtx::default());
35//! let env = store.create_environment(&ws.id, "dev", Draft::new(manifest))?;
36//! let rev = store.commit_draft(&env.id)?;
37//! let instance = store.create_instance(&env.id, rev.number())?;
38//! let lease = store.lease_slot(&instance.id)?;
39//! println!("dev r{} on slot {}", rev.number(), lease.slot);
40//! # Ok(())
41//! # }
42//! ```
43
44mod error;
45mod model;
46mod store;
47mod transfer;
48mod watch;
49
50pub use error::{Error, Result};
51pub use model::{
52    Desired, Draft, Environment, EnvironmentId, Instance, InstanceId, Revision, SecretRef,
53    SlotLease, SourceBinding, VarScope, VarSet, VarValue, Workspace, WorkspaceId,
54};
55pub use store::{DB_FILE, SCHEMA_VERSION, Store, TRESTLE_HOME_VAR, trestle_home};
56pub use transfer::{ENV_FILE, read_env_dir};
57pub use watch::Watcher;