Files
argus/src/sys/tests/scripts/01_bootstrap.sh

294 lines
10 KiB
Bash
Executable File
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
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
TEST_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
REPO_ROOT="$(cd "$TEST_ROOT/../../.." && pwd)"
PRIVATE_CORE="$TEST_ROOT/private"
PRIVATE_NODEA="$TEST_ROOT/private-nodea"
PRIVATE_NODEB="$TEST_ROOT/private-nodeb"
TMP_DIR="$TEST_ROOT/tmp"
source "$REPO_ROOT/scripts/common/build_user.sh"
load_build_user
ensure_image() {
local image="$1"
if ! docker image inspect "$image" >/dev/null 2>&1; then
echo "[ERROR] Missing image: $image. Please run ./build/build_images.sh" >&2
exit 1
fi
}
echo "[INFO] Preparing directories..."
ensure_writable_dir() {
local path="$1"
local parent
parent="$(dirname "$path")"
mkdir -p "$parent" 2>/dev/null || true
mkdir -p "$path" 2>/dev/null || true
if [[ ! -w "$path" ]]; then
docker run --rm -v "$parent:/target" ubuntu:24.04 bash -lc "chown -R $(id -u):$(id -g) /target" >/dev/null 2>&1 || true
fi
mkdir -p "$path"
}
# preflight: make base dirs writable if inherited from root-owned mounts
ensure_writable_dir "$PRIVATE_CORE/argus"
ensure_writable_dir "$PRIVATE_CORE/argus/metric"
ensure_writable_dir "$PRIVATE_CORE/argus/metric/grafana"
ensure_writable_dir "$PRIVATE_CORE/argus/metric/prometheus"
mkdir -p \
"$PRIVATE_CORE/argus/etc" \
"$PRIVATE_CORE/argus/bind" \
"$PRIVATE_CORE/argus/master" \
"$PRIVATE_CORE/argus/metric/prometheus" \
"$PRIVATE_CORE/argus/alert/alertmanager" \
"$PRIVATE_CORE/argus/metric/ftp/share" \
"$PRIVATE_CORE/argus/metric/grafana/data" \
"$PRIVATE_CORE/argus/metric/grafana/logs" \
"$PRIVATE_CORE/argus/metric/grafana/plugins" \
"$PRIVATE_CORE/argus/metric/grafana/provisioning/datasources" \
"$PRIVATE_CORE/argus/metric/grafana/provisioning/dashboards" \
"$PRIVATE_CORE/argus/metric/grafana/data/sessions" \
"$PRIVATE_CORE/argus/metric/grafana/data/dashboards" \
"$PRIVATE_CORE/argus/metric/grafana/config" \
"$PRIVATE_CORE/argus/metric/prometheus/data" \
"$PRIVATE_CORE/argus/metric/prometheus/rules" \
"$PRIVATE_CORE/argus/metric/prometheus/targets" \
"$PRIVATE_CORE/argus/agent" \
"$PRIVATE_CORE/argus/log/elasticsearch" \
"$PRIVATE_CORE/argus/log/kibana" \
"$PRIVATE_NODEA/argus/agent/dev-yyrshare-nbnyx10-cp2f-pod-0/health" \
"$PRIVATE_NODEB/argus/agent/dev-yyrshare-uuuu10-ep2f-pod-0/health" \
"$TMP_DIR"
# Align ownership for supervisor-managed services (ES/Kibana/Grafana expect UID/GID inside container)
echo "[INFO] Fixing ownership for core private directories..."
chown -R "${ARGUS_BUILD_UID}:${ARGUS_BUILD_GID}" \
"$PRIVATE_CORE/argus/log/elasticsearch" \
"$PRIVATE_CORE/argus/log/kibana" \
"$PRIVATE_CORE/argus/metric/grafana" \
"$PRIVATE_CORE/argus/metric/prometheus" \
"$PRIVATE_CORE/argus/alert" \
"$PRIVATE_CORE/argus/metric/ftp" \
"$PRIVATE_CORE/argus/agent" \
"$PRIVATE_CORE/argus/etc" 2>/dev/null || true
# 确保 alert 与 etc 目录组可写,便于非 root 且仅匹配 GID 的服务写入运行文件
chmod -R g+w "$PRIVATE_CORE/argus/alert" "$PRIVATE_CORE/argus/etc" 2>/dev/null || true
echo "[INFO] Using compose-managed network (auto-created by docker compose)"
echo "[INFO] Distributing update-dns.sh for core services (bind/master/es/kibana)"
BIND_UPDATE_SRC="$REPO_ROOT/src/bind/build/update-dns.sh"
BIND_UPDATE_DEST="$PRIVATE_CORE/argus/etc/update-dns.sh"
if [[ -f "$BIND_UPDATE_SRC" ]]; then
cp "$BIND_UPDATE_SRC" "$BIND_UPDATE_DEST"
chmod +x "$BIND_UPDATE_DEST"
else
echo "[WARN] bind update-dns.sh not found at $BIND_UPDATE_SRC"
fi
echo "[INFO] Ensuring images present..."
ensure_image "argus-elasticsearch:latest"
ensure_image "argus-kibana:latest"
ensure_image "argus-bind9:latest"
ensure_image "argus-master:latest"
ensure_image "argus-metric-ftp:latest"
ensure_image "argus-metric-prometheus:latest"
ensure_image "argus-metric-grafana:latest"
ensure_image "argus-web-frontend:latest"
ensure_image "argus-web-proxy:latest"
ensure_image "argus-alertmanager:latest"
echo "[INFO] Preparing Fluent Bit local dependency packages..."
FLB_BUILD_PACKAGES_DIR="$REPO_ROOT/src/log/fluent-bit/build/packages"
mkdir -p "$FLB_BUILD_PACKAGES_DIR"
for deb in \
"$REPO_ROOT/src/metric/client-plugins/all-in-one-full/plugins/fluent-bit/bin/libyaml-0-2_"*_amd64.deb \
"$REPO_ROOT/src/metric/client-plugins/all-in-one-full/plugins/fluent-bit/bin/libpq5_"*_amd64.deb ; do
if ls $deb >/dev/null 2>&1; then
for f in $deb; do
base="$(basename "$f")"
if [[ ! -f "$FLB_BUILD_PACKAGES_DIR/$base" ]]; then
cp "$f" "$FLB_BUILD_PACKAGES_DIR/"
echo " [+] copied $base"
fi
done
fi
done
# 额外:从 all-in-one-full 的 ubuntu22/curl.tar.gz 解包必要依赖(libsasl2/ldap),便于离线安装
CURLOPT_TAR="$REPO_ROOT/src/metric/client-plugins/all-in-one-full/deps/ubuntu22/curl.tar.gz"
if [[ -f "$CURLOPT_TAR" ]]; then
tmpdir=$(mktemp -d)
if tar -xzf "$CURLOPT_TAR" -C "$tmpdir" 2>/dev/null; then
for p in \
libsasl2-2_*_amd64.deb \
libsasl2-modules-db_*_amd64.deb \
libldap-2.5-0_*_amd64.deb \
libidn2-0_*_amd64.deb \
libbrotli1_*_amd64.deb \
libssl3_*_amd64.deb ; do
src=$(ls "$tmpdir"/curl/$p 2>/dev/null | head -n1 || true)
if [[ -n "$src" ]]; then
base="$(basename "$src")"
[[ -f "$FLB_BUILD_PACKAGES_DIR/$base" ]] || cp "$src" "$FLB_BUILD_PACKAGES_DIR/" && echo " [+] staged $base"
fi
done
fi
rm -rf "$tmpdir"
fi
echo "[INFO] Building agent binary..."
pushd "$REPO_ROOT/src/agent" >/dev/null
./scripts/build_binary.sh
popd >/dev/null
AGENT_BIN="$REPO_ROOT/src/agent/dist/argus-agent"
if [[ ! -x "$AGENT_BIN" ]]; then
echo "[ERROR] Agent binary not found at $AGENT_BIN" >&2
exit 1
fi
echo "$AGENT_BIN" > "$TMP_DIR/agent_binary_path"
# 检测GPU环境
REQUEST_GPU=${ARGUS_SYS_ENABLE_GPU:-false}
GPU_CHECK_SCRIPT="$REPO_ROOT/src/metric/tests/scripts/common/check-gpu.sh"
if [[ "$REQUEST_GPU" == "true" ]]; then
echo "[INFO] --enable-gpu 已启用,开始检测GPU环境..."
if [[ -f "$GPU_CHECK_SCRIPT" ]]; then
if bash "$GPU_CHECK_SCRIPT" >/dev/null 2>&1; then
echo "[INFO] GPU环境可用,将在 compose 中启用 test-gpu-node"
GPU_AVAILABLE=true
else
echo "[ERROR] 未检测到可用 GPU,但指定了 --enable-gpu" >&2
exit 1
fi
else
echo "[ERROR] 未找到 GPU 检测脚本: $GPU_CHECK_SCRIPT" >&2
exit 1
fi
else
GPU_AVAILABLE=false
echo "[INFO] GPU 支持未启用,跳过 GPU 检测"
fi
echo "[INFO] Writing .env with UID/GID and metric configuration"
#############################################
# 动态分配宿主机端口并写入 .env
#############################################
# 读取现有 .env(若存在),用于保留密码/域名等
EXIST_DOTENV="$TEST_ROOT/.env"
if [[ -f "$EXIST_DOTENV" ]]; then
EXISTING_FTP_PASSWORD="$(grep -E '^FTP_PASSWORD=' "$EXIST_DOTENV" | tail -n1 | sed 's/^FTP_PASSWORD=//')"
EXISTING_FTP_DOMAIN="$(grep -E '^FTP_DOMAIN=' "$EXIST_DOTENV" | tail -n1 | sed 's/^FTP_DOMAIN=//')"
EXISTING_USE_INTRANET="$(grep -E '^USE_INTRANET=' "$EXIST_DOTENV" | tail -n1 | sed 's/^USE_INTRANET=//')"
else
EXISTING_FTP_PASSWORD=""
EXISTING_FTP_DOMAIN=""
EXISTING_USE_INTRANET=""
fi
is_port_free() {
local p="$1"
ss -ltnH 2>/dev/null | awk -v pat=":${p}$" '$4 ~ pat{f=1} END{exit f?1:0}'
}
find_free_port() {
local prefer="$1"; local start_scan="${2:-20000}"; local max="${3:-65000}"
if is_port_free "$prefer"; then echo "$prefer"; return 0; fi
local p
for (( p=start_scan; p<=max; p++ )); do
if is_port_free "$p"; then echo "$p"; return 0; fi
done
return 1
}
find_free_range() {
local begin="$1"; local end="$2"; local need_count=$((end-begin+1))
local try_start="$begin"
while (( try_start + need_count - 1 <= 65000 )); do
local ok=1
for (( p=try_start; p<try_start+need_count; p++ )); do
if ! is_port_free "$p"; then ok=0; break; fi
done
if (( ok==1 )); then
echo "${try_start}-$((try_start+need_count-1))"; return 0
fi
((try_start++))
done
return 1
}
# 优先端口(若占用则回退到 20000+ 的空闲)
MASTER_PORT_VAL=$(find_free_port 32300)
ES_HTTP_PORT_VAL=$(find_free_port 9200)
KIBANA_PORT_VAL=$(find_free_port 5601)
NODE_A_PORT_VAL=$(find_free_port 2020)
NODE_B_PORT_VAL=$(find_free_port 2021)
PROMETHEUS_PORT_VAL=$(find_free_port 9090)
GRAFANA_PORT_VAL=$(find_free_port 3000)
ALERTMANAGER_PORT_VAL=$(find_free_port 9093)
WEB_PROXY_PORT_8080_VAL=$(find_free_port 8080 18080 65000)
WEB_PROXY_PORT_8081_VAL=$(find_free_port 8081 18081 65000)
WEB_PROXY_PORT_8082_VAL=$(find_free_port 8082 18082 65000)
WEB_PROXY_PORT_8083_VAL=$(find_free_port 8083 18083 65000)
WEB_PROXY_PORT_8084_VAL=$(find_free_port 8084 18084 65000)
WEB_PROXY_PORT_8085_VAL=$(find_free_port 8085 18085 65000)
# FTP 控制/数据端口:若 21/20 被占用则回退到空闲
FTP_PORT_VAL=$(find_free_port 21 2121 65000)
FTP_DATA_PORT_VAL=$(find_free_port 20 2120 65000)
# FTP 被动端口范围:优先 21100-21110,若被占用则向后平移
FTP_PASV_RANGE_VAL="$(find_free_range 21100 21110 || echo 22100-22110)"
# 变量持久化到 .env
cat > "$TEST_ROOT/.env" <<EOF
ARGUS_BUILD_UID=$ARGUS_BUILD_UID
ARGUS_BUILD_GID=$ARGUS_BUILD_GID
# GPU 配置
ENABLE_GPU=$GPU_AVAILABLE
# 测试节点(CPU/GPU)默认标识与实例
METRIC_TEST_HOSTNAME_CPU=test-metric-node-001
METRIC_TEST_INSTANCE_CPU=172.31.0.50:9100
METRIC_TEST_HOSTNAME_GPU=test-metric-gpu-node-001
METRIC_TEST_INSTANCE_GPU=172.31.0.51:9100
METRIC_TEST_DCGM_GPU=172.31.0.51:9400
# Master/日志/监控等服务的宿主机端口(自动分配)
MASTER_PORT=$MASTER_PORT_VAL
ES_HTTP_PORT=$ES_HTTP_PORT_VAL
KIBANA_PORT=$KIBANA_PORT_VAL
NODE_A_PORT=$NODE_A_PORT_VAL
NODE_B_PORT=$NODE_B_PORT_VAL
PROMETHEUS_PORT=$PROMETHEUS_PORT_VAL
GRAFANA_PORT=$GRAFANA_PORT_VAL
ALERTMANAGER_PORT=$ALERTMANAGER_PORT_VAL
WEB_PROXY_PORT_8080=$WEB_PROXY_PORT_8080_VAL
WEB_PROXY_PORT_8081=$WEB_PROXY_PORT_8081_VAL
WEB_PROXY_PORT_8082=$WEB_PROXY_PORT_8082_VAL
WEB_PROXY_PORT_8083=$WEB_PROXY_PORT_8083_VAL
WEB_PROXY_PORT_8084=$WEB_PROXY_PORT_8084_VAL
WEB_PROXY_PORT_8085=$WEB_PROXY_PORT_8085_VAL
# FTP 配置(自动分配:若21/20占用则使用高位端口)
FTP_PORT=$FTP_PORT_VAL
FTP_DATA_PORT=$FTP_DATA_PORT_VAL
FTP_PASSIVE_HOST_RANGE=$FTP_PASV_RANGE_VAL
FTP_PASSWORD=${EXISTING_FTP_PASSWORD:-ZGClab1234!}
FTP_DOMAIN=${EXISTING_FTP_DOMAIN:-ftp.metric.argus.com}
# 网络配置
USE_INTRANET=${EXISTING_USE_INTRANET:-false}
EOF
echo "[OK] Bootstrap completed. Ports written to $TEST_ROOT/.env"