#!/bin/bash # 인페인팅 서버 정지 스크립트 # Jetson Xavier와 x86 시스템을 모두 지원합니다. set -e # 색상 코드 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # 로그 함수들 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" } # 기본 설정 - 동적 경로 처리 SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" PID_FILE="$PROJECT_ROOT/server.pid" LOG_FILE="$PROJECT_ROOT/logs/server.log" # 시스템 감지 detect_system() { if [ "$(uname -m)" = "aarch64" ] && uname -a | grep -q "tegra"; then SYSTEM_TYPE="jetson" log_info "🚁 Jetson Xavier (ARM64) 모드로 정지합니다" elif [ "$(uname -m)" = "x86_64" ]; then SYSTEM_TYPE="x86" log_info "🖥️ x86_64 모드로 정지합니다" else log_error "지원되지 않는 시스템 아키텍처: $(uname -m)" exit 1 fi } # 서버 프로세스 찾기 find_server_processes() { local processes=() # PID 파일에서 확인 if [ -f "$PID_FILE" ]; then local pid=$(cat "$PID_FILE") if ps -p "$pid" > /dev/null 2>&1; then processes+=("$pid") fi fi # 포트 8008에서 실행 중인 프로세스 찾기 local port_processes=$(lsof -ti:8008 2>/dev/null || echo "") if [ -n "$port_processes" ]; then for pid in $port_processes; do if [[ ! " ${processes[@]} " =~ " ${pid} " ]]; then processes+=("$pid") fi done fi # 포트 8888에서 실행 중인 프로세스 찾기 (모니터링) local monitor_processes=$(lsof -ti:8888 2>/dev/null || echo "") if [ -n "$monitor_processes" ]; then for pid in $monitor_processes; do if [[ ! " ${processes[@]} " =~ " ${pid} " ]]; then processes+=("$pid") fi done fi # Python 프로세스 중 인페인팅 서버 관련 찾기 local python_processes=$(ps aux | grep -E "(uvicorn|python.*main\.py|python.*dashboard\.py)" | grep -v grep | awk '{print $2}' || echo "") if [ -n "$python_processes" ]; then for pid in $python_processes; do if [[ ! " ${processes[@]} " =~ " ${pid} " ]]; then processes+=("$pid") fi done fi echo "${processes[@]}" } # 서버 정지 stop_server() { log_info "서버 정지 중..." local processes=($(find_server_processes)) if [ ${#processes[@]} -eq 0 ]; then log_warning "실행 중인 서버 프로세스를 찾을 수 없습니다" return 0 fi log_info "발견된 프로세스: ${processes[*]}" # 각 프로세스에 SIGTERM 전송 for pid in "${processes[@]}"; do if ps -p "$pid" > /dev/null 2>&1; then log_info "프로세스 $pid에 종료 신호 전송 중..." kill -TERM "$pid" 2>/dev/null || true # 5초 대기 후 강제 종료 sleep 5 if ps -p "$pid" > /dev/null 2>&1; then log_warning "프로세스 $pid 강제 종료 중..." kill -KILL "$pid" 2>/dev/null || true fi fi done # PID 파일 정리 if [ -f "$PID_FILE" ]; then rm -f "$PID_FILE" log_info "PID 파일 정리됨" fi # 포트 사용 상태 확인 sleep 2 if lsof -ti:8008 > /dev/null 2>&1; then log_warning "포트 8008이 여전히 사용 중입니다" else log_success "포트 8008 해제됨" fi if lsof -ti:8888 > /dev/null 2>&1; then log_warning "포트 8888이 여전히 사용 중입니다" else log_success "포트 8888 해제됨" fi log_success "서버 정지 완료" } # 강제 정지 force_stop() { log_warning "강제 정지 모드로 실행 중..." # 모든 관련 프로세스 강제 종료 local processes=($(find_server_processes)) for pid in "${processes[@]}"; do if ps -p "$pid" > /dev/null 2>&1; then log_info "프로세스 $pid 강제 종료 중..." kill -KILL "$pid" 2>/dev/null || true fi done # 포트 사용 프로세스 강제 종료 local port_8008=$(lsof -ti:8008 2>/dev/null || echo "") if [ -n "$port_8008" ]; then log_info "포트 8008 사용 프로세스 강제 종료 중..." kill -KILL $port_8008 2>/dev/null || true fi local port_8888=$(lsof -ti:8888 2>/dev/null || echo "") if [ -n "$port_8888" ]; then log_info "포트 8888 사용 프로세스 강제 종료 중..." kill -KILL $port_8888 2>/dev/null || true fi # PID 파일 정리 rm -f "$PID_FILE" log_success "강제 정지 완료" } # 서버 상태 확인 check_status() { log_info "서버 상태 확인 중..." local processes=($(find_server_processes)) if [ ${#processes[@]} -eq 0 ]; then log_info "실행 중인 서버가 없습니다" return 0 fi log_info "실행 중인 서버 프로세스:" for pid in "${processes[@]}"; do if ps -p "$pid" > /dev/null 2>&1; then local cmd=$(ps -p "$pid" -o cmd= 2>/dev/null || echo "Unknown") local mem=$(ps -p "$pid" -o rss= 2>/dev/null || echo "Unknown") log_info "PID $pid: $cmd (메모리: ${mem}KB)" fi done # 포트 상태 확인 if lsof -ti:8008 > /dev/null 2>&1; then log_info "포트 8008: 사용 중 (메인 서버)" else log_info "포트 8008: 사용 안함" fi if lsof -ti:8888 > /dev/null 2>&1; then log_info "포트 8888: 사용 중 (모니터링 대시보드)" else log_info "포트 8888: 사용 안함" fi } # 로그 확인 show_logs() { if [ -f "$LOG_FILE" ]; then log_info "최근 서버 로그 (마지막 50줄):" echo "----------------------------------------" tail -n 50 "$LOG_FILE" 2>/dev/null || echo "로그 파일을 읽을 수 없습니다" echo "----------------------------------------" else log_warning "로그 파일을 찾을 수 없습니다: $LOG_FILE" fi } # 정리 작업 cleanup() { log_info "정리 작업 중..." # 임시 파일들 정리 find /tmp -name "inpaint_*" -type f -mtime +1 -delete 2>/dev/null || true # 로그 파일 압축 (7일 이상 된 것) if [ -d "$PROJECT_ROOT/logs" ]; then find "$PROJECT_ROOT/logs" -name "*.log" -mtime +7 -exec gzip {} \; 2>/dev/null || true fi log_success "정리 작업 완료" } # 메인 함수 main() { local action="stop" local force=false local status=false local logs=false local cleanup_flag=false # 옵션 파싱 while [[ $# -gt 0 ]]; do case $1 in -f|--force) force=true shift ;; -s|--status) status=true shift ;; -l|--logs) logs=true shift ;; -c|--cleanup) cleanup_flag=true shift ;; -h|--help) echo "Usage: $0 [options]" echo "Options:" echo " -f, --force 강제 정지" echo " -s, --status 서버 상태 확인" echo " -l, --logs 로그 표시" echo " -c, --cleanup 정리 작업 수행" echo " -h, --help 이 도움말 표시" exit 0 ;; *) log_error "알 수 없는 옵션: $1" exit 1 ;; esac done # 시스템 감지 detect_system # 디렉토리 이동 cd "$PROJECT_ROOT" # 로그 디렉토리 생성 mkdir -p "$PROJECT_ROOT/logs" # 상태 확인 if [ "$status" = true ]; then check_status exit 0 fi # 로그 표시 if [ "$logs" = true ]; then show_logs exit 0 fi # 정리 작업 if [ "$cleanup_flag" = true ]; then cleanup exit 0 fi # 서버 정지 if [ "$force" = true ]; then force_stop else stop_server fi log_success "🚀 인페인팅 서버 정지 완료!" } # 스크립트 실행 main "$@"