#!/bin/bash set -euo pipefail COMPONENT="meshpress-bridge" TARGET_DIR="/opt/gracepress-meshpress-bridge" ENV_DIR="/etc/gracepress" ENV_FILE="$ENV_DIR/meshpress-bridge.env" CRON_FILE="/etc/cron.d/gracepress-meshpress-bridge" SERVICE_NAME="gp-meshpress-bridge" SOURCE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" VERSION="$(grep -m 1 '^# Version:' "$SOURCE_DIR/meshpress-bridge" | sed -E 's/^# Version:[[:space:]]*//')" SOURCE_REAL="$(realpath "$SOURCE_DIR")" TARGET_REAL="$(realpath -m "$TARGET_DIR")" if [ "$(id -u)" -ne 0 ]; then echo "Please run as root: sudo ./install.sh" exit 1 fi if [ "$SOURCE_REAL" = "$TARGET_REAL" ]; then echo "Same-directory install detected; delegating to safe in-place updater." exec "$TARGET_DIR/update.sh" fi mkdir -p "$ENV_DIR" touch "$ENV_FILE" chmod 600 "$ENV_FILE" rand_token() { if command -v openssl >/dev/null 2>&1; then openssl rand -hex 32 else date +%s%N | sha256sum | awk '{print $1}' fi } ensure_env() { local key="$1" local value="$2" if ! grep -q "^${key}=" "$ENV_FILE"; then echo "${key}=\"${value}\"" >> "$ENV_FILE" fi } ensure_env "MESHPRESS_BRIDGE_PORT" "${MESHPRESS_BRIDGE_PORT:-3099}" ensure_env "MESHPRESS_BRIDGE_BIND" "${MESHPRESS_BRIDGE_BIND:-127.0.0.1}" ensure_env "MESHPRESS_BRIDGE_TOKEN" "${MESHPRESS_BRIDGE_TOKEN:-$(rand_token)}" ensure_env "MESHPRESS_ALLOWED_IPS" "${MESHPRESS_ALLOWED_IPS:-}" ensure_env "MESHPRESS_AUTH_WINDOW_SECONDS" "${MESHPRESS_AUTH_WINDOW_SECONDS:-900}" ensure_env "MESHPRESS_AUTH_MAX_FAILURES" "${MESHPRESS_AUTH_MAX_FAILURES:-30}" ensure_env "MESHCTRL_URL" "${MESHCTRL_URL:-wss://127.0.0.1}" ensure_env "PUBLIC_MESH_URL" "${PUBLIC_MESH_URL:-https://mesh.example.com}" ensure_env "MESHCTRL_USER" "${MESHCTRL_USER:-admin}" ensure_env "MESHCTRL_PASS" "${MESHCTRL_PASS:-}" ensure_env "MESHCTRL_DOMAIN" "${MESHCTRL_DOMAIN:-}" ensure_env "MESHCTRL_LOGIN_KEY_FILE" "${MESHCTRL_LOGIN_KEY_FILE:-/etc/gracepress/meshcentral-login.key}" ensure_env "MESHCTRL_PATH" "${MESHCTRL_PATH:-}" ensure_env "MESHCTRL_IGNORE_CERT" "${MESHCTRL_IGNORE_CERT:-0}" ensure_env "MESHPRESS_CACHE_TTL_SECONDS" "${MESHPRESS_CACHE_TTL_SECONDS:-60}" ensure_env "MESHPRESS_LINK_HIDE" "${MESHPRESS_LINK_HIDE:-}" ensure_env "MESHPRESS_ALLOW_COMMANDS" "${MESHPRESS_ALLOW_COMMANDS:-0}" ensure_env "MESHPRESS_ALLOW_MAINTENANCE" "${MESHPRESS_ALLOW_MAINTENANCE:-0}" ensure_env "MESHCENTRAL_DIR" "${MESHCENTRAL_DIR:-}" ensure_env "MESHCENTRAL_DATA_DIR" "${MESHCENTRAL_DATA_DIR:-}" ensure_env "MESHCENTRAL_SERVICE_NAME" "${MESHCENTRAL_SERVICE_NAME:-meshcentral}" ensure_env "MESHPRESS_BACKUP_DIR" "${MESHPRESS_BACKUP_DIR:-/var/backups/gracepress-meshcentral}" ensure_env "WP_DOMAIN" "${WP_DOMAIN:-}" ensure_env "WP_API_KEY" "${WP_API_KEY:-}" ensure_env "MESHPRESS_PUSH_INTERVAL_SECONDS" "${MESHPRESS_PUSH_INTERVAL_SECONDS:-3600}" ensure_env "MESHPRESS_PUSH_EVENTS" "${MESHPRESS_PUSH_EVENTS:-1}" ensure_env "AUTO_UPDATE" "${AUTO_UPDATE:-1}" apt-get update -y >/dev/null apt-get install -y curl ca-certificates >/dev/null curl -fsSL https://deb.nodesource.com/setup_20.x | bash - >/dev/null apt-get install -y nodejs >/dev/null npm install -g pm2 >/dev/null pm2 install pm2-logrotate >/dev/null 2>&1 || true pm2 set pm2-logrotate:max_size 25M >/dev/null 2>&1 || true pm2 set pm2-logrotate:retain 5 >/dev/null 2>&1 || true STAGE_DIR="${TARGET_DIR}.installing.$$" rm -rf "$STAGE_DIR" mkdir -p "$STAGE_DIR" cp -a "$SOURCE_DIR"/. "$STAGE_DIR"/ echo "$VERSION" > "$STAGE_DIR/VERSION" cd "$STAGE_DIR" npm install --omit=dev >/dev/null node --check server.js >/dev/null chmod +x "$STAGE_DIR/update.sh" "$STAGE_DIR/meshpress-bridge" pm2 delete "$SERVICE_NAME" >/dev/null 2>&1 || true if [ -d "$TARGET_DIR" ]; then BACKUP_DIR="${TARGET_DIR}.old.$(date +%Y%m%d%H%M%S)" mv "$TARGET_DIR" "$BACKUP_DIR" echo "Previous install moved to $BACKUP_DIR" fi mv "$STAGE_DIR" "$TARGET_DIR" cd "$TARGET_DIR" pm2 start server.js --name "$SERVICE_NAME" --time --max-memory-restart 512M >/dev/null pm2 save >/dev/null pm2 startup | grep "sudo" | bash >/dev/null 2>&1 || true cat > "$CRON_FILE" </var/log/gracepress-meshpress-bridge-update.log 2>&1 EOF chmod 644 "$CRON_FILE" echo "GracePress MeshPress Bridge v$VERSION installed." echo "Config: $ENV_FILE" echo "Token: $(grep '^MESHPRESS_BRIDGE_TOKEN=' "$ENV_FILE" | cut -d= -f2- | sed 's/^\"//;s/\"$//')" echo "Next: edit $ENV_FILE and set MESHCTRL_URL, PUBLIC_MESH_URL, MESHCTRL_USER, MESHCTRL_PASS or MESHCTRL_LOGIN_KEY_FILE, MESHCTRL_PATH, WP_DOMAIN, and WP_API_KEY." echo "Then restart: pm2 restart $SERVICE_NAME --update-env"