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( descriptor = validate_device_plane_manager_release_payload(
payload_dir payload_dir
) )
@@ -12367,13 +12393,16 @@ def validate_device_plane_manager_activation_predecessor(payload_dir):
) )
if installed_descriptor != predecessor_descriptor: if installed_descriptor != predecessor_descriptor:
die("Device Manager release predecessor is not current") die("Device Manager release predecessor is not current")
for service in ( runtime = {
"device-control-core", "accepted": True,
"device-manager", "preservedRuntimeHealth": "deferred-to-apply",
"device-postgres", }
): if preflight_phase == "apply":
healthcheck_compose_service("device-plane", service) runtime["preservedRuntimeHealth"] = (
runtime = {"accepted": True} validate_device_plane_manager_preserved_runtime_health(
descriptor
)
)
v3_baseline = validate_device_plane_manager_v3_active_baseline( v3_baseline = validate_device_plane_manager_v3_active_baseline(
descriptor descriptor
) )
@@ -19306,7 +19335,8 @@ def plan_artifact(artifact):
): ):
device_plane_manager_activation_preflight = ( device_plane_manager_activation_preflight = (
validate_device_plane_manager_activation_predecessor( validate_device_plane_manager_activation_predecessor(
payload_dir payload_dir,
preflight_phase="plan",
) )
) )
if is_device_plane_edge_core_channel_bootstrap_slice( if is_device_plane_edge_core_channel_bootstrap_slice(
@@ -24614,7 +24644,8 @@ def apply_artifact(artifact):
entries, entries,
): ):
validate_device_plane_manager_activation_predecessor( validate_device_plane_manager_activation_predecessor(
payload_dir payload_dir,
preflight_phase="apply",
) )
if is_device_plane_edge_core_channel_bootstrap_slice( if is_device_plane_edge_core_channel_bootstrap_slice(
component, component,
@@ -1,6 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import importlib.machinery import importlib.machinery
import importlib.util import importlib.util
import inspect
import json import json
import tempfile import tempfile
import unittest import unittest
@@ -27,6 +28,75 @@ RUNNER = load_runner()
class DevicePlaneRegistryTest(unittest.TestCase): 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): def test_registry_has_exact_roots_project_and_stateless_services(self):
component = RUNNER.COMPONENTS["device-plane"] component = RUNNER.COMPONENTS["device-plane"]
root = Path("/volume1/docker/nodedc-device-plane") root = Path("/volume1/docker/nodedc-device-plane")