171 lines
4.8 KiB
Bash
Executable File
171 lines
4.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
# new-site.sh — Create a new static site: Gitea repo + Garage bucket.
|
|
#
|
|
# Usage: ./new-site.sh --name <name> --domain <domain> [--type static|hugo|mkdocs]
|
|
#
|
|
# Requires: tea CLI configured; kubectl with sjc001 context (for bucket setup).
|
|
|
|
usage() {
|
|
echo "Usage: $0 --name <name> --domain <domain> [--type static|hugo|mkdocs]" >&2
|
|
exit 1
|
|
}
|
|
|
|
NAME=""
|
|
DOMAIN=""
|
|
TYPE="static"
|
|
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
--name) NAME="$2"; shift 2 ;;
|
|
--domain) DOMAIN="$2"; shift 2 ;;
|
|
--type) TYPE="$2"; shift 2 ;;
|
|
*) usage ;;
|
|
esac
|
|
done
|
|
|
|
[ -z "$NAME" ] || [ -z "$DOMAIN" ] && usage
|
|
|
|
ORG="websites"
|
|
WORK_DIR="$(mktemp -d)"
|
|
trap 'rm -rf "$WORK_DIR"' EXIT
|
|
|
|
# --- Garage bucket setup (one-off, via in-cluster Job) ---
|
|
echo "Creating Garage bucket '${NAME}' and enabling web hosting..."
|
|
cat <<EOF | kubectl --context sjc001 -n storage apply -f - >/dev/null
|
|
apiVersion: batch/v1
|
|
kind: Job
|
|
metadata:
|
|
name: bucket-setup-${NAME//./-}
|
|
namespace: storage
|
|
spec:
|
|
ttlSecondsAfterFinished: 120
|
|
backoffLimit: 0
|
|
template:
|
|
spec:
|
|
restartPolicy: Never
|
|
containers:
|
|
- name: setup
|
|
image: alpine:3.20
|
|
command: [/bin/sh, -euc]
|
|
args:
|
|
- |
|
|
apk add --no-cache curl jq >/dev/null
|
|
H=http://garage.storage.svc:3903
|
|
AUTH="Authorization: Bearer \$TOKEN"
|
|
# ci-deploy-key id is fixed per cluster — update if re-keyed
|
|
CI_KID=GKbe265a2b8ea53695ae734787
|
|
BUCKET=${NAME}
|
|
# Create bucket (idempotent: 409 if exists)
|
|
curl -s -X POST -H "\$AUTH" -H "Content-Type: application/json" \
|
|
-d "{\"globalAlias\":\"\$BUCKET\"}" "\$H/v2/CreateBucket" -o /dev/null
|
|
BID=\$(curl -sf -H "\$AUTH" "\$H/v2/GetBucketInfo?globalAlias=\$BUCKET" | jq -r .id)
|
|
echo "bucket id: \$BID"
|
|
curl -s -X POST -H "\$AUTH" -H "Content-Type: application/json" \
|
|
-d "{\"bucketId\":\"\$BID\",\"accessKeyId\":\"\$CI_KID\",\"permissions\":{\"read\":true,\"write\":true,\"owner\":false}}" \
|
|
"\$H/v2/AllowBucketKey" -o /dev/null
|
|
curl -s -X POST -H "\$AUTH" -H "Content-Type: application/json" \
|
|
-d '{"websiteAccess":{"enabled":true,"indexDocument":"index.html","errorDocument":"404.html"}}' \
|
|
"\$H/v2/UpdateBucket?id=\$BID" -o /dev/null
|
|
curl -sf -H "\$AUTH" "\$H/v2/GetBucketInfo?globalAlias=\$BUCKET" | jq '{websiteAccess, keys: (.keys | map(.name))}'
|
|
env:
|
|
- name: TOKEN
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: garage-rpc-secret
|
|
key: admin-token
|
|
EOF
|
|
kubectl --context sjc001 -n storage wait --for=condition=complete --timeout=60s job/bucket-setup-${NAME//./-}
|
|
kubectl --context sjc001 -n storage logs job/bucket-setup-${NAME//./-}
|
|
kubectl --context sjc001 -n storage delete job bucket-setup-${NAME//./-} --ignore-not-found >/dev/null
|
|
|
|
# --- Gitea repo ---
|
|
echo "Creating Gitea repo ${ORG}/${NAME}..."
|
|
tea repo create --owner "$ORG" --name "$NAME" --init
|
|
|
|
echo "Cloning..."
|
|
git clone "ssh://git@code.fritzlab.net/${ORG}/${NAME}.git" "$WORK_DIR"
|
|
cd "$WORK_DIR"
|
|
|
|
# --- Starter content + site.yaml ---
|
|
case "$TYPE" in
|
|
static)
|
|
mkdir -p html
|
|
cat > html/index.html <<'HTML'
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>Welcome</title>
|
|
</head>
|
|
<body>
|
|
<h1>Hello from fritzlab</h1>
|
|
<p>Served from Garage S3.</p>
|
|
</body>
|
|
</html>
|
|
HTML
|
|
cat > site.yaml <<YAML
|
|
domain: ${DOMAIN}
|
|
type: static
|
|
content_dir: html
|
|
YAML
|
|
;;
|
|
hugo)
|
|
hugo new site . --force
|
|
cat > site.yaml <<YAML
|
|
domain: ${DOMAIN}
|
|
type: hugo
|
|
YAML
|
|
;;
|
|
mkdocs)
|
|
cat > mkdocs.yml <<YAML
|
|
site_name: ${NAME}
|
|
theme:
|
|
name: material
|
|
YAML
|
|
mkdir -p docs
|
|
cat > docs/index.md <<MD
|
|
# ${NAME}
|
|
|
|
Welcome.
|
|
MD
|
|
cat > site.yaml <<YAML
|
|
domain: ${DOMAIN}
|
|
type: mkdocs
|
|
YAML
|
|
;;
|
|
esac
|
|
|
|
# --- CI workflow ---
|
|
mkdir -p .gitea/workflows
|
|
cat > .gitea/workflows/publish.yaml <<'WORKFLOW'
|
|
name: Publish
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
jobs:
|
|
publish:
|
|
runs-on: fritzlab
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: https://code.fritzlab.net/action/site-publish@v1
|
|
with:
|
|
token: ${{ secrets.CI_BOT_TOKEN }}
|
|
s3-access-key: ${{ secrets.GARAGE_S3_ACCESS_KEY }}
|
|
s3-secret-key: ${{ secrets.GARAGE_S3_SECRET_KEY }}
|
|
WORKFLOW
|
|
|
|
git add -A
|
|
git commit -m "Initial site scaffold"
|
|
git push
|
|
|
|
echo
|
|
echo "Site created: ${ORG}/${NAME}"
|
|
echo "First build will trigger on push."
|
|
echo
|
|
echo "DNS: ${DOMAIN} is covered by the *.vino.network wildcard (→ traefik.edge)."
|
|
echo "For a domain outside vino.network, add an explicit CNAME:"
|
|
echo " ${DOMAIN} 300 IN CNAME traefik.edge.svc.k8s.sjc001.fritzlab.net."
|