126 lines
3.6 KiB
Bash
Executable File
126 lines
3.6 KiB
Bash
Executable File
#!/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"
|