Add the service archetype and a builder for a rented host #59

Closed
opened 2026-08-31 03:41:34 +01:00 by vnprc-agent · 2 comments

Add service as a fourth archetype and the builder that composes it, so a rented internet-facing host can be built the same way every other machine is.

Primary goals:

  • A fourth archetype beside dev, hypervisor and privacy.
  • A builder shaped like mkHypervisor — no runtime, no guest module, because nothing in this fleet runs the machine.
  • Composed from what already existsmodules/public-host.nix and modules/static-site.nix are already here and already tested.

What exists already

modules/public-host.nix provides the base: Caddy with ACME, administrative SSH on a caller-chosen non-standard port with keys only, fail2ban, and a firewall opening 80, 443, the administrative port, and whatever a service contributes. A service contributes a virtual host and its ports and nothing machine-wide.

modules/static-site.nix, nix/build-zola-site.nix and the four static-site checks are also here. So the first consumer of this archetype is already written and verified; only the builder and the archetype registration are missing.

flake.nix carries a comment where mkServiceVm used to be, explaining why a builder was not written earlier: the shape was unknown from a single machine, and a rented host has no inventory representation. The first is now answered — see below. The second is tracked in allod/inventory.

The builder's shape

mkDevVm and mkPrivacyVm take runtime ? machines.${name}.runtime and map it to a libvirt or microvm guest module, failing when there is none. mkHypervisor takes no runtime at all, because nexus is bare metal and no guest module applies.

A rented host is the same shape as mkHypervisor in the only respect that matters here: nothing in this fleet runs it, so there is no guest module to select. That is the template. It differs from a hypervisor in owning no guests, so the microvmGuests machinery does not apply either.

Expect this to be small — the interesting decisions are all in the modules it composes and in the registry it reads.

Depends on

allod/inventory must first accept a machine with no runtime under the service type, and constrain such machines to x86_64-linux. Reasoning and the rejected alternatives are recorded there. This builder cannot read a machine the registry refuses to describe, so that lands first.

Scope

In scope: registering service in the archetype names the framework validates, the builder, and a check exercising it.

Not in scope: any actual machine. The first service machine is a profile entry in a profiles repository, added once its host is rented.

Refs #55, #56, #57.

Add `service` as a fourth archetype and the builder that composes it, so a rented internet-facing host can be built the same way every other machine is. Primary goals: - **A fourth archetype** beside `dev`, `hypervisor` and `privacy`. - **A builder shaped like `mkHypervisor`** — no `runtime`, no guest module, because nothing in this fleet runs the machine. - **Composed from what already exists** — `modules/public-host.nix` and `modules/static-site.nix` are already here and already tested. ### What exists already `modules/public-host.nix` provides the base: Caddy with ACME, administrative SSH on a caller-chosen non-standard port with keys only, fail2ban, and a firewall opening 80, 443, the administrative port, and whatever a service contributes. A service contributes a virtual host and its ports and nothing machine-wide. `modules/static-site.nix`, `nix/build-zola-site.nix` and the four static-site checks are also here. So the first consumer of this archetype is already written and verified; only the builder and the archetype registration are missing. `flake.nix` carries a comment where `mkServiceVm` used to be, explaining why a builder was not written earlier: the shape was unknown from a single machine, and a rented host has no inventory representation. The first is now answered — see below. The second is tracked in `allod/inventory`. ### The builder's shape `mkDevVm` and `mkPrivacyVm` take `runtime ? machines.${name}.runtime` and map it to a libvirt or microvm guest module, failing when there is none. `mkHypervisor` takes no `runtime` at all, because nexus is bare metal and no guest module applies. A rented host is the same shape as `mkHypervisor` in the only respect that matters here: nothing in this fleet runs it, so there is no guest module to select. That is the template. It differs from a hypervisor in owning no guests, so the `microvmGuests` machinery does not apply either. Expect this to be small — the interesting decisions are all in the modules it composes and in the registry it reads. ### Depends on `allod/inventory` must first accept a machine with no `runtime` under the `service` type, and constrain such machines to `x86_64-linux`. Reasoning and the rejected alternatives are recorded there. This builder cannot read a machine the registry refuses to describe, so that lands first. ### Scope In scope: registering `service` in the archetype names the framework validates, the builder, and a check exercising it. Not in scope: any actual machine. The first service machine is a profile entry in a profiles repository, added once its host is rented. Refs #55, #56, #57.
Member

Closing: the service archetype was built, reviewed four times, and abandoned. allod/archetypes#60 carries the full reasoning; the short version is that this repo predicted the outcome before the work started.

