Create MeshCentral workspace
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
COMPONENT="meshpress-bridge"
|
||||
TARGET_DIR="/opt/gracepress-meshpress-bridge"
|
||||
ENV_FILE="/etc/gracepress/meshpress-bridge.env"
|
||||
SERVICE_NAME="gp-meshpress-bridge"
|
||||
LOG_PREFIX="[meshpress-bridge-update]"
|
||||
LOCK_FILE="/tmp/gracepress-meshpress-bridge-update.lock"
|
||||
TMP_DIR="$(mktemp -d)"
|
||||
STAGE_DIR=""
|
||||
BACKUP_DIR=""
|
||||
|
||||
cleanup() {
|
||||
rm -rf "$TMP_DIR"
|
||||
if [ -n "$STAGE_DIR" ] && [ -d "$STAGE_DIR" ]; then rm -rf "$STAGE_DIR"; fi
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
log() { echo "$LOG_PREFIX $(date -Is) $*"; }
|
||||
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
log "Please run as root."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exec 9>"$LOCK_FILE"
|
||||
if command -v flock >/dev/null 2>&1; then
|
||||
flock -n 9 || { log "Another bridge update is already running."; exit 1; }
|
||||
fi
|
||||
|
||||
[ -f "$ENV_FILE" ] && . "$ENV_FILE"
|
||||
CATALOG_URL="${GRACEPRESS_CATALOG_URL:-https://christit.com/gracepress/api.php?endpoint=manifest&slug=meshpress-bridge}"
|
||||
|
||||
apt-get update -y >/dev/null
|
||||
apt-get install -y curl unzip python3 ca-certificates nodejs npm >/dev/null
|
||||
if ! command -v pm2 >/dev/null 2>&1; then
|
||||
npm install -g pm2 >/dev/null
|
||||
fi
|
||||
|
||||
log "Checking catalog: $CATALOG_URL"
|
||||
curl -fsSL "$CATALOG_URL&nocache=$(date +%s)" -o "$TMP_DIR/manifest.json"
|
||||
DOWNLOAD_URL="$(python3 -c 'import json,sys; print(json.load(open(sys.argv[1])).get("download_url",""))' "$TMP_DIR/manifest.json")"
|
||||
VERSION="$(python3 -c 'import json,sys; print(json.load(open(sys.argv[1])).get("version","0.0.0"))' "$TMP_DIR/manifest.json")"
|
||||
|
||||
if [ -z "$DOWNLOAD_URL" ]; then
|
||||
log "No download_url found in catalog manifest."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
CURRENT="$(cat "$TARGET_DIR/VERSION" 2>/dev/null || echo 0.0.0)"
|
||||
if [ "$CURRENT" = "$VERSION" ]; then
|
||||
log "$COMPONENT is already current: $CURRENT"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
log "Updating $COMPONENT from $CURRENT to $VERSION"
|
||||
curl -fL "$DOWNLOAD_URL" -o "$TMP_DIR/package.zip"
|
||||
unzip -q "$TMP_DIR/package.zip" -d "$TMP_DIR/pkg"
|
||||
PKG_DIR="$(find "$TMP_DIR/pkg" -maxdepth 3 -type f -name server.js -printf '%h\n' | head -n 1)"
|
||||
if [ -z "$PKG_DIR" ] || [ ! -f "$PKG_DIR/package.json" ]; then
|
||||
log "Package does not contain a valid bridge payload."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
STAGE_DIR="${TARGET_DIR}.next.${VERSION}.$$"
|
||||
rm -rf "$STAGE_DIR"
|
||||
mkdir -p "$STAGE_DIR"
|
||||
cp -a "$PKG_DIR"/. "$STAGE_DIR"/
|
||||
echo "$VERSION" > "$STAGE_DIR/VERSION"
|
||||
chmod +x "$STAGE_DIR/update.sh" "$STAGE_DIR/meshpress-bridge" 2>/dev/null || true
|
||||
|
||||
log "Installing node dependencies in staging directory."
|
||||
(cd "$STAGE_DIR" && npm install --omit=dev >/dev/null && node --check server.js >/dev/null)
|
||||
|
||||
BACKUP_DIR="${TARGET_DIR}.old.$(date +%Y%m%d%H%M%S)"
|
||||
if [ -d "$TARGET_DIR" ]; then
|
||||
mv "$TARGET_DIR" "$BACKUP_DIR"
|
||||
log "Previous install moved to $BACKUP_DIR"
|
||||
fi
|
||||
|
||||
mv "$STAGE_DIR" "$TARGET_DIR"
|
||||
STAGE_DIR=""
|
||||
|
||||
rollback() {
|
||||
log "Update failed after swap; attempting rollback."
|
||||
local failed="${TARGET_DIR}.failed.$(date +%Y%m%d%H%M%S)"
|
||||
if [ -d "$TARGET_DIR" ]; then mv "$TARGET_DIR" "$failed"; fi
|
||||
if [ -n "$BACKUP_DIR" ] && [ -d "$BACKUP_DIR" ]; then mv "$BACKUP_DIR" "$TARGET_DIR"; fi
|
||||
if [ -f "$TARGET_DIR/server.js" ]; then
|
||||
pm2 start "$TARGET_DIR/server.js" --name "$SERVICE_NAME" --time --max-memory-restart 512M >/dev/null 2>&1 || pm2 restart "$SERVICE_NAME" --update-env >/dev/null 2>&1 || true
|
||||
pm2 save >/dev/null 2>&1 || true
|
||||
fi
|
||||
}
|
||||
|
||||
if pm2 describe "$SERVICE_NAME" >/dev/null 2>&1; then
|
||||
if ! (cd "$TARGET_DIR" && pm2 restart "$SERVICE_NAME" --update-env >/dev/null); then
|
||||
rollback
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
if ! (cd "$TARGET_DIR" && pm2 start server.js --name "$SERVICE_NAME" --time --max-memory-restart 512M >/dev/null); then
|
||||
rollback
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
pm2 save >/dev/null
|
||||
log "$COMPONENT updated to $VERSION"
|
||||
Reference in New Issue
Block a user