deploy: register Manager v4 persistent data

This commit is contained in:
Codex
2026-08-22 09:47:57 +03:00
parent 12901e0e19
commit 6123a06527
2 changed files with 381 additions and 17 deletions
@@ -3,6 +3,7 @@ import importlib.machinery
import importlib.util
import inspect
import json
import stat
import tempfile
import unittest
from pathlib import Path
@@ -28,6 +29,30 @@ RUNNER = load_runner()
class DevicePlaneRegistryTest(unittest.TestCase):
def test_manager_v4_pins_032_and_persistent_white_boundary(self):
self.assertEqual(
RUNNER.DEVICE_PLANE_MANAGER_RELEASE_V4_PREDECESSOR_PATCH_ID,
"device-manager-release-v3-20260822-032",
)
self.assertEqual(
RUNNER.DEVICE_PLANE_MANAGER_RELEASE_V4_PREDECESSOR_ARTIFACT_SHA256,
"6e0eb3a0a6f19ceab92d46832b93bffbcea21247dbdc2ea50625a51ff460e4ca",
)
self.assertEqual(
RUNNER.DEVICE_PLANE_MANAGER_RELEASE_V4_COMPOSE_SHA256,
"e7dff0f5873ad4586bd55946d3db2bb86092a5e149e886d120adc041e056c256",
)
boundaries = RUNNER.expected_device_plane_manager_release_v4_boundaries()
self.assertEqual(boundaries["defaultAccentHex"], "#f5f5f5")
self.assertEqual(
boundaries["presentationDataHostPath"],
"/volume1/docker/nodedc-device-plane/data/device-manager",
)
self.assertEqual(
boundaries["presentationDataContainerPath"],
"/var/lib/nodedc-device-manager",
)
def test_manager_v3_targets_applied_control_core_recovery(self):
self.assertEqual(
RUNNER.DEVICE_PLANE_MANAGER_RELEASE_V3_CONTROL_CORE_PREDECESSOR_PATCH_ID,
@@ -295,6 +320,110 @@ class DevicePlaneRegistryTest(unittest.TestCase):
core_network_mode="private-egress",
)
def test_manager_v4_post_apply_requires_persistent_data(self):
with (
mock.patch.object(
RUNNER,
"healthcheck_compose_service_with_grace",
),
mock.patch.object(
RUNNER,
"component_healthchecks",
return_value=(),
),
mock.patch.object(
RUNNER,
"validate_device_manager_control_plane_runtime",
) as runtime_acceptance,
):
RUNNER.run_healthchecks(
"device-plane",
RUNNER.DEVICE_PLANE_MANAGER_RELEASE_V4_ENTRIES,
("device-manager",),
)
runtime_acceptance.assert_called_once_with(
require_edge_channel=True,
core_network_mode="private-egress",
require_persistent_data=True,
)
def test_manager_v4_prepare_owns_new_parent_and_managed_data_directory(self):
with tempfile.TemporaryDirectory(
prefix="nodedc-manager-v4-data-",
) as directory:
data_dir = Path(directory) / "data" / "device-manager"
with (
mock.patch.object(
RUNNER,
"DEVICE_PLANE_MANAGER_DATA_DIR",
data_dir,
),
mock.patch.object(RUNNER.os, "chown") as chown,
mock.patch.object(
RUNNER,
"validate_device_plane_manager_persistent_data_metadata",
return_value="uid-1000-gid-1000-mode-0750",
) as validate,
):
result = RUNNER.ensure_device_plane_manager_persistent_data()
self.assertEqual(result, "uid-1000-gid-1000-mode-0750")
self.assertEqual(
chown.call_args_list,
[
mock.call(data_dir.parent, 0, 0),
mock.call(data_dir, 1000, 1000),
],
)
validate.assert_called_once_with()
def test_manager_v4_prepare_preserves_existing_safe_parent_metadata(self):
with tempfile.TemporaryDirectory(
prefix="nodedc-manager-v4-parent-",
) as directory:
data_parent = Path(directory) / "data"
data_parent.mkdir(mode=0o700)
data_dir = data_parent / "device-manager"
with (
mock.patch.object(
RUNNER,
"DEVICE_PLANE_MANAGER_DATA_DIR",
data_dir,
),
mock.patch.object(RUNNER.os, "chown") as chown,
mock.patch.object(
RUNNER,
"validate_device_plane_manager_persistent_data_metadata",
return_value="uid-1000-gid-1000-mode-0750",
),
):
RUNNER.ensure_device_plane_manager_persistent_data()
self.assertEqual(stat.S_IMODE(data_parent.stat().st_mode), 0o700)
chown.assert_called_once_with(data_dir, 1000, 1000)
def test_manager_v4_prepare_rejects_symlink_parent_before_child_creation(self):
with tempfile.TemporaryDirectory(
prefix="nodedc-manager-v4-symlink-",
) as directory:
root = Path(directory)
outside = root / "outside"
outside.mkdir()
data_parent = root / "data"
data_parent.symlink_to(outside, target_is_directory=True)
with mock.patch.object(
RUNNER,
"DEVICE_PLANE_MANAGER_DATA_DIR",
data_parent / "device-manager",
):
with self.assertRaisesRegex(
RUNNER.DeployError,
"persistent data parent is unsafe",
):
RUNNER.ensure_device_plane_manager_persistent_data()
self.assertFalse((outside / "device-manager").exists())
def test_manager_predecessor_health_is_phase_scoped(self):
with self.assertRaisesRegex(
RUNNER.DeployError,