108 lines
3.1 KiB
Bash
Executable File
108 lines
3.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
if [[ "${EUID}" -ne 0 ]]; then
|
|
echo "请用 sudo 执行此脚本。" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [[ "$#" -ne 3 ]]; then
|
|
echo "用法: $0 <server-url> <pair-code> <node-name>" >&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"
|