143 lines
5.8 KiB
Bash
Executable File
143 lines
5.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# upgrade.sh — bring an existing (bare-metal) MAESTRO checkout safely up to the
|
|
# latest version after a `git pull`.
|
|
#
|
|
# Why this exists
|
|
# ---------------
|
|
# `scripts/server.sh restart` rebuilds the server (dist/) but NOT the UI:
|
|
# `ui/dist` is gitignored and built separately, and npm deps are never
|
|
# refreshed. So after a `git pull` that touched dependencies or the frontend, a
|
|
# plain restart can leave a stale/missing UI bundle or ABI-mismatched native
|
|
# modules. This script runs the full, correct update sequence instead:
|
|
#
|
|
# git pull (optional) -> build-all.sh (deps + server + UI) -> restart
|
|
#
|
|
# Network bind migration (2026-06-10)
|
|
# -----------------------------------
|
|
# A security fix changed the default bind from 0.0.0.0 to 127.0.0.1 (loopback
|
|
# only). If you used to reach MAESTRO from another machine on a bare-metal
|
|
# install, after upgrading you'll get ERR_CONNECTION_REFUSED until you set HOST
|
|
# explicitly. This script detects that and offers to write HOST to .env (with a
|
|
# warning that you must enable auth before exposing a non-loopback interface).
|
|
#
|
|
# Usage:
|
|
# scripts/upgrade.sh # interactive: pull, build, restart
|
|
# scripts/upgrade.sh --no-pull # skip `git pull` (build + restart only)
|
|
# scripts/upgrade.sh --no-restart # build only, leave the server as-is
|
|
# scripts/upgrade.sh --yes # non-interactive (CI); never edits .env
|
|
# scripts/upgrade.sh --help
|
|
#
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
|
ENV_FILE="$PROJECT_DIR/.env"
|
|
|
|
DO_PULL=1
|
|
DO_RESTART=1
|
|
ASSUME_YES=0
|
|
|
|
for arg in "$@"; do
|
|
case "$arg" in
|
|
--no-pull) DO_PULL=0 ;;
|
|
--no-restart) DO_RESTART=0 ;;
|
|
--yes|-y) ASSUME_YES=1 ;;
|
|
-h|--help)
|
|
sed -n '2,29p' "$0" | sed 's/^# \{0,1\}//'
|
|
exit 0
|
|
;;
|
|
*)
|
|
echo "upgrade.sh: unknown option '$arg' (try --help)" >&2
|
|
exit 2
|
|
;;
|
|
esac
|
|
done
|
|
|
|
cd "$PROJECT_DIR"
|
|
|
|
say() { printf '\n\033[1;36m==>\033[0m %s\n' "$1"; }
|
|
warn() { printf '\033[1;33mWARN:\033[0m %s\n' "$1" >&2; }
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 1. git pull (fast-forward only; never silently merge or rewrite local work)
|
|
# ---------------------------------------------------------------------------
|
|
if [[ "$DO_PULL" -eq 1 ]]; then
|
|
if [[ -n "$(git -C "$PROJECT_DIR" status --porcelain 2>/dev/null)" ]]; then
|
|
warn "working tree has local changes — skipping 'git pull'. Commit/stash and re-run, or use --no-pull."
|
|
else
|
|
say "Pulling latest changes (git pull --ff-only)"
|
|
if ! git -C "$PROJECT_DIR" pull --ff-only; then
|
|
warn "git pull --ff-only failed (diverged or offline). Continuing with the current checkout."
|
|
fi
|
|
fi
|
|
else
|
|
say "Skipping git pull (--no-pull)"
|
|
fi
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 2. Full rebuild: refresh deps + build server dist/ AND ui/dist/ + prebake.
|
|
# This is the step a plain `server.sh restart` skips for the UI.
|
|
# ---------------------------------------------------------------------------
|
|
say "Rebuilding (deps + server + UI) via scripts/build-all.sh"
|
|
"$SCRIPT_DIR/build-all.sh"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 3. Network bind migration check (0.0.0.0 -> 127.0.0.1 default since 2026-06-10)
|
|
# ---------------------------------------------------------------------------
|
|
host_in_env=""
|
|
if [[ -f "$ENV_FILE" ]]; then
|
|
# First non-comment HOST=... line, value with surrounding quotes stripped.
|
|
host_in_env="$(grep -E '^[[:space:]]*(export[[:space:]]+)?HOST=' "$ENV_FILE" \
|
|
| grep -vE '^[[:space:]]*#' \
|
|
| head -1 | sed -E 's/^[[:space:]]*(export[[:space:]]+)?HOST=//; s/^["'\'']//; s/["'\'']$//')"
|
|
fi
|
|
|
|
say "Checking network bind"
|
|
if [[ -n "${HOST:-}" ]]; then
|
|
echo " HOST is set in the environment ($HOST) — bind is explicit, nothing to migrate."
|
|
elif [[ -n "$host_in_env" ]]; then
|
|
echo " HOST=$host_in_env found in .env — bind is explicit, nothing to migrate."
|
|
else
|
|
cat <<'EOF'
|
|
HOST is not set, so the server now binds 127.0.0.1 (loopback only).
|
|
Since 2026-06-10 the default changed from 0.0.0.0 for security: the agent
|
|
API includes a Bash tool, so an auth-less instance on the LAN is effectively
|
|
unauthenticated remote code execution.
|
|
|
|
If you ONLY open MAESTRO from this same machine (http://localhost:9876),
|
|
no action is needed.
|
|
|
|
If you reach it from ANOTHER machine, that is why you now get
|
|
ERR_CONNECTION_REFUSED. To restore remote access you must set HOST
|
|
explicitly -- and you should enable auth (auth.local or OAuth) in
|
|
config.yaml before exposing a non-loopback interface.
|
|
EOF
|
|
if [[ "$ASSUME_YES" -eq 0 ]]; then
|
|
printf '\n Append HOST=0.0.0.0 to .env now? Only do this if auth is (or will be) enabled. [y/N] '
|
|
read -r reply || reply=""
|
|
if [[ "$reply" =~ ^[Yy]$ ]]; then
|
|
{ [[ -f "$ENV_FILE" && -n "$(tail -c1 "$ENV_FILE" 2>/dev/null)" ]] && echo "" >> "$ENV_FILE"; } || true
|
|
printf '\n# Added by scripts/upgrade.sh: restore non-loopback bind (enable auth first!)\nHOST=0.0.0.0\n' >> "$ENV_FILE"
|
|
echo " Wrote HOST=0.0.0.0 to $ENV_FILE"
|
|
else
|
|
echo " Left .env unchanged. Set HOST=0.0.0.0 in .env manually when ready."
|
|
fi
|
|
else
|
|
warn "non-interactive (--yes): not editing .env. Set HOST in .env manually if you need remote access."
|
|
fi
|
|
fi
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 4. Restart
|
|
# ---------------------------------------------------------------------------
|
|
if [[ "$DO_RESTART" -eq 1 ]]; then
|
|
say "Restarting server (scripts/server.sh restart)"
|
|
"$SCRIPT_DIR/server.sh" restart
|
|
echo
|
|
echo "Done. If the server is healthy, open it at the bind address reported above"
|
|
echo "(loopback default: http://localhost:9876)."
|
|
else
|
|
say "Build complete (--no-restart). Start the server with: scripts/server.sh restart"
|
|
fi
|