Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/panel-scripts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ jobs:
- uses: actions/checkout@v4
- run: shellcheck -x utils/ensure_auth_cookie_domain.sh utils/ensure_node_ip.sh utils/dev_game_server.sh utils/gpu_nodes.sh tests/scripts/*.sh tests/scripts/stub/kubectl
- run: bash tests/scripts/setup_env_test.sh
- run: bash tests/scripts/apply_overlay_test.sh
- run: bash tests/scripts/debug_test.sh
- run: bash tests/scripts/startup_probe_test.sh
- run: bash tests/scripts/system_upgrade_test.sh
Expand Down
68 changes: 68 additions & 0 deletions tests/scripts/apply_overlay_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#!/bin/bash

# shellcheck source=tests/scripts/lib.sh
source "$(dirname "${BASH_SOURCE[0]}")/lib.sh"

RENDERED='apiVersion: v1
kind: ConfigMap
metadata:
name: example'

setup_stubs() {
PANEL_DIR="$WORK_DIR/panel"
mkdir -p "$PANEL_DIR/overlay" "$WORK_DIR/bin"
printf '#!/bin/sh\ncat <<EOF\n%s\nEOF\n' "$RENDERED" >"$PANEL_DIR/kustomize"
cat >"$WORK_DIR/bin/kubectl" <<EOF
#!/bin/sh
echo "\$*" >>"$WORK_DIR/kubectl-calls"
if [ "\$1" = apply ]; then cp "\$3" "$WORK_DIR/applied"; fi
EOF
chmod +x "$PANEL_DIR/kustomize" "$WORK_DIR/bin/kubectl"
export PATH="$WORK_DIR/bin:$PATH" PANEL_DIR KUBECONFIG=""
}

hook() {
cat >"$WORK_DIR/pre-apply" <<EOF
#!/bin/sh
cp "\$1" "$WORK_DIR/checked"
echo "$2"
exit $1
EOF
chmod +x "$WORK_DIR/pre-apply"
export FIVESTACK_PRE_APPLY="$WORK_DIR/pre-apply"
}

run_apply() {
(
# shellcheck source=utils/colors.sh
source "$TEST_ROOT/utils/colors.sh"
# shellcheck source=utils/apply_overlay.sh
source "$TEST_ROOT/utils/apply_overlay.sh"
apply_overlay overlay 1 0
) >"$WORK_DIR/output" 2>&1
}

test_an_apply_without_the_5stack_service_goes_straight_to_kubectl() {
setup_stubs
run_apply || fail "apply_overlay exited $?: $(cat "$WORK_DIR/output")"
assert_eq "$(cat "$WORK_DIR/applied")" "$RENDERED"
}

test_the_5stack_service_sees_the_rendered_overlay_before_it_is_applied() {
setup_stubs
hook 0 "no rollout without zero downtime"
run_apply || fail "apply_overlay exited $?: $(cat "$WORK_DIR/output")"
assert_eq "$(cat "$WORK_DIR/checked")" "$RENDERED"
assert_eq "$(cat "$WORK_DIR/applied")" "$RENDERED"
}

test_the_5stack_service_can_stop_an_apply() {
setup_stubs
hook 1 "the panel did not drain within 30 minutes"
run_apply && fail "apply_overlay carried on after the 5Stack service refused"
[ ! -e "$WORK_DIR/kubectl-calls" ] || fail "kubectl ran: $(cat "$WORK_DIR/kubectl-calls")"
assert_contains "$(cat "$WORK_DIR/output")" "the 5Stack service stopped overlay from being applied"
assert_contains "$(cat "$WORK_DIR/output")" "the panel did not drain within 30 minutes"
}

run_tests
46 changes: 46 additions & 0 deletions tests/scripts/setup_env_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -181,4 +181,50 @@ test_custom_ports_move_from_nginx_config_env_to_traefik_config_env() {
[ ! -e "$PANEL/overlays/config/nginx-config.env" ] || fail "nginx-config.env was left behind"
}

test_a_missing_steam_key_with_no_terminal_stops_instead_of_waiting() {
make_panel
set_sibling_domains
set_env overlays/local-secrets/steam-secrets.env STEAM_WEB_API_KEY ""
bash -c 'source "$1/utils/utils.sh"' _ "$PANEL" </dev/null >"$WORK_DIR/setup-output" 2>&1 &
local pid=$! ticks=0 status
while kill -0 "$pid" 2>/dev/null; do
if [ "$ticks" -ge 100 ]; then
kill "$pid"
fail "setup-env.sh kept waiting for a Steam key with nothing to read from"
fi
sleep 0.1
ticks=$((ticks + 1))
done
wait "$pid"
status=$?
[ "$status" -ne 0 ] || fail "setup-env.sh carried on without a Steam key"
assert_contains "$(cat "$WORK_DIR/setup-output")" "has no STEAM_WEB_API_KEY"
}

use_vault() {
sed 's/^VAULT_MANAGER=false$/VAULT_MANAGER=true/' "$PANEL/.5stack-env.config" >"$PANEL/.5stack-env.config.tmp"
mv "$PANEL/.5stack-env.config.tmp" "$PANEL/.5stack-env.config"
mkdir -p "$WORK_DIR/bin"
printf '#!/bin/sh\necho "$*" >>"%s/vault-calls"\nexit 1\n' "$WORK_DIR" >"$WORK_DIR/bin/vault"
chmod +x "$WORK_DIR/bin/vault"
export PATH="$WORK_DIR/bin:$PATH"
}

test_the_5stack_service_runs_a_vault_install_without_the_vault_cli() {
make_panel
set_sibling_domains
use_vault
FIVESTACK_RELEASE=2026.11.1.1 run_setup_env
[ ! -e "$WORK_DIR/vault-calls" ] || fail "setup-env.sh called vault: $(cat "$WORK_DIR/vault-calls")"
}

test_update_sh_on_a_vault_install_still_checks_the_vault_login() {
make_panel
set_sibling_domains
use_vault
bash -c 'source "$1/utils/utils.sh"' _ "$PANEL" </dev/null >"$WORK_DIR/setup-output" 2>&1 && fail "setup-env.sh carried on without a Vault login"
assert_contains "$(cat "$WORK_DIR/vault-calls")" "status"
assert_contains "$(cat "$WORK_DIR/setup-output")" "Not logged into vault"
}

run_tests
2 changes: 1 addition & 1 deletion update.sh
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ step "Updating the TimescaleDB extension"
update_timescaledb_extension
finish_timescaledb_major_upgrade

GIT_SHA=$(git rev-parse HEAD)
GIT_SHA="${FIVESTACK_RELEASE:-$(git rev-parse HEAD)}"

kubectl --kubeconfig=$KUBECONFIG label node $(kubectl --kubeconfig=$KUBECONFIG get nodes --selector='node-role.kubernetes.io/control-plane' -o jsonpath='{.items[0].metadata.name}') 5stack-panel-version=$GIT_SHA --overwrite

Expand Down
7 changes: 7 additions & 0 deletions utils/apply_overlay.sh
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,13 @@ apply_overlay() {
return 1
fi

# Set by the 5Stack service: it checks what this apply changes and may hold new matches first.
if [ -n "${FIVESTACK_PRE_APPLY:-}" ] && ! output="$("$FIVESTACK_PRE_APPLY" "$rendered" 2>&1)"; then
err "the 5Stack service stopped $overlay from being applied:"
echo "$output" | sed 's/^/ /' >&2
return 1
fi

for ((attempt = 1; attempt <= attempts; attempt++)); do
if output="$(kubectl "${kc[@]}" apply -f "$rendered" 2>&1)"; then
if [ "$DEBUG" = true ]; then
Expand Down
3 changes: 2 additions & 1 deletion utils/setup-env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,8 @@ fi

setup_steam_web_api_key "overlays/local-secrets/steam-secrets.env"

if [ "$VAULT_MANAGER" = true ]; then
# The 5Stack service sets FIVESTACK_RELEASE and handles Vault itself; it asks before writing to it.
if [ "$VAULT_MANAGER" = true ] && [ -z "${FIVESTACK_RELEASE:-}" ]; then
if ! command -v vault &> /dev/null; then
echo "Error: vault CLI is not installed. Please install it first (https://developer.hashicorp.com/vault/install)."
exit 1
Expand Down
4 changes: 3 additions & 1 deletion utils/setup_steam_web_api_key.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ setup_steam_web_api_key() {

while [ -z "$STEAM_WEB_API_KEY" ]; do
echo "Please enter your Steam Web API key (required for Steam authentication). Get one at: https://steamcommunity.com/dev/apikey"
read STEAM_WEB_API_KEY
if ! read -r STEAM_WEB_API_KEY; then
die "$secrets_file has no STEAM_WEB_API_KEY and there is no terminal to ask for one. Add it to that file and run this again."
fi
done

update_env_var "$secrets_file" "STEAM_WEB_API_KEY" "$STEAM_WEB_API_KEY"
Expand Down
Loading