RFC-0001: The Configuration Store #155
Closed
kn4oqw-clint
announced in
RFCs
Replies: 1 comment
|
This has already been implimented. |
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Summary
All Waypoint configuration lives in a single SQLite database owned by
waypointd. Gateway INI files are deterministic, diffable compiled outputs of that store. Nothing ever parses a generated file back. This RFC defines the store's shape, the generation pipeline, the override layer, and the losslessness test contract.Motivation
The single largest complaint family across the incumbent platforms is configuration destruction: web forms POST → regex-rewrite INI files → unrelated settings vanish (Pi-Star #58, #72, #86, #98, #103, #132, #182–#185, #190). The root cause is architectural — the INI files are simultaneously the UI's read model, the write target, and the daemons' input, with no schema between them. The fix is to make the store authoritative and the files disposable.
Design
Store
/var/lib/waypoint/config.db, WAL mode, owned bywaypointd(never edited by hand — the override layer is the human escape hatch).settings(key TEXT PRIMARY KEY, value JSON, updated_at, updated_by)— a typed key tree (dmr.network.brandmeister.enabled = true), validated against a versioned JSON Schema before write. Unknown keys are rejected, not silently kept.meta(schema_version, device_id, claimed_at, ...).dmr.enabled, it deletes nothing. This makes the incumbent failure mode structurally impossible rather than carefully avoided.Generation pipeline
/etc/waypoint/generated/atomically (rename), then affected daemons restart via the supervisor. A header comment in every generated file names the source and warns that edits will be overwritten — and points at the override layer.Override layer
/etc/waypoint/overrides.d/<daemon>.d/*.conffragments merge last into the rendered output, keyed by INI section: an override section replaces keys it names, leaves the rest.10-name.confconvention); when two fragments set the same section/key, the later filename wins. The UI's override view shows the effective winner per key.!unsetremoves that key from the rendered output entirely (suppressing a rendered default, not just replacing its value).disktoday;uireserved) so UI-managed overrides can later reuse theappliesjournal without a schema migration.prepend.d/append.dhooks instead (they aren't INI)./etc/waypoint/overrides.d.Profiles
network.*andmode.*namespaces by default), stored in aprofilestable and exportable as a JSON file (optionally minisign-signed).sensitive: true, and sensitive keys are excluded from profile export (exported as a named placeholder requiring re-entry on import). In-store profile switching retains them. This annotation also drives redaction in UI diffs and logs.API surface
GET/PUT /api/config/{key}(typed, schema-validated),POST /api/config/apply(render+swap+restart, returns the diff it applied),GET /api/config/preview, profile CRUD +POST /api/profiles/{name}/activate.appliestable: who, when, diff) — the UI's "what changed" history and the debugging story for "it worked yesterday."The losslessness contract (test harness)
CI enforces, as release-blocking property tests:
*.enabledoff, applying unrelated changes, toggling back on ⇒ byte-identical section to the original.!unsetmarkers), properties 1–3 still hold for the non-overridden surface, and the override-affected keys re-render identically across repeated applies and unrelated store changes.sensitive: truekeys verified absent from the export artifact.Alternatives considered
waypointdis the only writer.Open questions
sensitive: trueschema annotation, excluded from profile exports, redacted in diffs/logs.)Whether profile export should include a hardware-fingerprint block(Settled in review: yes — the schema field ships with the export format; the warning UI may follow later.)Migrated from
docs/rfcs/0001-config-store.md; the drafting history is in the git log.All reactions