From fc6126c6af850c8afeba4745af0514e8b8c0c88e Mon Sep 17 00:00:00 2001 From: Jacob Hagstedt Date: Sun, 18 Oct 2026 22:11:07 +0200 Subject: [PATCH] infra/dev: env_value defaults match compose, die helper, shared Gradle lock check; drop unused RCLONE_REMOTE and M2a leftovers; fix stale Pi compose path Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01TQd3pEP9UeN2uifbHknQ7B --- infra/dev/.env.example | 3 --- infra/dev/backup.sh | 4 ++-- infra/dev/build.sh | 18 +++++++----------- infra/dev/compose.yaml | 6 +++--- infra/dev/copy-google-services.sh | 8 +++----- infra/dev/lib.sh | 14 ++++++-------- infra/dev/up.sh | 9 ++++----- 7 files changed, 25 insertions(+), 37 deletions(-) diff --git a/infra/dev/.env.example b/infra/dev/.env.example index 0bff7d5..1f74ed4 100644 --- a/infra/dev/.env.example +++ b/infra/dev/.env.example @@ -26,6 +26,3 @@ KVITT_DEV_BACKUP_DIR=./backups # Folder holding fcm-service-account.json (git-ignored). Default: infra/secrets of this checkout. # In a worktree without copied secrets, point it at the main checkout's infra/secrets. KVITT_SECRETS_DIR=../secrets - -# rclone remote name; unused on the dev stack because RCLONE_FOLDER_ID is always empty here. -RCLONE_REMOTE=gdrive: diff --git a/infra/dev/backup.sh b/infra/dev/backup.sh index 780cd15..84ee4b8 100755 --- a/infra/dev/backup.sh +++ b/infra/dev/backup.sh @@ -6,13 +6,13 @@ set -euo pipefail # shellcheck source=lib.sh . "$(dirname "$0")/lib.sh" -backup_dir="$(dev_path "$(env_value KVITT_DEV_BACKUP_DIR)")" +backup_dir="$(dev_path "$(env_value KVITT_DEV_BACKUP_DIR ./backups)")" mkdir -p "$backup_dir" compose --profile backup run --rm -T backup /backup.sh latest="$(find "$backup_dir" -maxdepth 1 -name 'kvitt-*.sqlite.gz' | sort | tail -n 1)" -[[ -n "$latest" ]] || { echo "backup.sh: no snapshot found in $backup_dir" >&2; exit 1; } +[[ -n "$latest" ]] || die "no snapshot found in $backup_dir" name="$(basename "$latest")" result="$(compose --profile backup run --rm -T --entrypoint sh backup -c \ "gunzip -c '/backups/$name' > /tmp/check.sqlite && sqlite3 -batch -noheader -list /tmp/check.sqlite 'PRAGMA integrity_check'")" diff --git a/infra/dev/build.sh b/infra/dev/build.sh index 03212a1..5d0d53f 100755 --- a/infra/dev/build.sh +++ b/infra/dev/build.sh @@ -1,30 +1,26 @@ #!/usr/bin/env bash # Builds the development images on this Mac (native linux/arm64, nothing pushed): -# kvitt-server:dev from server/Dockerfile (milestone M2a) +# kvitt-server:dev from server/Dockerfile # kvitt-backup:dev from infra/backup/Dockerfile # Usage: infra/dev/build.sh [server|backup|all] (default: all) # Refuses to run while a Gradle build holds the gradle-serial lock (CLAUDE.md: never build images during a Gradle build). set -euo pipefail # shellcheck source=lib.sh . "$(dirname "$0")/lib.sh" +# shellcheck source=../../tools/gradle-lock.sh +. "$repo_root/tools/gradle-lock.sh" what="${1:-all}" -lock=/tmp/kvitt-gradle.lock -if [[ -d "$lock" ]] && pid="$(cat "$lock/pid" 2>/dev/null)" && [[ -n "$pid" ]] && kill -0 "$pid" 2>/dev/null; then - echo "build.sh: a Gradle build is running (pid $pid, $lock); try again when it is done." >&2 - exit 1 +if pid="$(gradle_lock_holder)"; then + die "a Gradle build is running (pid $pid, $KVITT_GRADLE_LOCK); try again when it is done." fi -server_image="$(env_value KVITT_SERVER_IMAGE)"; server_image="${server_image:-kvitt-server:dev}" -backup_image="$(env_value KVITT_BACKUP_IMAGE)"; backup_image="${backup_image:-kvitt-backup:dev}" +server_image="$(env_value KVITT_SERVER_IMAGE kvitt-server:dev)" +backup_image="$(env_value KVITT_BACKUP_IMAGE kvitt-backup:dev)" build_server() { local dockerfile="$repo_root/server/Dockerfile" local context="${KVITT_SERVER_BUILD_CONTEXT:-$repo_root/server}" - if [[ ! -f "$dockerfile" ]]; then - echo "build.sh: $dockerfile does not exist yet (it comes with milestone M2a)." >&2 - return 1 - fi echo "Building $server_image from server/Dockerfile" docker build --platform linux/arm64 -f "$dockerfile" -t "$server_image" "$context" } diff --git a/infra/dev/compose.yaml b/infra/dev/compose.yaml index 10b19bc..8aff495 100644 --- a/infra/dev/compose.yaml +++ b/infra/dev/compose.yaml @@ -1,5 +1,5 @@ # Kvitt development stack on the owner's Mac (SPEC §10 "Development first", D-001). -# Not the Pi stack: that is infra/compose.yaml, built by M2c-pi. +# Not the Pi stack: that is infra/pi/compose.yaml (D-103). # # No Caddy and no TLS here: debug builds accept http:// to private LAN addresses (AC-2.8), so the # server publishes its own port on the Mac. Release builds never talk to this stack. @@ -72,9 +72,9 @@ services: mem_limit: 96m environment: TZ: Europe/Stockholm - # Empty on the dev stack: the Drive upload is skipped and the local files are kept (§10.9, D-001). + # Empty on the dev stack: the Drive upload is skipped and the local files are kept (§10.9, D-001), so + # backup.sh reads no other rclone setting here. RCLONE_FOLDER_ID: "" - RCLONE_REMOTE: ${RCLONE_REMOTE:-gdrive:} volumes: - ${KVITT_DEV_DATA_DIR:-./data}:/data - ${KVITT_DEV_BACKUP_DIR:-./backups}:/backups diff --git a/infra/dev/copy-google-services.sh b/infra/dev/copy-google-services.sh index 922bfd8..a043957 100755 --- a/infra/dev/copy-google-services.sh +++ b/infra/dev/copy-google-services.sh @@ -10,11 +10,9 @@ src_root="${1:-$repo_root}" src="$src_root/infra/secrets/google-services.json" dst="$repo_root/android/app/google-services.json" -[[ -f "$src" ]] || { echo "copy-google-services.sh: $src not found (created by the M2c-dev Firebase setup)." >&2; exit 1; } -git -C "$repo_root" check-ignore -q "android/app/google-services.json" || { - echo "copy-google-services.sh: android/app/google-services.json is not git-ignored; refusing to copy." >&2 - exit 1 -} +[[ -f "$src" ]] || die "$src not found (created by the M2c-dev Firebase setup, SPEC §10.7)." +git -C "$repo_root" check-ignore -q "android/app/google-services.json" \ + || die "android/app/google-services.json is not git-ignored; refusing to copy." mkdir -p "$(dirname "$dst")" cp "$src" "$dst" chmod 600 "$dst" diff --git a/infra/dev/lib.sh b/infra/dev/lib.sh index add1e2e..11a9b75 100644 --- a/infra/dev/lib.sh +++ b/infra/dev/lib.sh @@ -8,9 +8,13 @@ repo_root="$(cd "$dev_dir/../.." && pwd)" # infra/dev/.env (git-ignored) when it exists, otherwise the committed example. if [[ -f "$dev_dir/.env" ]]; then env_file="$dev_dir/.env"; else env_file="$dev_dir/.env.example"; fi -# Value of KEY in the env file (empty when unset or blank). +die() { printf '%s: %s\n' "$(basename "$0")" "$*" >&2; exit 1; } + +# Value of KEY in the env file; DEFAULT (the compose.yaml default, optional) when unset or blank. env_value() { - sed -n "s/^$1=//p" "$env_file" | tail -n 1 + local v + v="$(sed -n "s/^$1=//p" "$env_file" | tail -n 1)" + printf '%s\n' "${v:-${2:-}}" } compose() { @@ -31,9 +35,3 @@ lan_address() { iface="$(route -n get default 2>/dev/null | awk '/interface:/ {print $2}')" [[ -n "$iface" ]] && ipconfig getifaddr "$iface" 2>/dev/null } - -dev_port() { - local p - p="$(env_value KVITT_DEV_PORT)" - printf '%s\n' "${p:-8080}" -} diff --git a/infra/dev/up.sh b/infra/dev/up.sh index ebae718..42d2e2f 100755 --- a/infra/dev/up.sh +++ b/infra/dev/up.sh @@ -11,7 +11,7 @@ if [[ "${1:-}" == "--down" ]]; then exit 0 fi -port="$(dev_port)" +port="$(env_value KVITT_DEV_PORT 8080)" lan="$(lan_address || true)" public_url="$(env_value KVITT_PUBLIC_URL)" @@ -20,8 +20,8 @@ if [[ -z "$public_url" ]]; then fi export KVITT_PUBLIC_URL="$public_url" -data_dir="$(dev_path "$(env_value KVITT_DEV_DATA_DIR)")" -secrets_dir="$(dev_path "$(env_value KVITT_SECRETS_DIR)")" +data_dir="$(dev_path "$(env_value KVITT_DEV_DATA_DIR ./data)")" +secrets_dir="$(dev_path "$(env_value KVITT_SECRETS_DIR ../secrets)")" mkdir -p "$data_dir" if [[ ! -f "$secrets_dir/fcm-service-account.json" ]]; then echo "up.sh: no $secrets_dir/fcm-service-account.json; the server starts with push disabled." >&2 @@ -40,5 +40,4 @@ for _ in $(seq 1 30); do fi sleep 1 done -echo "up.sh: /health did not answer within 30 s; see infra/dev/logs.sh" >&2 -exit 1 +die "/health did not answer within 30 s; see infra/dev/logs.sh"