fix: 统一端口并完善桌面端授权和安装
This commit is contained in:
@@ -32,7 +32,7 @@ async def health_check():
|
||||
return {
|
||||
"status": "healthy" if is_healthy else "unhealthy",
|
||||
"timestamp": datetime.now().isoformat(),
|
||||
"version": "2.0.3",
|
||||
"version": "3.0.0",
|
||||
"uptime_pid": os.getpid(),
|
||||
"checks": checks,
|
||||
}
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
import os
|
||||
import platform
|
||||
import time
|
||||
from threading import Thread
|
||||
|
||||
from fastapi import APIRouter
|
||||
|
||||
from app.services.runtime import (
|
||||
is_container_runtime,
|
||||
is_supervisor_running,
|
||||
restart_method_name,
|
||||
restart_via_supervisor,
|
||||
terminate_current_process,
|
||||
)
|
||||
|
||||
|
||||
router = APIRouter(tags=["service"])
|
||||
|
||||
|
||||
@router.post("/api/service/restart")
|
||||
async def restart_service():
|
||||
supervisor_running = is_supervisor_running()
|
||||
container_runtime = is_container_runtime()
|
||||
|
||||
if supervisor_running:
|
||||
success, message = restart_via_supervisor()
|
||||
if success:
|
||||
return {
|
||||
"success": True,
|
||||
"message": message,
|
||||
"method": "supervisor",
|
||||
"container": container_runtime,
|
||||
}
|
||||
|
||||
method = restart_method_name(supervisor_running)
|
||||
thread = Thread(target=_delayed_exit, daemon=True)
|
||||
thread.start()
|
||||
|
||||
message = "服务正在重启,请稍后刷新页面..."
|
||||
if supervisor_running:
|
||||
message = "supervisor 命令不可用,已切换为进程重启..."
|
||||
elif container_runtime:
|
||||
message = "服务进程正在退出,容器或进程管理器将拉起服务..."
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"message": message,
|
||||
"method": method,
|
||||
"container": container_runtime,
|
||||
}
|
||||
|
||||
|
||||
@router.get("/api/service/status")
|
||||
async def get_service_status():
|
||||
return {
|
||||
"status": "running",
|
||||
"version": "2.0.3",
|
||||
"platform": platform.system(),
|
||||
"supervisor": is_supervisor_running(),
|
||||
"container": is_container_runtime(),
|
||||
"pid": os.getpid(),
|
||||
"python_version": platform.python_version(),
|
||||
}
|
||||
|
||||
|
||||
def _delayed_exit() -> None:
|
||||
time.sleep(1)
|
||||
terminate_current_process()
|
||||
+2
-3
@@ -7,12 +7,12 @@ from fastapi.middleware.cors import CORSMiddleware
|
||||
from fastapi.responses import FileResponse, JSONResponse
|
||||
|
||||
from app import state
|
||||
from app.api.routers import auth, cache, config, database, health, history, license, remote, script, service, tasks, upload
|
||||
from app.api.routers import auth, cache, config, database, health, history, license, remote, script, tasks, upload
|
||||
from app.auth import verify_jwt_token
|
||||
from app.config import BASE_DIR
|
||||
|
||||
|
||||
APP_VERSION = "2.0.3"
|
||||
APP_VERSION = "3.0.0"
|
||||
APP_HOST = "0.0.0.0"
|
||||
APP_PORT = 9081
|
||||
FRONTEND_DIST_DIR = BASE_DIR / "frontend" / "dist"
|
||||
@@ -71,7 +71,6 @@ def register_routes(app: FastAPI) -> None:
|
||||
database.router,
|
||||
config.router,
|
||||
cache.router,
|
||||
service.router,
|
||||
script.router,
|
||||
]
|
||||
for router in routers:
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
import os
|
||||
import platform
|
||||
import signal
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def is_supervisor_running() -> bool:
|
||||
if os.environ.get("SUPERVISOR_ENABLED") == "1":
|
||||
return True
|
||||
|
||||
supervisor_sock = Path("/var/run/supervisor.sock")
|
||||
if supervisor_sock.exists() and _command_succeeds(["supervisorctl", "status"], timeout=5):
|
||||
return True
|
||||
|
||||
try:
|
||||
import psutil # pyright: ignore[reportMissingModuleSource]
|
||||
|
||||
parent = psutil.Process().parent()
|
||||
if parent and "supervisor" in parent.name().lower():
|
||||
return True
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return _command_succeeds(["pgrep", "-f", "supervisord"], timeout=2)
|
||||
|
||||
|
||||
def is_container_runtime() -> bool:
|
||||
if os.environ.get("container"):
|
||||
return True
|
||||
if Path("/.dockerenv").exists():
|
||||
return True
|
||||
|
||||
cgroup_path = Path("/proc/1/cgroup")
|
||||
if not cgroup_path.exists():
|
||||
return False
|
||||
|
||||
try:
|
||||
cgroup = cgroup_path.read_text(encoding="utf-8", errors="ignore").lower()
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
return any(marker in cgroup for marker in ("docker", "kubepods", "containerd"))
|
||||
|
||||
|
||||
def restart_via_supervisor() -> tuple[bool, str]:
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["supervisorctl", "restart", "fastapi"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=30,
|
||||
)
|
||||
if result.returncode == 0:
|
||||
return True, "服务正在通过 supervisor 重启..."
|
||||
|
||||
error_msg = result.stderr or result.stdout or "未知错误"
|
||||
return False, f"重启失败: {error_msg}"
|
||||
except subprocess.TimeoutExpired:
|
||||
return False, "重启操作超时"
|
||||
except FileNotFoundError:
|
||||
return False, "找不到 supervisorctl 命令"
|
||||
except Exception as exc:
|
||||
return False, f"重启异常: {exc}"
|
||||
|
||||
|
||||
def terminate_current_process() -> None:
|
||||
if platform.system() == "Windows":
|
||||
os._exit(0)
|
||||
os.kill(os.getpid(), signal.SIGTERM)
|
||||
|
||||
|
||||
def restart_method_name(supervisor_running: bool) -> str:
|
||||
if supervisor_running:
|
||||
return "supervisor"
|
||||
if platform.system() == "Windows":
|
||||
return "windows-process"
|
||||
if is_container_runtime():
|
||||
return "container-process"
|
||||
return "process"
|
||||
|
||||
|
||||
def _command_succeeds(command: list[str], timeout: int) -> bool:
|
||||
try:
|
||||
result = subprocess.run(command, capture_output=True, text=True, timeout=timeout)
|
||||
return result.returncode == 0 and bool(result.stdout.strip() or command[0] == "supervisorctl")
|
||||
except Exception:
|
||||
return False
|
||||
Reference in New Issue
Block a user