Files
.pouch/skills/deployer/scripts/deploy/remote.py
T
laily c2d6a5a0d7 feat(deployer): skip sync on localhost and complete skill READMEs
Redeploy locally with docker compose when the node is 127.0.0.1 and
the image already exists. Make list/sync/remote/deb importable under
python3 -I -S. Add human README.md for every builtin skill, slim ack's
user-facing docs, and drop unused OpenSpec config.
2026-09-04 00:07:15 +08:00

67 lines
1.9 KiB
Python
Executable File

#!/usr/bin/env python3
"""
在远程节点上执行 docker compose 操作。
用法:
python remote.py <服务目录> <命令>
命令:
up 启动/更新容器(不拉镜像)
recreate 强制重建容器(up -d --force-recreate,改配置后用)
restart 重启 compose 内所有服务
upgrade 拉取镜像并重建容器
ps 查看容器状态
logs 查看最近日志(非 follow)
"""
from __future__ import annotations
import argparse
import os
import subprocess
import sys
from pathlib import Path
_SCRIPT_DIR = Path(__file__).resolve().parent
if str(_SCRIPT_DIR) not in sys.path:
sys.path.insert(0, str(_SCRIPT_DIR))
from lib import project_root, run_remote, service_info # noqa: E402
REMOTE_COMMANDS = {
"up": "docker compose up -d",
"recreate": "docker compose up -d --force-recreate",
"restart": "docker compose restart",
"upgrade": "docker compose pull && docker compose up -d",
"ps": "docker compose ps",
"logs": "docker compose logs --tail=100",
}
def run_for_service(service_dir: str, action: str) -> int:
info = service_info(service_dir)
compose_command = REMOTE_COMMANDS[action]
endpoint = info["node"]
if info.get("port") is not None:
endpoint = f"{endpoint}:{info['port']}"
print(f"服务: {service_dir} -> {endpoint}:{info['remote_dir']}")
return run_remote(info, compose_command, remote_cwd=info["remote_dir"])
def main() -> int:
parser = argparse.ArgumentParser(description="在远程节点执行 docker compose 操作")
parser.add_argument("target", help="服务目录,例如 hosts/web1/myapp")
parser.add_argument(
"action",
choices=sorted(REMOTE_COMMANDS),
help="远程操作",
)
args = parser.parse_args()
os.chdir(project_root())
return run_for_service(args.target, args.action)
if __name__ == "__main__":
sys.exit(main())