| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758 |
- #!/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
- import pathlib
- import sys
- import time
- ROOT = pathlib.Path(__file__).resolve().parents[1]
- sys.path.insert(0, str(ROOT))
- import guanlan 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())
|