Skip to main content

Crate gunnar_server

Crate gunnar_server 

Source
Expand description

The gunnar git server: everything that used to live behind gunnar-cli’s --features server, now its own crate.

Nothing in here may reach gunnar-client except the client-gated [mirror] module (replication’s send-pack). That edge is what would drag gix’s worktree, status and index machinery into an appliance image, and it is asserted absent from a resolved dependency graph in gunnar-cli/tests/feature_split.rs.

Re-exports§

pub use storage::encrypted_quarantine;
pub use attest::AttestationLog;
pub use attest::ATTESTATION_LOG;
pub use control_plane::CoreControlPlane;
pub use grpc_gate::activity_ledger;
pub use grpc_gate::control_audit_ledger;
pub use grpc_gate::control_transfer_gate;
pub use serve::GrpcTls;
pub use serve::ServeConfig;
pub use serve::Server;
pub use stores::ServerStores;
pub use stores::CONTROL_DB;
pub use stores::CONTROL_DIR;
pub use transport::WireConfig;
pub use transport::WireTransport;

Modules§

account_audit_sweep
The account audit logs’ retention sweep (2026-10-05). The account audit logs’ retention sweep (2026-10-05): every few hours, each account’s log drops the days past its retention (a year by default), so an account nothing happens in for a while does not keep entries the promise says are gone. An append does the same for its own account first; this is the rest. Never on a twin: its control store is a replica, and the primary’s sweep reaches it as transactions.
account_purge
What emptying an account means, in one place: the four classes of bytes a user owns and the walk that reclaims them. What emptying an account actually means, in one place.
admin
The administrative verbs: namespaces, repositories, principals, keys, grants, and gc.
attest
The attestation log, on the server’s own store.
blame
Whole-file blame: verify’s line→commit link 1, done once for every line of a file. Reuses verify’s tree/blob and parent readers and the diff engine (one implementation). gunnar blame — who wrote each line, walked backwards.
boot
Gunnar’s end of PID 1. The jobs an operating system used to do for the server (signals, reaping, the network, DHCP, the stop and the power-off) are edda’s appliance-pid1, shared with Holger; this is what Gunnar says about itself to it (GUNNAR_NET, the host name, the narration tap, GN-99). Gunnar’s end of PID 1. Everything an OS-less PID 1 owes the kernel — the signals, the reaper, the netlink writer, the DHCPv4 client and its renewal, the resolver file, the stop sources and the power-off, the install record, the graphics-console mirror, the boot narration’s secret door, the panic as a fault — is edda’s appliance-pid1 (0.1.5, lanes G4 and G6), the one PID 1 Gunnar and Holger both run. Gunnar’s own pid1.rs and dhcp.rs were moved there whole and deleted here (lane L10).
budget
The declared budgets — concurrent transfers, open repository handles and the git memory budget — derived from cores + RLIMIT_NOFILE + MemAvailable and named in one INFO row at start. The replacement for the three emergent ceilings of 2026-08-29 (19, 25, 256). The declared budgets: how many git transfers may be in flight, how many repository handles may be open, and how much memory the two of them may hold — every one of them derived from the box and said out loud at start.
capacity
Admin.Capacity: “if a tenant’s cap rose to N bytes, could you serve it?” — the question monetize must ask before it buys a disk. Answers with a verdict measured off the SAME statvfs the push door refuses under, and, independently, whether this data set can ever grow at all: the appliance is SEALED (an md set laid once at install, no runtime growth path, PID 1 with no shell), so a disk bought for it is billed and invisible. “If a tenant’s cap rose to N bytes, could you serve it?” — Admin.Capacity.
clock
The fourth of those jobs, added 2026-09-14: the wall clock. The appliance booted two hours fast and refused every genuine credential and every Stripe webhook for it; UDP/123 is closed on that network, so “now” arrives in the Date header of an HTTPS response, from three sources that must agree. The appliance’s wall clock: glue between PID 1 and edda estate-clock.
control_plane
gunnar-grpc’s ControlPlane seam, over gunnar-core and gunnar-store: the adapter its module docs asked for.
dashboard
The VGA-console status screen the appliance draws as PID 1 (header band + rolling events off the log tap). The console dashboard: what a human sees on the appliance’s VGA screen (/dev/tty0) when the box is otherwise dark — a Talos-style status band and a rolling list of what the server is doing.
diff
The tree diff Refs.Diff serves (the event stream).
disktest
The start-up disk test: what /data can actually do, said once on the screen.
durable
The start-up disk test the appliance runs on /data (seq write/read, 4 KiB fsync ops) — one disktest row on the screen. One place that writes a small control file durably.
feed
The estate values the installer’s door feeds (monetize key, clock key and peer), taken instead of the medium’s — see the module. The estate values the installer’s door FEEDS, taken instead of the medium’s — so one medium serves any estate.
first_commit
A repository’s first commit, written by the server (Repos.Create{readme}). A repository’s first commit, written by the server (the owner, 2026-10-08: a sold private Gunnar is handed over with ONE welcome repository whose README thanks the buyer and says how to start — with no git client anywhere in the sale).
gc_queue
One gc at a time, for the whole box — the queue behind Repos.Gc. One gc at a time, for the whole box.
glance
The machine at a glance (StorageReality.glance, 2026-10-04): the Machine card’s lines, decided here. The machine at a glance (StorageReality.glance, owner 2026-10-04): the four lines the console’s Machine card shows — /data’s shape, the off-stripe copies on /serialdat, the free space, the disk speed — each with gunnar’s own verdict.
grow
The runtime data-set growth (DATA-SET-GROWTH-FLOW.md §3): the phase machine over a World seam, the go-ahead, and — with grow-runtime — the appliance world that links edda’s engine. The runtime data-set growth — /data grows WITHOUT a restart (private-gunnar-ops/DATA-SET-GROWTH-FLOW.md §0 ruling 1, §3; the torture test’s T1, T2, T6, T9, T11 are binding).
grpc_gate
The control plane’s one transfer, on the same gate as git — one implementation, not a second gate.
identity
The identity core’s Gunnar host, built at the start (IDENTITY-HOST). The identity core, built at the start (IDENTITY-HOST, 2026-10-27): edda’s nornir_identity::Identity over gunnar_grpc::identity::GunnarHost. Its own records (sessions and invites as hashes, the floors, the sign-up state) live in <data root>/identity.json, written atomically and framed in the transaction log like every other document, so a twin holds them too. Mail: none (airgap) — an invite’s link is handed over, and a sold estate’s first-login link is the shop’s to mail.
import_room
An import’s memory against the memory this server may really use (IMPORT-2): the box’s MemTotal or the cgroup’s memory.max, a named refusal before an index that would not fit, and the cgroup’s memory in the shape the indexer’s guard reads. An import’s memory, against the memory this server may really use (IMPORT-2, 2026-10-27).
job_queue
One worker, one job at a time, FIFO, deduplicated by subject — the runner gc_queue and purge_queue are two kinds on, and the hook a third kind plugs into without editing it. One worker, one job at a time, FIFO, deduplicated by subject — for any kind of job the box has to do slowly.
layout_config
The layout config (/boot/korp/layout.conf): what the installer decided, written down and sealed by the thing that did the deciding. gunnar is TOLD where its storage is and obeys; it never surveys disks, an absent config is answered as absent rather than inferred, and an unsigned one is never presented as verified. The layout config: gunnar is TOLD where its data lives, and obeys.
limits
The descriptor limit: raised once (PID 1 to a million, anyone else to its hard limit), and the open-repository handle cache sized to fit under it. The fix for the rig’s “202nd repository” EMFILE (2026-08-29). The descriptor limit: raised once, read once, and the handle cache sized to fit under it.
live_update
Live update (owner 2026-10-12): what this box runs, a new app staged, the graceful re-exec, the confirm — generic primitives over korp-installer’s live. Live update, gunnar’s side (owner 2026-10-12, TURNAROUND §8) — generic primitives only; the decisions are korp-installer’s (korp_installer::live), the wire is nordisk-pairing’s (nordisk_pairing::live, the installer’s log door, its own certificate only):
mirror_fetch
What a mirror sync does: one gunnar-wire fetch_pack over one of two transports, and one compare-and-swap that moves the references. What Mirror.Sync actually does: one fetch from an upstream, into this box’s own storage engine, and one compare-and-swap that moves the references.
mirror_queue
One mirror sync at a time, for the whole box — the third kind on the one runner, and the queue behind Mirror.Sync. One mirror sync at a time, for the whole box.
narrate
The fifth of those jobs, added 2026-09-23: saying where the boot is. boot::ship_boot_narration ends at end of hand-off and the estate’s twin died in the silence after it; this is the narrator that speaks from there on — a stage line at every boundary, a tick a minute, and a fatal fault that sends a stable code, waits to be heard and then powers the box off cleanly. The app’s half of the boot narration: stages, ticks and fault codes.
oci
The artifact registry and the OCI images it holds. The artifact registry, and the images it holds (roadmap phase 4).
purge_queue
One account purge at a time, and the lockout always comes off. The Accounts.Purge queue; see its module docs for why it is its own line and not the gc one. One account purge at a time, and the lockout always comes off.
push_space
The receive path’s half of space admission (gunnar_ssh::space): the reader a pushed (or mirrored) pack is read through, which asks the data set’s ledger before every chunk it hands on, and the sweep of spool files a crash left behind.
readiness
The boot window: whether the stores have finished their post-crash work, and the retryable starting answer a client gets until they have. The 0.6-0.7 s of the repository is unavailable; try again after a power cut. Is this server ready to serve git? — one flag, set once, and the honest answer while it is clear.
registry
The registry’s one rule: no artifact without valid, logged provenance. The registry’s one rule (roadmap phase 4).
replication_view
What replication looks like from outside it — the one shape the console band, Admin.Stats and the log all read.
runner
The build runner: checkout, sandbox, artifacts, signed provenance. The build runner (roadmap phase 3).
sandbox
The build sandbox: a network namespace of the build’s own, unprivileged. The build sandbox: no network, by construction (roadmap phase 3).
scrape
The counters over HTTP. Opt-in; binds nothing by default. The counters, over HTTP: one opt-in read-only listener that answers “is it slow or is it stuck” without perf and without a restart.
search
Latest-revision literal code search: walk the tree at a ref, scan text blobs. Bounded by a file-size and a match ceiling; not a persistent index. gunnar search — a literal string, across one revision’s files.
serve
gunnar serve starts its listeners together and stops them together. They share nothing but the control plane behind them.
slow
The slow disk (/serialdat): the other spindle, and the other failure domain. One code path whatever is underneath it, and a three-valued claim — off-stripe, same-device, unverified — over the three copies that are supposed to outlive losing a data disk. Where each kind of data goes, and what gunnar may claim about it.
sso_import_queue
The directory import on its own jera lane (A34-17). The directory import, one per account at a time, on its own jera lane (A34-17).
stop_record
The last stop, kept where it survives the stop (2026-10-01, the real test2 run 9: vm1 stopped cleanly, but its power-off steps were lost — the narration and the disk log die with the read-only remount of /data — and UpCloud reported stopped 46 s after the soft stop, so nobody could tell the guest’s power-off from the provider’s reporting). After the quiesce and just before the power goes, ONE line is written on the ESP (its own filesystem, flipped read-write for that write); the next boot says it at INFO and removes it.
storage
The znippy cold tier, wired where objects enter the server. Which storage engine this binary carries, and which one it is running.
stores
Where the server’s state lives on this box, and the one place a repository is turned into a pair of stores.
tls_preflight
Can this control plane be moved onto mutual TLS, and who does it cost? The one preflight gunnar serve --grpc-tls-self refuses on and gunnar issuer readiness asks in advance. Moving a control plane onto mutual TLS, after it has been enrolled.
topology
Admin.Topology’s facts from this server: the pairing feed, the front’s principals, the plugin registration (2026-10-04). Admin.Topology’s facts from this server (2026-10-04): what only gunnar-server holds — the installer’s pairing feed (joined.toml) with the ESTATE RECORD it carries (the estate.* keys: every box as the kit laid it), which principals run on the front, the plugin registration, this box’s own data volume. The assembly and every verdict are gunnar_grpc::topology’s; this module only reads.
transport
The join. gunnar-ssh’s GitTransport seam, implemented over gunnar-wire’s state machines, with gunnar-wire’s PushGate seam implemented over gunnar-policy’s engine.
tunnel_addr
Where the WireGuard tunnel is, for the listeners that follow it (owner’s ruling 2026-09-22, amended 2026-09-24): the mutual replication listener (:50052) answers on the outer address (eth1) for the process lifetime and, once the tunnel is up, ALSO on wg0’s address (replication_extra). :50051 does not move.
twin
The twin: follows the primary’s transaction log, applies it, restores from it. The twin: the box that holds every transaction the primary was told, in order, durably, and is never promoted. .nornir/twin-transaction-log.md §“The twin’s loop”.
twin_tls
The twin’s mutual-TLS credential: minted at pairing, never on the medium. The twin’s mutual-TLS credential, minted at PAIRING and never on the medium.
txlog_lfs
The LFS tee: an object is a transaction-log frame before it is published. The LFS tee: an LFS object is a frame in the transaction log before the store publishes it. The fourth decorator of .nornir/twin-transaction-log.md; the other three live in gunnar_core::txlog::tee, and this one is here because the server is the crate that sees gunnar-lfs.
usage_ledger
The usage ledger (2026-10-06): every namespace’s stock meters, re-measured only where something changed — what UsageBatch.ReadMany answers from. The usage ledger: every namespace’s stock meters, kept current by re-measuring only what changed (2026-10-06).
verify
gunnar verify — the unbroken chain, walked backwards from a line of source. gunnar verify — the unbroken chain, walked backwards.

Constants§

SERVER_ALLOCATOR
The value to declare. See ServerAllocator.

Functions§

functional_status
Record one functional-status row for the nornir test matrix.
run
Dispatch a server verb. The one entry point both this crate’s binary and gunnar-cli’s run() route server commands through, so the wiring lives exactly once (one implementation).

Type Aliases§

ServerAllocator
The allocator every gunnar that serves is built on.