fix(flr): 10.9 session list + download path (#1)
Co-authored-by: claude <[email protected]>
This commit was merged in pull request #1.
This commit is contained in:
1 parent
38ba9c1b50
commit
2473d22d2e
4 files changed
+69
-21
No files matched your search
@@ -8,6 +8,15 @@ from typing import Any
|
||||
from zerto_rewind_mcp.client import ZertoClient, ZertoError
|
||||
from zerto_rewind_mcp.util import pick
|
||||
|
||||
READY_STATUSES = {
|
||||
"ready",
|
||||
"mounted",
|
||||
"available",
|
||||
"mountcompletedsuccessfully",
|
||||
"completed",
|
||||
}
|
||||
FAILED_STATUSES = {"failed", "error", "mountfailed"}
|
||||
|
||||
|
||||
def session_id_from(payload: Any) -> str:
|
||||
if payload is None:
|
||||
@@ -17,6 +26,7 @@ def session_id_from(payload: Any) -> str:
|
||||
if isinstance(payload, dict):
|
||||
value = pick(
|
||||
payload,
|
||||
"FlrSessionIdentifier",
|
||||
"sessionId",
|
||||
"SessionId",
|
||||
"flrSessionIdentifier",
|
||||
@@ -40,6 +50,22 @@ def download_token_from(payload: Any) -> str:
|
||||
raise ZertoError(f"Could not read FLR download token from {payload!r}")
|
||||
|
||||
|
||||
def flr_row(payload: Any) -> dict[str, Any]:
|
||||
if isinstance(payload, list):
|
||||
if not payload:
|
||||
return {}
|
||||
first = payload[0]
|
||||
return first if isinstance(first, dict) else {}
|
||||
if isinstance(payload, dict):
|
||||
return payload
|
||||
return {}
|
||||
|
||||
|
||||
def flr_status(row: dict[str, Any]) -> str:
|
||||
value = pick(row, "FlrSessionStatus", "Status", "status", "state", "State") or ""
|
||||
return str(value)
|
||||
|
||||
|
||||
async def wait_flr_ready(
|
||||
client: ZertoClient,
|
||||
session_id: str,
|
||||
@@ -51,19 +77,18 @@ async def wait_flr_ready(
|
||||
last: Any = None
|
||||
while asyncio.get_event_loop().time() < deadline:
|
||||
last = await client.get_flr(session_id)
|
||||
status = ""
|
||||
if isinstance(last, dict):
|
||||
status = str(pick(last, "Status", "status", "state", "State") or "")
|
||||
if status.lower() in {"ready", "mounted", "available"}:
|
||||
return last if isinstance(last, dict) else {"status": status}
|
||||
if "mountinprogress" in status.lower() or "inprogress" in status.lower():
|
||||
row = flr_row(last)
|
||||
status = flr_status(row)
|
||||
low = status.lower()
|
||||
if low in READY_STATUSES:
|
||||
return row
|
||||
if "mountinprogress" in low or (low.endswith("inprogress") and "fail" not in low):
|
||||
await asyncio.sleep(interval_s)
|
||||
continue
|
||||
if status.lower() in {"failed", "error"}:
|
||||
if low in FAILED_STATUSES:
|
||||
raise ZertoError(f"FLR session {session_id} failed: {last}")
|
||||
# some appliances omit status once mounted
|
||||
if isinstance(last, dict) and not status:
|
||||
return last
|
||||
if row and not status:
|
||||
return row
|
||||
await asyncio.sleep(interval_s)
|
||||
raise ZertoError(
|
||||
f"FLR session {session_id} not ready within {timeout_s:.0f}s (last={last!r}). "
|
||||
|
||||
Reference in new issue
Block a user