156 lines
5.8 KiB
Bash
Executable File
156 lines
5.8 KiB
Bash
Executable File
#!/bin/sh
|
|
set -eu
|
|
|
|
ROOT=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
|
|
"$ROOT/scripts/bootstrap-kubernetes-tools.sh"
|
|
PATH="$ROOT/.tools/bin:$PATH"
|
|
export PATH
|
|
|
|
CLUSTER=who-need-help
|
|
MARKER="$ROOT/.tools/${CLUSTER}.owned"
|
|
NAMESPACE=who-need-help
|
|
SECRET_NAME=who-need-help-local
|
|
POSTGIS_IMAGE=postgis/postgis:18-3.6-alpine
|
|
POSTGIS_SOURCE="${POSTGIS_IMAGE}@sha256:05d68c7f0f19b9aa0bf7c4a2049b2e8b38b44a63116392b95726a4c913766cf6"
|
|
MAILPIT_IMAGE=axllent/mailpit:v1.30.4
|
|
MAILPIT_SOURCE="${MAILPIT_IMAGE}@sha256:5a49a77c5bdbe7c5474450b4f46348d09949df3695257729c93a30369382d4f6"
|
|
|
|
kube() {
|
|
kubectl --context "kind-${CLUSTER}" "$@"
|
|
}
|
|
|
|
case "$(uname -m)" in
|
|
x86_64) IMAGE_ARCH=amd64 ;;
|
|
aarch64|arm64) IMAGE_ARCH=arm64 ;;
|
|
*) echo "Unsupported container architecture: $(uname -m)" >&2; exit 1 ;;
|
|
esac
|
|
|
|
load_pinned_image() {
|
|
source=$1
|
|
local_tag=$2
|
|
archive=$3
|
|
|
|
docker pull --platform "linux/${IMAGE_ARCH}" "$source"
|
|
image_id=$(docker image inspect "$source" --format '{{.Id}}')
|
|
docker tag "$image_id" "$local_tag"
|
|
docker image save --platform "linux/${IMAGE_ARCH}" --output "$archive" "$local_tag"
|
|
kind load image-archive "$archive" --name "$CLUSTER"
|
|
rm -f "$archive"
|
|
}
|
|
|
|
remove_legacy_inline_secrets() {
|
|
legacy_secret=who-need-help-who-need-help
|
|
|
|
# Older chart revisions rendered credentials from tracked Helm values. Once
|
|
# the new deployments are healthy, remove the obsolete Secret and only those
|
|
# release-history records that still contain the former inline secret keys.
|
|
kube --namespace "$NAMESPACE" delete secret "$legacy_secret" \
|
|
--ignore-not-found >/dev/null
|
|
|
|
for revision in $(
|
|
helm history who-need-help \
|
|
--kube-context "kind-${CLUSTER}" \
|
|
--namespace "$NAMESPACE" |
|
|
awk 'NR > 1 {print $1}'
|
|
); do
|
|
if helm get values who-need-help \
|
|
--revision "$revision" \
|
|
--kube-context "kind-${CLUSTER}" \
|
|
--namespace "$NAMESPACE" |
|
|
grep -Eq '^[[:space:]]*(databaseUrl|secretKeyBase|handoverSecret|releaseCookie):'; then
|
|
kube --namespace "$NAMESPACE" delete secret \
|
|
--selector="owner=helm,name=who-need-help,version=${revision}"
|
|
fi
|
|
done
|
|
}
|
|
|
|
if kind get clusters | grep -Fxq "$CLUSTER"; then
|
|
if [ ! -f "$MARKER" ]; then
|
|
echo "A kind cluster named '$CLUSTER' already exists but was not created by this project." >&2
|
|
echo "Refusing to modify it. Rename/remove it yourself or inspect it first." >&2
|
|
exit 1
|
|
fi
|
|
else
|
|
kind create cluster --config "$ROOT/deploy/kind/cluster.yaml"
|
|
touch "$MARKER"
|
|
fi
|
|
|
|
load_pinned_image "$POSTGIS_SOURCE" "$POSTGIS_IMAGE" "$ROOT/.tools/postgis-kind.tar"
|
|
load_pinned_image "$MAILPIT_SOURCE" "$MAILPIT_IMAGE" "$ROOT/.tools/mailpit-kind.tar"
|
|
|
|
docker build --tag who-need-help:local "$ROOT"
|
|
kind load docker-image who-need-help:local --name "$CLUSTER"
|
|
|
|
kube create namespace "$NAMESPACE" --dry-run=client --output=yaml | kube apply -f -
|
|
|
|
legacy_backup=
|
|
if kube --namespace "$NAMESPACE" get deployment postgis >/dev/null 2>&1; then
|
|
backup_dir="$ROOT/output/backups"
|
|
mkdir -p "$backup_dir"
|
|
umask 077
|
|
legacy_backup="$backup_dir/kind-who-need-help-$(date +%Y%m%d-%H%M%S).dump"
|
|
kube --namespace "$NAMESPACE" exec deployment/postgis -- \
|
|
pg_dump --username postgres --dbname who_need_help --format custom >"$legacy_backup"
|
|
test -s "$legacy_backup"
|
|
kube --namespace "$NAMESPACE" exec --stdin deployment/postgis -- \
|
|
pg_restore --list <"$legacy_backup" >/dev/null
|
|
echo "Validated legacy kind database backup: $legacy_backup"
|
|
fi
|
|
|
|
if ! kube --namespace "$NAMESPACE" get secret "$SECRET_NAME" >/dev/null 2>&1; then
|
|
if kube --namespace "$NAMESPACE" get statefulset postgis >/dev/null 2>&1; then
|
|
echo "Secret '$SECRET_NAME' is missing while the persistent PostGIS StatefulSet exists." >&2
|
|
echo "Refusing to generate credentials that would not match the existing database." >&2
|
|
exit 1
|
|
fi
|
|
|
|
postgres_password=$(openssl rand -hex 32)
|
|
secret_key_base=$(openssl rand -hex 64)
|
|
handover_secret=$(openssl rand -hex 64)
|
|
release_cookie=$(openssl rand -hex 64)
|
|
|
|
kube --namespace "$NAMESPACE" create secret generic "$SECRET_NAME" \
|
|
--from-literal=POSTGRES_DB=who_need_help \
|
|
--from-literal=POSTGRES_USER=postgres \
|
|
--from-literal="POSTGRES_PASSWORD=$postgres_password" \
|
|
--from-literal="DATABASE_URL=ecto://postgres:${postgres_password}@postgis/who_need_help" \
|
|
--from-literal="SECRET_KEY_BASE=$secret_key_base" \
|
|
--from-literal="HANDOVER_SECRET=$handover_secret" \
|
|
--from-literal="RELEASE_COOKIE=$release_cookie"
|
|
|
|
unset postgres_password secret_key_base handover_secret release_cookie
|
|
fi
|
|
|
|
if [ -n "$legacy_backup" ]; then
|
|
kube --namespace "$NAMESPACE" delete deployment postgis --wait=true
|
|
fi
|
|
|
|
kube --namespace "$NAMESPACE" apply -f "$ROOT/deploy/kind/dependencies.yaml"
|
|
kube --namespace "$NAMESPACE" rollout status statefulset/postgis
|
|
kube --namespace "$NAMESPACE" rollout status deployment/mailpit
|
|
|
|
if [ -n "$legacy_backup" ]; then
|
|
kube --namespace "$NAMESPACE" exec --stdin statefulset/postgis -- \
|
|
pg_restore --username postgres --dbname who_need_help \
|
|
--clean --if-exists --no-owner <"$legacy_backup"
|
|
echo "Restored legacy kind database backup."
|
|
fi
|
|
|
|
helm upgrade --install who-need-help "$ROOT/deploy/helm/who-need-help" \
|
|
--kube-context "kind-${CLUSTER}" \
|
|
--namespace "$NAMESPACE" \
|
|
--values "$ROOT/deploy/helm/who-need-help/values-kind.yaml" \
|
|
--set-string app.codexSessionId="${CODEX_SESSION_ID:-${CODEX_THREAD_ID:-not-configured}}" \
|
|
--wait
|
|
|
|
kube --namespace "$NAMESPACE" rollout restart \
|
|
deployment/who-need-help-who-need-help-web \
|
|
deployment/who-need-help-who-need-help-worker
|
|
kube --namespace "$NAMESPACE" rollout status deployment/who-need-help-who-need-help-web
|
|
kube --namespace "$NAMESPACE" rollout status deployment/who-need-help-who-need-help-worker
|
|
remove_legacy_inline_secrets
|
|
"$ROOT/scripts/verify-realtime-cluster.sh" kind
|
|
|
|
echo "Who Need Help: http://localhost:4011"
|
|
echo "Mailpit: http://localhost:8028"
|