feat: expand vehicle data platform capabilities
This commit is contained in:
121
vehicle-data-platform/deploy/install-open-platform-release.sh
Executable file
121
vehicle-data-platform/deploy/install-open-platform-release.sh
Executable file
@@ -0,0 +1,121 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
RELEASE_ID=${1:?release id is required}
|
||||
WEB_ARCHIVE=${2:?open portal web archive is required}
|
||||
API_BINARY=${3:?open platform API binary is required}
|
||||
ROOT=${OPEN_PLATFORM_ROOT:-/opt/lingniu-vehicle-open-platform}
|
||||
BASE_URL=${OPEN_PLATFORM_BASE_URL:-http://127.0.0.1:20310}
|
||||
SERVICE=${OPEN_PLATFORM_SERVICE:-lingniu-vehicle-open-platform}
|
||||
SYSTEMCTL_BIN=${SYSTEMCTL_BIN:-systemctl}
|
||||
CURL_BIN=${CURL_BIN:-curl}
|
||||
RELEASE_HISTORY_LIMIT=${RELEASE_HISTORY_LIMIT:-12}
|
||||
|
||||
case "$RELEASE_ID" in
|
||||
''|*[!A-Za-z0-9._-]*) printf 'invalid release id: %s\n' "$RELEASE_ID" >&2; exit 1 ;;
|
||||
esac
|
||||
test -f "$WEB_ARCHIVE" || { printf 'open portal archive is missing\n' >&2; exit 1; }
|
||||
test -f "$API_BINARY" || { printf 'open platform API binary is missing\n' >&2; exit 1; }
|
||||
|
||||
old=
|
||||
if test -L "$ROOT/current"; then
|
||||
old=$(readlink -f "$ROOT/current")
|
||||
fi
|
||||
next="$ROOT/releases/$RELEASE_ID"
|
||||
env_file="$ROOT/env/open-platform.env"
|
||||
switched=false
|
||||
|
||||
set_release_env() {
|
||||
python3 - "$env_file" "$1" <<'PY'
|
||||
import pathlib
|
||||
import sys
|
||||
path = pathlib.Path(sys.argv[1])
|
||||
release = sys.argv[2]
|
||||
lines = path.read_text(encoding="utf-8").splitlines() if path.exists() else []
|
||||
updated = []
|
||||
found = False
|
||||
for line in lines:
|
||||
if line.startswith("OPEN_PLATFORM_RELEASE="):
|
||||
updated.append("OPEN_PLATFORM_RELEASE=" + release)
|
||||
found = True
|
||||
else:
|
||||
updated.append(line)
|
||||
if not found:
|
||||
updated.append("OPEN_PLATFORM_RELEASE=" + release)
|
||||
path.write_text("\n".join(updated) + "\n", encoding="utf-8")
|
||||
PY
|
||||
chmod 0600 "$env_file"
|
||||
}
|
||||
|
||||
rollback() {
|
||||
status=$?
|
||||
trap - ERR
|
||||
set +e
|
||||
if test "$switched" = true && test -n "$old"; then
|
||||
ln -s "$old" "$ROOT/current.rollback"
|
||||
python3 -c 'import os,sys; os.replace(sys.argv[1],sys.argv[2])' "$ROOT/current.rollback" "$ROOT/current"
|
||||
set_release_env "$(basename "$old")"
|
||||
"$SYSTEMCTL_BIN" restart "$SERVICE"
|
||||
elif test "$switched" = true; then
|
||||
"$SYSTEMCTL_BIN" stop "$SERVICE"
|
||||
rm -f "$ROOT/current"
|
||||
set_release_env ""
|
||||
fi
|
||||
printf 'open platform release failed; current restored to %s\n' "${old:-none}" >&2
|
||||
exit "$status"
|
||||
}
|
||||
trap rollback ERR
|
||||
|
||||
test ! -e "$next" || { printf 'release already exists: %s\n' "$next" >&2; exit 1; }
|
||||
mkdir -p "$next/web" "$ROOT/env"
|
||||
cp "$API_BINARY" "$next/open-platform-api"
|
||||
chmod 0755 "$next/open-platform-api"
|
||||
|
||||
while IFS= read -r member; do
|
||||
case "$member" in
|
||||
/*|../*|*/../*|*/..) printf 'web archive contains unsafe path: %s\n' "$member" >&2; exit 1 ;;
|
||||
esac
|
||||
done < <(tar -tzf "$WEB_ARCHIVE")
|
||||
tar --no-same-owner -xzf "$WEB_ARCHIVE" -C "$next/web"
|
||||
test -f "$next/web/index.html" || { printf 'open portal index is missing\n' >&2; exit 1; }
|
||||
|
||||
ln -s "$next" "$ROOT/current.next"
|
||||
python3 -c 'import os,sys; os.replace(sys.argv[1],sys.argv[2])' "$ROOT/current.next" "$ROOT/current"
|
||||
switched=true
|
||||
set_release_env "$RELEASE_ID"
|
||||
"$SYSTEMCTL_BIN" restart "$SERVICE"
|
||||
|
||||
ready=false
|
||||
for _ in $(seq 1 20); do
|
||||
if "$SYSTEMCTL_BIN" is-active --quiet "$SERVICE" && "$CURL_BIN" -fsS "$BASE_URL/healthz" >/dev/null; then
|
||||
ready=true
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
test "$ready" = true || { printf 'open platform service did not become ready\n' >&2; exit 1; }
|
||||
"$CURL_BIN" -fsS "$BASE_URL/" | grep -q '<div id="root"></div>'
|
||||
"$CURL_BIN" -fsS "$BASE_URL/open-api/openapi.yaml" | grep -q '^openapi: 3.0.3'
|
||||
"$CURL_BIN" -fsS "$BASE_URL/portal-api/catalog" | grep -q 'daily_hydrogen'
|
||||
|
||||
python3 - "$ROOT" "$RELEASE_HISTORY_LIMIT" "$next" "$old" <<'PY'
|
||||
import pathlib
|
||||
import shutil
|
||||
import sys
|
||||
root = pathlib.Path(sys.argv[1])
|
||||
limit = int(sys.argv[2])
|
||||
protected = {pathlib.Path(value).resolve() for value in sys.argv[3:] if value}
|
||||
releases = sorted(
|
||||
(p for p in (root / "releases").iterdir() if p.is_dir()),
|
||||
key=lambda p: p.stat().st_mtime,
|
||||
reverse=True,
|
||||
)
|
||||
for path in releases[limit:]:
|
||||
if path.resolve() not in protected:
|
||||
shutil.rmtree(path)
|
||||
PY
|
||||
|
||||
switched=false
|
||||
trap - ERR
|
||||
printf 'open_platform_release_install=ok release=%s previous=%s\n' "$RELEASE_ID" "${old##*/}"
|
||||
Reference in New Issue
Block a user