fix(api): honor upstream docker repair success
This commit is contained in:
@@ -1057,6 +1057,38 @@ class AutoRepairService:
|
||||
required_scope="write",
|
||||
)
|
||||
|
||||
def _upstream_repair_success_result(
|
||||
self,
|
||||
incident: Incident,
|
||||
command: str,
|
||||
) -> str | None:
|
||||
"""Treat trusted upstream host repair labels as a successful no-op.
|
||||
|
||||
Some host monitors already perform the Docker restart before sending the
|
||||
alert. Re-running the restart from AwoooP would create duplicate
|
||||
disruption; the flywheel should record that the execute stage converged
|
||||
and leave evidence in the execution row instead.
|
||||
"""
|
||||
|
||||
if "docker restart" not in (command or "").lower():
|
||||
return None
|
||||
|
||||
labels = self._incident_labels(incident)
|
||||
repair_result = str(labels.get("repair_result") or "").strip().lower()
|
||||
repair_action = str(labels.get("repair_action") or "").strip().lower()
|
||||
if repair_result not in {"success", "succeeded", "ok"}:
|
||||
return None
|
||||
if repair_action not in {"restart", "restarted", "docker_restart", "docker-restart"}:
|
||||
return None
|
||||
|
||||
container_name = self._resolve_container_name_for_incident(incident, command)
|
||||
source = str(labels.get("source") or "upstream_monitor").strip() or "upstream_monitor"
|
||||
target = f" container={container_name}" if container_name else ""
|
||||
return (
|
||||
"SUCCESS: upstream repair already completed "
|
||||
f"(source={source} action={repair_action} result={repair_result}{target})"
|
||||
)
|
||||
|
||||
def preview_read_only_ssh_mcp_route(
|
||||
self,
|
||||
incident: Incident,
|
||||
@@ -1313,6 +1345,10 @@ class AutoRepairService:
|
||||
|
||||
# 2026-04-06 Claude Code: Sprint 3 — repair_by_uri (URI scheme 路由)
|
||||
if step.action_type == ActionType.SSH_COMMAND:
|
||||
upstream_success = self._upstream_repair_success_result(incident, step.command)
|
||||
if upstream_success is not None:
|
||||
return upstream_success
|
||||
|
||||
route = self._route_legacy_ssh_command_to_mcp(incident, step.command)
|
||||
if route is not None:
|
||||
return await self._execute_ssh_mcp_route(incident, route)
|
||||
|
||||
@@ -497,6 +497,44 @@ class TestAutoRepairService:
|
||||
|
||||
assert route is None
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_execute_legacy_ssh_restart_noops_when_upstream_repair_succeeded(
|
||||
self,
|
||||
service,
|
||||
monkeypatch,
|
||||
):
|
||||
"""Do not restart twice when the host monitor already repaired it."""
|
||||
incident = create_test_incident(
|
||||
severity=Severity.P2,
|
||||
alert_category="infrastructure",
|
||||
alert_name="DockerContainerUnhealthy",
|
||||
)
|
||||
incident.signals[0].labels.update({
|
||||
"host": "wooo",
|
||||
"container": "stockplatform-v2-edge-1",
|
||||
"source": "docker-health-monitor",
|
||||
"repair_action": "restarted",
|
||||
"repair_result": "success",
|
||||
})
|
||||
step = RepairStep(
|
||||
step_number=1,
|
||||
action_type=ActionType.SSH_COMMAND,
|
||||
command='ssh {host} \'docker inspect {container} --format="{{.State.Health.Status}}" && docker restart {container}\'',
|
||||
risk_level=RiskLevel.MEDIUM,
|
||||
requires_approval=False,
|
||||
)
|
||||
|
||||
async def fail_if_called(*args, **kwargs):
|
||||
raise AssertionError("MCP Gateway should not be called after upstream repair success")
|
||||
|
||||
monkeypatch.setattr(service, "_execute_ssh_mcp_route", fail_if_called)
|
||||
|
||||
result = await service._execute_step(incident, step)
|
||||
|
||||
assert result.startswith("SUCCESS: upstream repair already completed")
|
||||
assert "docker-health-monitor" in result
|
||||
assert "stockplatform-v2-edge-1" in result
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_execute_legacy_ssh_diagnostic_uses_mcp_gateway(
|
||||
self,
|
||||
|
||||
Reference in New Issue
Block a user