#!/usr/bin/env bash set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" TEST_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" TMP_ROOT="$TEST_ROOT/tmp" API_BASE="http://localhost:32300/api/v1/master" NODE_ID="$(cat "$TMP_ROOT/node_id")" AGENT_HOSTNAME="dev-e2euser-e2einst-pod-0" NETWORK_NAME="tests_default" NEW_AGENT_IP="172.28.0.200" ENTRYPOINT_SCRIPT="$SCRIPT_DIR/agent_entrypoint.sh" # 中文提示:重启场景也需要同样的入口脚本,确保 DNS 注册逻辑一致 if [[ ! -f "$ENTRYPOINT_SCRIPT" ]]; then echo "[ERROR] agent entrypoint script missing at $ENTRYPOINT_SCRIPT" >&2 exit 1 fi if [[ ! -f "$TMP_ROOT/agent_binary_path" ]]; then echo "[ERROR] Agent binary path missing; rerun bootstrap" >&2 exit 1 fi AGENT_BINARY="$(cat "$TMP_ROOT/agent_binary_path")" if [[ ! -x "$AGENT_BINARY" ]]; then echo "[ERROR] Agent binary not executable: $AGENT_BINARY" >&2 exit 1 fi compose() { if docker compose version >/dev/null 2>&1; then docker compose "$@" else docker-compose "$@" fi } before_file="$TMP_ROOT/before_restart.json" curl -sS "$API_BASE/nodes/$NODE_ID" -o "$before_file" prev_last_updated=$(python3 - "$before_file" <<'PY' import json, sys with open(sys.argv[1]) as handle: node = json.load(handle) print(node.get("last_updated", "")) PY ) prev_ip=$(python3 - "$before_file" <<'PY' import json, sys with open(sys.argv[1]) as handle: node = json.load(handle) print(node["meta_data"].get("ip", "")) PY ) initial_ip=$(cat "$TMP_ROOT/initial_ip") if [[ "$prev_ip" != "$initial_ip" ]]; then echo "[ERROR] Expected initial IP $initial_ip, got $prev_ip" >&2 exit 1 fi pushd "$TEST_ROOT" >/dev/null compose rm -sf agent popd >/dev/null docker container rm -f argus-agent-e2e >/dev/null 2>&1 || true AGENT_DIR="$TEST_ROOT/private/argus/agent/$AGENT_HOSTNAME" HEALTH_DIR="$TEST_ROOT/private/argus/agent/health/$AGENT_HOSTNAME" # 先以 sleep 方式启动容器,确保我们掌握注册时的网络状态 if ! docker run -d \ --name argus-agent-e2e \ --hostname "$AGENT_HOSTNAME" \ --network "$NETWORK_NAME" \ --ip "$NEW_AGENT_IP" \ -v "$AGENT_DIR:/private/argus/agent/$AGENT_HOSTNAME" \ -v "$HEALTH_DIR:/private/argus/agent/health/$AGENT_HOSTNAME" \ -v "$TEST_ROOT/private/argus/etc:/private/argus/etc" \ -v "$AGENT_BINARY:/usr/local/bin/argus-agent:ro" \ -v "$ENTRYPOINT_SCRIPT:/usr/local/bin/agent-entrypoint.sh:ro" \ -e MASTER_ENDPOINT=http://master.argus.com:3000 \ -e REPORT_INTERVAL_SECONDS=2 \ --entrypoint /usr/local/bin/agent-entrypoint.sh \ ubuntu:24.04 >/dev/null; then echo "[ERROR] Failed to start agent container with custom IP" >&2 exit 1 fi success=false detail_file="$TMP_ROOT/post_restart.json" for _ in {1..20}; do sleep 3 if ! curl -sS "$API_BASE/nodes/$NODE_ID" -o "$detail_file"; then continue fi if python3 - "$detail_file" "$prev_last_updated" "$NODE_ID" "$prev_ip" "$NEW_AGENT_IP" <<'PY' import json, sys with open(sys.argv[1]) as handle: node = json.load(handle) prev_last_updated = sys.argv[2] expected_id = sys.argv[3] old_ip = sys.argv[4] expected_ip = sys.argv[5] last_updated = node.get("last_updated") current_ip = node["meta_data"].get("ip") assert node["id"] == expected_id if current_ip != expected_ip: raise SystemExit(1) if current_ip == old_ip: raise SystemExit(1) if not last_updated or last_updated == prev_last_updated: raise SystemExit(1) PY then success=true break fi done if [[ "$success" != true ]]; then echo "[ERROR] Agent did not report expected new IP $NEW_AGENT_IP after restart" >&2 exit 1 fi echo "[INFO] Agent restart produced successful re-registration with IP change"