#!/usr/bin/env python3 # -*- coding: utf-8 -*- """停掉**组件服务**, 保留网关 —— 给运维控制台用 (2026-09-12)。 为什么不能直接 `guanlan.py stop`: 那个会把网关也停掉, 而控制台页面正是网关提供的 —— 按钮刚点完页面就没了, 再也没法"启动服务"。所以这里只停 detail/cms/sim/sim_sys/viewer, 网关(28084)留着, 页面继续可用, 并如实报告"哪些还占着端口"。 复用 guanlan.py 的 kill/alive/services (同一套 taskkill /T /F 语义), 不另造一套。 """ from __future__ import annotations try: from app_common.app_common_guanlan.api import install_root as _install_root except ImportError: # 极端兜底(包结构异常时按位置上跳) from pathlib import Path as _P def _install_root(_f): return _P(_f).resolve().parents[3] import pathlib import sys import time ROOT = _install_root(__file__) sys.path.insert(0, str(ROOT)) from . import cli as G # noqa: E402 KEEP = {'gateway'} def main() -> int: c = G.cfg() pids = G.jload(G.PIDS) if G.PIDS.exists() else {} stopped = kept = 0 for name, port, _ in G.services(c): if name in KEEP: kept += 1 print(f' 保留 {name} 端口 {port} (控制台本体)') continue v = pids.get(name) or {} pid = v.get('pid') if pid and G.alive(pid): G.kill(pid) print(f' 停 {name} pid {pid}') stopped += 1 elif G.up(c['host'], port): print(f' [!] {name} 端口 {port} 在监听, 但 pids.json 里没有活进程 —— 不是本启动器起的, 不动它') else: print(f' - {name} 本来就没在跑') pids.pop(name, None) G.PIDS.write_text(__import__('json').dumps(pids, ensure_ascii=False, indent=1), encoding='utf-8') time.sleep(1.5) left = [f'{n}:{p}' for n, p, _ in G.services(c) if n not in KEEP and G.up(c['host'], p)] print(f'\n已停 {stopped} 个组件服务, 保留 {kept} 个 (网关)。') print(f'仍占端口的: {", ".join(left) if left else "无"}') print('页面现在应显示"无产物/服务未运行"; 要恢复请点控制台里的"启动服务"。') return 0 if __name__ == '__main__': for _s in (sys.stdout, sys.stderr): try: _s.reconfigure(errors='replace') except Exception: pass sys.exit(main())