Add cluster management script for 3 server nodes and 1 HTTP proxy
Provides start/stop/status/restart/clean commands to manage a local ToastyFS cluster. Nodes listen on 127.0.0.1:8001-8003 with the HTTP proxy on 127.0.0.1:3000. Each node gets its own chunk storage directory under cluster-data/. Logs and PID files are stored there as well. https://claude.ai/code/session_01FAL4T35UGYqXexbaxvihRp
This commit is contained in:
@@ -23,3 +23,4 @@ vsr_boot_marker
|
||||
*.pem
|
||||
*.exe
|
||||
.claude/
|
||||
cluster-data/
|
||||
Executable
+177
@@ -0,0 +1,177 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Cluster management script for ToastyFS.
|
||||
# Manages a 3-node server cluster with 1 HTTP proxy.
|
||||
#
|
||||
# Usage:
|
||||
# ./cluster.sh start - Build (if needed) and start all nodes + proxy
|
||||
# ./cluster.sh stop - Stop all running nodes and the proxy
|
||||
# ./cluster.sh status - Show the status of each process
|
||||
# ./cluster.sh restart - Stop then start
|
||||
# ./cluster.sh clean - Stop everything and remove data/log directories
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
DATA_DIR="$SCRIPT_DIR/cluster-data"
|
||||
LOG_DIR="$DATA_DIR/logs"
|
||||
PID_DIR="$DATA_DIR/pids"
|
||||
|
||||
NODE1_ADDR="127.0.0.1:8001"
|
||||
NODE2_ADDR="127.0.0.1:8002"
|
||||
NODE3_ADDR="127.0.0.1:8003"
|
||||
|
||||
build() {
|
||||
echo "Building ToastyFS..."
|
||||
(cd "$SCRIPT_DIR" && bash build.sh)
|
||||
echo "Build complete."
|
||||
}
|
||||
|
||||
ensure_dirs() {
|
||||
mkdir -p "$LOG_DIR" "$PID_DIR"
|
||||
mkdir -p "$DATA_DIR/chunks-node1"
|
||||
mkdir -p "$DATA_DIR/chunks-node2"
|
||||
mkdir -p "$DATA_DIR/chunks-node3"
|
||||
}
|
||||
|
||||
start_node() {
|
||||
local name="$1"
|
||||
local addr="$2"
|
||||
local peer1="$3"
|
||||
local peer2="$4"
|
||||
local chunks="$5"
|
||||
|
||||
local pidfile="$PID_DIR/$name.pid"
|
||||
local logfile="$LOG_DIR/$name.log"
|
||||
|
||||
if [ -f "$pidfile" ] && kill -0 "$(cat "$pidfile")" 2>/dev/null; then
|
||||
echo " $name is already running (pid $(cat "$pidfile"))"
|
||||
return
|
||||
fi
|
||||
|
||||
"$SCRIPT_DIR/toasty" \
|
||||
--addr "$addr" \
|
||||
--peer "$peer1" \
|
||||
--peer "$peer2" \
|
||||
--chunks "$chunks" \
|
||||
> "$logfile" 2>&1 &
|
||||
|
||||
local pid=$!
|
||||
echo "$pid" > "$pidfile"
|
||||
echo " $name started (pid $pid) on $addr"
|
||||
}
|
||||
|
||||
start_proxy() {
|
||||
local pidfile="$PID_DIR/proxy.pid"
|
||||
local logfile="$LOG_DIR/proxy.log"
|
||||
|
||||
if [ -f "$pidfile" ] && kill -0 "$(cat "$pidfile")" 2>/dev/null; then
|
||||
echo " proxy is already running (pid $(cat "$pidfile"))"
|
||||
return
|
||||
fi
|
||||
|
||||
"$SCRIPT_DIR/toasty_proxy" \
|
||||
--server "$NODE1_ADDR" \
|
||||
--server "$NODE2_ADDR" \
|
||||
--server "$NODE3_ADDR" \
|
||||
> "$logfile" 2>&1 &
|
||||
|
||||
local pid=$!
|
||||
echo "$pid" > "$pidfile"
|
||||
echo " proxy started (pid $pid) on 127.0.0.1:3000"
|
||||
}
|
||||
|
||||
stop_process() {
|
||||
local name="$1"
|
||||
local pidfile="$PID_DIR/$name.pid"
|
||||
|
||||
if [ ! -f "$pidfile" ]; then
|
||||
echo " $name is not running (no pid file)"
|
||||
return
|
||||
fi
|
||||
|
||||
local pid
|
||||
pid=$(cat "$pidfile")
|
||||
|
||||
if kill -0 "$pid" 2>/dev/null; then
|
||||
kill "$pid"
|
||||
# Wait briefly for graceful shutdown
|
||||
local i=0
|
||||
while kill -0 "$pid" 2>/dev/null && [ $i -lt 10 ]; do
|
||||
sleep 0.1
|
||||
i=$((i + 1))
|
||||
done
|
||||
if kill -0 "$pid" 2>/dev/null; then
|
||||
kill -9 "$pid" 2>/dev/null || true
|
||||
fi
|
||||
echo " $name stopped (was pid $pid)"
|
||||
else
|
||||
echo " $name was not running (stale pid $pid)"
|
||||
fi
|
||||
|
||||
rm -f "$pidfile"
|
||||
}
|
||||
|
||||
do_start() {
|
||||
if [ ! -f "$SCRIPT_DIR/toasty" ] || [ ! -f "$SCRIPT_DIR/toasty_proxy" ]; then
|
||||
build
|
||||
fi
|
||||
|
||||
ensure_dirs
|
||||
|
||||
echo "Starting cluster..."
|
||||
start_node "node1" "$NODE1_ADDR" "$NODE2_ADDR" "$NODE3_ADDR" "$DATA_DIR/chunks-node1"
|
||||
start_node "node2" "$NODE2_ADDR" "$NODE1_ADDR" "$NODE3_ADDR" "$DATA_DIR/chunks-node2"
|
||||
start_node "node3" "$NODE3_ADDR" "$NODE1_ADDR" "$NODE2_ADDR" "$DATA_DIR/chunks-node3"
|
||||
|
||||
# Give servers a moment to start listening before launching the proxy
|
||||
sleep 1
|
||||
|
||||
start_proxy
|
||||
echo "Cluster is running. HTTP proxy at http://127.0.0.1:3000"
|
||||
}
|
||||
|
||||
do_stop() {
|
||||
echo "Stopping cluster..."
|
||||
stop_process "proxy"
|
||||
stop_process "node1"
|
||||
stop_process "node2"
|
||||
stop_process "node3"
|
||||
echo "Cluster stopped."
|
||||
}
|
||||
|
||||
do_status() {
|
||||
local all_stopped=true
|
||||
for name in node1 node2 node3 proxy; do
|
||||
local pidfile="$PID_DIR/$name.pid"
|
||||
if [ -f "$pidfile" ] && kill -0 "$(cat "$pidfile")" 2>/dev/null; then
|
||||
echo " $name: running (pid $(cat "$pidfile"))"
|
||||
all_stopped=false
|
||||
else
|
||||
echo " $name: stopped"
|
||||
fi
|
||||
done
|
||||
if $all_stopped; then
|
||||
echo "Cluster is not running."
|
||||
fi
|
||||
}
|
||||
|
||||
do_clean() {
|
||||
do_stop
|
||||
echo "Removing cluster data..."
|
||||
rm -rf "$DATA_DIR"
|
||||
echo "Clean complete."
|
||||
}
|
||||
|
||||
case "${1:-}" in
|
||||
start) do_start ;;
|
||||
stop) do_stop ;;
|
||||
status) do_status ;;
|
||||
restart) do_stop; do_start ;;
|
||||
clean) do_clean ;;
|
||||
*)
|
||||
echo "Usage: $0 {start|stop|status|restart|clean}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
Reference in New Issue
Block a user