fix(device-edge): pin accepted foundation baseline
This commit is contained in:
@@ -197,6 +197,25 @@ PHASE_FILE_SHA256 = {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Exact immutable baselines from terminally accepted predecessor artifacts.
|
||||||
|
# This is intentionally keyed by both patch id and artifact digest so a later
|
||||||
|
# artifact cannot inherit compatibility from a merely similar deployment.
|
||||||
|
ACCEPTED_PREDECESSOR_FILE_SHA256 = {
|
||||||
|
"foundation": {
|
||||||
|
(
|
||||||
|
"device-edge-vps-foundation-20260806-003",
|
||||||
|
"1be852f144e9f0fea32af70bebd07a2607b6a1818825094bd4c1b4062064716a",
|
||||||
|
): {
|
||||||
|
"vps/config/00-nodedc-b2-vps.conf":
|
||||||
|
"cc94d0579f85d0af9746b9ce760bc72980f4a22fb59027e1f5f9c7bf3aaebd64",
|
||||||
|
"vps/config/nftables-foundation.conf":
|
||||||
|
"4d44f902d8d98d1aa8506fca9d9582e700f6424def2b1d667ab2cd5a5ee84934",
|
||||||
|
"deployment/device-edge-vps-foundation-v1.json":
|
||||||
|
"317c98b42520fff3238275908482de7aa611b4ee41c6b1f8062abd2730ab072a",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class DeployError(RuntimeError):
|
class DeployError(RuntimeError):
|
||||||
pass
|
pass
|
||||||
@@ -455,8 +474,24 @@ def assert_management_key():
|
|||||||
die("verified Mac management key is missing")
|
die("verified Mac management key is missing")
|
||||||
|
|
||||||
|
|
||||||
|
def phase_file_sha256(phase: str):
|
||||||
|
expected = dict(PHASE_FILE_SHA256[phase])
|
||||||
|
accepted = [
|
||||||
|
record
|
||||||
|
for record in journal_records(APPLIED_JOURNAL)
|
||||||
|
if record.get("phase") == phase and record.get("status") == "ok"
|
||||||
|
]
|
||||||
|
if len(accepted) == 1:
|
||||||
|
record = accepted[0]
|
||||||
|
identity = (record.get("patch"), record.get("sha256"))
|
||||||
|
expected.update(
|
||||||
|
ACCEPTED_PREDECESSOR_FILE_SHA256.get(phase, {}).get(identity, {})
|
||||||
|
)
|
||||||
|
return expected
|
||||||
|
|
||||||
|
|
||||||
def source_file_state(phase: str):
|
def source_file_state(phase: str):
|
||||||
expected = PHASE_FILE_SHA256[phase]
|
expected = phase_file_sha256(phase)
|
||||||
actual = {}
|
actual = {}
|
||||||
for relative, digest in expected.items():
|
for relative, digest in expected.items():
|
||||||
path = LIVE_ROOT / relative
|
path = LIVE_ROOT / relative
|
||||||
|
|||||||
@@ -261,6 +261,50 @@ class DeviceEdgeVpsArtifactTest(unittest.TestCase):
|
|||||||
self.assertIn("command_transport=disabled", rendered)
|
self.assertIn("command_transport=disabled", rendered)
|
||||||
self.assertIn("gelios=untouched", rendered)
|
self.assertIn("gelios=untouched", rendered)
|
||||||
|
|
||||||
|
def test_source_baseline_is_pinned_to_the_exact_accepted_predecessor(self):
|
||||||
|
with tempfile.TemporaryDirectory(prefix="nodedc-vps-baseline-") as directory:
|
||||||
|
journal = Path(directory) / "applied.jsonl"
|
||||||
|
old_journal = RUNNER.APPLIED_JOURNAL
|
||||||
|
RUNNER.APPLIED_JOURNAL = journal
|
||||||
|
try:
|
||||||
|
journal.write_text(json.dumps({
|
||||||
|
"patch": "device-edge-vps-foundation-20260806-003",
|
||||||
|
"phase": "foundation",
|
||||||
|
"sha256": (
|
||||||
|
"1be852f144e9f0fea32af70bebd07a2607b6a1818825094bd4c1b4062064716a"
|
||||||
|
),
|
||||||
|
"status": "ok",
|
||||||
|
}) + "\n", encoding="utf-8")
|
||||||
|
expected = RUNNER.phase_file_sha256("foundation")
|
||||||
|
self.assertEqual(
|
||||||
|
expected["vps/config/00-nodedc-b2-vps.conf"],
|
||||||
|
"cc94d0579f85d0af9746b9ce760bc72980f4a22fb59027e1f5f9c7bf3aaebd64",
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
expected["vps/config/nftables-foundation.conf"],
|
||||||
|
"4d44f902d8d98d1aa8506fca9d9582e700f6424def2b1d667ab2cd5a5ee84934",
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
expected["deployment/device-edge-vps-foundation-v1.json"],
|
||||||
|
"317c98b42520fff3238275908482de7aa611b4ee41c6b1f8062abd2730ab072a",
|
||||||
|
)
|
||||||
|
|
||||||
|
journal.write_text(json.dumps({
|
||||||
|
"patch": "device-edge-vps-foundation-20260806-003",
|
||||||
|
"phase": "foundation",
|
||||||
|
"sha256": "0" * 64,
|
||||||
|
"status": "ok",
|
||||||
|
}) + "\n", encoding="utf-8")
|
||||||
|
unexpected = RUNNER.phase_file_sha256("foundation")
|
||||||
|
self.assertEqual(
|
||||||
|
unexpected["vps/config/00-nodedc-b2-vps.conf"],
|
||||||
|
RUNNER.PHASE_FILE_SHA256[
|
||||||
|
"foundation"
|
||||||
|
]["vps/config/00-nodedc-b2-vps.conf"],
|
||||||
|
)
|
||||||
|
finally:
|
||||||
|
RUNNER.APPLIED_JOURNAL = old_journal
|
||||||
|
|
||||||
def test_units_and_firewalls_keep_the_required_boundaries(self):
|
def test_units_and_firewalls_keep_the_required_boundaries(self):
|
||||||
source_root = SCRIPT_DIR.parent.parent / "device-plane"
|
source_root = SCRIPT_DIR.parent.parent / "device-plane"
|
||||||
foundation = (source_root / "vps/config/nftables-foundation.conf").read_text()
|
foundation = (source_root / "vps/config/nftables-foundation.conf").read_text()
|
||||||
|
|||||||
Reference in New Issue
Block a user