host-metrics: entrypoint + offline tests
Add telegraf-entrypoint.sh to render telegraf.conf from the template (replacing @@HOST_TAG_BLOCK@@ and @@ZFS_BLOCK@@ markers via awk) and exec telegraf. Add test-telegraf-entrypoint.sh with 8 offline tests (10 assertions) covering marker substitution and required-env validation. Fix run() stderr redirect from >/dev/null 2>&1 to >/dev/null so that entrypoint error output reaches the T6-T8 assertion captures. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>pull/753/head
parent
f5adcfc77e
commit
f898d65983
|
|
@ -0,0 +1,68 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# host-metrics telegraf-entrypoint.sh
|
||||||
|
# Render telegraf.conf from telegraf.conf.tpl, then exec telegraf.
|
||||||
|
#
|
||||||
|
# Substitutions performed here (by awk):
|
||||||
|
# @@HOST_TAG_BLOCK@@ -> "[global_tags]\n host = \"$HOST_TAG\"" if set, else empty.
|
||||||
|
# @@ZFS_BLOCK@@ -> "[[inputs.zfs]]\n poolMetrics = true" if COLLECT_ZFS=true, else empty.
|
||||||
|
#
|
||||||
|
# Variables of the form ${VAR} in the template (INFLUXDB_URL, INFLUXDB_DB,
|
||||||
|
# INFLUXDB_USER, INFLUXDB_PASSWORD, COLLECT_INTERVAL) are resolved by
|
||||||
|
# telegraf's own env-var substitution at config-load time and are NOT
|
||||||
|
# touched by this script.
|
||||||
|
#
|
||||||
|
# TELEGRAF_CONF_DIR overrides the conf directory for tests; defaults to
|
||||||
|
# /etc/telegraf which is the standard path inside the official image.
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
CONF_DIR="${TELEGRAF_CONF_DIR:-/etc/telegraf}"
|
||||||
|
TPL="$CONF_DIR/telegraf.conf.tpl"
|
||||||
|
OUT="$CONF_DIR/telegraf.conf"
|
||||||
|
|
||||||
|
# Fail-fast required env. Empty string counts as missing -- a half-rendered
|
||||||
|
# conf or a noisy telegraf auth error is worse than a clear startup failure.
|
||||||
|
for v in INFLUXDB_URL INFLUXDB_USER INFLUXDB_PASSWORD; do
|
||||||
|
eval val=\${$v:-}
|
||||||
|
if [ -z "$val" ]; then
|
||||||
|
echo "FATAL: $v is required but empty" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Apply defaults for optional vars.
|
||||||
|
: "${INFLUXDB_DB:=host_metrics}"
|
||||||
|
: "${COLLECT_INTERVAL:=10s}"
|
||||||
|
: "${HOST_TAG:=}"
|
||||||
|
: "${COLLECT_ZFS:=false}"
|
||||||
|
|
||||||
|
# Build the marker substitutions. Use printf for the newline so the
|
||||||
|
# rendered block lands on its own line.
|
||||||
|
if [ -n "$HOST_TAG" ]; then
|
||||||
|
HOST_TAG_BLOCK=$(printf '[global_tags]\n host = "%s"' "$HOST_TAG")
|
||||||
|
else
|
||||||
|
HOST_TAG_BLOCK=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$COLLECT_ZFS" = "true" ]; then
|
||||||
|
ZFS_BLOCK=$(printf '[[inputs.zfs]]\n poolMetrics = true')
|
||||||
|
else
|
||||||
|
ZFS_BLOCK=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Export telegraf hostfs envs so /proc, /sys, and root come from the
|
||||||
|
# bind-mount under /hostfs (set in compose).
|
||||||
|
export HOST_PROC=/hostfs/proc
|
||||||
|
export HOST_SYS=/hostfs/sys
|
||||||
|
export HOST_MOUNT_PREFIX=/hostfs
|
||||||
|
|
||||||
|
# Render with awk: handles multi-line replacement values cleanly,
|
||||||
|
# avoids sed's newline-in-replacement portability quirks across BusyBox /
|
||||||
|
# GNU / BSD sed.
|
||||||
|
awk -v ht="$HOST_TAG_BLOCK" -v zb="$ZFS_BLOCK" '
|
||||||
|
{ gsub(/@@HOST_TAG_BLOCK@@/, ht);
|
||||||
|
gsub(/@@ZFS_BLOCK@@/, zb);
|
||||||
|
print }
|
||||||
|
' "$TPL" > "$OUT"
|
||||||
|
|
||||||
|
exec telegraf --config "$OUT"
|
||||||
|
|
@ -0,0 +1,121 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Offline tests for host-metrics telegraf-entrypoint.sh.
|
||||||
|
# Stubs telegraf and envsubst's downstream consumer; no telegraf binary needed.
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
|
||||||
|
ENTRYPOINT="$SCRIPT_DIR/telegraf-entrypoint.sh"
|
||||||
|
|
||||||
|
[ -x "$ENTRYPOINT" ] || { echo "FATAL: $ENTRYPOINT not executable"; exit 2; }
|
||||||
|
|
||||||
|
TMP=$(mktemp -d)
|
||||||
|
trap 'rm -rf "$TMP"' EXIT
|
||||||
|
mkdir -p "$TMP/bin" "$TMP/etc/telegraf"
|
||||||
|
|
||||||
|
# Stub telegraf so `exec telegraf` is a no-op.
|
||||||
|
cat > "$TMP/bin/telegraf" <<'EOF'
|
||||||
|
#!/bin/sh
|
||||||
|
exit 0
|
||||||
|
EOF
|
||||||
|
chmod +x "$TMP/bin/telegraf"
|
||||||
|
|
||||||
|
# Minimal template that exercises both markers.
|
||||||
|
cat > "$TMP/etc/telegraf/telegraf.conf.tpl" <<'EOF'
|
||||||
|
@@HOST_TAG_BLOCK@@
|
||||||
|
|
||||||
|
[agent]
|
||||||
|
interval = "${COLLECT_INTERVAL}"
|
||||||
|
|
||||||
|
[[outputs.influxdb]]
|
||||||
|
urls = ["${INFLUXDB_URL}"]
|
||||||
|
|
||||||
|
@@ZFS_BLOCK@@
|
||||||
|
EOF
|
||||||
|
|
||||||
|
PASS=0
|
||||||
|
FAIL=0
|
||||||
|
|
||||||
|
# run sets required env defaults, then layers caller env on top.
|
||||||
|
run() {
|
||||||
|
env PATH="$TMP/bin:$PATH" \
|
||||||
|
TELEGRAF_CONF_DIR="$TMP/etc/telegraf" \
|
||||||
|
INFLUXDB_URL="${INFLUXDB_URL-http://example/}" \
|
||||||
|
INFLUXDB_USER="${INFLUXDB_USER-writer}" \
|
||||||
|
INFLUXDB_PASSWORD="${INFLUXDB_PASSWORD-secret}" \
|
||||||
|
INFLUXDB_DB="${INFLUXDB_DB-host_metrics}" \
|
||||||
|
COLLECT_INTERVAL="${COLLECT_INTERVAL-10s}" \
|
||||||
|
HOST_TAG="${HOST_TAG-}" \
|
||||||
|
COLLECT_ZFS="${COLLECT_ZFS-false}" \
|
||||||
|
sh "$ENTRYPOINT" >/dev/null
|
||||||
|
rc=$?
|
||||||
|
[ -f "$TMP/etc/telegraf/telegraf.conf" ] && cat "$TMP/etc/telegraf/telegraf.conf"
|
||||||
|
return $rc
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_grep() {
|
||||||
|
name=$1; actual=$2; pattern=$3
|
||||||
|
if printf '%s' "$actual" | grep -qE "$pattern"; then
|
||||||
|
echo "PASS: $name"; PASS=$((PASS + 1))
|
||||||
|
else
|
||||||
|
echo "FAIL: $name"
|
||||||
|
echo " expected pattern: $pattern"
|
||||||
|
echo " actual: $actual"
|
||||||
|
FAIL=$((FAIL + 1))
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_not_grep() {
|
||||||
|
name=$1; actual=$2; pattern=$3
|
||||||
|
if printf '%s' "$actual" | grep -qE "$pattern"; then
|
||||||
|
echo "FAIL: $name (matched pattern $pattern)"; FAIL=$((FAIL + 1))
|
||||||
|
else
|
||||||
|
echo "PASS: $name"; PASS=$((PASS + 1))
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# T1: HOST_TAG unset -> no [global_tags] block emitted
|
||||||
|
out=$(HOST_TAG="" run)
|
||||||
|
assert_not_grep "T1: HOST_TAG empty -> no global_tags" "$out" '^\[global_tags\]'
|
||||||
|
|
||||||
|
# T2: HOST_TAG set -> [global_tags] block with host = "<value>"
|
||||||
|
out=$(HOST_TAG="validator-1" run)
|
||||||
|
assert_grep "T2: HOST_TAG set -> [global_tags] block" "$out" '^\[global_tags\]'
|
||||||
|
assert_grep "T2: HOST_TAG set -> host = \"validator-1\"" "$out" 'host = "validator-1"'
|
||||||
|
|
||||||
|
# T3: COLLECT_ZFS=true -> [[inputs.zfs]] block present
|
||||||
|
out=$(COLLECT_ZFS="true" run)
|
||||||
|
assert_grep "T3: COLLECT_ZFS true -> inputs.zfs block" "$out" '\[\[inputs\.zfs\]\]'
|
||||||
|
|
||||||
|
# T4: COLLECT_ZFS=false -> no inputs.zfs block
|
||||||
|
out=$(COLLECT_ZFS="false" run)
|
||||||
|
assert_not_grep "T4: COLLECT_ZFS false -> no inputs.zfs" "$out" '\[\[inputs\.zfs\]\]'
|
||||||
|
|
||||||
|
# T5: markers fully removed even when block bodies are empty
|
||||||
|
out=$(HOST_TAG="" COLLECT_ZFS="false" run)
|
||||||
|
assert_not_grep "T5: no leftover @@HOST_TAG_BLOCK@@" "$out" '@@HOST_TAG_BLOCK@@'
|
||||||
|
assert_not_grep "T5: no leftover @@ZFS_BLOCK@@" "$out" '@@ZFS_BLOCK@@'
|
||||||
|
|
||||||
|
# T6: missing INFLUXDB_URL -> exit non-zero, error on stderr
|
||||||
|
rc=0
|
||||||
|
INFLUXDB_URL="" run 2>"$TMP/err" || rc=$?
|
||||||
|
[ "$rc" -ne 0 ] && grep -q INFLUXDB_URL "$TMP/err" \
|
||||||
|
&& { echo "PASS: T6: missing INFLUXDB_URL -> error"; PASS=$((PASS + 1)); } \
|
||||||
|
|| { echo "FAIL: T6: missing INFLUXDB_URL handling (rc=$rc)"; FAIL=$((FAIL + 1)); }
|
||||||
|
|
||||||
|
# T7: missing INFLUXDB_USER -> exit non-zero
|
||||||
|
rc=0
|
||||||
|
INFLUXDB_USER="" run 2>"$TMP/err" || rc=$?
|
||||||
|
[ "$rc" -ne 0 ] && grep -q INFLUXDB_USER "$TMP/err" \
|
||||||
|
&& { echo "PASS: T7: missing INFLUXDB_USER -> error"; PASS=$((PASS + 1)); } \
|
||||||
|
|| { echo "FAIL: T7: missing INFLUXDB_USER handling (rc=$rc)"; FAIL=$((FAIL + 1)); }
|
||||||
|
|
||||||
|
# T8: missing INFLUXDB_PASSWORD -> exit non-zero
|
||||||
|
rc=0
|
||||||
|
INFLUXDB_PASSWORD="" run 2>"$TMP/err" || rc=$?
|
||||||
|
[ "$rc" -ne 0 ] && grep -q INFLUXDB_PASSWORD "$TMP/err" \
|
||||||
|
&& { echo "PASS: T8: missing INFLUXDB_PASSWORD -> error"; PASS=$((PASS + 1)); } \
|
||||||
|
|| { echo "FAIL: T8: missing INFLUXDB_PASSWORD handling (rc=$rc)"; FAIL=$((FAIL + 1)); }
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "Results: $PASS passed, $FAIL failed"
|
||||||
|
[ "$FAIL" = "0" ]
|
||||||
Loading…
Reference in New Issue