183 lines
6.4 KiB
Bash
Executable file
183 lines
6.4 KiB
Bash
Executable file
#!/bin/bash
|
|
# install-fleet_base.sh — taskserv installer for fleet base node setup.
|
|
# Runs on the target Debian/Ubuntu host as root. Idempotent.
|
|
#
|
|
# Inputs (env file scp'd alongside this script):
|
|
# FLEET_AGE_KEY — age private key content
|
|
# FLEET_KEY_INSTALL_PATH — target path (default /etc/fleet/age.key)
|
|
# FLEET_REGISTRY_COUNT — number of registries
|
|
# FLEET_REGISTRY_N_NAME — registry name (N = 0-based index)
|
|
# FLEET_REGISTRY_N_ENDPOINT — registry endpoint
|
|
# FLEET_REGISTRY_N_USERNAME — registry username
|
|
# FLEET_REGISTRY_N_PASSWORD — registry password
|
|
# SCCACHE_ENDPOINT — (optional) S3 endpoint
|
|
# SCCACHE_BUCKET — (optional) S3 bucket
|
|
# SCCACHE_REGION — (optional) S3 region
|
|
# SCCACHE_DISK_PATH — (optional) local disk cache path
|
|
# SCCACHE_ACCESS_KEY — (optional) S3 access key id
|
|
# SCCACHE_SECRET_KEY — (optional) S3 secret access key
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
|
|
for f in env-fleet_base _credentials.env; do
|
|
[ -f "${SCRIPT_DIR}/${f}" ] && source "${SCRIPT_DIR}/${f}" || true
|
|
done
|
|
|
|
: "${FLEET_AGE_KEY:?FLEET_AGE_KEY must be set}"
|
|
|
|
FLEET_KEY_INSTALL_PATH="${FLEET_KEY_INSTALL_PATH:-/etc/fleet/age.key}"
|
|
FLEET_REGISTRY_COUNT="${FLEET_REGISTRY_COUNT:-0}"
|
|
|
|
bold() { printf "\033[1m%s\033[0m\n" "$*"; }
|
|
fatal() { printf "\033[31mFATAL:\033[0m %s\n" "$*" >&2; exit 1; }
|
|
|
|
[ "$(id -u)" -eq 0 ] || fatal "must run as root"
|
|
[ "$FLEET_AGE_KEY" != "UNSET" ] || fatal "FLEET_AGE_KEY is sentinel 'UNSET'"
|
|
|
|
ACTION="${1:-install}"
|
|
|
|
cmd_install() {
|
|
bold "==> [1/4] System packages"
|
|
export DEBIAN_FRONTEND=noninteractive
|
|
apt-get update -qq
|
|
apt-get install -y -qq openssl openssh-server
|
|
systemctl enable --now ssh
|
|
|
|
bold "==> [2/4] Fleet age key → ${FLEET_KEY_INSTALL_PATH}"
|
|
install -d -m 0700 "$(dirname "${FLEET_KEY_INSTALL_PATH}")"
|
|
printf '%s\n' "${FLEET_AGE_KEY}" > "${FLEET_KEY_INSTALL_PATH}"
|
|
chmod 0600 "${FLEET_KEY_INSTALL_PATH}"
|
|
echo " installed age key at ${FLEET_KEY_INSTALL_PATH}"
|
|
|
|
bold "==> [3/4] OCI registry auth (${FLEET_REGISTRY_COUNT} registries)"
|
|
if [ "${FLEET_REGISTRY_COUNT}" -gt 0 ]; then
|
|
AUTH_DIR="/etc/containers"
|
|
install -d -m 0755 "${AUTH_DIR}"
|
|
|
|
# Build auths JSON by iterating indexed env vars — no jq required
|
|
AUTHS_JSON="{"
|
|
SEP=""
|
|
for i in $(seq 0 $((FLEET_REGISTRY_COUNT - 1))); do
|
|
name_var="FLEET_REGISTRY_${i}_NAME"
|
|
ep_var="FLEET_REGISTRY_${i}_ENDPOINT"
|
|
user_var="FLEET_REGISTRY_${i}_USERNAME"
|
|
pass_var="FLEET_REGISTRY_${i}_PASSWORD"
|
|
|
|
name="${!name_var}"
|
|
endpoint="${!ep_var}"
|
|
username="${!user_var:-}"
|
|
password="${!pass_var:-}"
|
|
|
|
[ -n "${username}" ] || { echo " WARN: ${name} has no username, skipping"; continue; }
|
|
|
|
b64=$(printf '%s:%s' "${username}" "${password}" | openssl base64 -A)
|
|
AUTHS_JSON="${AUTHS_JSON}${SEP}\"${endpoint}\":{\"auth\":\"${b64}\"}"
|
|
SEP=","
|
|
echo " configured registry ${name} (${endpoint})"
|
|
done
|
|
AUTHS_JSON="${AUTHS_JSON}}"
|
|
|
|
# Merge with any existing auth.json in pure bash — no extra tooling on the node.
|
|
# This manager writes compact JSON and auth values are flat objects
|
|
# ("ep":{"auth":"b64"[,"identitytoken":"…"]}), so each entry is matched by a
|
|
# single grep; existing entries the incoming set overrides are dropped.
|
|
if [ -f "${AUTH_DIR}/auth.json" ]; then
|
|
incoming_body="${AUTHS_JSON#\{}"; incoming_body="${incoming_body%\}}"
|
|
|
|
incoming_keys=" "
|
|
while IFS= read -r _e; do
|
|
[ -z "$_e" ] && continue
|
|
_k="${_e%%\":*}"; _k="${_k#\"}"
|
|
incoming_keys="${incoming_keys}${_k} "
|
|
done < <(printf '%s' "${incoming_body}" | grep -oE '"[^"]+":\{[^}]*\}')
|
|
|
|
existing_compact="$(tr -d ' \t\n' < "${AUTH_DIR}/auth.json")"
|
|
existing_entries="${existing_compact#\{\"auths\":\{}"
|
|
existing_entries="${existing_entries%\}\}}"
|
|
|
|
kept=""
|
|
while IFS= read -r _e; do
|
|
[ -z "$_e" ] && continue
|
|
_k="${_e%%\":*}"; _k="${_k#\"}"
|
|
case "${incoming_keys}" in *" ${_k} "*) continue ;; esac
|
|
kept="${kept},${_e}"
|
|
done < <(printf '%s' "${existing_entries}" | grep -oE '"[^"]+":\{[^}]*\}')
|
|
|
|
merged="${incoming_body}${kept}"; merged="${merged#,}"
|
|
printf '{"auths":{%s}}\n' "${merged}" > "${AUTH_DIR}/auth.json.new"
|
|
mv "${AUTH_DIR}/auth.json.new" "${AUTH_DIR}/auth.json"
|
|
else
|
|
printf '{"auths":%s}\n' "${AUTHS_JSON}" > "${AUTH_DIR}/auth.json"
|
|
fi
|
|
chmod 0600 "${AUTH_DIR}/auth.json"
|
|
echo " wrote ${AUTH_DIR}/auth.json"
|
|
else
|
|
echo " no registries configured"
|
|
fi
|
|
|
|
bold "==> [4/4] sccache env"
|
|
if [ -n "${SCCACHE_ENDPOINT:-}" ]; then
|
|
SCCACHE_DIR="/etc/sccache"
|
|
install -d -m 0755 "${SCCACHE_DIR}"
|
|
DISK_PATH="${SCCACHE_DISK_PATH:-/var/cache/sccache}"
|
|
install -d -m 1777 "${DISK_PATH}"
|
|
|
|
cat > "${SCCACHE_DIR}/sccache.env" <<EOF
|
|
SCCACHE_ENDPOINT=${SCCACHE_ENDPOINT}
|
|
SCCACHE_BUCKET=${SCCACHE_BUCKET:-}
|
|
SCCACHE_REGION=${SCCACHE_REGION:-}
|
|
SCCACHE_CACHE_SIZE=50G
|
|
SCCACHE_DIR=${DISK_PATH}
|
|
AWS_ACCESS_KEY_ID=${SCCACHE_ACCESS_KEY:-}
|
|
AWS_SECRET_ACCESS_KEY=${SCCACHE_SECRET_KEY:-}
|
|
EOF
|
|
chmod 0640 "${SCCACHE_DIR}/sccache.env"
|
|
echo " wrote ${SCCACHE_DIR}/sccache.env"
|
|
else
|
|
echo " sccache not configured"
|
|
fi
|
|
|
|
bold "==> Done"
|
|
}
|
|
|
|
cmd_status() {
|
|
echo "=== Fleet age key ==="
|
|
if [ -f "${FLEET_KEY_INSTALL_PATH}" ]; then
|
|
stat "${FLEET_KEY_INSTALL_PATH}"
|
|
head -1 "${FLEET_KEY_INSTALL_PATH}" | grep -o '^AGE-SECRET-KEY-1' || echo " (present, header not AGE-SECRET-KEY-1)"
|
|
else
|
|
echo " NOT installed at ${FLEET_KEY_INSTALL_PATH}"
|
|
fi
|
|
|
|
echo ""
|
|
echo "=== OCI registry auth ==="
|
|
if [ -f /etc/containers/auth.json ]; then
|
|
# list endpoints without exposing credentials
|
|
grep -o '"[^"]*":{"auth"' /etc/containers/auth.json | sed 's/:{"auth"//' || echo " (empty)"
|
|
else
|
|
echo " /etc/containers/auth.json not present"
|
|
fi
|
|
|
|
echo ""
|
|
echo "=== sccache env ==="
|
|
if [ -f /etc/sccache/sccache.env ]; then
|
|
grep -v 'SECRET\|KEY' /etc/sccache/sccache.env || true
|
|
else
|
|
echo " /etc/sccache/sccache.env not present"
|
|
fi
|
|
}
|
|
|
|
cmd_uninstall() {
|
|
rm -f "${FLEET_KEY_INSTALL_PATH}"
|
|
rmdir --ignore-fail-on-non-empty "$(dirname "${FLEET_KEY_INSTALL_PATH}")" 2>/dev/null || true
|
|
echo "uninstalled (auth.json and sccache.env preserved)"
|
|
}
|
|
|
|
case "$ACTION" in
|
|
install) cmd_install ;;
|
|
status) cmd_status ;;
|
|
uninstall) cmd_uninstall ;;
|
|
*) fatal "unknown action: $ACTION (install|status|uninstall)" ;;
|
|
esac
|