fix(deploy): reconcile device plane foundation

This commit is contained in:
Codex
2026-07-25 23:11:14 +03:00
parent 1102e25e6e
commit aca47c6143
8 changed files with 1692 additions and 15 deletions
@@ -1,6 +1,7 @@
#!/usr/bin/env python3
import importlib.machinery
import importlib.util
import json
import tempfile
import unittest
from pathlib import Path
@@ -207,6 +208,15 @@ class DevicePlaneRegistryTest(unittest.TestCase):
"\n".join(entries) + "\n",
encoding="utf-8",
)
(backup / "runtime-before.json").write_text(
json.dumps({
"schemaVersion":
"nodedc.device-plane.runtime-inventory.v1",
"composeProject": "nodedc-device-plane",
"services": [],
}),
encoding="utf-8",
)
with (
mock.patch.object(
RUNNER,
@@ -234,6 +244,165 @@ class DevicePlaneRegistryTest(unittest.TestCase):
restore.assert_called_once()
self.assertEqual(result, "source-restored-runtime-unchanged:3")
def test_db_bootstrap_compose_does_not_invent_stateless_baseline(self):
entries = (
"docker-compose.device-plane.yml",
"services/device-control-core",
"services/device-gateway",
)
with tempfile.TemporaryDirectory(
prefix="nodedc-device-plane-compose-predecessor-",
) as directory:
root = Path(directory) / "live"
backup = Path(directory) / "backup"
root.mkdir()
backup.mkdir()
(backup / "existing-files.txt").write_text(
"docker-compose.device-plane.yml\n",
encoding="utf-8",
)
(backup / "missing-files.txt").write_text(
"services/device-control-core\n"
"services/device-gateway\n",
encoding="utf-8",
)
(backup / "runtime-before.json").write_text(
json.dumps({
"schemaVersion":
"nodedc.device-plane.runtime-inventory.v1",
"composeProject": "nodedc-device-plane",
"services": [{
"service": "device-postgres",
"containerId": "a" * 64,
"imageId": "sha256:" + "b" * 64,
"status": "running",
"running": True,
"health": "healthy",
"restartCount": 0,
}],
}),
encoding="utf-8",
)
with (
mock.patch.object(
RUNNER,
"stop_and_remove_compose_services",
) as stop,
mock.patch.object(
RUNNER,
"restore_platform_overlay",
return_value=3,
),
mock.patch.object(
RUNNER,
"run_component_runtime",
) as run_runtime,
):
result = RUNNER.rollback_device_plane_apply(
root,
backup,
entries,
"test-stamp",
True,
("device-control-core", "device-gateway"),
)
stop.assert_called_once_with(
"device-plane",
("device-control-core", "device-gateway"),
)
run_runtime.assert_not_called()
self.assertEqual(result, "source-restored-runtime-unchanged:3")
def test_installed_stateless_baseline_is_restored_from_runtime_inventory(
self,
):
entries = (
"docker-compose.device-plane.yml",
"services/device-control-core",
"services/device-gateway",
)
with tempfile.TemporaryDirectory(
prefix="nodedc-device-plane-installed-predecessor-",
) as directory:
root = Path(directory) / "live"
backup = Path(directory) / "backup"
root.mkdir()
backup.mkdir()
(backup / "existing-files.txt").write_text(
"\n".join(entries) + "\n",
encoding="utf-8",
)
(backup / "missing-files.txt").write_text(
"",
encoding="utf-8",
)
(backup / "runtime-before.json").write_text(
json.dumps({
"schemaVersion":
"nodedc.device-plane.runtime-inventory.v1",
"composeProject": "nodedc-device-plane",
"services": [
{
"service": "device-control-core",
"containerId": "a" * 64,
"imageId": "sha256:" + "b" * 64,
"status": "running",
"running": True,
"health": "healthy",
"restartCount": 0,
},
{
"service": "device-gateway",
"containerId": "c" * 64,
"imageId": "sha256:" + "d" * 64,
"status": "running",
"running": True,
"health": "healthy",
"restartCount": 0,
},
],
}),
encoding="utf-8",
)
with (
mock.patch.object(
RUNNER,
"stop_and_remove_compose_services",
) as stop,
mock.patch.object(
RUNNER,
"restore_platform_overlay",
return_value=3,
),
mock.patch.object(
RUNNER,
"run_component_runtime",
) as run_runtime,
mock.patch.object(RUNNER, "run_healthchecks") as healthchecks,
):
result = RUNNER.rollback_device_plane_apply(
root,
backup,
entries,
"test-stamp",
True,
("device-control-core", "device-gateway"),
)
stop.assert_not_called()
run_runtime.assert_called_once_with(
"device-plane",
list(entries),
("device-control-core", "device-gateway"),
)
healthchecks.assert_called_once_with(
"device-plane",
list(entries),
("device-control-core", "device-gateway"),
)
self.assertEqual(result, "source+runtime-restored:3")
if __name__ == "__main__":
unittest.main(verbosity=2)