Files
Genarrative/scripts/deploy/install-jenkins-inbound-agent.sh
kdletters 01b302d7eb
Some checks failed
CI / verify (push) Has been cancelled
Add resilient Jenkins inbound agent setup
2026-05-03 14:01:19 +08:00

219 lines
6.0 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
set -euo pipefail
usage() {
cat >&2 <<'EOF'
用法:
sudo scripts/deploy/install-jenkins-inbound-agent.sh \
--agent-name genarrative-release-deploy-01 \
--jenkins-url http://<jenkins-controller>:8080/ \
--secret-file /path/to/inbound-agent.secret
可选参数:
--run-user <user> systemd 运行用户,默认 root当前生产流水线仍需要特权操作。
--run-group <group> systemd 运行用户组,默认跟随 --run-user。
--workdir <path> agent 工作目录,默认 /var/lib/jenkins/agent/<agent-name>。
--jar-path <path> agent.jar 落盘路径,默认 /opt/jenkins-agent/agent.jar。
--java-bin <path> Java 命令路径,默认 java需要固定 JDK 时传绝对路径。
--no-websocket 不使用 WebSocket inbound 连接。
--no-enable 只安装 unit不执行 systemctl enable。
--no-start 只安装 unit不立即启动服务。
--dry-run 只打印操作,不写入系统。
密钥来源:
优先使用 --secret-file如果未传入则读取环境变量 JENKINS_AGENT_SECRET
如果目标机已存在 /etc/jenkins-agent/<agent-name>.secret则保留原密钥。
EOF
}
AGENT_NAME=""
JENKINS_URL_VALUE=""
SECRET_FILE=""
RUN_USER="root"
RUN_GROUP=""
WORKDIR=""
JAR_PATH="/opt/jenkins-agent/agent.jar"
JAVA_BIN="java"
USE_WEBSOCKET="true"
ENABLE_SERVICE="true"
START_SERVICE="true"
DRY_RUN="false"
while [[ $# -gt 0 ]]; do
case "$1" in
--agent-name)
AGENT_NAME="${2:?缺少 --agent-name 的值}"
shift 2
;;
--jenkins-url)
JENKINS_URL_VALUE="${2:?缺少 --jenkins-url 的值}"
shift 2
;;
--secret-file)
SECRET_FILE="${2:?缺少 --secret-file 的值}"
shift 2
;;
--run-user)
RUN_USER="${2:?缺少 --run-user 的值}"
shift 2
;;
--run-group)
RUN_GROUP="${2:?缺少 --run-group 的值}"
shift 2
;;
--workdir)
WORKDIR="${2:?缺少 --workdir 的值}"
shift 2
;;
--jar-path)
JAR_PATH="${2:?缺少 --jar-path 的值}"
shift 2
;;
--java-bin)
JAVA_BIN="${2:?缺少 --java-bin 的值}"
shift 2
;;
--no-websocket)
USE_WEBSOCKET="false"
shift
;;
--no-enable)
ENABLE_SERVICE="false"
shift
;;
--no-start)
START_SERVICE="false"
shift
;;
--dry-run)
DRY_RUN="true"
shift
;;
-h|--help)
usage
exit 0
;;
*)
echo "[jenkins-agent-install] 未知参数: $1" >&2
usage
exit 2
;;
esac
done
if [[ -z "${AGENT_NAME}" || -z "${JENKINS_URL_VALUE}" ]]; then
usage
exit 2
fi
if [[ -z "${RUN_GROUP}" ]]; then
RUN_GROUP="${RUN_USER}"
fi
if [[ -z "${WORKDIR}" ]]; then
WORKDIR="/var/lib/jenkins/agent/${AGENT_NAME}"
fi
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
START_SOURCE="${SCRIPT_DIR}/jenkins-inbound-agent-start.sh"
UNIT_SOURCE="${REPO_ROOT}/deploy/systemd/jenkins-agent@.service"
CONFIG_DIR="/etc/jenkins-agent"
CONFIG_FILE="${CONFIG_DIR}/${AGENT_NAME}.env"
SECRET_TARGET="${CONFIG_DIR}/${AGENT_NAME}.secret"
SERVICE_NAME="jenkins-agent@${AGENT_NAME}.service"
run_cmd() {
echo "+ $*"
if [[ "${DRY_RUN}" != "true" ]]; then
"$@"
fi
}
write_file() {
local target="$1"
local mode="$2"
local owner="$3"
local group="$4"
local temp_file
temp_file="$(mktemp)"
cat >"${temp_file}"
echo "+ install -m ${mode} ${temp_file} ${target}"
if [[ "${DRY_RUN}" != "true" ]]; then
install -m "${mode}" -o "${owner}" -g "${group}" "${temp_file}" "${target}"
fi
rm -f "${temp_file}"
}
if [[ ! -f "${START_SOURCE}" ]]; then
echo "[jenkins-agent-install] 缺少启动脚本: ${START_SOURCE}" >&2
exit 1
fi
if [[ ! -f "${UNIT_SOURCE}" ]]; then
echo "[jenkins-agent-install] 缺少 systemd 模板: ${UNIT_SOURCE}" >&2
exit 1
fi
if [[ "${RUN_USER}" != "root" ]] && ! id "${RUN_USER}" >/dev/null 2>&1; then
run_cmd useradd --system --create-home --home-dir "/var/lib/${RUN_USER}" --shell /bin/bash "${RUN_USER}"
fi
run_cmd mkdir -p "${CONFIG_DIR}" "$(dirname "${JAR_PATH}")" "${WORKDIR}"
run_cmd chmod 0755 "${CONFIG_DIR}" "$(dirname "${JAR_PATH}")"
if [[ "${DRY_RUN}" != "true" ]]; then
chown -R "${RUN_USER}:${RUN_GROUP}" "$(dirname "${JAR_PATH}")" "${WORKDIR}"
fi
run_cmd install -m 0755 "${START_SOURCE}" /usr/local/bin/jenkins-inbound-agent-start
UNIT_TMP="$(mktemp)"
sed \
-e "s|^User=.*|User=${RUN_USER}|" \
-e "s|^Group=.*|Group=${RUN_GROUP}|" \
"${UNIT_SOURCE}" >"${UNIT_TMP}"
run_cmd install -m 0644 "${UNIT_TMP}" /etc/systemd/system/jenkins-agent@.service
rm -f "${UNIT_TMP}"
write_file "${CONFIG_FILE}" 0644 root root <<EOF
JENKINS_URL='${JENKINS_URL_VALUE}'
JENKINS_AGENT_NAME='${AGENT_NAME}'
JENKINS_AGENT_WORKDIR='${WORKDIR}'
JENKINS_AGENT_JAR='${JAR_PATH}'
JENKINS_AGENT_SECRET_FILE='${SECRET_TARGET}'
JENKINS_AGENT_USE_WEBSOCKET='${USE_WEBSOCKET}'
JENKINS_AGENT_JAVA_BIN='${JAVA_BIN}'
EOF
if [[ -n "${SECRET_FILE}" ]]; then
if [[ ! -r "${SECRET_FILE}" ]]; then
echo "[jenkins-agent-install] 密钥文件不可读: ${SECRET_FILE}" >&2
exit 1
fi
run_cmd install -m 0600 -o "${RUN_USER}" -g "${RUN_GROUP}" "${SECRET_FILE}" "${SECRET_TARGET}"
elif [[ -n "${JENKINS_AGENT_SECRET:-}" ]]; then
write_file "${SECRET_TARGET}" 0600 "${RUN_USER}" "${RUN_GROUP}" <<EOF
${JENKINS_AGENT_SECRET}
EOF
elif [[ -f "${SECRET_TARGET}" ]]; then
echo "[jenkins-agent-install] 已存在密钥文件,保留不覆盖: ${SECRET_TARGET}"
else
echo "[jenkins-agent-install] 缺少 inbound agent secret。请传 --secret-file或设置 JENKINS_AGENT_SECRET。" >&2
exit 1
fi
run_cmd systemctl daemon-reload
if [[ "${ENABLE_SERVICE}" == "true" ]]; then
run_cmd systemctl enable "${SERVICE_NAME}"
fi
if [[ "${START_SERVICE}" == "true" ]]; then
run_cmd systemctl restart "${SERVICE_NAME}"
run_cmd systemctl status "${SERVICE_NAME}" --no-pager -l
fi
echo "[jenkins-agent-install] 完成: ${SERVICE_NAME}"