387 lines
12 KiB
Bash
Executable File
387 lines
12 KiB
Bash
Executable File
#!/bin/bash
|
|
# Restart Ginxsom Development Environment
|
|
# Combines nginx and FastCGI restart operations for debugging
|
|
# WARNING: This script DELETES all databases in db/ for fresh testing
|
|
|
|
# Configuration
|
|
|
|
# Parse command line arguments
|
|
TEST_MODE=1 # Default to test mode
|
|
FOLLOW_LOGS=0
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case $1 in
|
|
-t|--test-keys)
|
|
TEST_MODE=1
|
|
shift
|
|
;;
|
|
-p|--production)
|
|
TEST_MODE=0
|
|
shift
|
|
;;
|
|
--follow)
|
|
FOLLOW_LOGS=1
|
|
shift
|
|
;;
|
|
*)
|
|
echo "Unknown option: $1"
|
|
echo "Usage: $0 [-t|--test-keys] [-p|--production] [--follow]"
|
|
echo " -t, --test-keys Use test mode with keys from .test_keys (DEFAULT)"
|
|
echo " -p, --production Use production mode (generate new keys)"
|
|
echo " --follow Follow logs in real-time"
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# Check for --follow flag
|
|
if [[ $FOLLOW_LOGS -eq 1 ]]; then
|
|
echo "=== Following logs in real-time ==="
|
|
echo "Monitoring: nginx error, nginx access, app stderr, app stdout"
|
|
echo "Press Ctrl+C to stop following logs"
|
|
echo
|
|
|
|
# Start tailing multiple log files
|
|
mkdir -p logs/nginx logs/app
|
|
touch logs/nginx/error.log logs/nginx/access.log logs/app/stderr.log logs/app/stdout.log
|
|
|
|
tail -f logs/nginx/error.log logs/nginx/access.log logs/app/stderr.log logs/app/stdout.log &
|
|
wait
|
|
exit 0
|
|
fi
|
|
# Detect architecture for static binary name
|
|
ARCH=$(uname -m)
|
|
case "$ARCH" in
|
|
x86_64) STATIC_BINARY="./build/ginxsom-fcgi_static_x86_64" ;;
|
|
aarch64|arm64) STATIC_BINARY="./build/ginxsom-fcgi_static_arm64" ;;
|
|
*) STATIC_BINARY="./build/ginxsom-fcgi_static_${ARCH}" ;;
|
|
esac
|
|
|
|
# Use static binary if available, fallback to dynamic
|
|
if [ -f "$STATIC_BINARY" ]; then
|
|
FCGI_BINARY="$STATIC_BINARY"
|
|
echo "Using static binary: $FCGI_BINARY"
|
|
else
|
|
FCGI_BINARY="./build/ginxsom-fcgi"
|
|
echo "Static binary not found, using dynamic binary: $FCGI_BINARY"
|
|
fi
|
|
SOCKET_PATH="/tmp/ginxsom-fcgi.sock"
|
|
PID_FILE="/tmp/ginxsom-fcgi.pid"
|
|
NGINX_CONFIG="config/local-nginx.conf"
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Ensure log directories exist with proper permissions
|
|
echo "Creating log directories..."
|
|
mkdir -p logs/nginx logs/app
|
|
touch logs/app/stderr.log logs/app/stdout.log logs/nginx/error.log logs/nginx/access.log
|
|
chmod 644 logs/app/stderr.log logs/app/stdout.log logs/nginx/error.log logs/nginx/access.log
|
|
chmod 755 logs/nginx logs/app
|
|
|
|
if [ $TEST_MODE -eq 1 ]; then
|
|
echo -e "${YELLOW}=== Ginxsom Development Environment Restart (TEST MODE) ===${NC}"
|
|
echo "Using test keys from .test_keys file"
|
|
else
|
|
echo -e "${YELLOW}=== Ginxsom Development Environment Restart ===${NC}"
|
|
fi
|
|
echo "Starting full restart sequence..."
|
|
|
|
# Function to check if a process is running
|
|
check_process() {
|
|
local pid=$1
|
|
kill -0 "$pid" 2>/dev/null
|
|
}
|
|
|
|
# Function to wait for process to stop
|
|
wait_for_stop() {
|
|
local pid=$1
|
|
local timeout=${2:-10}
|
|
local count=0
|
|
|
|
while check_process "$pid" && [ $count -lt $timeout ]; do
|
|
sleep 1
|
|
((count++))
|
|
done
|
|
|
|
if check_process "$pid"; then
|
|
echo -e "${RED}Warning: Process $pid still running after ${timeout}s${NC}"
|
|
return 1
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
# Step 1: Stop nginx
|
|
echo -e "\n${YELLOW}1. Stopping nginx...${NC}"
|
|
|
|
# First try to stop nginx gracefully using our config
|
|
if pgrep -f "nginx.*${NGINX_CONFIG}" > /dev/null; then
|
|
echo "Found nginx processes with our config, stopping gracefully..."
|
|
nginx -p . -c "${NGINX_CONFIG}" -s stop 2>/dev/null
|
|
sleep 2
|
|
fi
|
|
|
|
# Kill any remaining nginx processes (including those on port 9001)
|
|
NGINX_PIDS=$(pgrep nginx)
|
|
if [ ! -z "$NGINX_PIDS" ]; then
|
|
echo "Found running nginx processes, stopping..."
|
|
echo "Nginx PIDs: $NGINX_PIDS"
|
|
# Try graceful stop first
|
|
sudo nginx -s stop 2>/dev/null || true
|
|
sleep 2
|
|
|
|
# Force kill any remaining nginx processes
|
|
NGINX_PIDS=$(pgrep nginx)
|
|
if [ ! -z "$NGINX_PIDS" ]; then
|
|
echo "Force killing remaining nginx processes: $NGINX_PIDS"
|
|
sudo kill -9 $NGINX_PIDS 2>/dev/null || true
|
|
fi
|
|
echo -e "${GREEN}nginx stopped${NC}"
|
|
else
|
|
echo "nginx not running"
|
|
fi
|
|
|
|
# Step 2: Stop FastCGI
|
|
echo -e "\n${YELLOW}2. Stopping FastCGI application...${NC}"
|
|
|
|
# Method 1: Stop via PID file
|
|
if [ -f "$PID_FILE" ]; then
|
|
PID=$(cat "$PID_FILE")
|
|
echo "Found PID file with process $PID"
|
|
if check_process "$PID"; then
|
|
echo "Stopping FastCGI process $PID"
|
|
kill "$PID"
|
|
if wait_for_stop "$PID" 5; then
|
|
echo -e "${GREEN}FastCGI process stopped gracefully${NC}"
|
|
else
|
|
echo "Force killing FastCGI process $PID"
|
|
kill -9 "$PID" 2>/dev/null
|
|
fi
|
|
else
|
|
echo "PID $PID not running, cleaning up PID file"
|
|
fi
|
|
rm -f "$PID_FILE"
|
|
fi
|
|
|
|
# Method 2: Kill any remaining ginxsom-fcgi processes
|
|
FCGI_PIDS=$(pgrep -f "ginxsom-fcgi")
|
|
if [ ! -z "$FCGI_PIDS" ]; then
|
|
echo "Found additional FastCGI processes: $FCGI_PIDS"
|
|
kill $FCGI_PIDS 2>/dev/null
|
|
sleep 2
|
|
# Force kill if still running
|
|
FCGI_PIDS=$(pgrep -f "ginxsom-fcgi")
|
|
if [ ! -z "$FCGI_PIDS" ]; then
|
|
echo "Force killing FastCGI processes: $FCGI_PIDS"
|
|
kill -9 $FCGI_PIDS 2>/dev/null
|
|
fi
|
|
fi
|
|
|
|
# Method 3: Clean up socket
|
|
if [ -S "$SOCKET_PATH" ]; then
|
|
echo "Removing old socket: $SOCKET_PATH"
|
|
rm -f "$SOCKET_PATH"
|
|
fi
|
|
|
|
echo -e "${GREEN}FastCGI cleanup complete${NC}"
|
|
|
|
# Step 3: Always rebuild FastCGI binary with static build
|
|
echo -e "\n${YELLOW}3. Rebuilding FastCGI binary (static build)...${NC}"
|
|
echo "Cleaning old build artifacts to ensure fresh embedding..."
|
|
make clean
|
|
echo "Removing local embedded header to prevent Docker cache issues..."
|
|
rm -f src/admin_interface_embedded.h
|
|
echo "Building static binary with Docker..."
|
|
make static
|
|
if [ $? -ne 0 ]; then
|
|
echo -e "${RED}Static build failed! Cannot continue.${NC}"
|
|
echo -e "${RED}Docker must be available and running for static builds.${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
# Update FCGI_BINARY to use the newly built static binary
|
|
ARCH=$(uname -m)
|
|
case "$ARCH" in
|
|
x86_64) FCGI_BINARY="./build/ginxsom-fcgi_static_x86_64" ;;
|
|
aarch64|arm64) FCGI_BINARY="./build/ginxsom-fcgi_static_arm64" ;;
|
|
*) FCGI_BINARY="./build/ginxsom-fcgi_static_${ARCH}" ;;
|
|
esac
|
|
echo -e "${GREEN}Static build complete: $FCGI_BINARY${NC}"
|
|
|
|
# Step 3.5: Clean database directory for fresh testing
|
|
echo -e "\n${YELLOW}3.5. Cleaning database directory...${NC}"
|
|
echo "Removing all existing databases for fresh start..."
|
|
|
|
# Remove all .db files in db/ directory
|
|
if ls db/*.db 1> /dev/null 2>&1; then
|
|
echo "Found databases to remove:"
|
|
ls -lh db/*.db
|
|
rm -f db/*.db
|
|
echo -e "${GREEN}Database cleanup complete${NC}"
|
|
else
|
|
echo "No existing databases found"
|
|
fi
|
|
|
|
# Step 3.75: Handle keys based on mode
|
|
echo -e "\n${YELLOW}3.75. Configuring server keys...${NC}"
|
|
|
|
if [ $TEST_MODE -eq 1 ]; then
|
|
# Test mode: verify .test_keys file exists
|
|
if [ ! -f ".test_keys" ]; then
|
|
echo -e "${RED}ERROR: .test_keys file not found${NC}"
|
|
echo -e "${RED}Test mode requires .test_keys file in project root${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
# Extract test server pubkey to determine database name
|
|
TEST_PUBKEY=$(grep "^SERVER_PUBKEY=" .test_keys | cut -d"'" -f2)
|
|
if [ -z "$TEST_PUBKEY" ]; then
|
|
echo -e "${RED}ERROR: Could not extract SERVER_PUBKEY from .test_keys${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
echo -e "${GREEN}Test mode: Will use keys from .test_keys${NC}"
|
|
echo -e "${GREEN}Fresh test database will be created as: db/${TEST_PUBKEY}.db${NC}"
|
|
else
|
|
# Production mode: databases were cleaned, will generate new keypair
|
|
echo -e "${YELLOW}Production mode: Fresh start with new keypair${NC}"
|
|
echo -e "${YELLOW}New database will be created as db/<new_pubkey>.db${NC}"
|
|
fi
|
|
|
|
# Step 4: Start FastCGI
|
|
echo -e "\n${YELLOW}4. Starting FastCGI application...${NC}"
|
|
echo "Socket: $SOCKET_PATH"
|
|
echo "Binary: $FCGI_BINARY"
|
|
|
|
# Check if spawn-fcgi is available
|
|
if ! command -v spawn-fcgi &> /dev/null; then
|
|
echo -e "${RED}Error: spawn-fcgi not found. Please install it:${NC}"
|
|
echo " Ubuntu/Debian: sudo apt-get install spawn-fcgi"
|
|
echo " macOS: brew install spawn-fcgi"
|
|
exit 1
|
|
fi
|
|
|
|
# Start FastCGI application with proper logging (daemonized but with redirected streams)
|
|
# Set debug environment variable for pubkey extraction diagnostics
|
|
echo "Setting GINX_DEBUG environment for pubkey extraction diagnostics"
|
|
export GINX_DEBUG=1
|
|
|
|
# Build command line arguments based on mode
|
|
FCGI_ARGS="--storage-dir blobs"
|
|
if [ $TEST_MODE -eq 1 ]; then
|
|
FCGI_ARGS="$FCGI_ARGS --test-keys"
|
|
echo -e "${YELLOW}Starting FastCGI in TEST MODE with test keys${NC}"
|
|
else
|
|
# Production mode: databases were cleaned, will generate new keys
|
|
echo -e "${YELLOW}Starting FastCGI in production mode - will generate new keys and create database${NC}"
|
|
fi
|
|
|
|
# Start FastCGI application with proper logging
|
|
echo "FastCGI starting at $(date)" >> logs/app/stderr.log
|
|
|
|
# Use nohup with spawn-fcgi -n to keep process running with redirected output
|
|
# The key is: nohup prevents HUP signal, -n prevents daemonization (keeps stderr connected)
|
|
nohup spawn-fcgi -n -s "$SOCKET_PATH" -M 666 -u "$USER" -g "$USER" -- "$FCGI_BINARY" $FCGI_ARGS >>logs/app/stdout.log 2>>logs/app/stderr.log </dev/null &
|
|
SPAWN_PID=$!
|
|
|
|
# Wait for spawn-fcgi to spawn the child
|
|
sleep 1
|
|
|
|
# Get the actual FastCGI process PID (child of spawn-fcgi)
|
|
FCGI_PID=$(pgrep -f "ginxsom-fcgi.*--storage-dir" | head -1)
|
|
if [ -z "$FCGI_PID" ]; then
|
|
echo -e "${RED}Warning: Could not find FastCGI process${NC}"
|
|
FCGI_PID=$SPAWN_PID
|
|
fi
|
|
|
|
# Save PID
|
|
echo $FCGI_PID > "$PID_FILE"
|
|
|
|
# Give it a moment to start
|
|
sleep 1
|
|
|
|
if check_process "$FCGI_PID"; then
|
|
echo -e "${GREEN}FastCGI application started successfully${NC}"
|
|
echo "PID: $FCGI_PID"
|
|
echo -e "${GREEN}Process confirmed running${NC}"
|
|
else
|
|
echo -e "${RED}Failed to start FastCGI application${NC}"
|
|
echo -e "${RED}Process may have crashed immediately${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
# Step 5: Start nginx
|
|
echo -e "\n${YELLOW}5. Starting nginx...${NC}"
|
|
if [ ! -f "$NGINX_CONFIG" ]; then
|
|
echo -e "${RED}Error: nginx config not found at $NGINX_CONFIG${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
# Test nginx configuration first
|
|
nginx -p . -c "$NGINX_CONFIG" -t
|
|
if [ $? -ne 0 ]; then
|
|
echo -e "${RED}nginx configuration test failed!${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
# Start nginx
|
|
nginx -p . -c "$NGINX_CONFIG"
|
|
if [ $? -eq 0 ]; then
|
|
echo -e "${GREEN}nginx started successfully${NC}"
|
|
|
|
# Verify nginx is running
|
|
sleep 1
|
|
if pgrep -f "nginx.*${NGINX_CONFIG}" > /dev/null; then
|
|
echo -e "${GREEN}nginx confirmed running${NC}"
|
|
else
|
|
echo -e "${RED}Warning: nginx may have crashed${NC}"
|
|
exit 1
|
|
fi
|
|
else
|
|
echo -e "${RED}Failed to start nginx${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
# Step 6: Final status check
|
|
echo -e "\n${YELLOW}6. Final status check...${NC}"
|
|
|
|
# Check FastCGI
|
|
if [ -f "$PID_FILE" ]; then
|
|
PID=$(cat "$PID_FILE")
|
|
if check_process "$PID"; then
|
|
echo -e "${GREEN}✓ FastCGI running (PID: $PID)${NC}"
|
|
else
|
|
echo -e "${RED}✗ FastCGI not running${NC}"
|
|
fi
|
|
else
|
|
echo -e "${RED}✗ FastCGI PID file missing${NC}"
|
|
fi
|
|
|
|
# Check nginx
|
|
if pgrep -f "nginx.*${NGINX_CONFIG}" > /dev/null; then
|
|
NGINX_PIDS=$(pgrep -f "nginx.*${NGINX_CONFIG}" | tr '\n' ' ')
|
|
echo -e "${GREEN}✓ nginx running (PIDs: $NGINX_PIDS)${NC}"
|
|
else
|
|
echo -e "${RED}✗ nginx not running${NC}"
|
|
fi
|
|
|
|
# Check socket
|
|
if [ -S "$SOCKET_PATH" ]; then
|
|
echo -e "${GREEN}✓ FastCGI socket exists: $SOCKET_PATH${NC}"
|
|
else
|
|
echo -e "${RED}✗ FastCGI socket missing: $SOCKET_PATH${NC}"
|
|
fi
|
|
|
|
echo -e "\n${GREEN}=== Restart sequence complete ===${NC}"
|
|
echo -e "${YELLOW}To stop all processes, run: nginx -p . -c $NGINX_CONFIG -s stop && kill \$(cat $PID_FILE 2>/dev/null)${NC}"
|
|
echo -e "${YELLOW}To monitor logs, check: logs/nginx/error.log, logs/nginx/access.log, logs/app/stderr.log, logs/app/stdout.log${NC}"
|
|
echo -e "\n${YELLOW}Server is available at:${NC}"
|
|
echo -e " ${GREEN}HTTP:${NC} http://localhost:9001"
|
|
echo -e " ${GREEN}HTTPS:${NC} https://localhost:9443"
|
|
echo -e "\n${YELLOW}Admin WebSocket endpoint:${NC}"
|
|
echo -e " ${GREEN}WSS:${NC} wss://localhost:9443/admin (via nginx proxy)"
|
|
echo -e " ${GREEN}WS:${NC} ws://localhost:9001/admin (via nginx proxy)"
|
|
echo -e " ${GREEN}Direct:${NC} ws://localhost:9442 (direct connection)" |