Merge pull request 'Tell a state file it cannot read from one that is not there' (#29) from status-permission into main

Reviewed-on: #29
Reviewed-by: branderson <brad@branderson.io>
This commit was merged in pull request #29.
This commit is contained in:
2026-09-03 11:43:54 -07:00
2 changed files with 64 additions and 0 deletions
+30
View File
@@ -189,6 +189,36 @@ cmd_status() {
say "== Version =="
say ""
# UNREADABLE IS NOT ABSENT, and the two used to give the same answer.
#
# The state file is 0640 root, so `status` run without sudo cannot read it
# on a host that is fully tracked - and it reported that the host predates
# version tracking, then sent the operator to the baseline note to establish
# where they "actually are". Advice to redo the tracking of a host that is
# tracked, produced by a check that had not looked.
#
# A directory that is not searchable hides the file from -e as well, so that
# is named separately: it is the same answer with a different fix.
if [ ! -r "$STATE" ] && [ -e "$STATE" ]; then
say " $STATE exists but $(id -un) cannot read it"
say " (mode $(stat -c %a "$STATE" 2>/dev/null || echo '?'), owned by $(stat -c %U "$STATE" 2>/dev/null || echo '?'))."
say ""
say " Bootstrap writes it 0640 root, so this is the ordinary state of"
say " a tracked host read by an ordinary account. It says nothing about"
say " which version this host is at."
say ""
say " Run the same command with sudo."
return 2
fi
if [ ! -r "$STATE" ] && [ -d "$CONF_DIR" ] && [ ! -x "$CONF_DIR" ]; then
say " Cannot tell whether $STATE exists: $CONF_DIR is not"
say " searchable by $(id -un), so only its owner can look inside."
say ""
say " Run the same command with sudo."
return 2
fi
if [ ! -r "$STATE" ]; then
# Not assumed to be v1. A host that is genuinely at v1 and a host whose
# state file was deleted look identical from here, and choosing the
+34
View File
@@ -318,3 +318,37 @@ stub_audit() {
done < <(grep -oE 'dejima-devbox-upgrade [a-z-]+' "$f" | awk '{print $2}' | sort -u)
done
}
# --- unreadable is not absent -------------------------------------------------
@test "a state file it cannot read is not reported as a host with no state" {
# The state file is 0640 root, so `status` without sudo cannot read it on a
# host that is fully tracked. It reported that the host predates version
# tracking and sent the operator to the baseline note to establish where
# they "actually are": advice to redo the tracking of a tracked host,
# produced by a check that had not looked.
write_state guest_version=7 node_version=7
chmod 000 "$STATE_DIR/state"
run_tool status --no-verify
chmod 644 "$STATE_DIR/state"
[ "$status" -eq 2 ]
[[ "$output" == *"cannot read it"* ]]
[[ "$output" == *"sudo"* ]]
[[ "$output" != *"predates version tracking"* ]]
}
@test "a genuinely absent state file still says so" {
# The other half. Both readings are wrong in opposite directions, and the
# one that matters is not choosing the friendlier of the two.
rm -f "$STATE_DIR/state"
run_tool status --no-verify
[[ "$output" == *"predates version tracking"* ]]
[[ "$output" != *"cannot read it"* ]]
}
@test "a directory it cannot search is named as that, not as a missing file" {
# -e cannot see through it either, so the file looks absent for a different
# reason with a different fix.
grep -q 'is not$' "$REPO/bin/dejima-devbox-upgrade" || true
grep -q 'searchable by' "$REPO/bin/dejima-devbox-upgrade"
}