Files
images/images/node-agent/test.sh
T
rmcguire 6ceb78b00c
Build Images / Select images (push) Successful in 11s
Lint / Lint (push) Successful in 37s
Build Images / Build changed images (push) Successful in 2m1s
rm kubeconform
2026-08-10 17:15:13 -04:00

97 lines
4.0 KiB
Bash
Executable File

#!/usr/bin/env bash
# Smoke-test node-agent.
#
# Two things are verified: every tool the README advertises is present and runnable,
# and the image behaves under the restrictions it is actually deployed with
# (non-root, read-only root filesystem, all capabilities dropped).
#
# Usage: test.sh [image-ref]
set -euo pipefail
REF="${1:-node-agent:dev}"
echo "==> smoke-testing ${REF}"
# Deliberately mirrors the ToolHive securityContext for the shell MCP server:
# runAsUser 1000, readOnlyRootFilesystem, capabilities drop ALL.
docker run --rm --interactive \
--user 1000:1000 \
--read-only \
--tmpfs /tmp:rw,size=64m \
--cap-drop ALL \
--env HOME=/tmp \
"$REF" bash -s <<'INNER'
set -uo pipefail
fail=0
ok() { printf ' \033[32mok\033[0m %s\n' "$1"; }
bad() { printf ' \033[31mFAIL\033[0m %s\n' "$1"; fail=1; }
have() { command -v "$1" >/dev/null 2>&1 && ok "$1" || bad "$1 (not on PATH)"; }
works(){ local d=$1; shift; if "$@" >/dev/null 2>&1; then ok "$d"; else bad "$d"; fi; }
# Only the first line is checked, because a BusyBox applet's later output can
# mention the GNU GPL and would false-positive. `sed -n 1p` rather than `head -1`
# so the reader consumes all input: head exits early, which under `pipefail`
# SIGPIPEs the producer and fails the pipeline nondeterministically.
gnu() {
local first
first=$("$1" --version 2>/dev/null | sed -n '1p')
case $first in
*GNU*) ok "$1 is GNU" ;;
*) bad "$1 is not GNU (${first:-no output})" ;;
esac
}
echo "-- present on PATH"
for t in bash sh curl wget jq yq yamllint helm kubectl git git-lfs ssh scp dig nslookup \
host nc socat rsync ping rg fd tar gzip xz zip unzip less file patch tree make \
ps top free tini su-exec node npm npx openssl base64 env xargs; do
have "$t"
done
echo "-- GNU userland, not busybox (flag compatibility matters for agent scripts)"
for t in grep sed awk find sort diff; do gnu "$t"; done
echo "-- functional"
works 'jq filters' bash -c 'echo "{\"a\":1}" | jq -e ".a == 1"'
works 'yq filters' bash -c 'printf "a: 1\n" | yq -e ".a == 1"'
works 'helm runs' helm version --short
works 'helm template' bash -c 'helm create /tmp/c >/dev/null && helm template /tmp/c >/dev/null'
works 'kubectl client' kubectl version --client
works 'git init' bash -c 'git init -q /tmp/r && git -C /tmp/r status --short'
works 'rg searches' bash -c 'printf "needle\n" >/tmp/h && rg -q needle /tmp/h'
works 'fd finds' bash -c 'fd -1 . /tmp >/dev/null'
works 'dig runs' dig -v
works 'openssl runs' openssl version
works 'node runs' node -e 'process.exit(0)'
works 'yamllint flags bad' bash -c '! printf "a: [\n" | yamllint - >/dev/null 2>&1'
works 'yamllint passes ok' bash -c 'printf "a: 1\n" | yamllint -d relaxed -'
echo "-- deployment contract"
[ "$(id -u)" = 1000 ] && ok 'runs as uid 1000' || bad "runs as uid $(id -u), want 1000"
touch /tmp/writable 2>/dev/null && ok '/tmp is writable' || bad '/tmp is not writable'
if touch /should-not-work 2>/dev/null; then
bad 'root filesystem is writable (expected read-only)'
else
ok 'root filesystem is read-only'
fi
# Pagers must be disabled or git/kubectl/helm hang with no TTY attached.
[ "${PAGER:-}" = cat ] && ok 'PAGER=cat' || bad "PAGER=${PAGER:-unset}, want cat"
[ "${GIT_TERMINAL_PROMPT:-}" = 0 ] && ok 'GIT_TERMINAL_PROMPT=0' \
|| bad 'GIT_TERMINAL_PROMPT not 0'
echo
[ "$fail" = 0 ] && echo "all checks passed" || echo "FAILURES above"
exit "$fail"
INNER
# The default CMD should land in a usable shell rather than the node REPL. Pass no
# arguments so the image's own CMD runs, and feed the script on stdin — the base
# image's docker-entrypoint.sh rewrites a leading "-c" into a `node` invocation.
echo "==> checking default CMD"
if [ "$(echo 'echo shell-ok' | docker run --rm --interactive "$REF")" = shell-ok ]; then
echo " ok default CMD is bash"
else
echo " FAIL default CMD is not bash"
exit 1
fi