The note above builders said a service builder would "either invent [an inventory concept] now or take every value as an argument, which is a builder in name only." Four review rounds produced exactly that: platform became an argument so the builder stopped reading machines, the builder moved to its own file so inventory left its lexical scope, and adminAuthorizedKeys became required so it stopped reaching into secrets. Every coupling to the framework turned out to be a defect, including one real security hole — the old key default handed root on a rented internet-facing box to the nexus host identity, a recipient of every ciphertext in the fleet.

A builder here is the join of inventory × secrets × profiles. A dev guest has all three legs; the hypervisor has all three; a rented static-site host has none. A service inventory entry was a single permitted platform value plus the literal string service, with every other field null or meaningless.

What a rented host needs already exists and is exported: nixosModules.publicHost, staticSite, rentedKvmGuest, and lib.buildZolaSite. It is a nixosConfigurations entry composed from those, inside the management path and outside the data-model path.

The unknown machine type assertion in machineConfigurations is untouched and will loudly reject a service machine, which is now the correct behaviour.

Closed as not planned.

Closing: the service archetype was built, reviewed four times, and abandoned. `allod/archetypes#60` carries the full reasoning; the short version is that this repo predicted the outcome before the work started. The note above `builders` said a service builder would "either invent [an inventory concept] now or take every value as an argument, which is a builder in name only." Four review rounds produced exactly that: `platform` became an argument so the builder stopped reading `machines`, the builder moved to its own file so `inventory` left its lexical scope, and `adminAuthorizedKeys` became required so it stopped reaching into `secrets`. Every coupling to the framework turned out to be a defect, including one real security hole — the old key default handed root on a rented internet-facing box to the nexus host identity, a recipient of every ciphertext in the fleet. A builder here is the join of inventory × secrets × profiles. A dev guest has all three legs; the hypervisor has all three; a rented static-site host has none. A service inventory entry was a single permitted platform value plus the literal string `service`, with every other field null or meaningless. What a rented host needs already exists and is exported: `nixosModules.publicHost`, `staticSite`, `rentedKvmGuest`, and `lib.buildZolaSite`. It is a `nixosConfigurations` entry composed from those, inside the management path and outside the data-model path. The `unknown machine type` assertion in `machineConfigurations` is untouched and will loudly reject a `service` machine, which is now the correct behaviour. Closed as not planned.
Member

Closing: the service archetype was built, reviewed four times, and abandoned. allod/archetypes#60 carries the full reasoning; the short version is that this repo predicted the outcome before the work started.

The note above builders said a service builder would "either invent [an inventory concept] now or take every value as an argument, which is a builder in name only." Four review rounds produced exactly that: platform became an argument so the builder stopped reading machines, the builder moved to its own file so inventory left its lexical scope, and adminAuthorizedKeys became required so it stopped reaching into secrets. Every coupling to the framework turned out to be a defect, including one real security hole — the old key default handed root on a rented internet-facing box to the nexus host identity, a recipient of every ciphertext in the fleet.

A builder here is the join of inventory × secrets × profiles. A dev guest has all three legs; the hypervisor has all three; a rented static-site host has none. A service inventory entry was a single permitted platform value plus the literal string service, with every other field null or meaningless.

What a rented host needs already exists and is exported: nixosModules.publicHost, staticSite, rentedKvmGuest, and lib.buildZolaSite. It is a nixosConfigurations entry composed from those, inside the management path and outside the data-model path.

The unknown machine type assertion in machineConfigurations is untouched and will loudly reject a service machine, which is now the correct behaviour.

Closed as not planned.

Closing: the service archetype was built, reviewed four times, and abandoned. `allod/archetypes#60` carries the full reasoning; the short version is that this repo predicted the outcome before the work started. The note above `builders` said a service builder would "either invent [an inventory concept] now or take every value as an argument, which is a builder in name only." Four review rounds produced exactly that: `platform` became an argument so the builder stopped reading `machines`, the builder moved to its own file so `inventory` left its lexical scope, and `adminAuthorizedKeys` became required so it stopped reaching into `secrets`. Every coupling to the framework turned out to be a defect, including one real security hole — the old key default handed root on a rented internet-facing box to the nexus host identity, a recipient of every ciphertext in the fleet. A builder here is the join of inventory × secrets × profiles. A dev guest has all three legs; the hypervisor has all three; a rented static-site host has none. A service inventory entry was a single permitted platform value plus the literal string `service`, with every other field null or meaningless. What a rented host needs already exists and is exported: `nixosModules.publicHost`, `staticSite`, `rentedKvmGuest`, and `lib.buildZolaSite`. It is a `nixosConfigurations` entry composed from those, inside the management path and outside the data-model path. The `unknown machine type` assertion in `machineConfigurations` is untouched and will loudly reject a `service` machine, which is now the correct behaviour. Closed as not planned.
Sign in to join this conversation.
No description provided.