Files
memind/scripts/install-local-goosed-pool.sh
T
john 0dfb2e2b82
Memind CI / Test, build, and release guards (pull_request) Has been cancelled
docs(ops): record 103 goosed native migration and add migrate tooling
Document the completed Docker-to-native goosed pool cutover on 103, add the production migrate script with backup/rollback paths, and extend local native pool soak/metrics helpers used as migration gates.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-30 20:24:22 +08:00

120 lines
3.2 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
GOOSED_ROOT="${GOOSED_ROOT:-/Users/john/Project/tkmind_go-v141-prod-prep}"
RUN_SCRIPT="${GOOSED_RUN_SCRIPT:-${GOOSED_ROOT}/scripts/run-goosed-local.sh}"
PORTS="${GOOSED_NATIVE_POOL_PORTS:-18006,18007}"
LAUNCHD_DIR="${HOME}/Library/LaunchAgents"
GUI="gui/$(id -u)"
LOG_ROOT="${GOOSED_ROOT}"
usage() {
cat <<EOF
Install native goosed launchd agents for local multi-instance simulation.
Usage:
bash scripts/install-local-goosed-pool.sh [--ports 18006,18007]
Environment:
GOOSED_ROOT goosed checkout (default: tkmind_go-v141-prod-prep)
GOOSED_NATIVE_POOL_PORTS comma-separated host ports
This script only targets local dev. It refuses prod Portal port 8081 conflicts.
EOF
}
while [[ $# -gt 0 ]]; do
case "$1" in
--ports)
PORTS="${2:?missing value for --ports}"
shift 2
;;
-h|--help)
usage
exit 0
;;
*)
echo "unknown argument: $1" >&2
usage >&2
exit 2
;;
esac
done
if [[ ! -x "${RUN_SCRIPT}" ]]; then
echo "run script not found: ${RUN_SCRIPT}" >&2
exit 1
fi
if lsof -nP -iTCP:8081 -sTCP:LISTEN 2>/dev/null | grep -q "cn.tkmind.memind-portal"; then
echo "refusing to continue: production Portal appears to own 8081" >&2
exit 1
fi
mkdir -p "${LAUNCHD_DIR}" "${LOG_ROOT}"
IFS=',' read -r -a port_list <<< "${PORTS}"
install_port() {
local port="$1"
local label="com.tkmind.local-goosed-${port}"
local plist="${LAUNCHD_DIR}/${label}.plist"
local stdout_log="${LOG_ROOT}/goosed.local-${port}.launchd.log"
local stderr_log="${LOG_ROOT}/goosed.local-${port}.launchd.err.log"
cat > "${plist}" <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>${label}</string>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>${RUN_SCRIPT}</string>
<string>${port}</string>
</array>
<key>WorkingDirectory</key>
<string>${GOOSED_ROOT}</string>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>${stdout_log}</string>
<key>StandardErrorPath</key>
<string>${stderr_log}</string>
</dict>
</plist>
EOF
plutil -lint "${plist}" >/dev/null
launchctl bootout "${GUI}/${label}" 2>/dev/null || true
launchctl bootstrap "${GUI}" "${plist}"
launchctl enable "${GUI}/${label}"
launchctl kickstart -k "${GUI}/${label}"
echo "installed ${label} on port ${port}"
}
# Retire legacy single-instance label in favor of per-port labels.
launchctl bootout "${GUI}/com.tkmind.local-goosed" 2>/dev/null || true
legacy_plist="${LAUNCHD_DIR}/com.tkmind.local-goosed.plist"
if [[ -f "${legacy_plist}" ]]; then
mv "${legacy_plist}" "${legacy_plist}.bak-$(date +%Y%m%d-%H%M%S)"
echo "archived legacy plist: ${legacy_plist}"
fi
for port in "${port_list[@]}"; do
port="${port// /}"
[[ -n "${port}" ]] || continue
install_port "${port}"
done
echo ""
echo "Verify:"
echo " for p in ${PORTS//,/ }; do curl -kfsS https://127.0.0.1:\$p/status; echo \" <- \$p\"; done"
echo " node ${ROOT}/scripts/check-local-goosed-pool.mjs"