Move kea entrypoints out of Go fmt.Sprintf into an initContainer
Container entrypoints were rendered as `fmt.Sprintf` shell strings in Go, so every entrypoint fix needed a full operator release, nothing was shellcheckable, and the escaping was a hazard. How: - Add a `kea-init` initContainer that finalises the per-pod config and bounded-waits for HA peer DNS, replacing the in-entrypoint retry. It hardens the shared run dir to 0750, substitutes `this-server-name` from the pod ordinal (`POD_NAME` via the downward API), stages both configs into the shared emptyDir, and gates on `kea-dhcp4 -t` (60x2s) — failing loud after the cap so the kubelet restarts it instead of starting a doomed server. - Run the main kea-dhcp4 / kea-ctrl-agent containers with kea exec'd directly, dropping both wrapper shells. - Replace the two `fmt.Sprintf` entrypoints with a single committed `internal/kea/scripts/init.sh` embedded via `go:embed` and parameterised entirely by env vars — no Go string interpolation. - Add a shellcheck step to the pre-commit pipeline. Test: - Assert the pod shape: one kea-init initContainer, POD_NAME from the downward API, main containers exec kea directly, and the ConfigMap carries init.sh (not the old per-container entrypoints). - Assert init.sh hardens the socket dir, gates on `kea-dhcp4 -t`, fails loud after the cap, and is free of fmt verbs. - shellcheck the embedded script.
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
#!/bin/sh
|
||||
# kea-operator initContainer.
|
||||
#
|
||||
# Prepares the shared run dir, finalises this pod's kea-dhcp4 config (the HA
|
||||
# this-server-name is derived from the StatefulSet ordinal, known only at pod
|
||||
# start), and waits for the HA peer DNS to resolve before the main kea
|
||||
# containers start. Every input arrives as an environment variable set by the
|
||||
# operator; nothing is interpolated into this file, so it is shellcheck-clean
|
||||
# and testable on its own.
|
||||
set -eu
|
||||
|
||||
# StatefulSet pod names are "<sts>-<ordinal>"; the ordinal is this HA peer's id.
|
||||
ord="${POD_NAME##*-}"
|
||||
|
||||
# The run dir is a shared emptyDir. Kea 2.6+ refuses a control socket in a
|
||||
# world-accessible directory, so tighten it to 0750.
|
||||
mkdir -p "$RUN_DIR"
|
||||
chmod 0750 "$RUN_DIR"
|
||||
|
||||
# Finalise the per-pod dhcp4 config: substitute this pod's HA peer name into the
|
||||
# shared (pod-independent) config projected from the ConfigMap.
|
||||
sed "s/${THIS_SERVER_PLACEHOLDER}/server${ord}/g" \
|
||||
"${CONFIG_DIR}/kea-dhcp4.conf" >"$DHCP4_CONF"
|
||||
|
||||
# The ctrl-agent config is pod-independent; stage it in the shared run dir so
|
||||
# the main container can exec kea directly with no wrapper.
|
||||
cp "${CONFIG_DIR}/kea-ctrl-agent.conf" "$CTRL_AGENT_CONF"
|
||||
|
||||
# The HA hook resolves peer URL hostnames once at load; on a cold start the
|
||||
# StatefulSet peer DNS records may not resolve yet and kea exits hard instead of
|
||||
# retrying. Wait (bounded) for the config to validate, then fail loud so the
|
||||
# kubelet restarts this initContainer rather than starting a doomed server.
|
||||
i=0
|
||||
until "$DHCP4_BIN" -t "$DHCP4_CONF" >/dev/null 2>&1; do
|
||||
i=$((i + 1))
|
||||
if [ "$i" -ge "$WAIT_ATTEMPTS" ]; then
|
||||
echo "kea-init: config failed to validate after ${WAIT_ATTEMPTS} attempts" >&2
|
||||
exit 1
|
||||
fi
|
||||
sleep "$WAIT_SLEEP"
|
||||
done
|
||||
Reference in New Issue
Block a user