#!/usr/bin/env bash set -euo pipefail if [[ "${EUID}" -ne 0 ]]; then echo "请用 sudo 执行此脚本。" >&2 exit 1 fi if [[ "$#" -ne 3 ]]; then echo "用法: $0 " >&2 exit 1 fi server_url="$1" pair_code="$2" node_name="$3" if ! id canger-agent >/dev/null 2>&1; then useradd --system --home-dir /var/lib/canger-node --create-home \ --shell /usr/sbin/nologin canger-agent fi install -d -m 0755 /opt/canger-node install -d -o canger-agent -g canger-agent -m 0700 /etc/canger-node install -d -o canger-agent -g canger-agent -m 0750 /var/lib/canger-node install -d -o canger-agent -g canger-agent -m 0750 /srv/canger install -m 0755 "$(dirname "$0")/../node/canger_node.py" /opt/canger-node/canger_node.py install -m 0755 "$(dirname "$0")/preflight-linux.py" /opt/canger-node/preflight-linux.py install -m 0644 "$(dirname "$0")/../systemd/canger-node.service" /etc/systemd/system/canger-node.service already_paired=false if [[ -f /etc/canger-node/config.json ]] && \ runuser -u canger-agent -- python3 - /etc/canger-node/config.json <<'PY' import json import sys with open(sys.argv[1], encoding="utf-8") as handle: config = json.load(handle) raise SystemExit(0 if config.get("node_id") and config.get("node_token") else 1) PY then already_paired=true fi if [[ "${already_paired}" == "false" ]]; then python3 - "$server_url" "$node_name" <<'PY' import json import os import pwd import sys server_url, node_name = sys.argv[1:] config = { "server_url": server_url, "node_name": node_name, "node_id": None, "node_token": None, "allowed_roots": ["/srv/canger"], "enabled_actions": [ "system.status", "repo.status", "repo.fetch", "service.logs", "command.run", ], "executable_allowlist": ["git", "python3", "pytest", "node", "npm", "pnpm"], "poll_seconds": 5, "verify_tls": True, } path = "/etc/canger-node/config.json" with open(path, "w", encoding="utf-8") as handle: json.dump(config, handle, ensure_ascii=False, indent=2) handle.write("\n") os.chmod(path, 0o600) account = pwd.getpwnam("canger-agent") os.chown(path, account.pw_uid, account.pw_gid) PY else echo "检测到现有有效节点身份,保留原身份并跳过重复配对。" fi /usr/bin/python3 /opt/canger-node/preflight-linux.py \ --output /var/lib/canger-node/preflight.json install -d -m 0755 /etc/systemd/system/canger-node.service.d python3 - <<'PY' import os path = "/etc/systemd/system/canger-node.service.d/paths.conf" with open(path, "w", encoding="utf-8") as handle: handle.write("[Service]\n") handle.write("ReadWritePaths=/etc/canger-node\n") handle.write("ReadWritePaths=/srv/canger\n") os.chmod(path, 0o644) PY if [[ "${already_paired}" == "false" ]]; then runuser -u canger-agent -- /usr/bin/python3 /opt/canger-node/canger_node.py \ --config /etc/canger-node/config.json pair --code "$pair_code" fi systemctl daemon-reload systemctl enable --now canger-node.service systemctl --no-pager --full status canger-node.service echo "安装完成。今后开机自动启动,断网后自动重连。" echo "环境检测报告: /var/lib/canger-node/preflight.json"