#!/usr/bin/env bash set -euo pipefail release_id=${1:?release id is required} archive=${2:?release archive is required} root=${VEHICLE_MAP_ROOT:-/opt/lingniu-vehicle-map} service=${VEHICLE_MAP_SERVICE:-lingniu-vehicle-map.service} base_url=${VEHICLE_MAP_BASE_URL:-http://127.0.0.1:20800} case "$release_id" in ''|*[!A-Za-z0-9._-]*) printf 'invalid release id: %s\n' "$release_id" >&2; exit 1 ;; esac test -f "$archive" if ! id vehicle-map >/dev/null 2>&1; then useradd --system --home-dir "$root" --shell /sbin/nologin vehicle-map fi mkdir -p "$root/releases" "$root/env" next="$root/releases/$release_id" test ! -e "$next" mkdir -p "$next" while IFS= read -r member; do case "$member" in /*|../*|*/../*|*/..) printf 'archive contains unsafe path: %s\n' "$member" >&2; exit 1 ;; esac done < <(tar -tzf "$archive") tar --no-same-owner -xzf "$archive" -C "$next" test -f "$next/server.py" test -f "$next/index.html" chown -R root:vehicle-map "$next" chmod -R u=rwX,g=rX,o= "$next" chown root:vehicle-map "$root/env/vehicle-map.env" chmod 0640 "$root/env/vehicle-map.env" ln -s "$next" "$root/current.next" python3 -c 'import os,sys; os.replace(sys.argv[1],sys.argv[2])' "$root/current.next" "$root/current" systemctl restart "$service" for _ in $(seq 1 30); do if systemctl is-active --quiet "$service" && curl -fsS "$base_url/api/health" >/dev/null; then curl -fsS "$base_url/" | grep -q 'id="dashboardTitle"' curl -fsS "$base_url/api/public/stations" | python3 -c 'import json,sys; d=json.load(sys.stdin); assert d["status"]=="ok" and d["summary"]["totalStations"]>400' printf 'vehicle_map_release_install=ok release=%s\n' "$release_id" exit 0 fi sleep 1 done systemctl status "$service" --no-pager >&2 || true exit 1