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 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TQd3pEP9UeN2uifbHknQ7B
This commit is contained in:
@@ -26,6 +26,3 @@ KVITT_DEV_BACKUP_DIR=./backups
|
|||||||
# Folder holding fcm-service-account.json (git-ignored). Default: infra/secrets of this checkout.
|
# 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.
|
# In a worktree without copied secrets, point it at the main checkout's infra/secrets.
|
||||||
KVITT_SECRETS_DIR=../secrets
|
KVITT_SECRETS_DIR=../secrets
|
||||||
|
|
||||||
# rclone remote name; unused on the dev stack because RCLONE_FOLDER_ID is always empty here.
|
|
||||||
RCLONE_REMOTE=gdrive:
|
|
||||||
|
|||||||
+2
-2
@@ -6,13 +6,13 @@ set -euo pipefail
|
|||||||
# shellcheck source=lib.sh
|
# shellcheck source=lib.sh
|
||||||
. "$(dirname "$0")/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"
|
mkdir -p "$backup_dir"
|
||||||
|
|
||||||
compose --profile backup run --rm -T backup /backup.sh
|
compose --profile backup run --rm -T backup /backup.sh
|
||||||
|
|
||||||
latest="$(find "$backup_dir" -maxdepth 1 -name 'kvitt-*.sqlite.gz' | sort | tail -n 1)"
|
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")"
|
name="$(basename "$latest")"
|
||||||
result="$(compose --profile backup run --rm -T --entrypoint sh backup -c \
|
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'")"
|
"gunzip -c '/backups/$name' > /tmp/check.sqlite && sqlite3 -batch -noheader -list /tmp/check.sqlite 'PRAGMA integrity_check'")"
|
||||||
|
|||||||
+7
-11
@@ -1,30 +1,26 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# Builds the development images on this Mac (native linux/arm64, nothing pushed):
|
# 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
|
# kvitt-backup:dev from infra/backup/Dockerfile
|
||||||
# Usage: infra/dev/build.sh [server|backup|all] (default: all)
|
# 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).
|
# Refuses to run while a Gradle build holds the gradle-serial lock (CLAUDE.md: never build images during a Gradle build).
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
# shellcheck source=lib.sh
|
# shellcheck source=lib.sh
|
||||||
. "$(dirname "$0")/lib.sh"
|
. "$(dirname "$0")/lib.sh"
|
||||||
|
# shellcheck source=../../tools/gradle-lock.sh
|
||||||
|
. "$repo_root/tools/gradle-lock.sh"
|
||||||
|
|
||||||
what="${1:-all}"
|
what="${1:-all}"
|
||||||
lock=/tmp/kvitt-gradle.lock
|
if pid="$(gradle_lock_holder)"; then
|
||||||
if [[ -d "$lock" ]] && pid="$(cat "$lock/pid" 2>/dev/null)" && [[ -n "$pid" ]] && kill -0 "$pid" 2>/dev/null; then
|
die "a Gradle build is running (pid $pid, $KVITT_GRADLE_LOCK); try again when it is done."
|
||||||
echo "build.sh: a Gradle build is running (pid $pid, $lock); try again when it is done." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
server_image="$(env_value KVITT_SERVER_IMAGE)"; server_image="${server_image:-kvitt-server:dev}"
|
server_image="$(env_value KVITT_SERVER_IMAGE kvitt-server:dev)"
|
||||||
backup_image="$(env_value KVITT_BACKUP_IMAGE)"; backup_image="${backup_image:-kvitt-backup:dev}"
|
backup_image="$(env_value KVITT_BACKUP_IMAGE kvitt-backup:dev)"
|
||||||
|
|
||||||
build_server() {
|
build_server() {
|
||||||
local dockerfile="$repo_root/server/Dockerfile"
|
local dockerfile="$repo_root/server/Dockerfile"
|
||||||
local context="${KVITT_SERVER_BUILD_CONTEXT:-$repo_root/server}"
|
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"
|
echo "Building $server_image from server/Dockerfile"
|
||||||
docker build --platform linux/arm64 -f "$dockerfile" -t "$server_image" "$context"
|
docker build --platform linux/arm64 -f "$dockerfile" -t "$server_image" "$context"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# Kvitt development stack on the owner's Mac (SPEC §10 "Development first", D-001).
|
# 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
|
# 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.
|
# server publishes its own port on the Mac. Release builds never talk to this stack.
|
||||||
@@ -72,9 +72,9 @@ services:
|
|||||||
mem_limit: 96m
|
mem_limit: 96m
|
||||||
environment:
|
environment:
|
||||||
TZ: Europe/Stockholm
|
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_FOLDER_ID: ""
|
||||||
RCLONE_REMOTE: ${RCLONE_REMOTE:-gdrive:}
|
|
||||||
volumes:
|
volumes:
|
||||||
- ${KVITT_DEV_DATA_DIR:-./data}:/data
|
- ${KVITT_DEV_DATA_DIR:-./data}:/data
|
||||||
- ${KVITT_DEV_BACKUP_DIR:-./backups}:/backups
|
- ${KVITT_DEV_BACKUP_DIR:-./backups}:/backups
|
||||||
|
|||||||
@@ -10,11 +10,9 @@ src_root="${1:-$repo_root}"
|
|||||||
src="$src_root/infra/secrets/google-services.json"
|
src="$src_root/infra/secrets/google-services.json"
|
||||||
dst="$repo_root/android/app/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; }
|
[[ -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" || {
|
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
|
|| die "android/app/google-services.json is not git-ignored; refusing to copy."
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
mkdir -p "$(dirname "$dst")"
|
mkdir -p "$(dirname "$dst")"
|
||||||
cp "$src" "$dst"
|
cp "$src" "$dst"
|
||||||
chmod 600 "$dst"
|
chmod 600 "$dst"
|
||||||
|
|||||||
+6
-8
@@ -8,9 +8,13 @@ repo_root="$(cd "$dev_dir/../.." && pwd)"
|
|||||||
# infra/dev/.env (git-ignored) when it exists, otherwise the committed example.
|
# 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
|
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() {
|
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() {
|
compose() {
|
||||||
@@ -31,9 +35,3 @@ lan_address() {
|
|||||||
iface="$(route -n get default 2>/dev/null | awk '/interface:/ {print $2}')"
|
iface="$(route -n get default 2>/dev/null | awk '/interface:/ {print $2}')"
|
||||||
[[ -n "$iface" ]] && ipconfig getifaddr "$iface" 2>/dev/null
|
[[ -n "$iface" ]] && ipconfig getifaddr "$iface" 2>/dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
dev_port() {
|
|
||||||
local p
|
|
||||||
p="$(env_value KVITT_DEV_PORT)"
|
|
||||||
printf '%s\n' "${p:-8080}"
|
|
||||||
}
|
|
||||||
|
|||||||
+4
-5
@@ -11,7 +11,7 @@ if [[ "${1:-}" == "--down" ]]; then
|
|||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
port="$(dev_port)"
|
port="$(env_value KVITT_DEV_PORT 8080)"
|
||||||
lan="$(lan_address || true)"
|
lan="$(lan_address || true)"
|
||||||
|
|
||||||
public_url="$(env_value KVITT_PUBLIC_URL)"
|
public_url="$(env_value KVITT_PUBLIC_URL)"
|
||||||
@@ -20,8 +20,8 @@ if [[ -z "$public_url" ]]; then
|
|||||||
fi
|
fi
|
||||||
export KVITT_PUBLIC_URL="$public_url"
|
export KVITT_PUBLIC_URL="$public_url"
|
||||||
|
|
||||||
data_dir="$(dev_path "$(env_value KVITT_DEV_DATA_DIR)")"
|
data_dir="$(dev_path "$(env_value KVITT_DEV_DATA_DIR ./data)")"
|
||||||
secrets_dir="$(dev_path "$(env_value KVITT_SECRETS_DIR)")"
|
secrets_dir="$(dev_path "$(env_value KVITT_SECRETS_DIR ../secrets)")"
|
||||||
mkdir -p "$data_dir"
|
mkdir -p "$data_dir"
|
||||||
if [[ ! -f "$secrets_dir/fcm-service-account.json" ]]; then
|
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
|
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
|
fi
|
||||||
sleep 1
|
sleep 1
|
||||||
done
|
done
|
||||||
echo "up.sh: /health did not answer within 30 s; see infra/dev/logs.sh" >&2
|
die "/health did not answer within 30 s; see infra/dev/logs.sh"
|
||||||
exit 1
|
|
||||||
|
|||||||
Reference in New Issue
Block a user