start.sh 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. #!/bin/bash
  2. # KVM Manager 启动脚本
  3. set -e
  4. SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
  5. BACKEND_DIR="$SCRIPT_DIR/backend"
  6. FRONTEND_DIR="$SCRIPT_DIR/frontend"
  7. LOG_DIR="/tmp/kvm-manager-logs"
  8. # 颜色定义
  9. RED='\033[0;31m'
  10. GREEN='\033[0;32m'
  11. YELLOW='\033[1;33m'
  12. NC='\033[0m' # No Color
  13. usage() {
  14. echo "用法: $0 [选项]"
  15. echo ""
  16. echo "选项:"
  17. echo " -b, --backend 只启动后端服务"
  18. echo " -f, --frontend 只启动前端服务"
  19. echo " -a, --all 启动所有服务 (默认)"
  20. echo " -s, --stop 停止所有服务"
  21. echo " -r, --restart 重启所有服务"
  22. echo " -h, --help 显示帮助"
  23. echo ""
  24. echo "示例:"
  25. echo " $0 # 启动所有服务"
  26. echo " $0 -b # 只启动后端"
  27. echo " $0 -s # 停止所有服务"
  28. }
  29. # 创建日志目录
  30. mkdir -p "$LOG_DIR"
  31. # 检查端口是否被占用
  32. check_port() {
  33. local port=$1
  34. if lsof -i:$port &>/dev/null; then
  35. return 1 # 端口被占用
  36. fi
  37. return 0 # 端口空闲
  38. }
  39. # 停止服务
  40. stop_services() {
  41. echo -e "${YELLOW}停止 KVM Manager 服务...${NC}"
  42. # 停止后端
  43. if [ -f "$LOG_DIR/backend.pid" ]; then
  44. local pid=$(cat "$LOG_DIR/backend.pid")
  45. if ps -p "$pid" &>/dev/null; then
  46. kill "$pid" 2>/dev/null || true
  47. echo " 后端服务已停止 (PID: $pid)"
  48. fi
  49. rm -f "$LOG_DIR/backend.pid"
  50. fi
  51. # 停止前端
  52. if [ -f "$LOG_DIR/frontend.pid" ]; then
  53. local pid=$(cat "$LOG_DIR/frontend.pid")
  54. if ps -p "$pid" &>/dev/null; then
  55. kill "$pid" 2>/dev/null || true
  56. echo " 前端服务已停止 (PID: $pid)"
  57. fi
  58. rm -f "$LOG_DIR/frontend.pid"
  59. fi
  60. # 强制停止残留进程
  61. pkill -f "uvicorn.*app.main:app" 2>/dev/null || true
  62. pkill -f "vite" 2>/dev/null || true
  63. echo -e "${GREEN}所有服务已停止${NC}"
  64. }
  65. # 启动后端
  66. start_backend() {
  67. echo -e "${YELLOW}启动后端服务...${NC}"
  68. if ! check_port 8004; then
  69. echo -e "${RED}错误: 端口 8004 已被占用${NC}"
  70. return 1
  71. fi
  72. cd "$BACKEND_DIR"
  73. # 检查虚拟环境
  74. if [ ! -d "venv" ]; then
  75. echo -e "${RED}错误: 未找到虚拟环境,请先运行: cd backend && python -m venv venv${NC}"
  76. return 1
  77. fi
  78. source "$BACKEND_DIR/venv/bin/activate"
  79. nohup uvicorn app.main:app --host 0.0.0.0 --port 8004 > "$LOG_DIR/backend.log" 2>&1 &
  80. local pid=$!
  81. echo $pid > "$LOG_DIR/backend.pid"
  82. sleep 2
  83. if ps -p "$pid" &>/dev/null; then
  84. echo -e "${GREEN}✓ 后端服务已启动 (PID: $pid, 端口: 8004)${NC}"
  85. echo " 日志: $LOG_DIR/backend.log"
  86. else
  87. echo -e "${RED}✗ 后端服务启动失败${NC}"
  88. tail -20 "$LOG_DIR/backend.log"
  89. return 1
  90. fi
  91. }
  92. # 启动前端
  93. start_frontend() {
  94. echo -e "${YELLOW}启动前端服务...${NC}"
  95. if ! check_port 8005; then
  96. echo -e "${RED}错误: 端口 8005 已被占用${NC}"
  97. return 1
  98. fi
  99. cd "$FRONTEND_DIR"
  100. # 检查 node_modules
  101. if [ ! -d "node_modules" ]; then
  102. echo -e "${YELLOW}首次运行,需要安装依赖...${NC}"
  103. npm install
  104. fi
  105. nohup npm run dev -- --host 0.0.0.0 --port 8005 > "$LOG_DIR/frontend.log" 2>&1 &
  106. local pid=$!
  107. echo $pid > "$LOG_DIR/frontend.pid"
  108. sleep 5
  109. if ps -p "$pid" &>/dev/null; then
  110. echo -e "${GREEN}✓ 前端服务已启动 (PID: $pid, 端口: 8005)${NC}"
  111. echo " 日志: $LOG_DIR/frontend.log"
  112. else
  113. echo -e "${RED}✗ 前端服务启动失败${NC}"
  114. tail -20 "$LOG_DIR/frontend.log"
  115. return 1
  116. fi
  117. }
  118. # 查看状态
  119. show_status() {
  120. echo ""
  121. echo "========== KVM Manager 服务状态 =========="
  122. echo ""
  123. # 后端状态
  124. if [ -f "$LOG_DIR/backend.pid" ]; then
  125. local pid=$(cat "$LOG_DIR/backend.pid")
  126. if ps -p "$pid" &>/dev/null; then
  127. echo -e "${GREEN}✓ 后端服务${NC} - 运行中 (PID: $pid, 端口: 8004)"
  128. else
  129. echo -e "${RED}✗ 后端服务${NC} - 未运行 (PID 文件过期)"
  130. fi
  131. else
  132. echo -e "${YELLOW}○ 后端服务${NC} - 未启动"
  133. fi
  134. # 前端状态
  135. if [ -f "$LOG_DIR/frontend.pid" ]; then
  136. local pid=$(cat "$LOG_DIR/frontend.pid")
  137. if ps -p "$pid" &>/dev/null; then
  138. echo -e "${GREEN}✓ 前端服务${NC} - 运行中 (PID: $pid, 端口: 8005)"
  139. else
  140. echo -e "${RED}✗ 前端服务${NC} - 未运行 (PID 文件过期)"
  141. fi
  142. else
  143. echo -e "${YELLOW}○ 前端服务${NC} - 未启动"
  144. fi
  145. echo ""
  146. echo "=========================================="
  147. echo ""
  148. echo "访问地址:"
  149. echo " 前端: http://localhost:8005"
  150. echo " API: http://localhost:8004"
  151. echo " 文档: http://localhost:8004/docs"
  152. echo ""
  153. }
  154. # 主程序
  155. main() {
  156. case "${1:-all}" in
  157. -b|--backend)
  158. start_backend
  159. ;;
  160. -f|--frontend)
  161. start_frontend
  162. ;;
  163. -a|--all)
  164. start_backend
  165. start_frontend
  166. show_status
  167. ;;
  168. -s|--stop)
  169. stop_services
  170. ;;
  171. -r|--restart)
  172. stop_services
  173. sleep 1
  174. start_backend
  175. start_frontend
  176. show_status
  177. ;;
  178. -h|--help)
  179. usage
  180. ;;
  181. status)
  182. show_status
  183. ;;
  184. *)
  185. usage
  186. exit 1
  187. ;;
  188. esac
  189. }
  190. main "$@"