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:
@@ -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"
|
||||
|
||||
|
||||
@@ -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"
|
||||
Reference in New Issue
Block a user