#!/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://:8080/ \ --secret-file /path/to/inbound-agent.secret 可选参数: --run-user systemd 运行用户,默认 root;当前生产流水线仍需要特权操作。 --run-group systemd 运行用户组,默认跟随 --run-user。 --workdir agent 工作目录,默认 /var/lib/jenkins/agent/。 --jar-path agent.jar 落盘路径,默认 /opt/jenkins-agent/agent.jar。 --java-bin 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/.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 <&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}" <&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}"