From 68b8461ea09c59aa02c9244dc80da667a4fada2f Mon Sep 17 00:00:00 2001 From: yuyr Date: Thu, 16 Oct 2025 17:03:48 +0800 Subject: [PATCH] =?UTF-8?q?[#23]=20=E5=A2=9E=E5=8A=A0=E4=BB=8E=E6=8C=81?= =?UTF-8?q?=E4=B9=85=E5=8C=96=E6=96=87=E4=BB=B6=E5=8A=A0=E8=BD=BDenv/user/?= =?UTF-8?q?instance=E5=85=83=E4=BF=A1=E6=81=AF=EF=BC=8C=E9=87=8D=E5=90=AF?= =?UTF-8?q?=E4=B8=8D=E5=86=8D=E4=BE=9D=E8=B5=96=E7=8E=AF=E5=A2=83=E5=8F=98?= =?UTF-8?q?=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/agent/README.md | 7 +- src/agent/app/config.py | 58 ++++++---- src/agent/dist/argus-agent | Bin 7579616 -> 7580232 bytes .../07_restart_agent_and_reregister.sh | 104 ++++++++++++++++++ src/agent/tests/test_config_metadata.py | 18 +++ 5 files changed, 166 insertions(+), 21 deletions(-) diff --git a/src/agent/README.md b/src/agent/README.md index 55877d2..df96bdb 100644 --- a/src/agent/README.md +++ b/src/agent/README.md @@ -41,8 +41,11 @@ Agent 不再依赖配置文件;所有参数均由环境变量与主机名推 主机名与元数据的解析优先级: 1. 若设置 `AGENT_ENV` / `AGENT_USER` / `AGENT_INSTANCE` 且全部存在,则直接使用这些值。 -2. 否则按历史约定从主机名解析 `env-user-instance` 前缀。 -3. 如果两者都无法得到完整结果,Agent 启动会失败并提示需要提供上述环境变量。 +2. 否则检查历史 `node.json`(注册成功后由 Master 返回的信息),若包含 `env` / `user` / `instance` 则沿用。 +3. 若以上均不可用,则按历史约定从主机名解析 `env-user-instance` 前缀。 +4. 如果仍无法得到完整结果,Agent 启动会失败并提示需要提供上述环境变量。 + +> 提示:在首次部署时需确保环境变量或主机名能够提供完整信息。完成注册后,Agent 会把 Master 返回的元数据写入 `node.json`,后续重启无需再次提供环境变量就能保持一致性。 派生路径: diff --git a/src/agent/app/config.py b/src/agent/app/config.py index bf02cf5..057b92a 100644 --- a/src/agent/app/config.py +++ b/src/agent/app/config.py @@ -6,10 +6,14 @@ from dataclasses import dataclass from pathlib import Path from typing import Final +from .state import load_node_state from .version import VERSION +from .log import get_logger DEFAULT_REPORT_INTERVAL_SECONDS: Final[int] = 60 +LOGGER = get_logger("argus.agent.config") + @dataclass(frozen=True) class AgentConfig: @@ -50,7 +54,28 @@ def _resolve_hostname() -> str: return os.environ.get("AGENT_HOSTNAME") or socket.gethostname() -def _resolve_metadata_fields(hostname: str) -> tuple[str, str, str]: +def _load_metadata_from_state(node_file: str) -> tuple[str, str, str] | None: + state = load_node_state(node_file) + if not state: + return None + + meta = state.get("meta_data") or {} + env = meta.get("env") or state.get("env") + user = meta.get("user") or state.get("user") + instance = meta.get("instance") or state.get("instance") + + if env and user and instance: + LOGGER.debug("Metadata resolved from node state", extra={"node_file": node_file}) + return env, user, instance + + LOGGER.warning( + "node.json missing metadata fields; ignoring", + extra={"node_file": node_file, "meta_data": meta}, + ) + return None + + +def _resolve_metadata_fields(hostname: str, node_file: str) -> tuple[str, str, str]: env = os.environ.get("AGENT_ENV") user = os.environ.get("AGENT_USER") instance = os.environ.get("AGENT_INSTANCE") @@ -59,23 +84,18 @@ def _resolve_metadata_fields(hostname: str) -> tuple[str, str, str]: return env, user, instance if any([env, user, instance]): - LOGGER = None - try: - from .log import get_logger + LOGGER.warning( + "Incomplete metadata environment variables; falling back to persisted metadata", + extra={ + "has_env": bool(env), + "has_user": bool(user), + "has_instance": bool(instance), + }, + ) - LOGGER = get_logger("argus.agent.config") - except Exception: # pragma: no cover - defensive - LOGGER = None - if LOGGER is not None: - LOGGER.warning( - "Incomplete metadata environment variables; falling back to hostname parsing", - extra={ - "has_env": bool(env), - "has_user": bool(user), - "has_instance": bool(instance), - }, - ) - env = user = instance = None + state_metadata = _load_metadata_from_state(node_file) + if state_metadata is not None: + return state_metadata from .collector import _parse_hostname # Local import to avoid circular dependency @@ -93,9 +113,9 @@ def load_config() -> AgentConfig: """从环境变量推导配置,移除了外部配置文件依赖。""" hostname = _resolve_hostname() - environment, user, instance = _resolve_metadata_fields(hostname) - node_file = f"/private/argus/agent/{hostname}/node.json" + environment, user, instance = _resolve_metadata_fields(hostname, node_file) + health_dir = f"/private/argus/agent/{hostname}/health/" master_endpoint_env = os.environ.get("MASTER_ENDPOINT") diff --git a/src/agent/dist/argus-agent b/src/agent/dist/argus-agent index d5703fed0e1fdd9bf3e9d5802dd02e7779639076..1a335c454e26c0e2fb7a0312c4c9881db2ca539f 100755 GIT binary patch delta 9900 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 P`=Vm7@UQ8P3yb9e)M1xl delta 9505 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 diff --git a/src/agent/tests/scripts/07_restart_agent_and_reregister.sh b/src/agent/tests/scripts/07_restart_agent_and_reregister.sh index 9fa272e..4da99d3 100755 --- a/src/agent/tests/scripts/07_restart_agent_and_reregister.sh +++ b/src/agent/tests/scripts/07_restart_agent_and_reregister.sh @@ -6,9 +6,18 @@ 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")" +ENV_NODE_ID_FILE="$TMP_ROOT/node_id_host_abc" +if [[ ! -f "$ENV_NODE_ID_FILE" ]]; then + echo "[ERROR] Env agent node id file missing at $ENV_NODE_ID_FILE" >&2 + exit 1 +fi + +ENV_NODE_ID="$(cat "$ENV_NODE_ID_FILE")" AGENT_HOSTNAME="dev-e2euser-e2einst-pod-0" +ENV_AGENT_HOSTNAME="host_abc" NETWORK_NAME="tests_default" NEW_AGENT_IP="172.28.0.200" +NEW_ENV_AGENT_IP="172.28.0.210" ENTRYPOINT_SCRIPT="$SCRIPT_DIR/agent_entrypoint.sh" VERIFY_SCRIPT="$TEST_ROOT/../scripts/agent_deployment_verify.sh" ENV_FILE="$TEST_ROOT/.env" @@ -80,15 +89,37 @@ if [[ "$prev_ip" != "$initial_ip" ]]; then exit 1 fi +env_before_file="$TMP_ROOT/env_before_restart.json" +curl -sS "$API_BASE/nodes/$ENV_NODE_ID" -o "$env_before_file" +env_prev_last_updated=$(python3 - "$env_before_file" <<'PY' +import json, sys +with open(sys.argv[1]) as handle: + node = json.load(handle) +print(node.get("last_updated", "")) +PY +) +env_prev_ip=$(python3 - "$env_before_file" <<'PY' +import json, sys +with open(sys.argv[1]) as handle: + node = json.load(handle) +print(node["meta_data"].get("ip", "")) +PY +) + pushd "$TEST_ROOT" >/dev/null compose rm -sf agent +compose rm -sf agent_env popd >/dev/null docker container rm -f argus-agent-e2e >/dev/null 2>&1 || true +docker container rm -f argus-agent-env-e2e >/dev/null 2>&1 || true AGENT_DIR="$TEST_ROOT/private/argus/agent/$AGENT_HOSTNAME" HEALTH_DIR="$TEST_ROOT/private/argus/agent/$AGENT_HOSTNAME/health" +ENV_AGENT_DIR="$TEST_ROOT/private/argus/agent/$ENV_AGENT_HOSTNAME" +ENV_HEALTH_DIR="$TEST_ROOT/private/argus/agent/$ENV_AGENT_HOSTNAME/health" + # 先以 sleep 方式启动容器,确保我们掌握注册时的网络状态 if ! docker run -d \ --name argus-agent-e2e \ @@ -148,3 +179,76 @@ if [[ "$success" != true ]]; then fi echo "[INFO] Agent restart produced successful re-registration with IP change" + +# ---- Restart env-driven agent without metadata environment variables ---- + +if [[ ! -d "$ENV_AGENT_DIR" ]]; then + echo "[ERROR] Env agent data dir missing at $ENV_AGENT_DIR" >&2 + exit 1 +fi + +if [[ ! -d "$ENV_HEALTH_DIR" ]]; then + mkdir -p "$ENV_HEALTH_DIR" +fi + +if ! docker run -d \ + --name argus-agent-env-e2e \ + --hostname "$ENV_AGENT_HOSTNAME" \ + --network "$NETWORK_NAME" \ + --ip "$NEW_ENV_AGENT_IP" \ + -v "$ENV_AGENT_DIR:/private/argus/agent/$ENV_AGENT_HOSTNAME" \ + -v "$ENV_HEALTH_DIR:/private/argus/agent/$ENV_AGENT_HOSTNAME/health" \ + -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" \ + -v "$VERIFY_SCRIPT:/usr/local/bin/agent_deployment_verify.sh:ro" \ + -e MASTER_ENDPOINT=http://master.argus.com:3000 \ + -e REPORT_INTERVAL_SECONDS=2 \ + -e ARGUS_BUILD_UID="$AGENT_UID" \ + -e ARGUS_BUILD_GID="$AGENT_GID" \ + --entrypoint /usr/local/bin/agent-entrypoint.sh \ + ubuntu:22.04 >/dev/null; then + echo "[ERROR] Failed to start env-driven agent container without metadata env" >&2 + exit 1 +fi + +env_success=false +env_detail_file="$TMP_ROOT/env_post_restart.json" +for _ in {1..20}; do + sleep 3 + if ! curl -sS "$API_BASE/nodes/$ENV_NODE_ID" -o "$env_detail_file"; then + continue + fi + if python3 - "$env_detail_file" "$env_prev_last_updated" "$ENV_NODE_ID" "$env_prev_ip" "$NEW_ENV_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") +meta = node.get("meta_data", {}) +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) +if meta.get("env") != "prod" or meta.get("user") != "ml" or meta.get("instance") != "node-3": + raise SystemExit(1) +PY + then + env_success=true + break + fi +done + +if [[ "$env_success" != true ]]; then + echo "[ERROR] Env-driven agent did not reuse persisted metadata after restart" >&2 + exit 1 +fi + +echo "[INFO] Env-driven agent restart succeeded with persisted metadata" diff --git a/src/agent/tests/test_config_metadata.py b/src/agent/tests/test_config_metadata.py index 390fd7d..2ddd45a 100644 --- a/src/agent/tests/test_config_metadata.py +++ b/src/agent/tests/test_config_metadata.py @@ -60,6 +60,24 @@ class LoadConfigMetadataTests(unittest.TestCase): self.assertEqual(config.instance, "abc") mock_mkdir.assert_called() + @patch("app.config._load_metadata_from_state", return_value=("prod", "ops", "node-1")) + @patch("app.config.Path.mkdir") + def test_metadata_from_node_state(self, mock_mkdir, mock_state): + with temp_env( + MASTER_ENDPOINT="http://master.local", + AGENT_HOSTNAME="host_abc", + AGENT_ENV=None, + AGENT_USER=None, + AGENT_INSTANCE=None, + ): + config = load_config() + + self.assertEqual(config.environment, "prod") + self.assertEqual(config.user, "ops") + self.assertEqual(config.instance, "node-1") + mock_state.assert_called_once() + mock_mkdir.assert_called() + @patch("app.config.Path.mkdir") def test_partial_environment_variables_fallback(self, mock_mkdir): with temp_env(