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
//! Isoloom's Docker Compose backend: the Compose file the `docker` and `hosted` targets run (and
//! the Docker-on-a-VM targets carry), at `.isoloom/docker/compose.yml`, with the files it mounts
//! and the `docker` target's run manifest.
//!
//! - Each network becomes a Compose network with its subnet (Docker at `.1`, or at the last
//! address when a machine is the network's gateway); `internet: false` makes it `internal`
//! when nothing routes between networks.
//! - A machine that is a network's gateway gets forwarding and `NET_ADMIN`; the machines
//! behind it route everything through it (in a sidecar, once it answers).
//! - Each machine becomes a service with its fixed address on every network; services find
//! each other by name (Compose DNS).
//! - Machines with services get a healthcheck (a TCP probe, and the machine's own `healthcheck`
//! beside it), so `depends_on` waits for them to answer and `docker compose up --wait` means
//! "everything answers". The probe is Isoloom's own static busybox (a one-shot
//! `isoloom-probe-<arch>` copies it into a volume), so it needs nothing from the image:
//! distroless and `scratch` machines work too.
//! - `init:` scripts run once, in one-shot containers of the machine's image on its networks,
//! after it answers; machines depending on it wait for them to finish.
//! - Inputs become environment variables read from the shell (`${NAME:-}`), only on the
//! machines that list them.
//! - Checks run in a `check` profile, one runner per position (`isoloom-check` where a user
//! stands, `isoloom-check-<machine>` for the others), each a sh script in `checks/`.
//! - A service's `publish` port is published on the host's loopback (127.0.0.1) only, on an
//! ephemeral host port Docker picks, so two labs publishing the same port never collide; the
//! runner reads the real port back from `docker compose ps`. `ISOLOOM_PUBLISH_ADDRESS`
//! overrides the address and `ISOLOOM_PUBLISH_FIXED` pins the host port to `publish` (both
//! set inside the docker-vm and cloud VMs, where the lab is alone and that fixed port is
//! forwarded from loopback).
//! - `volumes:` become named volumes: they survive re-creating a container, and go with
//! `docker compose down -v`.
//! - Network appliances (`docker.appliance`) run router and switch OSes in containers, wired
//! the way their image expects.
//!
//! It sits with the other backends, above the rendering layer (`isoloom-render`) and below the
//! targets' registry (`isoloom-targets`), and depends on no other backend: [`ComposeBackend`]
//! renders a planned [`Environment`](isoloom_plan::Environment), purely, into files, through
//! typed Compose structs. [`hybrid`] adapts the same file to the `hybrid` target's Docker host,
//! and [`start_plan`] reads back how to start a file an embedder holds.
//!
//! # Example
//!
//! ```
//! use isoloom_compose::{ComposeBackend, start_plan};
//! use isoloom_plan::{Environment, Lab};
//! use isoloom_render::backend::Backend;
//! use isoloom_spec::model::Target;
//!
//! let lab = Lab::new(isoloom_spec::parse(
//! "version: 1
//! name: hello
//! networks: { lan: { cidr: 10.9.0.0/24 } }
//! machines:
//! web: { networks: { lan: 10 }, ports: { web: 80 }, app: { image: nginx } }
//! ",
//! )?);
//! let env = Environment::build(&lab.for_target(Target::Docker), Target::Docker, None);
//! let files = ComposeBackend(Target::Docker).render(&env)?;
//! let compose = files.iter().find(|f| f.path == ".isoloom/docker/compose.yml").ok_or("no Compose file")?;
//! assert!(compose.contents.contains("ipv4_address: 10.9.0.10"));
//! // Nothing runs once and exits: everything is waited for.
//! assert_eq!(start_plan(&compose.contents)?.jobs, Vec::<String>::new());
//! # Ok::<(), Box<dyn std::error::Error>>(())
//! ```
pub use ;
pub use ;
pub use ;
pub use render;
pub use ;