syntaxai/tdd.md · main · scripts / p620 / deploy-cloudflared.sh
#!/usr/bin/env bash
# Deploy Cloudflare Tunnel connector voor tdd.md op een remote host
# (default: p620) als podman Quadlet. Volledig idempotent: detecteert
# wijzigingen in Quadlet + secret, restart alleen indien nodig.
#
# Aparte container/secret-naam zodat dit naast een eventuele bestaande
# 'cloudflared' (Umbraco-tunnel) kan draaien.
#
# Token-input (eerste run of bij rotatie):
# echo 'eyJh...' | ./scripts/p620/deploy-cloudflared.sh
# TDD_CLOUDFLARED_TOKEN='eyJh...' ./scripts/p620/deploy-cloudflared.sh
#
# Zonder token-input: gebruikt de al aanwezige secret op de remote (no-op
# bij niets gewijzigd).
#
# Usage:
# ./scripts/p620/deploy-cloudflared.sh
# ./scripts/p620/deploy-cloudflared.sh --host other-host
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SSH_HOST="p620"
while [[ $# -gt 0 ]]; do
case "$1" in
--host) SSH_HOST="$2"; shift 2 ;;
-h|--help) sed -n '2,18p' "$0" | sed 's/^# \?//'; exit 0 ;;
*) echo "✗ unknown arg: $1"; exit 1 ;;
esac
done
# Token uit env of stdin lezen (lege string = geen update).
TOKEN=""
if [[ -n "${TDD_CLOUDFLARED_TOKEN:-}" ]]; then
TOKEN="$TDD_CLOUDFLARED_TOKEN"
elif [[ ! -t 0 ]]; then
TOKEN=$(cat)
fi
TOKEN="${TOKEN//[$'\r\n\t ']/}"
echo "→ preflight op $SSH_HOST"
ssh "$SSH_HOST" 'command -v podman >/dev/null && command -v systemctl >/dev/null' \
|| { echo "✗ podman of systemctl ontbreekt op $SSH_HOST"; exit 1; }
need_restart=0
hash_str() { printf '%s' "$1" | sha256sum | awk '{print $1}'; }
echo "→ token secret"
secret_exists=$(ssh "$SSH_HOST" "podman secret exists tdd_cloudflared_token && echo yes || echo no")
if [[ -n "$TOKEN" ]]; then
want=$(hash_str "$TOKEN")
have=""
if [[ "$secret_exists" == "yes" ]]; then
have=$(ssh "$SSH_HOST" "podman secret inspect tdd_cloudflared_token --format '{{if .Spec.Labels}}{{index .Spec.Labels \"hash\"}}{{end}}'" 2>/dev/null || true)
fi
if [[ "$want" == "$have" ]]; then
echo " ✓ secret 'tdd_cloudflared_token' actueel"
else
ssh "$SSH_HOST" "podman secret rm tdd_cloudflared_token >/dev/null 2>&1 || true"
printf '%s' "$TOKEN" | ssh "$SSH_HOST" "podman secret create --label hash=$want tdd_cloudflared_token -" >/dev/null
echo " ✓ secret 'tdd_cloudflared_token' geüpdatet"
need_restart=1
fi
else
if [[ "$secret_exists" != "yes" ]]; then
echo "✗ geen token meegegeven en geen bestaande secret op $SSH_HOST."
echo " Eerste keer: pipe de Tunnel-token via stdin."
echo " echo '<token>' | ./scripts/p620/deploy-cloudflared.sh"
exit 1
fi
echo " ✓ bestaande secret hergebruikt"
fi
echo "→ Quadlet sync"
ssh "$SSH_HOST" 'mkdir -p ~/.config/containers/systemd'
local_hash=$(sha256sum "$SCRIPT_DIR/tdd-cloudflared.container" | awk '{print $1}')
remote_hash=$(ssh "$SSH_HOST" 'sha256sum ~/.config/containers/systemd/tdd-cloudflared.container 2>/dev/null | awk "{print \$1}"' || true)
if [[ "$local_hash" != "$remote_hash" ]]; then
scp -q "$SCRIPT_DIR/tdd-cloudflared.container" \
"$SSH_HOST:.config/containers/systemd/tdd-cloudflared.container"
echo " ✓ Quadlet bijgewerkt"
need_restart=1
else
echo " ✓ Quadlet ongewijzigd"
fi
echo "→ systemd apply (need_restart=$need_restart)"
if [[ "$need_restart" -eq 1 ]]; then
ssh "$SSH_HOST" 'systemctl --user daemon-reload && systemctl --user restart tdd-cloudflared.service'
else
ssh "$SSH_HOST" 'systemctl --user daemon-reload && systemctl --user start tdd-cloudflared.service'
fi
echo -n "→ wachten tot tunnel verbonden is "
for _ in $(seq 1 20); do
if ssh "$SSH_HOST" 'podman logs --tail 50 tdd-cloudflared 2>&1 | grep -q "Registered tunnel connection"'; then
echo "✓"
echo "✓ deploy klaar — tunnel is verbonden met Cloudflare"
exit 0
fi
echo -n "."
sleep 2
done
echo ""
echo "⚠ tunnel-registratie nog niet gezien in logs. Recente output:"
ssh "$SSH_HOST" 'podman logs --tail 30 tdd-cloudflared 2>&1' | sed 's/^/ /'
exit 1