Skip to main content
Glama
services.sh13.4 kB
#!/bin/bash # Iris Services Management Script # Manages OAuth Server (8000), MCP Server (8001), and Booking Page (8081) SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PID_DIR="$SCRIPT_DIR/.pids" LOG_DIR="$SCRIPT_DIR/logs" # Create directories mkdir -p "$PID_DIR" "$LOG_DIR" # Service definitions declare -A SERVICES=( ["oauth"]="8000:src.oauth_server.app:uvicorn src.oauth_server.app:app --host 0.0.0.0 --port 8000" ["mcp"]="8001:src.mcp_servers.microsoft.server:python -m src.mcp_servers.microsoft.server" ["booking"]="8081:src.booking_page.app:uvicorn src.booking_page.app:app --host 0.0.0.0 --port 8081" ) # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Helper functions log_info() { echo -e "${BLUE}[INFO]${NC} $1" } log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" } log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } log_error() { echo -e "${RED}[ERROR]${NC} $1" } # Get service info get_service_port() { local service=$1 echo "${SERVICES[$service]}" | cut -d: -f1 } get_service_name() { local service=$1 echo "${SERVICES[$service]}" | cut -d: -f2 } get_service_cmd() { local service=$1 echo "${SERVICES[$service]}" | cut -d: -f3- } # Check if service is running is_running() { local service=$1 local pid_file="$PID_DIR/$service.pid" if [ -f "$pid_file" ]; then local pid=$(cat "$pid_file") if ps -p "$pid" > /dev/null 2>&1; then return 0 else # PID file exists but process is dead rm -f "$pid_file" return 1 fi fi return 1 } # Get PID get_pid() { local service=$1 local pid_file="$PID_DIR/$service.pid" if [ -f "$pid_file" ]; then cat "$pid_file" else echo "" fi } # Start a service start_service() { local service=$1 local port=$(get_service_port "$service") local service_name=$(get_service_name "$service") local cmd=$(get_service_cmd "$service") local log_file="$LOG_DIR/$service.log" local pid_file="$PID_DIR/$service.pid" if is_running "$service"; then log_warning "$service is already running (PID: $(get_pid "$service"))" return 0 fi log_info "Starting $service on port $port..." # Find and kill any process using the port local pids_to_kill=$(python3 << EOF import os port_target = $port port_hex = format(port_target, '04X') pids = [] try: with open('/proc/net/tcp', 'r') as f: lines = f.readlines() for line in lines[1:]: # Skip header if port_hex in line: parts = line.split() if len(parts) > 9: inode = parts[9] # Find which process owns this inode for pid in os.listdir('/proc'): if not pid.isdigit(): continue try: fd_dir = f'/proc/{pid}/fd' for fd in os.listdir(fd_dir): link = os.readlink(f'{fd_dir}/{fd}') if f'socket:[{inode}]' in link: pids.append(pid) break except (FileNotFoundError, PermissionError, OSError): pass except Exception: pass print(' '.join(set(pids))) EOF ) if [ -n "$pids_to_kill" ]; then for pid in $pids_to_kill; do # Skip critical system processes if [ "$pid" != "1" ] && [ "$pid" != "7" ]; then log_warning "Killing process $pid occupying port $port" kill -9 "$pid" 2>/dev/null fi done sleep 1 fi # Start the service cd "$SCRIPT_DIR" nohup $cmd > "$log_file" 2>&1 & local pid=$! # Save PID echo "$pid" > "$pid_file" # Wait and verify sleep 2 if ps -p "$pid" > /dev/null 2>&1; then # Additional verification - check if port is listening local retries=5 while [ $retries -gt 0 ]; do if nc -z localhost $port 2>/dev/null || curl -s http://localhost:$port/health > /dev/null 2>&1; then log_success "$service started successfully (PID: $pid, Port: $port)" return 0 fi sleep 1 retries=$((retries - 1)) done log_warning "$service process is running but port $port is not responding yet" return 0 else log_error "$service failed to start. Check logs: $log_file" rm -f "$pid_file" return 1 fi } # Stop a service stop_service() { local service=$1 local port=$(get_service_port "$service") local pid_file="$PID_DIR/$service.pid" # First, try to stop from PID file if is_running "$service"; then local pid=$(get_pid "$service") log_info "Stopping $service (PID: $pid)..." # Try graceful shutdown first kill "$pid" 2>/dev/null # Wait up to 5 seconds for graceful shutdown local count=0 while [ $count -lt 5 ] && ps -p "$pid" > /dev/null 2>&1; do sleep 1 count=$((count + 1)) done # Force kill if still running if ps -p "$pid" > /dev/null 2>&1; then log_warning "Graceful shutdown failed, forcing kill..." kill -9 "$pid" 2>/dev/null sleep 1 fi else log_warning "$service PID file not found, searching by port..." fi # Also find and kill any process still using the port local pids_to_kill=$(python3 << EOF import os port_target = $port port_hex = format(port_target, '04X') pids = [] try: with open('/proc/net/tcp', 'r') as f: lines = f.readlines() for line in lines[1:]: # Skip header if port_hex in line: parts = line.split() if len(parts) > 9: inode = parts[9] # Find which process owns this inode for pid in os.listdir('/proc'): if not pid.isdigit(): continue try: fd_dir = f'/proc/{pid}/fd' for fd in os.listdir(fd_dir): link = os.readlink(f'{fd_dir}/{fd}') if f'socket:[{inode}]' in link: pids.append(pid) break except (FileNotFoundError, PermissionError, OSError): pass except Exception: pass print(' '.join(set(pids))) EOF ) if [ -n "$pids_to_kill" ]; then for pid in $pids_to_kill; do # Skip critical system processes if [ "$pid" != "1" ] && [ "$pid" != "7" ]; then log_warning "Killing remaining process $pid on port $port" kill -9 "$pid" 2>/dev/null fi done sleep 1 fi # Clean up PID file rm -f "$pid_file" log_success "$service stopped successfully" return 0 } # Restart a service restart_service() { local service=$1 log_info "Restarting $service..." stop_service "$service" sleep 1 start_service "$service" } # Reload a service (graceful restart) reload_service() { restart_service "$1" } # Show status status_service() { local service=$1 local port=$(get_service_port "$service") if is_running "$service"; then local pid=$(get_pid "$service") echo -e "${GREEN}●${NC} $service is ${GREEN}running${NC} (PID: $pid, Port: $port)" # Check if port is responding if nc -z localhost $port 2>/dev/null || curl -s http://localhost:$port/health > /dev/null 2>&1; then echo " └─ Port $port is responding" else echo -e " └─ ${YELLOW}Warning: Port $port is not responding${NC}" fi else echo -e "${RED}○${NC} $service is ${RED}stopped${NC}" fi } # Show all status status_all() { log_info "Service Status:" echo "" for service in "${!SERVICES[@]}"; do status_service "$service" done } # Start all services start_all() { log_info "Starting all services..." for service in oauth mcp booking; do start_service "$service" done } # Stop all services stop_all() { log_info "Stopping all services..." for service in booking mcp oauth; do stop_service "$service" done } # Restart all services restart_all() { log_info "Restarting all services..." stop_all sleep 2 start_all } # Show logs logs() { local service=$1 local log_file="$LOG_DIR/$service.log" if [ -f "$log_file" ]; then tail -f "$log_file" else log_error "Log file not found: $log_file" return 1 fi } # Show last N lines of logs logs_tail() { local service=$1 local lines=${2:-50} local log_file="$LOG_DIR/$service.log" if [ -f "$log_file" ]; then tail -n "$lines" "$log_file" else log_error "Log file not found: $log_file" return 1 fi } # Usage usage() { cat << EOF Iris Services Management Script Usage: $0 <command> [service] Commands: start [service] Start service(s) (all if no service specified) stop [service] Stop service(s) (all if no service specified) restart [service] Restart service(s) (all if no service specified) reload [service] Reload service(s) (same as restart) status [service] Show status of service(s) (all if no service specified) logs <service> Follow logs of a service tail <service> [N] Show last N lines of service logs (default: 50) Services: oauth OAuth Server (port 8000) mcp MCP Server (port 8001) booking Booking Page (port 8081) all All services (default) Examples: $0 start # Start all services $0 start booking # Start only booking service $0 stop # Stop all services $0 restart mcp # Restart only MCP service $0 status # Show status of all services $0 logs booking # Follow booking service logs $0 tail mcp 100 # Show last 100 lines of MCP logs EOF } # Main main() { local command=${1:-status} local service=${2:-all} case "$command" in start) if [ "$service" = "all" ]; then start_all else if [ -n "${SERVICES[$service]}" ]; then start_service "$service" else log_error "Unknown service: $service" usage exit 1 fi fi ;; stop) if [ "$service" = "all" ]; then stop_all else if [ -n "${SERVICES[$service]}" ]; then stop_service "$service" else log_error "Unknown service: $service" usage exit 1 fi fi ;; restart|reload) if [ "$service" = "all" ]; then restart_all else if [ -n "${SERVICES[$service]}" ]; then restart_service "$service" else log_error "Unknown service: $service" usage exit 1 fi fi ;; status) if [ "$service" = "all" ]; then status_all else if [ -n "${SERVICES[$service]}" ]; then status_service "$service" else log_error "Unknown service: $service" usage exit 1 fi fi ;; logs) if [ "$service" = "all" ]; then log_error "Please specify a service for logs" usage exit 1 else if [ -n "${SERVICES[$service]}" ]; then logs "$service" else log_error "Unknown service: $service" usage exit 1 fi fi ;; tail) local lines=${3:-50} if [ "$service" = "all" ]; then log_error "Please specify a service for logs" usage exit 1 else if [ -n "${SERVICES[$service]}" ]; then logs_tail "$service" "$lines" else log_error "Unknown service: $service" usage exit 1 fi fi ;; help|--help|-h) usage ;; *) log_error "Unknown command: $command" usage exit 1 ;; esac } # Run main "$@"

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ilvolodel/iris-legacy'

If you have feedback or need assistance with the MCP directory API, please join our Discord server