Files
config-public/scripts/test-stackctl.sh
T
Lucas WintherandClaude Opus 5.5 35b1378080
lint / yamllint + ansible-lint + syntax (push) Successful in 56s
lint / shellcheck (push) Successful in 7s
lint / secret scan (push) Successful in 2s
Add stackctl for running stacks by hand on a host
One shared script installed into /srv/stacks on every host, with per-host
groups in server/<host>/stack-groups. Tested in check.sh. Also two new
common mistakes in the adding-a-stack skill.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-03 17:49:12 +02:00

116 lines
3.5 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# Tests for server/shared/components/stackctl, against a throwaway stack root and a stub
# `docker` that records what it was asked to do instead of doing it.
#
# scripts/test-stackctl.sh
#
# Run by scripts/check.sh. Needs nothing but bash.
set -euo pipefail
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
work="$(mktemp -d)"
trap 'rm -rf "$work"' EXIT
root="$work/stacks"
bin="$work/bin"
log="$work/calls"
mkdir -p "$root" "$bin"
cp "$repo_root/server/shared/components/stackctl" "$root/stackctl"
for s in reverse-proxy openbao webapp grafana prometheus static-site wiki; do
mkdir -p "$root/$s"
touch "$root/$s/docker-compose.yml"
done
mkdir -p "$root/not-a-stack"
cat > "$root/stack-groups" <<'EOF'
# a comment
order: reverse-proxy openbao
confirm: openbao
system: openbao webapp
monitoring: grafana prometheus
monitoring: ghost
sites: static-site
EOF
# Records "<stack> <args>" and fails for any stack named in $FAIL.
cat > "$bin/docker" <<'EOF'
#!/usr/bin/env bash
stack="$(basename "$PWD")"
echo "$stack $*" >> "$STACKCTL_TEST_LOG"
case " ${FAIL:-} " in *" $stack "*) exit 1 ;; esac
if [ "$2" = ps ]; then printf 'running\nexited\n'; fi
EOF
chmod +x "$bin/docker"
export PATH="$bin:$PATH" STACKCTL_TEST_LOG="$log"
failures=0
run() { : > "$log"; set +e; out="$("$root/stackctl" "$@" 2>&1 </dev/null)"; status=$?; set -e; }
calls() { cut -d' ' -f1-3 "$log" | paste -sd, -; }
check() {
local name="$1" want="$2" got="$3"
if [ "$want" = "$got" ]; then
printf 'ok %s\n' "$name"
else
printf 'FAIL %s\n want: %s\n got: %s\n' "$name" "$want" "$got"
failures=$((failures + 1))
fi
}
run up all
check "up all runs order first, then alphabetical" \
"reverse-proxy compose up,openbao compose up,grafana compose up,prometheus compose up,static-site compose up,webapp compose up,wiki compose up" \
"$(calls)"
check "up all succeeds" 0 "$status"
run -y down all
check "down reverses the order" \
"wiki compose down,webapp compose down,static-site compose down,prometheus compose down,grafana compose down,openbao compose down,reverse-proxy compose down" \
"$(calls)"
run up monitoring sites
check "groups expand, and repeated lines append" \
"grafana compose up,prometheus compose up,static-site compose up" "$(calls)"
check "a missing group member is warned about" yes \
"$(grep -q 'ghost' <<<"$out" && echo yes || echo no)"
run up grafana nope
check "an unknown target runs nothing" "" "$(calls)"
check "an unknown target fails" 2 "$status"
run up order
check "reserved names are not targets" 2 "$status"
run down system
check "down of a confirm stack without a TTY runs nothing" "" "$(calls)"
check "down of a confirm stack without a TTY fails" 1 "$status"
run -y down system
check "-y allows it" "webapp compose down,openbao compose down" "$(calls)"
run up openbao
check "up of a confirm stack needs no confirmation" "openbao compose up" "$(calls)"
FAIL=webapp run up system
check "a failing stack does not stop the rest" \
"openbao compose up,webapp compose up" "$(calls)"
check "a failing stack fails the run" 1 "$status"
check "a failing stack is named at the end" yes \
"$(tail -n1 <<<"$out" | grep -q webapp && echo yes || echo no)"
run logs grafana prometheus
check "logs takes exactly one stack" 2 "$status"
run ps grafana
check "ps counts running containers" yes \
"$(grep -Eq 'grafana +1/2' <<<"$out" && echo yes || echo no)"
run frobnicate all
check "an unknown command fails" 2 "$status"
[ "$failures" -eq 0 ] || { echo "$failures failed"; exit 1; }
echo "all stackctl tests passed"