Expand description
The target-neutral plan of a lab: the authored spec lowered for a target (Lab, lower),
then planned into the Environment a backend renders (networks, machines, their addresses,
routes, volumes and set-up steps), its checks resolved to positions and probes, and the
requirements a backend must meet to render it.
It sits between the spec (isoloom-spec, below) and the rendering layer and backends
(isoloom-render and up), and is a functional core: every function here is pure over the
spec, with no I/O, clock or environment, except Lab::problems_with_files, which looks at
the project folder it is given.
§Example
use isoloom_plan::{Environment, Lab, MachineShape};
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: { site: 80 }, app: { image: nginx } }
",
)?);
assert!(lab.problems().is_empty());
assert!(lab.possible().contains(&Target::Docker));
let env = Environment::build(&lab.for_target(Target::Docker), Target::Docker, None);
let web = env.machines.get("web").ok_or("web is planned")?;
assert_eq!(web.shape, MachineShape::Container);
assert_eq!(web.addresses.get("lan").map(ToString::to_string).as_deref(), Some("10.9.0.10"));Re-exports§
pub use environment::Build;pub use environment::Controller;pub use environment::Environment;pub use environment::Image;pub use environment::MachinePlan;pub use environment::MachineShape;pub use environment::NetworkPlan;pub use environment::PublishedPort;pub use environment::Route;pub use environment::Settings;pub use environment::Size;pub use environment::Volume;pub use environment::VolumeKind;pub use lab::Lab;pub use lab::problems_in;pub use lifecycle::MachineLifecycle;pub use lifecycle::Step;pub use outside::Join;pub use outside::OutsideAddress;pub use outside::OutsideNetwork;pub use private_dns::PrivateDns;pub use process::Health;pub use process::HealthTest;pub use process::Process;pub use requirements::Capabilities;pub use requirements::Feature;pub use requirements::Refusal;pub use requirements::Requirement;pub use requirements::refusal;pub use secrets::SecretFile;pub use secrets::ValueSource;pub use storage::DataDisk;pub use storage::Lifetime;
Modules§
- addressing
- Where every machine sits: its address on each network, the address another machine reaches
it at, its names, and the order machines start in. Pure functions of a validated spec, shared
by the plan and every backend (re-exported by
isoloom-render). - ansible
- What Ansible needs to know about an environment, whatever the target: the inventory groups
(the
provision:steps’groups:and the spec’s owngroups:) and each machine’shost_vars. How a target reaches its hosts (users, keys, WinRM) is the renderer’s business (isoloom_render::inventory). - boot
- A VM’s own image and boot, as the plan carries them: which machines boot their own way (a requirement only some backends meet), and the network boots each network serves.
- checks
- Checks: what proves an environment behaves as its spec says, on every target.
- configure
- The configuration model resolved (PLAN §3, design
plan/phase4/design.md§1–§3): what a machine’s recipe is once its OS, its ports and the daemon table have been read, with nothing left to resolve. The CM renderers (isoloom-render::configure: the shell and PowerShell libraries, the Dockerfile, cloud-init, Ansible) render aRecipe; they never read the authored steps. - environment
- The environment as one target builds it: every fact a backend needs, resolved once from a validated spec (addresses, names, routes, published ports, volumes, settings, images, start order, checks, requirements), so backends render the same decisions instead of each re-deriving them from the spec.
- hardware
- What a machine asks of the hardware under it (
gpus,devices,nested_virtualization), and what that requires of the backend, by the machine’s shape on the target: a container gets the host’s GPUs and devices from its runtime, a VM gets GPUs passed through or sized in and runs VMs of its own through its hypervisor. An existing host is used as it is. - images
- Which image a machine pulls: the spec’s
constraints.registriessend each pull through its registry’s mirror, decided here once so a backend writes the final reference instead of patching its output afterwards. - ipv6
- IPv6: each network’s IPv6 block, each machine’s IPv6 address (derived from its octet, or
left to the target), the router’s IPv6 addresses and the IPv6 routes through it. Pure
functions of a validated spec, beside their IPv4 counterparts in
addressingandrouting. - lab
- A lab: a spec as its author wrote it, ready to be planned for any target. It lowers the spec once per target (with the runner’s image table, when one is given), says which targets can run it, and validates it: the authored spec’s own checks, then those of its lowered form, each problem reported at the field the author wrote.
- lifecycle
- A VM’s set-up, as an ordered list of steps every VM backend runs the same way. The plan says
what each step does;
isoloom-render’sstepsmodule writes each one as Linux shell (and PowerShell where Windows has it); a backend only picks the transport (a Vagrant provisioner, cloud-init,remote-exec, WinRM). - links
- A network’s
mtuand a machine’srate_limit: what they ask of a backend, and why one without them refuses. Only the proxmox target sets them (on its network devices) for now. - lower
- Lowering: the spec as an author writes it (
isoloom_spec::syntax) into the form the plan and the backends read (isoloom_spec::model), once per target. A machine keeps every form it has (each target picks the one it runs, both onhybrid); the overrides of the target being lowered fill in its platform facts; and a machine the target can’t run is a refusal naming the field that rules it out (machines.web.app.build), never a silent stand-in. - machine_
files - A machine’s
filesin the plan: the VM set-up step that places them, and what they ask of a backend. A container gets them from its runtime (a Compose config, aConfigMapcopied into place on Kubernetes), a VM from itsStep::Filesstep, after the project is unpacked (a file’ssourceis read from there). - more_
addresses - A machine’s several addresses on one network (
networks: { lan: [10, 11, 12] }): the addresses after its primary one, where a VM’s set-up puts them (on the interface that holds the primary one), and why a target that can’t give them refuses. - outside
- Networks outside the environment: an existing network the machines join by name
(
external), or the host’s own LAN through a bridged interface (bridged). The plan keeps them apart from the environment’s own networks: the router, the controller, the checks and every target’s own networks never see them, and a machine’s place on them is an extra interface after its own networks. A target renders them, or refuses them through its capabilities (requirements). - private_
dns - The environment’s private DNS zone (
dns.private): every machine’s name andaliasesunder the zone’s domain, at its first address. The clouds with a DNS of their own write the zone and its records; the Docker targets give the names to Docker’s DNS as network aliases; every VM’s hosts file carries them too, so they resolve where the platform has no DNS to serve them (Vagrant, Proxmox, DigitalOcean, Linode) and before a cloud’s zone answers. - process
- What a machine runs and when it is healthy, resolved once for every target: its command, the directory it runs in, and its healthcheck with every pace in seconds (Kubernetes counts in seconds; Compose and the VM scripts are given the same).
- requirements
- What an environment asks of a backend, and what a backend offers. A backend refuses an environment when it lacks the capability one of its requirements needs: the refusal comes from the plan, without generating anything.
- routing
- How traffic crosses networks: Isoloom’s router (a machine on every network it routes, at the
last address, when
reachrules need one) or a machine named as a network’sgateway. Facts only;isoloom-render’sroutermodule renders them (routes as commands, the nftables ruleset, netem) and re-exports these. - secrets
- A machine’s secrets as files: which secret, at what path, owned by whom, with what mode.
The plan never holds a value:
isoloom runreads each from its store and hands it to the target’s own mechanism (Compose secrets, a Kubernetes Secret). - storage
- A machine’s storage beyond its root disk, as every target reads it: how long a volume lives (with the environment, past it, or already there), its data disks with their filesystem resolved for its OS, and what that storage asks of a backend.
Enums§
- Error
- Why the plan can’t use a value it was given.