Merge upstream sync b86d4505 (README resolved toward CN rewrite)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKxGW1raAWaqeU8WdHsMsp
This commit is contained in:
2026-08-25 01:18:23 -04:00
co-authored by Claude Fable 5
10 changed files with 276 additions and 33 deletions
+18 -3
View File
@@ -39,16 +39,30 @@ cat >"$stub_bin/gpasswd" <<'STUB'
#!/bin/bash
echo "$@" >>"${GPASSWD_CALLS:?}"
STUB
chmod +x "$stub_bin/id" "$stub_bin/sudo" "$stub_bin/gpasswd"
# gum confirm always says yes, and reboot records that it fired: the migration
# must still NOT reboot (it defers to omarchy-update-restart), so neither should
# be reached.
cat >"$stub_bin/gum" <<'STUB'
#!/bin/bash
[[ $1 == confirm ]] && exit 0
exit 0
STUB
cat >"$stub_bin/omarchy-system-reboot" <<'STUB'
#!/bin/bash
touch "${REBOOT_CALLED:?}"
STUB
chmod +x "$stub_bin/id" "$stub_bin/sudo" "$stub_bin/gpasswd" "$stub_bin/gum" "$stub_bin/omarchy-system-reboot"
reboot_flag="$home/.local/state/omarchy/reboot-required"
gpasswd_calls="$test_dir/gpasswd-calls"
reboot_called="$test_dir/reboot-called"
launcher="$home/.local/share/applications/Docker.desktop"
run_migration() {
rm -f "$gpasswd_calls" "$reboot_flag"
rm -f "$gpasswd_calls" "$reboot_flag" "$reboot_called"
HOME="$home" OMARCHY_PATH="$omarchy_path" USER="tester" STUB_GROUPS="$1" \
GPASSWD_CALLS="$gpasswd_calls" PATH="$stub_bin:$ROOT/bin:$PATH" \
GPASSWD_CALLS="$gpasswd_calls" REBOOT_CALLED="$reboot_called" \
PATH="$stub_bin:$ROOT/bin:$PATH" \
bash -euo pipefail "$migration" >/dev/null 2>&1
}
@@ -56,6 +70,7 @@ run_migration() {
run_migration "wheel input docker" || fail "migration runs when the user is in the docker group"
grep -q -- "-d tester docker" "$gpasswd_calls" || fail "migration removes the user from the docker group"
[[ -f $reboot_flag ]] || fail "migration flags a reboot so the group change takes effect"
[[ ! -f $reboot_called ]] || fail "migration must defer the reboot (not reboot mid-update)"
[[ $(cat "$launcher") == "NEW-LAUNCHER" ]] || fail "migration refreshes the stale Docker launcher entry"
pass "migration removes the group, flags a reboot, and refreshes the launcher"
+67
View File
@@ -0,0 +1,67 @@
#!/bin/bash
#
# omarchy-sudo-docker is the single answer to "does Docker need sudo", and it
# answers two different questions on purpose. The default asks whether this
# session can reach the socket, which is what decides if a command must elevate.
# --configured asks whether the account is set up for sudoless Docker, which is
# what the menu needs so it offers the toggle that can change state. Between
# enabling sudoless Docker and the reboot that grants the group, those disagree.
set -euo pipefail
source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh"
TMPDIR=$(mktemp -d)
trap 'rm -rf "$TMPDIR"' EXIT
command="$ROOT/bin/omarchy-sudo-docker"
# Stub id so the configured groups are controllable.
mkdir -p "$TMPDIR/bin"
cat >"$TMPDIR/bin/id" <<'STUB'
#!/bin/bash
printf '%s\n' "${STUB_GROUPS:-wheel input}"
STUB
chmod +x "$TMPDIR/bin/id"
# A writable stand-in means the socket is reachable; an unwritable one means it
# is not. Test the file mode rather than a live daemon.
reachable_socket="$TMPDIR/reachable.sock"
blocked_socket="$TMPDIR/blocked.sock"
touch "$reachable_socket" "$blocked_socket"
chmod 600 "$reachable_socket"
chmod 400 "$blocked_socket"
run() { # SOCKET GROUPS [--configured]
env PATH="$TMPDIR/bin:$PATH" OMARCHY_DOCKER_SOCKET="$1" STUB_GROUPS="$2" USER=tester \
bash "$command" ${3:+"$3"}
}
# Default mode follows the socket, not the group list.
run "$blocked_socket" "wheel input" || fail "an unreachable socket means Docker needs sudo"
run "$reachable_socket" "wheel input" && fail "a reachable socket means Docker does not need sudo"
pass "default mode answers from the socket this session can reach"
# A socket that isn't there at all still needs elevation (starting it is root work).
run "$TMPDIR/absent.sock" "wheel input docker" || fail "a missing socket means Docker needs sudo"
pass "a missing socket counts as needing sudo"
# --configured follows the account's groups, not the socket.
run "$blocked_socket" "wheel input docker" --configured && fail "a configured docker group means no sudo is needed"
run "$reachable_socket" "wheel input" --configured || fail "no docker group means sudo is needed"
pass "--configured answers from the account's groups"
# The window this split exists for: sudoless Docker has just been enabled, so the
# account carries the group while the running session still cannot use it. The
# menu must offer Remove (--configured says no sudo) while lazydocker and the
# Windows VM must still prompt (default says sudo).
run "$blocked_socket" "wheel input docker" || fail "the session still needs sudo before the reboot"
run "$blocked_socket" "wheel input docker" --configured && fail "the account is already configured for sudoless Docker"
pass "the two modes disagree between enabling sudoless Docker and the reboot"
# An unknown argument is a usage error, not a silent answer either way.
run "$reachable_socket" "wheel input" --bogus 2>/dev/null && fail "an unknown flag exits non-zero"
status=0
run "$reachable_socket" "wheel input" --bogus >/dev/null 2>&1 || status=$?
(( status == 2 )) || fail "an unknown flag exits 2, not the boolean 1"
pass "an unknown flag is a usage error"
@@ -0,0 +1,93 @@
#!/bin/bash
#
# Toggling sudoless Docker changes the docker group, which only takes effect on a
# reboot. The setup/remove commands must flag the reboot and offer to do it now
# (gum confirm), but defer it when OMARCHY_DEFER_REBOOT is set (the migration
# reuses them inside `omarchy update`, where omarchy-update-restart handles it).
set -euo pipefail
source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh"
test_dir=$(mktemp -d)
trap 'rm -rf "$test_dir"' EXIT
home="$test_dir/home"
stub_bin="$test_dir/bin"
mkdir -p "$home" "$stub_bin"
cat >"$stub_bin/id" <<'STUB'
#!/bin/bash
printf '%s\n' "${STUB_GROUPS:-wheel input}"
STUB
cat >"$stub_bin/sudo" <<'STUB'
#!/bin/bash
exec "$@"
STUB
cat >"$stub_bin/usermod" <<'STUB'
#!/bin/bash
echo "$@" >>"${USERMOD_CALLS:?}"
STUB
cat >"$stub_bin/gpasswd" <<'STUB'
#!/bin/bash
echo "$@" >>"${GPASSWD_CALLS:?}"
STUB
cat >"$stub_bin/gum" <<'STUB'
#!/bin/bash
touch "${GUM_CALLED:?}"
exit "${GUM_ANSWER:-0}"
STUB
cat >"$stub_bin/omarchy-system-reboot" <<'STUB'
#!/bin/bash
touch "${REBOOT_CALLED:?}"
STUB
chmod +x "$stub_bin"/*
reboot_flag="$home/.local/state/omarchy/reboot-required"
gum_called="$test_dir/gum-called"
reboot_called="$test_dir/reboot-called"
gpasswd_calls="$test_dir/gpasswd-calls"
usermod_calls="$test_dir/usermod-calls"
run() { # command STUB_GROUPS GUM_ANSWER DEFER(0|1)
rm -f "$reboot_flag" "$gum_called" "$reboot_called" "$gpasswd_calls" "$usermod_calls"
local defer_env=()
[[ ${4:-0} == 1 ]] && defer_env=(OMARCHY_DEFER_REBOOT=1)
env HOME="$home" USER="tester" STUB_GROUPS="$2" GUM_ANSWER="$3" \
GUM_CALLED="$gum_called" REBOOT_CALLED="$reboot_called" \
GPASSWD_CALLS="$gpasswd_calls" USERMOD_CALLS="$usermod_calls" \
PATH="$stub_bin:$ROOT/bin:$PATH" "${defer_env[@]}" \
bash "$ROOT/bin/$1" >/dev/null 2>&1
}
# Remove, interactive, reboot confirmed -> group removed, flag set, reboot fired.
run omarchy-remove-security-sudoless-docker "wheel input docker" 0 0
grep -q -- "-d tester docker" "$gpasswd_calls" || fail "remove drops the user from the docker group"
[[ -f $reboot_flag ]] || fail "remove flags a reboot"
[[ -f $reboot_called ]] || fail "remove reboots when the prompt is confirmed"
pass "remove drops the group, flags a reboot, and reboots on confirm"
# Remove, interactive, reboot declined -> flag set, but no reboot.
run omarchy-remove-security-sudoless-docker "wheel input docker" 1 0
[[ -f $reboot_flag ]] || fail "remove still flags a reboot when the prompt is declined"
[[ ! -f $reboot_called ]] || fail "remove does not reboot when the prompt is declined"
pass "remove leaves the reboot to the user when declined"
# Remove, deferred (migration/update) -> flag set, prompt never shown.
run omarchy-remove-security-sudoless-docker "wheel input docker" 0 1
[[ -f $reboot_flag ]] || fail "deferred remove still flags a reboot"
[[ ! -f $gum_called ]] || fail "deferred remove must not prompt to reboot"
[[ ! -f $reboot_called ]] || fail "deferred remove must not reboot"
pass "deferred remove flags the reboot without prompting"
# Remove, already out of the group -> no-op, nothing flagged.
run omarchy-remove-security-sudoless-docker "wheel input" 0 0
[[ ! -f $gpasswd_calls ]] || fail "remove is a no-op when the user is not in the docker group"
[[ ! -f $reboot_flag ]] || fail "remove does not flag a reboot when nothing changed"
pass "remove is a no-op when sudoless Docker is already off"
# Setup, enable confirmed then reboot confirmed -> group added, flag set, reboot.
run omarchy-setup-security-sudoless-docker "wheel input" 0 0
grep -q -- "-aG docker tester" "$usermod_calls" || fail "setup adds the user to the docker group"
[[ -f $reboot_flag ]] || fail "setup flags a reboot"
[[ -f $reboot_called ]] || fail "setup reboots when the prompt is confirmed"
pass "setup adds the group, flags a reboot, and reboots on confirm"