ops_stop_keep_gateway.py 2.5 KB

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