-
Notifications
You must be signed in to change notification settings - Fork 133
Restore the partition table if cfdisk Resize shrinks an existing OS #122
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
rastermanden
wants to merge
3
commits into
omacom:quattro
Choose a base branch
from
rastermanden:fix/cfdisk-resize-restores-table
base: quattro
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,182 @@ | ||
| #!/bin/bash | ||
| # | ||
| # The partition guard in the configurator is only worth anything if the script | ||
| # that launches it honours a refusal. .automated_script.sh hands off to the | ||
| # install dashboard unconditionally once the wizard returns, so these cases | ||
| # pin the two gates that stand between: the configurator's exit status, and | ||
| # the configuration file it is supposed to have produced. | ||
| # | ||
| # The launcher is a tty1-gated monolith that redirects its own output and | ||
| # execs the real installer, so the handoff region is lifted out and run in a | ||
| # sandbox with /root, /usr/local/bin and /run rewritten to throwaway paths. | ||
| # The lines under test are the file's own, unmodified. | ||
|
|
||
| set -uo pipefail | ||
|
|
||
| ROOT=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/../.." && pwd) | ||
| LAUNCHER="$ROOT/configs/airootfs/root/.automated_script.sh" | ||
|
|
||
| work=$(mktemp -d) | ||
| trap 'rm -rf "$work"' EXIT | ||
|
|
||
| failures=0 | ||
|
|
||
| check() { | ||
| local label="$1" expected="$2" actual="$3" | ||
| if [[ $expected == "$actual" ]]; then | ||
| printf ' ok %s\n' "$label" | ||
| else | ||
| printf ' FAIL %s: expected %s, got %s\n' "$label" "$expected" "$actual" | ||
| failures=$((failures + 1)) | ||
| fi | ||
| } | ||
|
|
||
| # Rebuild the sandbox and the handoff script for each case. CIDATA_EXIT and | ||
| # CONFIGURATOR_EXIT drive which branch runs; CONFIGURATOR_WRITES_CONFIG says | ||
| # whether the wizard got far enough to leave a configuration behind. | ||
| new_sandbox() { | ||
| sandbox=$(mktemp -d "$work/sandbox.XXXXXX") | ||
| mkdir -p "$sandbox/root" "$sandbox/bin" "$sandbox/run" | ||
|
|
||
| cat >"$sandbox/bin/omarchy-cidata-load" <<'STUB' | ||
| #!/bin/bash | ||
| exit "${CIDATA_EXIT:-1}" | ||
| STUB | ||
|
|
||
| cat >"$sandbox/root/configurator" <<'STUB' | ||
| #!/bin/bash | ||
| [[ ${CONFIGURATOR_WRITES_CONFIG:-0} == 1 ]] && echo '{"disk_config": {}}' >user_configuration.json | ||
| exit "${CONFIGURATOR_EXIT:-0}" | ||
| STUB | ||
|
|
||
| # The marker is the whole assertion: if it exists, an install was started. | ||
| cat >"$sandbox/bin/omarchy-install-dashboard" <<'STUB' | ||
| #!/bin/bash | ||
| touch "$SANDBOX/install-started" | ||
| STUB | ||
|
|
||
| cat >"$sandbox/bin/jq" <<'STUB' | ||
| #!/bin/bash | ||
| echo false | ||
| STUB | ||
|
|
||
| # tty is read for the dashboard's TTY handle; the test has no terminal. | ||
| cat >"$sandbox/bin/tty" <<'STUB' | ||
| #!/bin/bash | ||
| echo /dev/console | ||
| STUB | ||
|
|
||
| chmod +x "$sandbox/bin"/* "$sandbox/root/configurator" | ||
|
|
||
| sed -n '/^cd \/root$/,$p' "$LAUNCHER" | | ||
| sed -e "s#^cd /root\$#cd $sandbox/root#" \ | ||
| -e "s#/usr/local/bin/#$sandbox/bin/#g" \ | ||
| -e "s#/root/#$sandbox/root/#g" \ | ||
| -e "s#/run/omarchy-install/#$sandbox/run/#g" \ | ||
| >"$sandbox/handoff.sh" | ||
|
|
||
| # The lift has to keep the pieces under test. A silent sed miss would turn | ||
| # every case into a vacuous pass. | ||
| grep -q 'configurator || exit 1' "$sandbox/handoff.sh" && | ||
| grep -q 'user_configuration.json \]\] || exit 1' "$sandbox/handoff.sh" && | ||
| grep -q "$sandbox/bin/omarchy-install-dashboard" "$sandbox/handoff.sh" | ||
| } | ||
|
|
||
| run_handoff() { | ||
| SANDBOX="$sandbox" \ | ||
| OMARCHY_INSTALL_LOG_FILE="$sandbox/install.log" \ | ||
| PATH="$sandbox/bin:$PATH" \ | ||
| bash "$sandbox/handoff.sh" >/dev/null 2>&1 | ||
| } | ||
|
|
||
| installed() { | ||
| [[ -e $sandbox/install-started ]] && echo yes || echo no | ||
| } | ||
|
|
||
| echo "==> the handoff region is lifted intact" | ||
| new_sandbox | ||
| check "both gates and the dashboard handoff survive the rewrite" "0" "$?" | ||
|
|
||
| echo "==> a configurator that refuses does not start an install" | ||
| new_sandbox | ||
| CONFIGURATOR_EXIT=1 CONFIGURATOR_WRITES_CONFIG=0 run_handoff | ||
| check "the launcher exits nonzero" "1" "$?" | ||
| check "no install was started" "no" "$(installed)" | ||
|
|
||
| # The abort path tells the user to re-run the launcher. A configuration left | ||
| # by the run that just refused describes a partition layout the guard rejected. | ||
| echo "==> a stale configuration cannot stand in for a refused one" | ||
| new_sandbox | ||
| echo '{"disk_config": {}}' >"$sandbox/root/user_configuration.json" | ||
| CONFIGURATOR_EXIT=1 CONFIGURATOR_WRITES_CONFIG=0 run_handoff | ||
| check "the launcher still exits nonzero" "1" "$?" | ||
| check "no install was started" "no" "$(installed)" | ||
| [[ -e $sandbox/root/user_configuration.json ]] | ||
| check "the stale configuration was cleared" "1" "$?" | ||
|
|
||
| # An autoinstall attempt that aborts and is retried with the cidata drive | ||
| # pulled never reaches the loader's own cleanup — it exits as soon as no drive | ||
| # is found. The orchestrator treats these files as "present means use it", so | ||
| # anything left here is the previous attempt's remote access on the new machine. | ||
| echo "==> a pulled cidata drive leaves no remote-access credentials behind" | ||
| new_sandbox | ||
| echo 'ssh-ed25519 AAAA rig@imaging' >"$sandbox/root/authorized_keys" | ||
| echo 'tskey-auth-rig' >"$sandbox/root/tailscale_authkey" | ||
| echo '{"disk_config": {}}' >"$sandbox/root/user_configuration.json" | ||
| : >"$sandbox/root/defer-provisioning" | ||
| CONFIGURATOR_EXIT=0 CONFIGURATOR_WRITES_CONFIG=1 run_handoff | ||
| check "the interactive retry starts its own install" "yes" "$(installed)" | ||
| [[ -e $sandbox/root/authorized_keys ]] | ||
| check "the rig's SSH key was cleared" "1" "$?" | ||
| [[ -e $sandbox/root/tailscale_authkey ]] | ||
| check "the rig's Tailscale key was cleared" "1" "$?" | ||
| [[ -e $sandbox/root/defer-provisioning ]] | ||
| check "the stale defer-provisioning marker was cleared" "1" "$?" | ||
|
|
||
| # The launcher clears these because omarchy-cidata-load cannot: its cleanup is | ||
| # behind the drive-found check. Drift between the two lists reopens the leak, | ||
| # so compare them rather than trusting two hand-maintained copies. | ||
| echo "==> the launcher clears every input the cidata loader knows about" | ||
| CIDATA_LOAD="$ROOT/configs/airootfs/usr/local/bin/omarchy-cidata-load" | ||
| loader_inputs=$( | ||
| sed -n 's/^optional_inputs=(\(.*\))$/\1/p' "$CIDATA_LOAD" | | ||
| tr ' ' '\n' | sed '/^$/d' | sort -u | ||
| ) | ||
| loader_inputs=$(printf '%s\nuser_configuration.json\n' "$loader_inputs" | sort -u) | ||
| launcher_inputs=$( | ||
| awk '/^rm -f / { grab = 1 } | ||
| grab { sub(/^rm -f /, ""); cont = /\\$/; sub(/\\$/, ""); print; if (!cont) exit }' "$LAUNCHER" | | ||
| tr ' ' '\n' | sed '/^$/d' | sort -u | ||
| ) | ||
| check "the loader's input list was parsed" "0" "$([[ -n $loader_inputs ]] && echo 0 || echo 1)" | ||
| check "the two cleanup lists match" "$loader_inputs" "$launcher_inputs" | ||
|
|
||
| echo "==> a configurator that produced nothing does not start an install" | ||
| new_sandbox | ||
| CONFIGURATOR_EXIT=0 CONFIGURATOR_WRITES_CONFIG=0 run_handoff | ||
| check "the launcher exits nonzero" "1" "$?" | ||
| check "no install was started" "no" "$(installed)" | ||
|
|
||
| echo "==> a completed wizard still starts the install" | ||
| new_sandbox | ||
| CONFIGURATOR_EXIT=0 CONFIGURATOR_WRITES_CONFIG=1 run_handoff | ||
| check "the launcher exits clean" "0" "$?" | ||
| check "the install was started" "yes" "$(installed)" | ||
|
|
||
| echo "==> autoinstall from a cidata drive still starts the install" | ||
| new_sandbox | ||
| echo '{"disk_config": {}}' >"$sandbox/root/cidata-config" | ||
| cat >"$sandbox/bin/omarchy-cidata-load" <<STUB | ||
| #!/bin/bash | ||
| cp "$sandbox/root/cidata-config" "$sandbox/root/user_configuration.json" | ||
| STUB | ||
| chmod +x "$sandbox/bin/omarchy-cidata-load" | ||
| run_handoff | ||
| check "the launcher exits clean" "0" "$?" | ||
| check "the install was started" "yes" "$(installed)" | ||
|
|
||
| if (( failures > 0 )); then | ||
| printf '\n%d check(s) failed\n' "$failures" | ||
| exit 1 | ||
| fi | ||
| printf '\nall checks passed\n' |
Oops, something went wrong.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When
sfdiskfails to restore a shrunk partition table, this branch callsabort, but.automated_script.shignores the configurator's nonzero exit and unconditionally launches the installer dashboard. The install therefore continues after the safety guard reports that the existing filesystem remains behind a shortened partition boundary, producing a later failure or allowing retained configuration from an earlier attempt to operate against the damaged table.Knowledge Base Used:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed in 96927a6, with one correction:
.automated_script.shsetsset -euo pipefailat the top, and theelsebody inherits it (only theifcondition is exempt), so a failing configurator did already terminate the script. The install was not actually reachable that way.The guard is worth stating explicitly regardless, so the call is now
./configurator || exit 1, and a[[ -f user_configuration.json ]]gate covers both branches before the dashboard handoff. The launcher also clears the previous run's inputs first, since the abort message tells people to re-run it and a leftover configuration describes a partition layout the guard just rejected.test/unit/installer-gate-test.shruns the real handoff region against a sandboxed/rootand asserts no install starts without a clean configurator exit and a configuration this run produced.