Gunnar

nordisk/edda

crates/jera/Cargo.toml

[package]
name = "jera"
version = "0.2.1"
edition = "2021"
rust-version = "1.85"
description = "Shared infra runtime extracted from nornir: the durable job ledger + a no-shell container (bollard/podman REST) and KVM/VM boot runtime. Reused by nornir and korp."
license = "MIT OR Apache-2.0"
repository = "https://git.gunnar.rs/nordisk/edda"
keywords = ["jobs", "ledger", "container", "bollard", "kvm"]
categories = ["development-tools", "database"]
# Development notes, agent instructions and machine-local tooling stay in the
# repository; they are not part of the published crate.
exclude = [
    ".nornir/",
]

[features]
# Lean by default: NO container/VM backend linked. The `container`/`vm` modules +
# their delegation seams (mapping onto draupnir) always compile; the LIVE engines
# are opt-in behind `container-oci` / `vm-tunnr`, both routed THROUGH draupnir — the
# ONE bollard/podman + KVM engine for the constellation. jera never rolls its own.
# `runners` (lane B4): `boot`, `container` and `vm`, the runners that boot a job's
# instance through draupnir. In the default; a ledger-only consumer (Holger)
# takes `default-features = false` and links no draupnir.
default = ["runners"]
runners = ["dep:draupnir"]
# The REAL KVM boot backend — routed THROUGH draupnir (the shared boot library),
# which drives tunnr's `tunnr_vm::boot_test` primitive. jera never calls tunnr
# directly: the one KVM boot path in the constellation lives in draupnir. The `vm`
# module + its seam always compile (honest stub); this enables draupnir's KVM
# backend. Kept named `vm-tunnr` for back-compat (nornir forwards this feature).
vm-tunnr = ["runners", "draupnir/backend-tunnr"]
# The REAL OCI container boot + run-to-completion routed THROUGH draupnir (the
# shared boot library), which owns the ONE bollard/podman REST engine for the
# constellation. jera has NO second engine: with this on, `connect_default_runner`
# returns the `DraupnirContainerBootRunner` and `run_container` runs through
# `draupnir::container::run_to_completion` — exactly as a VM boot job goes through
# draupnir's KVM backend (`vm-tunnr`). The `container` module + its delegation seams
# always compile (daemon-free testable via draupnir's `Boot`/`ContainerControl`
# traits); this enables draupnir's live engine. OFF by default (lean std build).
container-oci = ["runners", "draupnir/backend-oci"]
# The multi-machine agent WIRE: a tonic gRPC `GrpcTransport impl AgentTransport`
# (client) + an `AgentWorker` server over a `LocalAgent`. OFF by default so the lean
# build never links tonic/prost — nornir/dwarves/holger consume jera unchanged.
# The Scheduler/match/kill semantics are already proven against the LoopbackTransport;
# this only adds the socket. The secured serve path (`serve_authed`) + bearer client
# (`connect_with_token`) compose `nornir-service`'s auth interceptor + serve loop —
# the wire auth is NOT re-rolled (LAW #5). See src/agent_grpc.rs.
agent-grpc = ["dep:tonic", "dep:prost", "dep:tonic-prost", "dep:nornir-service"]

[dependencies]
# gRPC agent transport (feature `agent-grpc` only). client=talk to a remote worker;
# server=run one. default-features off keeps it lean when the feature is on.
tonic = { version = "0.14", features = ["transport", "codegen", "server", "channel"], optional = true }
prost = { version = "0.14", optional = true }
tonic-prost = { version = "0.14", optional = true }
# The ONE shared bearer-auth interceptor + tonic serve loop (LAW #5) — the wire
# auth for the agent transport is composed, never hand-rolled. agent-grpc only.
nornir-service = { version = "0.1.10", path = "../nornir-service", optional = true }
# The ONE shared `Zone` primitive (platform-level environment axis) — a jera
# container job is tagged with its zone via `ContainerSpec::with_zone`. Dep-light
# leaf (std-only, zero runtime deps); path+version like the other edda siblings.
nornir-zone = { version = "0.1", path = "../nornir-zone", default-features = false }
anyhow = "1"
redb = "2"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
chrono = { version = "0.4", features = ["serde"] }
uuid = { version = "1", features = ["v4", "serde"] }
tempfile = "3"
# The job ledger's exclusive-scheduler gate uses a tokio Semaphore. Non-optional
# (the ledger always needs it); the container/VM engines live in draupnir.
tokio = { version = "1", features = ["sync", "macros", "rt-multi-thread", "time"] }
# Process-group SIGKILL for the Exe boot mode (spawning a *built binary*, not a
# container/VM — those are driven over Rust APIs only).
libc = "0.2"
# ── draupnir — the shared low-level boot/provisioning library ──
# jera's VM/container legs delegate instance-firing to draupnir instead of re-rolling
# it. Lean by default (draupnir's default build is pure-std, zero deps); the
# `vm-tunnr` feature turns on draupnir's KVM backend, so jera's VM boot goes THROUGH
# draupnir (which drives tunnr) — never a direct tunnr call from jera. Path dep
# (offline workspace); switch to a version once draupnir publishes to crates.io.
# >= 0.1.7 required: jera's container job carries published ports + full-machine
# resource caps (`cpus`/`mem_limit_mb` → podman `--cpus`/`--memory`) which landed on
# draupnir's `BootSpec` in 0.1.7 (exec + `ExecOutcome` landed in 0.1.6).
draupnir = { path = "../../../draupnir", version = "0.2", default-features = false, optional = true }

[build-dependencies]
# Pure-Rust proto codegen (no protoc); the codegen call in build.rs is gated on
# CARGO_FEATURE_AGENT_GRPC, so a lean build parses no proto.
tonic-prost-build = { version = "0.14" }
protox = "0.9"

[dev-dependencies]
tempfile = "3"