Co-authored-by: sundapeng <sundp@mail.zgclab.edu.cn> Co-authored-by: xuxt <xuxt@zgclab.edu.cn> Reviewed-on: #52
109 lines
4.7 KiB
Bash
109 lines
4.7 KiB
Bash
#!/usr/bin/env bash
|
||
set -euo pipefail
|
||
|
||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||
PKG_ROOT="$ROOT_DIR"
|
||
ENV_EX="$PKG_ROOT/compose/.env.example"
|
||
ENV_OUT="$PKG_ROOT/compose/.env"
|
||
|
||
info(){ echo -e "\033[34m[CONFIG]\033[0m $*"; }
|
||
err(){ echo -e "\033[31m[ERROR]\033[0m $*" >&2; }
|
||
require(){ local ok=1; for c in "$@"; do command -v "$c" >/dev/null 2>&1 || { err "缺少依赖: $c"; ok=0; }; done; [[ $ok -eq 1 ]]; }
|
||
# Compose 检测:优先 docker compose(v2),回退 docker-compose(v1)
|
||
require_compose(){
|
||
if docker compose version >/dev/null 2>&1; then return 0; fi
|
||
if command -v docker-compose >/dev/null 2>&1 && docker-compose version >/dev/null 2>&1; then return 0; fi
|
||
err "未检测到 Docker Compose,请安装 docker compose v2 或 docker-compose v1"; exit 1
|
||
}
|
||
|
||
require docker curl jq awk sed tar gzip
|
||
require_compose
|
||
|
||
# 磁盘空间检查(MB)
|
||
check_disk(){ local p="$1"; local need=10240; local free
|
||
free=$(df -Pm "$p" | awk 'NR==2{print $4+0}')
|
||
if [[ -z "$free" || "$free" -lt "$need" ]]; then err "磁盘空间不足: $p 剩余 ${free:-0}MB (<${need}MB)"; return 1; fi
|
||
}
|
||
|
||
check_disk "$PKG_ROOT"; check_disk "/var/lib/docker" || true
|
||
|
||
# 读取/生成 SWARM_MANAGER_ADDR
|
||
SWARM_MANAGER_ADDR=${SWARM_MANAGER_ADDR:-}
|
||
if [[ -z "${SWARM_MANAGER_ADDR}" ]]; then
|
||
read -rp "请输入本机管理地址 SWARM_MANAGER_ADDR: " SWARM_MANAGER_ADDR
|
||
fi
|
||
info "SWARM_MANAGER_ADDR=$SWARM_MANAGER_ADDR"
|
||
|
||
# 校验 IP 属于本机网卡
|
||
if ! ip -o addr | awk '{print $4}' | cut -d'/' -f1 | grep -qx "$SWARM_MANAGER_ADDR"; then
|
||
err "SWARM_MANAGER_ADDR 非本机地址: $SWARM_MANAGER_ADDR"; exit 1; fi
|
||
|
||
info "开始分配服务端口(起始=20000,避免系统占用与相互冲突)"
|
||
is_port_used(){ local p="$1"; ss -tulnH 2>/dev/null | awk '{print $5}' | sed 's/.*://g' | grep -qx "$p"; }
|
||
declare -A PRESENT=() CHOSEN=() USED=()
|
||
START_PORT="${START_PORT:-20000}"; cur=$START_PORT
|
||
ORDER=(MASTER_PORT ES_HTTP_PORT KIBANA_PORT PROMETHEUS_PORT GRAFANA_PORT ALERTMANAGER_PORT \
|
||
WEB_PROXY_PORT_8080 WEB_PROXY_PORT_8081 WEB_PROXY_PORT_8082 WEB_PROXY_PORT_8083 WEB_PROXY_PORT_8084 WEB_PROXY_PORT_8085 \
|
||
FTP_PORT FTP_DATA_PORT)
|
||
|
||
# 标记 .env.example 中实际存在的键
|
||
for key in "${ORDER[@]}"; do
|
||
if grep -q "^${key}=" "$ENV_EX"; then PRESENT[$key]=1; fi
|
||
done
|
||
|
||
next_free(){ local p="$1"; while :; do if [[ -n "${USED[$p]:-}" ]] || is_port_used "$p"; then p=$((p+1)); else echo "$p"; return; fi; done; }
|
||
|
||
for key in "${ORDER[@]}"; do
|
||
[[ -z "${PRESENT[$key]:-}" ]] && continue
|
||
p=$(next_free "$cur"); CHOSEN[$key]="$p"; USED[$p]=1; cur=$((p+1))
|
||
done
|
||
|
||
info "端口分配结果:MASTER=${CHOSEN[MASTER_PORT]:-} ES=${CHOSEN[ES_HTTP_PORT]:-} KIBANA=${CHOSEN[KIBANA_PORT]:-} PROM=${CHOSEN[PROMETHEUS_PORT]:-} GRAFANA=${CHOSEN[GRAFANA_PORT]:-} ALERT=${CHOSEN[ALERTMANAGER_PORT]:-} WEB_PROXY(8080..8085)=${CHOSEN[WEB_PROXY_PORT_8080]:-}/${CHOSEN[WEB_PROXY_PORT_8081]:-}/${CHOSEN[WEB_PROXY_PORT_8082]:-}/${CHOSEN[WEB_PROXY_PORT_8083]:-}/${CHOSEN[WEB_PROXY_PORT_8084]:-}/${CHOSEN[WEB_PROXY_PORT_8085]:-}"
|
||
|
||
cp "$ENV_EX" "$ENV_OUT"
|
||
# 覆盖端口(按唯一化结果写回)
|
||
for key in "${ORDER[@]}"; do
|
||
val="${CHOSEN[$key]:-}"
|
||
[[ -z "$val" ]] && continue
|
||
sed -i -E "s#^$key=.*#$key=${val}#" "$ENV_OUT"
|
||
done
|
||
info "已写入 compose/.env 的端口配置"
|
||
# 覆盖/补充 Overlay 名称
|
||
grep -q '^ARGUS_OVERLAY_NET=' "$ENV_OUT" || echo 'ARGUS_OVERLAY_NET=argus-sys-net' >> "$ENV_OUT"
|
||
# 以当前执行账户 UID/GID 写入(避免误选 docker 组)
|
||
RUID=$(id -u)
|
||
PRIMARY_GID=$(id -g)
|
||
PRIMARY_GRP=$(id -gn)
|
||
USER_NAME=$(id -un)
|
||
# 若主组名被解析为 docker,尝试用与用户名同名的组的 GID;否则回退主 GID
|
||
if [[ "$PRIMARY_GRP" == "docker" ]]; then
|
||
RGID=$(getent group "$USER_NAME" | awk -F: '{print $3}' 2>/dev/null || true)
|
||
[[ -z "$RGID" ]] && RGID="$PRIMARY_GID"
|
||
else
|
||
RGID="$PRIMARY_GID"
|
||
fi
|
||
info "使用构建账户 UID:GID=${RUID}:${RGID} (user=$USER_NAME primary_group=$PRIMARY_GRP)"
|
||
if grep -q '^ARGUS_BUILD_UID=' "$ENV_OUT"; then
|
||
sed -i -E "s#^ARGUS_BUILD_UID=.*#ARGUS_BUILD_UID=${RUID}#" "$ENV_OUT"
|
||
else
|
||
echo "ARGUS_BUILD_UID=${RUID}" >> "$ENV_OUT"
|
||
fi
|
||
if grep -q '^ARGUS_BUILD_GID=' "$ENV_OUT"; then
|
||
sed -i -E "s#^ARGUS_BUILD_GID=.*#ARGUS_BUILD_GID=${RGID}#" "$ENV_OUT"
|
||
else
|
||
echo "ARGUS_BUILD_GID=${RGID}" >> "$ENV_OUT"
|
||
fi
|
||
|
||
CI="$PKG_ROOT/cluster-info.env"
|
||
if [[ -f "$CI" ]]; then
|
||
if grep -q '^SWARM_MANAGER_ADDR=' "$CI"; then
|
||
sed -i -E "s#^SWARM_MANAGER_ADDR=.*#SWARM_MANAGER_ADDR=${SWARM_MANAGER_ADDR}#" "$CI"
|
||
else
|
||
echo "SWARM_MANAGER_ADDR=${SWARM_MANAGER_ADDR}" >> "$CI"
|
||
fi
|
||
else
|
||
echo "SWARM_MANAGER_ADDR=${SWARM_MANAGER_ADDR}" > "$CI"
|
||
fi
|
||
info "已生成 compose/.env 并更新 cluster-info.env 的 SWARM_MANAGER_ADDR。"
|
||
info "下一步可执行: scripts/install.sh"
|