deploy: keep manager health out of plan

This commit is contained in:
Codex
2026-08-21 16:23:59 +03:00
parent a9ea31f00a
commit 26dbcfd262
2 changed files with 111 additions and 10 deletions
+41 -10
View File
@@ -12234,7 +12234,33 @@ def validate_device_plane_manager_v3_active_baseline(descriptor):
}
def validate_device_plane_manager_activation_predecessor(payload_dir):
def device_plane_manager_preserved_runtime_health_services(descriptor):
if descriptor.get("schemaVersion") == (
"nodedc.device-plane.device-manager-release.v3"
):
return (
"device-control-core",
"device-postgres",
)
return ("device-postgres",)
def validate_device_plane_manager_preserved_runtime_health(descriptor):
services = device_plane_manager_preserved_runtime_health_services(
descriptor
)
for service in services:
healthcheck_compose_service("device-plane", service)
return services
def validate_device_plane_manager_activation_predecessor(
payload_dir,
*,
preflight_phase,
):
if preflight_phase not in ("plan", "apply"):
die("Device Manager predecessor preflight phase is invalid")
descriptor = validate_device_plane_manager_release_payload(
payload_dir
)
@@ -12367,13 +12393,16 @@ def validate_device_plane_manager_activation_predecessor(payload_dir):
)
if installed_descriptor != predecessor_descriptor:
die("Device Manager release predecessor is not current")
for service in (
"device-control-core",
"device-manager",
"device-postgres",
):
healthcheck_compose_service("device-plane", service)
runtime = {"accepted": True}
runtime = {
"accepted": True,
"preservedRuntimeHealth": "deferred-to-apply",
}
if preflight_phase == "apply":
runtime["preservedRuntimeHealth"] = (
validate_device_plane_manager_preserved_runtime_health(
descriptor
)
)
v3_baseline = validate_device_plane_manager_v3_active_baseline(
descriptor
)
@@ -19306,7 +19335,8 @@ def plan_artifact(artifact):
):
device_plane_manager_activation_preflight = (
validate_device_plane_manager_activation_predecessor(
payload_dir
payload_dir,
preflight_phase="plan",
)
)
if is_device_plane_edge_core_channel_bootstrap_slice(
@@ -24614,7 +24644,8 @@ def apply_artifact(artifact):
entries,
):
validate_device_plane_manager_activation_predecessor(
payload_dir
payload_dir,
preflight_phase="apply",
)
if is_device_plane_edge_core_channel_bootstrap_slice(
component,
@@ -1,6 +1,7 @@
#!/usr/bin/env python3
import importlib.machinery
import importlib.util
import inspect
import json
import tempfile
import unittest
@@ -27,6 +28,75 @@ RUNNER = load_runner()
class DevicePlaneRegistryTest(unittest.TestCase):
def test_manager_predecessor_health_is_phase_scoped(self):
with self.assertRaisesRegex(
RUNNER.DeployError,
"preflight phase is invalid",
):
RUNNER.validate_device_plane_manager_activation_predecessor(
Path("/not-used"),
preflight_phase="unknown",
)
plan_source = inspect.getsource(RUNNER.plan_artifact)
self.assertIn('preflight_phase="plan"', plan_source)
apply_source = inspect.getsource(RUNNER.apply_artifact)
self.assertIn('preflight_phase="apply"', apply_source)
def test_manager_v3_health_gate_checks_only_preserved_services(self):
descriptor = {
"schemaVersion": (
"nodedc.device-plane.device-manager-release.v3"
),
}
with mock.patch.object(
RUNNER,
"healthcheck_compose_service",
) as healthcheck:
services = (
RUNNER.validate_device_plane_manager_preserved_runtime_health(
descriptor
)
)
self.assertEqual(
services,
("device-control-core", "device-postgres"),
)
self.assertEqual(
healthcheck.call_args_list,
[
mock.call("device-plane", "device-control-core"),
mock.call("device-plane", "device-postgres"),
],
)
self.assertNotIn(
mock.call("device-plane", "device-manager"),
healthcheck.call_args_list,
)
def test_legacy_manager_health_gate_excludes_selected_services(self):
descriptor = {
"schemaVersion": (
"nodedc.device-plane.device-manager-release.v2"
),
}
with mock.patch.object(
RUNNER,
"healthcheck_compose_service",
) as healthcheck:
services = (
RUNNER.validate_device_plane_manager_preserved_runtime_health(
descriptor
)
)
self.assertEqual(services, ("device-postgres",))
healthcheck.assert_called_once_with(
"device-plane",
"device-postgres",
)
def test_registry_has_exact_roots_project_and_stateless_services(self):
component = RUNNER.COMPONENTS["device-plane"]
root = Path("/volume1/docker/nodedc-device-plane")