Skip to main content

oxide_update_engine/
lib.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
5#![cfg_attr(doc_cfg, feature(doc_cfg))]
6// Setting html_root_url allows cross-crate readme links to resolve. This
7// line is updated by cargo-release.
8#![doc(html_root_url = "https://docs.rs/oxide-update-engine/0.1.0")]
9
10//! An engine for declaring and executing sequential update steps with
11//! serializable event streams.
12//!
13//! The `oxide-update-engine` crate provides the execution engine for
14//! running update steps.
15//!
16//! * For types-only consumers (e.g. API clients), see
17//!   [`oxide-update-engine-types`](oxide_update_engine_types).
18//! * For code to display update engine events as a human-readable
19//!   stream, see [`oxide-update-engine-display`](https://docs.rs/oxide-update-engine-display).
20//!
21//! # Examples
22//!
23//! A minimal engine that runs a single update step:
24//!
25//! ```
26//! use oxide_update_engine::{
27//!     StepSuccess, UpdateEngine, channel,
28//! };
29//! use oxide_update_engine::types::spec::EngineSpec;
30//!
31//! // A EngineSpec defines the domain-specific types that flow
32//! // through the engine. Use () for metadata you don't need.
33//! enum MySpec {}
34//! impl EngineSpec for MySpec {
35//!     fn spec_name() -> String {
36//!         "example".into()
37//!     }
38//!     type Component = String;
39//!     type StepId = usize;
40//!     type StepMetadata = ();
41//!     type ProgressMetadata = ();
42//!     type CompletionMetadata = ();
43//!     type SkippedMetadata = ();
44//!     type Error = anyhow::Error;
45//! }
46//!
47//! # #[tokio::main]
48//! # async fn main() -> anyhow::Result<()> {
49//! let log =
50//!     slog::Logger::root(slog::Discard, slog::o!());
51//! let (sender, _receiver) = channel::<MySpec>();
52//! let engine = UpdateEngine::new(&log, sender);
53//!
54//! // Steps run sequentially in registration order.
55//! engine
56//!     .new_step(
57//!         "fw".to_owned(),
58//!         1,
59//!         "Write firmware image",
60//!         |_cx| async {
61//!             // ... perform update work here ...
62//!             StepSuccess::new(()).into()
63//!         },
64//!     )
65//!     .register();
66//!
67//! engine.execute().await?;
68//! # Ok(())
69//! # }
70//! ```
71//!
72//! For more complex engines, including engines that have nested local and
73//! remote steps, see [the full
74//! example](https://github.com/oxidecomputer/oxide-update-engine/blob/main/e2e-example/src/main.rs).
75
76mod context;
77mod engine;
78mod errors;
79mod macros;
80
81pub(crate) use context::StepContextPayload;
82pub use context::{
83    CompletionContext, MetadataContext, SharedStepHandle, StepContext,
84    StepHandle, StepHandleToken,
85};
86pub use engine::{
87    AbortHandle, AbortWaiter, ComponentRegistrar, ExecutionHandle, NewStep,
88    StepResult, StepSkipped, StepSuccess, StepWarning, UpdateEngine, channel,
89};
90pub use errors::ExecutionError;
91pub use oxide_update_engine_types as types;