Reinstall pre-fills the form with the previous install's non-secret answers - #805
Open
VijitSingh97 wants to merge 1 commit into
Open
Reinstall pre-fills the form with the previous install's non-secret answers#805VijitSingh97 wants to merge 1 commit into
VijitSingh97 wants to merge 1 commit into
Conversation
…ll's non-secret answers On a fresh-start reinstall the operator re-answered everything the machine already knew, and a bench session lost its remote-Tari setting that way: the form defaulted Tari back to a local chain the operator never wanted. The host (which already enumerates disks) now, when the inventory holds exactly one disk carrying an install, mounts its data partition read-only, reads the previous pithead/config.json, strips every secret and publishes the remainder through the same last-attempt.json channel the pre-seed path fills. The container never mounts anything; an operator pre-seed outranks the derived pre-fill. The strip (strip_config_secrets) removes every CONTROL_SECRET_PATHS leaf plus the whole objects whose value is access: dashboard.auth, workers (and the deprecated dashboard.workers), telegram, healthchecks, notifications, ssh, and the view-key pair. Wallet addresses, node modes and hosts, the pool tier survive — those are the answers the operator came back for. Fail open everywhere: no config, unreadable, oversized, non-object JSON, ambiguous targets (two disks with data), or a failed mount all mean the form opens blank — nothing may block an install. Derived fresh each boot and cleared first, so a fleet stick never carries machine 1's answers to machine 2. On wipe=keep nothing changes: the survivor config wins and no config crosses. Coverage: stack-suite units for the strip (every secret class via one marker) and the fail-open orchestration; wizard server contracts for pre-fill serving, broken-pre-fill degradation, and keep leaving the pre-fill alone; a KVM install-phase assertion (wallet pre-filled, no password in the state) for the next bench battery. Drive-by: ruff import sort in test_data_service.py that was failing make lint on the branch. Closes #794 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #794
On a fresh-start reinstall the operator re-answered everything the machine already knew, and a bench session lost its remote-Tari setting that way: the form defaulted Tari back to a local chain the operator never wanted.
What changes
Host side only (
pithead, two functions beside the disk-installer helpers):prefill_from_previous_install— when the published inventory holds exactly one disk in statepithead-with-data, mount itsdatapartition read-only (-t ext4 -o ro,nosuid,nodev), read the previouspithead/config.json, strip the secrets, and publish the remainder as$spool/last-attempt.json— the exact channel the pre-seed path already fills and the state API already merges over the defaults. No container change, no frontend change, no second channel.strip_config_secrets— everyCONTROL_SECRET_PATHSleaf plus whole-object deletes fordashboard.auth,workers+ the deprecateddashboard.workers(covers per-entry tokens in the variable-length list),telegram,healthchecks,notifications,ssh, andtari.spend_public_key. Wallet addresses, node modes/hosts, pool tier, timezone survive — the answers the operator came back for.Fail open everywhere. No config, unreadable, oversized (>1 MiB), non-object JSON, ambiguous targets (two disks with data), failed mount, or a symlinked
pithead//config.json(a crafted disk must not read the running host's files) — all mean the page opens blank and nothing blocks the install.Fleet-stick hygiene. The pre-fill is derived fresh each installer boot:
last-attempt.jsonis cleared before pre-seed/pre-fill runs, so machine 2 never opens on machine 1's answers. An operator pre-seed outranks the derived pre-fill. Onwipe=keepnothing changes — the form collapses, no config crosses, and the pre-fill is left untouched.Coverage (per docs/dev/testing-strategy.md tiers)
LEAK-marker sweep + keepers asserted; orchestration fail-open legs incl. both symlink-escape shapes. 1830 passed.tests/os/run.sh --phase install, reinstall leg): new assertions through the page's own state API — the first leg's wallet pre-fills, and no non-empty"password"appears in the state. Not runnable locally; lands with the next bench battery.make lintgreen; dashboard coverage 96.55%, patch coverage 90%. Drive-by: ruff import sort intests/service/test_data_service.pythat was failingmake linton this branch.The interplay with the upcoming role select is out of scope — this builds for today's form.
🤖 Generated with Claude Code