Read VM target/username/host-key from deploy-flake outputs, dropping side checkouts #6
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Follow-up to #5. That change made a single
DEPLOY_FLAKEthe source of truth for a VM's target IP, username, and host-key pin, but the scripts still read those facts out of localINVENTORY_CHECKOUTandSECRETS_CHECKOUTclones at the revisions the deploy flake'sflake.lockpins — so an operator still points at three things (DEPLOY_FLAKEplus two checkouts that must be clones able to fetch the pinned revs). Expose the derived facts as read-only outputs of the deploy flake and haverebuild-vm-from-host/provision-vm-from-hostread them withnix eval <deploy>#…, so the only pointer isDEPLOY_FLAKEand the side checkouts go away. This is the "expose the target IP and the pinned host keys as flake outputs" alternative #5 deferred as a larger cross-repo change.Context
rebuild-vm-from-hostandprovision-vm-from-host(viascripts/lib/rotation-common.sh) currently resolve the pinnedinventory/secretsrevisions from${DEPLOY_FLAKE}/flake.lock, ensure those commits are present locally (fetching if needed), then read the target IP fromgit show <inv-rev>:scripts/vm-specs.json, the username fromnix eval path:${SECRETS_CHECKOUT}#lib.vmUsernames.<vm>, and the host-key material fromgit show <secrets-rev>:machine-host-keys.json;provisionalso reads the age-encrypted host key at the pinned secrets rev. The checkouts exist only to supply file/eval content at the pinned commits, yet they are still two paths the operator must provide and keep as fetchable clones. Evaluating the deploy flake directly makes the pin inherent — the flake already composes the pinned inputs — and eliminates the checkout state entirely. That is the drift-free end state principle 8 points at (one source of truth per fact; consumers derive) and squares with principle 3 (build public, deploy private): the derivation logic lives in the public framework and any private deploy flake inherits it by composition rather than copying it.Direction (for the dev plan to settle)
Preferred shape: put the output-generating logic in the shared framework (a lib or module in
profilesorvm) so the public template flake and any deploy flake both expose the outputs by composing the framework and supplying only data — no per-fork duplication of logic. Candidate outputs, keyed by VM name, for example<deploy>#vmTarget.<vm>(IP, from inventory),<deploy>#vmUsername.<vm>(from secrets), and<deploy>#vmHostKeys.<vm>(the pinned active/staged public material the pin check compares against). The scripts then replace the flake-lock rev resolution, theensure_git_commit_availablefetches, and thegit showreads for these facts withnix eval.Security-sensitive decisions the plan must make and justify:
assert_any_vm_host_key_material_pinned/assert_vm_host_key_material_pinned) must be preserved at equal strength, now comparing against the material from the flake output instead ofgit show. A regression test that it fails closed on an unpinned or mismatched presented/derived key is required.provisionneeds the age-encrypted host private key to inject at install. Decide whether to expose that ciphertext as a flake output too — age blobs are safe to surface, and doing so lets provision also drop the secrets checkout — or keep that single file read. Exposing it is the "one pointer" end state; pick and justify.INVENTORY_CHECKOUT/SECRETS_CHECKOUTas optional fallbacks or remove them outright once the outputs exist.Boundaries
Public framework and provisioning tooling only:
allod/nexusscripts plus read-only outputs added inallod/profiles/allod/vm/allod/inventory/allod/secrets, all buildable and testable against the template machines (allod-dev, privacy-1). Private deployments inherit the pattern by composing the framework and supply their own data; their adoption and any data-contract sequencing is tracked privately and is out of scope here. Also out of scope: the deploy-flake composition model itself, machine-data schemas beyond adding outputs, and the separate smaller change of bakingDEPLOY_FLAKEinto the host environment so on-host invocations need no exports. Host-side live rebuild/provision remains a human gate.Validation
Fixture-based, extending the existing harness and gated on
nix flake check. Must include a genuine no-checkout invocation (onlyDEPLOY_FLAKEset) that derives IP, username, and host-key material vianix eval; the fail-closed pin regression on the output-fed path (refusal plus an assertion that no build ran); and, for provision, that host-key injection still works from whatever source the plan chooses.tests/rotate-token.shand the out-of-scope scripts that share the current helpers must stay green.Classification
Needs a dev plan (cross-repo:
allod/nexusplus framework outputs inallod/profiles/vm/inventory/secrets). Residual risk likely R3, the same class as #5: provisioning tooling on the host-key security and auth boundary with a cross-repo interface, recoverable by revert. The final integration PR — the nexus scripts consuming the outputs — carries the closing keyword; earlier framework-output PRs useRefs.Sequencing
Public-first and unblocked: this builds on #5 (the
DEPLOY_FLAKEconsumption already exists) and should land before any private adoption, so the private side copies a pattern that already builds and passes tests. Prove the output contract on the template machines first.