1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
//! Rust bindings for Apple's [Containerization] framework, which runs each
//! Linux container in its own lightweight VM, in-process and with no daemon.
//!
//! # Shape
//!
//! The Rust API mirrors Containerization's Swift API as closely as it can.
//! Modules are named after the Swift modules, types after the Swift types, and
//! methods after the Swift methods, in snake case. Within a module, the types
//! are grouped by what they work on, so `ImageStore` is in
//! `containerization::image` and `LinuxContainer` is in
//! `containerization::container`. A Swift type nested in another, like
//! `LinuxContainer.Configuration`, is in a module named after its parent, in
//! the parent's group: `container::linux_container::Configuration`.
//!
//! Swift's `async` methods block until they finish, and errors they throw are
//! returned as [`Error`].
//!
//! ```no_run
//! use containerization_framework as cfw;
//! use cfw::containerization as cz;
//! # fn main() -> Result<(), cfw::Error> {
//! let store = cz::image::ImageStore::new("/path/to/store".as_ref())?;
//! let kernel = cz::vm::Kernel::new("/path/to/vmlinux", cz::vm::SystemPlatform::LINUX_ARM);
//! let mut manager = cz::container::ContainerManager::with_initfs_reference(
//! &kernel,
//! cfw::versions::INIT_IMAGE,
//! &store,
//! Default::default(),
//! )?;
//! let image = store.get("docker.io/library/alpine:3", true)?;
//! let options = cz::container::container_manager::CreateOptions {
//! networking: false,
//! ..Default::default()
//! };
//! let container = manager.create("demo", &image, options, |config| {
//! config.process.arguments = vec!["/bin/sleep".into(), "infinity".into()];
//! Ok(())
//! })?;
//! container.create()?;
//! container.start()?;
//! let process = container.exec("ls", cz::process::LinuxProcessConfiguration::new(&["/bin/ls", "/"]))?;
//! process.start()?;
//! let status = process.wait(None)?;
//! process.delete()?;
//! container.stop()?;
//! manager.delete("demo")?;
//! # let _ = status;
//! # Ok(())
//! # }
//! ```
//!
//! # Requirements
//!
//! macOS 26 on Apple silicon, with Xcode 26 to build. The Swift package is
//! compiled by this crate's build script, which resolves Containerization and
//! its dependencies from the network on a first build.
//!
//! **A binary using this crate must be codesigned with the
//! `com.apple.security.virtualization` entitlement** to create a container. A
//! rebuild drops the signature, so after every build, sign the binary again
//! and pass this crate's `containerization.entitlements` to
//! `codesign --entitlements`.
//!
//! Elsewhere this crate compiles, so a cross-platform workspace builds, but
//! every call that would reach Swift fails with [`Error::Unavailable`]. Values
//! built purely in Rust work as usual.
//!
//! [Containerization]: https://github.com/apple/containerization
/// A Swift enum backed by strings: Rust's cases, each with its `rawValue`.
// The bridge's functions take Swift's arguments, however many there are.
pub use crateError;