fix(reboot): expose windows99 vmx repair package readback
Some checks failed
CD Pipeline / workflow-shape (push) Successful in 1s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 2m34s
CD Pipeline / post-deploy-checks (push) Has been cancelled
CD Pipeline / build-and-deploy (push) Has been cancelled
Some checks failed
CD Pipeline / workflow-shape (push) Successful in 1s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 2m34s
CD Pipeline / post-deploy-checks (push) Has been cancelled
CD Pipeline / build-and-deploy (push) Has been cancelled
This commit is contained in:
@@ -112,6 +112,34 @@ _WINDOWS99_POWERED_OFF_NEXT_SAFE_ACTION = (
|
||||
"build_windows99_vmware_autostart_check_mode_package_for_powered_off_aliases_"
|
||||
"then_rerun_no_secret_collector_no_vm_power_change"
|
||||
)
|
||||
_WINDOWS99_REQUIRED_VM_ALIASES = ["111", "188", "120", "121", "112"]
|
||||
_WINDOWS99_EXPECTED_VMX_CANDIDATES = {
|
||||
"111": [
|
||||
r"D:\Documents\Virtual Machines\192.168.0.111_Ubuntu_64-bit\192.168.0.111_Ubuntu_64-bit.vmx",
|
||||
],
|
||||
"188": [
|
||||
r"D:\Documents\Virtual Machines\Ollama_Ubuntu_64-bit\Ollama_Ubuntu_64-bit.vmx",
|
||||
],
|
||||
"120": [
|
||||
r"D:\Documents\Virtual Machines\192.168.0.120_Ubuntu_64-bit\192.168.0.120_Ubuntu_64-bit.vmx",
|
||||
],
|
||||
"121": [
|
||||
r"D:\Documents\Virtual Machines\192.168.0.121_Ubuntu_64-bit\192.168.0.121_Ubuntu_64-bit.vmx",
|
||||
],
|
||||
"112": [
|
||||
r"D:\Downloads\kali-linux-2025.4-vmware-amd64\kali-linux-2025.4-vmware-amd64.vmwarevm\kali-linux-2025.4-vmware-amd64.vmx",
|
||||
],
|
||||
}
|
||||
_WINDOWS99_VMX_REPAIR_FORBIDDEN_ACTIONS = [
|
||||
"read_windows_password_or_secret",
|
||||
"vm_power_change",
|
||||
"vmrun_start_or_stop",
|
||||
"host_reboot",
|
||||
"windows_service_restart",
|
||||
"windows_registry_apply",
|
||||
"scheduled_task_register_or_modify",
|
||||
"docker_nginx_k3s_db_firewall_restart",
|
||||
]
|
||||
|
||||
|
||||
def load_latest_reboot_auto_recovery_slo_scorecard(
|
||||
@@ -771,6 +799,12 @@ def _apply_prometheus_windows99_vmware_readback(
|
||||
rollups["windows99_verify_collection_blocker_count"] = len(
|
||||
_strings(collection.get("collection_blockers"))
|
||||
)
|
||||
_sync_windows99_vmx_source_repair_package(
|
||||
payload,
|
||||
generated_at=str(
|
||||
payload.get("runtime_readback_generated_at") or _taipei_now_iso()
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def _reconcile_prometheus_metric_active_blockers_with_source_controls(
|
||||
@@ -1643,6 +1677,12 @@ def _build_payload(scorecard: dict[str, Any], path: Path) -> dict[str, Any]:
|
||||
windows99_management=windows99_management,
|
||||
windows99_collector=windows99_collector,
|
||||
)
|
||||
windows99_vmx_source_repair_package = (
|
||||
_build_windows99_vmx_source_repair_package(
|
||||
windows99,
|
||||
generated_at=runtime_readback_generated_at,
|
||||
)
|
||||
)
|
||||
blocked_by_fresh_reboot_window_only = active_blockers == [
|
||||
"host_boot_observation_older_than_target_window"
|
||||
]
|
||||
@@ -1769,6 +1809,22 @@ def _build_payload(scorecard: dict[str, Any], path: Path) -> dict[str, Any]:
|
||||
"windows99_vmware_powered_off_count": len(
|
||||
_strings(windows99.get("powered_off_aliases"))
|
||||
),
|
||||
"windows99_vmx_source_repair_package_ready": (
|
||||
windows99_vmx_source_repair_package["package_ready"] is True
|
||||
),
|
||||
"windows99_vmx_source_repair_package_status": str(
|
||||
windows99_vmx_source_repair_package["status"]
|
||||
),
|
||||
"windows99_vmx_source_repair_package_safe_next_step": str(
|
||||
windows99_vmx_source_repair_package["safe_next_step"]
|
||||
),
|
||||
"windows99_vmx_source_repair_package_apply_allowed": (
|
||||
windows99_vmx_source_repair_package["apply_allowed_by_this_package"]
|
||||
is True
|
||||
),
|
||||
"windows99_vmx_source_repair_missing_vmx_aliases": _strings(
|
||||
windows99_vmx_source_repair_package.get("missing_vmx_aliases")
|
||||
),
|
||||
"windows99_verify_collection_status": windows99_verify_collection["status"],
|
||||
"windows99_verify_collection_can_collect_no_secret": (
|
||||
windows99_verify_collection["can_collect_no_secret_verify"] is True
|
||||
@@ -1960,6 +2016,21 @@ def _build_payload(scorecard: dict[str, Any], path: Path) -> dict[str, Any]:
|
||||
"windows99_update_no_auto_reboot_ready": rollups[
|
||||
"windows99_update_no_auto_reboot_ready"
|
||||
],
|
||||
"windows99_vmx_source_repair_package_ready": rollups[
|
||||
"windows99_vmx_source_repair_package_ready"
|
||||
],
|
||||
"windows99_vmx_source_repair_package_status": rollups[
|
||||
"windows99_vmx_source_repair_package_status"
|
||||
],
|
||||
"windows99_vmx_source_repair_package_safe_next_step": rollups[
|
||||
"windows99_vmx_source_repair_package_safe_next_step"
|
||||
],
|
||||
"windows99_vmx_source_repair_package_apply_allowed": rollups[
|
||||
"windows99_vmx_source_repair_package_apply_allowed"
|
||||
],
|
||||
"windows99_vmx_source_repair_missing_vmx_aliases": rollups[
|
||||
"windows99_vmx_source_repair_missing_vmx_aliases"
|
||||
],
|
||||
"windows99_verify_collection_status": rollups[
|
||||
"windows99_verify_collection_status"
|
||||
],
|
||||
@@ -2015,6 +2086,7 @@ def _build_payload(scorecard: dict[str, Any], path: Path) -> dict[str, Any]:
|
||||
"public_maintenance_fallback": public_maintenance,
|
||||
"windows99_vmware_autostart": windows99,
|
||||
"windows99_vmware_verify_collector": windows99_collector,
|
||||
"windows99_vmx_source_repair_package": windows99_vmx_source_repair_package,
|
||||
"windows99_verify_collection": windows99_verify_collection,
|
||||
"windows99_management_channel": windows99_management,
|
||||
"source_controls": source_controls,
|
||||
@@ -2357,6 +2429,132 @@ def _build_windows99_verify_collection_packet(
|
||||
}
|
||||
|
||||
|
||||
def _powershell_test_path(path: str) -> str:
|
||||
escaped = path.replace("'", "''")
|
||||
return f"Test-Path -LiteralPath '{escaped}'"
|
||||
|
||||
|
||||
def _build_windows99_vmx_source_repair_package(
|
||||
windows99: dict[str, Any],
|
||||
*,
|
||||
generated_at: str,
|
||||
) -> dict[str, Any]:
|
||||
missing_vmx_aliases = _unique_strings(
|
||||
_strings(windows99.get("missing_vmx_aliases"))
|
||||
)
|
||||
powered_off_aliases = _unique_strings(
|
||||
_strings(windows99.get("powered_off_aliases"))
|
||||
)
|
||||
required_aliases = _unique_strings(
|
||||
_strings(windows99.get("required_vm_aliases"))
|
||||
or _WINDOWS99_REQUIRED_VM_ALIASES
|
||||
)
|
||||
package_ready = bool(missing_vmx_aliases or powered_off_aliases)
|
||||
if missing_vmx_aliases:
|
||||
status = "check_mode_package_ready_windows99_vmx_source_repair_required"
|
||||
safe_next_step = _WINDOWS99_MISSING_VMX_NEXT_SAFE_ACTION
|
||||
elif powered_off_aliases:
|
||||
status = "check_mode_package_ready_windows99_power_check_required"
|
||||
safe_next_step = _WINDOWS99_POWERED_OFF_NEXT_SAFE_ACTION
|
||||
else:
|
||||
status = "ready_no_windows99_vmx_source_repair_required"
|
||||
safe_next_step = "rerun_no_secret_collector_and_reboot_slo_scorecard_verify_only"
|
||||
|
||||
rows: list[dict[str, Any]] = []
|
||||
for alias in required_aliases:
|
||||
candidates = _WINDOWS99_EXPECTED_VMX_CANDIDATES.get(alias, [])
|
||||
rows.append(
|
||||
{
|
||||
"alias": alias,
|
||||
"missing_vmx_source": alias in missing_vmx_aliases,
|
||||
"powered_off": alias in powered_off_aliases,
|
||||
"expected_vmx_candidates": candidates,
|
||||
"check_mode_probe_commands": [
|
||||
_powershell_test_path(candidate) for candidate in candidates
|
||||
],
|
||||
"controlled_restore_required": alias in missing_vmx_aliases,
|
||||
"controlled_restore_hint": (
|
||||
"restore_or_relink_existing_vmx_source_to_expected_path_then_verify"
|
||||
if alias in missing_vmx_aliases
|
||||
else ""
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
return {
|
||||
"schema_version": "windows99_vmx_source_repair_check_mode_package_v1",
|
||||
"generated_at": generated_at,
|
||||
"status": status,
|
||||
"package_ready": package_ready,
|
||||
"target_host_alias": "99",
|
||||
"missing_vmx_aliases": missing_vmx_aliases,
|
||||
"powered_off_aliases": powered_off_aliases,
|
||||
"required_vm_aliases": required_aliases,
|
||||
"vm_rows": rows,
|
||||
"safe_next_step": safe_next_step,
|
||||
"controlled_apply_mode": "check_mode_package_only_no_windows_or_vm_write",
|
||||
"apply_allowed_by_this_package": False,
|
||||
"post_verifier": [
|
||||
"bash scripts/reboot-recovery/collect-windows99-vmware-verify.sh --collect",
|
||||
"bash scripts/reboot-recovery/install-reboot-auto-recovery-slo-110.sh --verify-only",
|
||||
"GET /api/v1/agents/reboot-auto-recovery-slo-scorecard",
|
||||
],
|
||||
"forbidden_actions": _WINDOWS99_VMX_REPAIR_FORBIDDEN_ACTIONS,
|
||||
"operation_boundaries": {
|
||||
"secret_value_read": False,
|
||||
"remote_write_performed": False,
|
||||
"vm_power_change_performed": False,
|
||||
"windows_service_restart_performed": False,
|
||||
"windows_registry_apply_performed": False,
|
||||
"host_reboot_performed": False,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def _sync_windows99_vmx_source_repair_package(
|
||||
payload: dict[str, Any],
|
||||
*,
|
||||
generated_at: str,
|
||||
) -> dict[str, Any]:
|
||||
windows99 = _dict(payload.get("windows99_vmware_autostart"))
|
||||
package = _build_windows99_vmx_source_repair_package(
|
||||
windows99,
|
||||
generated_at=generated_at,
|
||||
)
|
||||
payload["windows99_vmx_source_repair_package"] = package
|
||||
|
||||
readback = _dict(payload.setdefault("readback", {}))
|
||||
readback["windows99_vmx_source_repair_package_ready"] = (
|
||||
package["package_ready"] is True
|
||||
)
|
||||
readback["windows99_vmx_source_repair_package_status"] = str(package["status"])
|
||||
readback["windows99_vmx_source_repair_package_safe_next_step"] = str(
|
||||
package["safe_next_step"]
|
||||
)
|
||||
readback["windows99_vmx_source_repair_package_apply_allowed"] = (
|
||||
package["apply_allowed_by_this_package"] is True
|
||||
)
|
||||
readback["windows99_vmx_source_repair_missing_vmx_aliases"] = _strings(
|
||||
package.get("missing_vmx_aliases")
|
||||
)
|
||||
|
||||
rollups = _dict(payload.setdefault("rollups", {}))
|
||||
rollups["windows99_vmx_source_repair_package_ready"] = (
|
||||
package["package_ready"] is True
|
||||
)
|
||||
rollups["windows99_vmx_source_repair_package_status"] = str(package["status"])
|
||||
rollups["windows99_vmx_source_repair_package_safe_next_step"] = str(
|
||||
package["safe_next_step"]
|
||||
)
|
||||
rollups["windows99_vmx_source_repair_package_apply_allowed"] = (
|
||||
package["apply_allowed_by_this_package"] is True
|
||||
)
|
||||
rollups["windows99_vmx_source_repair_missing_vmx_aliases"] = _strings(
|
||||
package.get("missing_vmx_aliases")
|
||||
)
|
||||
return package
|
||||
|
||||
|
||||
def _host_row_by_alias(
|
||||
host_boot_detection: dict[str, Any],
|
||||
alias: str,
|
||||
|
||||
@@ -440,6 +440,30 @@ def test_reboot_auto_recovery_slo_scorecard_overlays_prometheus_runtime_metrics(
|
||||
== WINDOWS99_RUNTIME_READBACK_ADDED_BLOCKERS
|
||||
)
|
||||
assert payload["runtime_metric_runtime_readback_added_blocker_count"] == 2
|
||||
package = payload["windows99_vmx_source_repair_package"]
|
||||
assert package["schema_version"] == (
|
||||
"windows99_vmx_source_repair_check_mode_package_v1"
|
||||
)
|
||||
assert package["package_ready"] is True
|
||||
assert package["apply_allowed_by_this_package"] is False
|
||||
assert package["missing_vmx_aliases"] == ["111"]
|
||||
assert package["safe_next_step"] == EXPECTED_WINDOWS99_MISSING_VMX_NEXT_STEP
|
||||
vm_rows = {row["alias"]: row for row in package["vm_rows"]}
|
||||
assert vm_rows["111"]["controlled_restore_required"] is True
|
||||
assert vm_rows["111"]["check_mode_probe_commands"] == [
|
||||
(
|
||||
"Test-Path -LiteralPath 'D:\\Documents\\Virtual Machines\\"
|
||||
"192.168.0.111_Ubuntu_64-bit\\192.168.0.111_Ubuntu_64-bit.vmx'"
|
||||
)
|
||||
]
|
||||
assert payload["readback"]["windows99_vmx_source_repair_package_ready"] is True
|
||||
assert (
|
||||
payload["readback"]["windows99_vmx_source_repair_package_apply_allowed"]
|
||||
is False
|
||||
)
|
||||
assert payload["rollups"]["windows99_vmx_source_repair_missing_vmx_aliases"] == [
|
||||
"111"
|
||||
]
|
||||
assert payload["service_green"] is True
|
||||
assert payload["backup_core_green"] is True
|
||||
assert payload["product_data_green"] is True
|
||||
|
||||
Reference in New Issue
Block a user