Files
feedc0de 9d0e7f5c95
Validate and deploy asciinema / Validate manifests (push) Successful in 13s
Validate and deploy asciinema / Deploy to Kubernetes (push) Successful in 36s
First try in deploying asciinema to kubernetes
2026-09-11 09:10:24 +02:00

103 lines
4.5 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
namespace=asciinema
rook_namespace=rook-ceph
script_dir=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
secret_name=asciinema-secrets
rook_secret=rook-ceph-object-user-my-store-asciinema
temp_dir=$(mktemp --directory)
trap 'rm -rf "${temp_dir}"' EXIT HUP INT TERM
chmod 0700 "${temp_dir}"
for command in kubectl jq openssl base64; do
if ! command -v "${command}" >/dev/null 2>&1; then
echo "Required command not found: ${command}" >&2
exit 1
fi
done
kubectl apply --filename "${script_dir}/namespace.yaml"
kubectl apply --filename "${script_dir}/ceph-object-user.yaml"
echo "Waiting for Rook to provision the asciinema S3 credentials..."
for _ in $(seq 1 60); do
if kubectl get secret "${rook_secret}" --namespace "${rook_namespace}" >/dev/null 2>&1; then
break
fi
sleep 2
done
kubectl get secret "${rook_secret}" --namespace "${rook_namespace}" >/dev/null
read_secret_file() {
local source_namespace=$1 source_secret=$2 source_key=$3 destination=$4
kubectl get secret "${source_secret}" --namespace "${source_namespace}" --output=json \
| jq --raw-output --join-output --arg key "${source_key}" '.data[$key]' \
| base64 --decode > "${destination}"
test -s "${destination}"
}
if kubectl get secret "${secret_name}" --namespace "${namespace}" >/dev/null 2>&1; then
read_secret_file "${namespace}" "${secret_name}" database-password "${temp_dir}/database-password"
read_secret_file "${namespace}" "${secret_name}" secret-key-base "${temp_dir}/secret-key-base"
read_secret_file "${namespace}" "${secret_name}" release-cookie "${temp_dir}/release-cookie"
else
openssl rand -hex 32 | tr -d '\r\n' > "${temp_dir}/database-password"
openssl rand -hex 64 | tr -d '\r\n' > "${temp_dir}/secret-key-base"
openssl rand -hex 32 | tr -d '\r\n' > "${temp_dir}/release-cookie"
fi
# Environment variables preserve newlines stored in Secret values, whereas
# command substitution below strips them. Normalize values created by older
# versions of this installer so the PostgreSQL container and DATABASE_URL see
# the exact same password.
for key in database-password secret-key-base release-cookie; do
value=$(<"${temp_dir}/${key}")
printf '%s' "${value}" > "${temp_dir}/${key}"
done
# Rook owns and may rotate these credentials. Refresh the namespaced copy on
# every installation while preserving the database and application secrets.
read_secret_file "${rook_namespace}" "${rook_secret}" AccessKey "${temp_dir}/s3-access-key-id"
read_secret_file "${rook_namespace}" "${rook_secret}" SecretKey "${temp_dir}/s3-secret-access-key"
database_password=$(<"${temp_dir}/database-password")
printf 'postgresql://asciinema:%s@postgresql.asciinema.svc.cluster.local:5432/asciinema?pool_size=5' \
"${database_password}" > "${temp_dir}/database-url"
kubectl create secret generic "${secret_name}" \
--namespace "${namespace}" \
--from-file="database-password=${temp_dir}/database-password" \
--from-file="database-url=${temp_dir}/database-url" \
--from-file="secret-key-base=${temp_dir}/secret-key-base" \
--from-file="release-cookie=${temp_dir}/release-cookie" \
--from-file="s3-access-key-id=${temp_dir}/s3-access-key-id" \
--from-file="s3-secret-access-key=${temp_dir}/s3-secret-access-key" \
--dry-run=client \
--output=yaml | kubectl apply --filename=-
kubectl apply --dry-run=server --filename "${script_dir}/infrastructure.yaml"
kubectl apply --filename "${script_dir}/infrastructure.yaml"
kubectl rollout status statefulset/postgresql --namespace "${namespace}" --timeout=10m
# Jobs are immutable and bucket bootstrap must be repeatable for restores.
# Only this exact, disposable Job is replaced.
kubectl delete job asciinema-bootstrap --namespace "${namespace}" --ignore-not-found
kubectl apply --filename "${script_dir}/bootstrap.yaml"
if ! kubectl wait --for=condition=complete job/asciinema-bootstrap \
--namespace "${namespace}" --timeout=5m; then
kubectl logs job/asciinema-bootstrap --namespace "${namespace}" --all-containers=true || true
exit 1
fi
kubectl apply --dry-run=server --filename "${script_dir}/asciinema.yaml"
kubectl apply --filename "${script_dir}/asciinema.yaml"
# envFrom values and Secret-backed environment variables are read only when a
# pod starts. Recreate the sole replica so config changes and rotated RGW keys
# take effect on every successful installer run.
kubectl rollout restart deployment/asciinema --namespace "${namespace}"
kubectl rollout status deployment/asciinema --namespace "${namespace}" --timeout=10m
echo
echo "asciinema is running for https://asciinema.brunner.ninja."