chore(release): add canonical ontology manager v8
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"schemaVersion": "nodedc.device-plane.device-manager-release.v8",
|
||||
"releaseId": "__PATCH_ID__",
|
||||
"action": "upgrade",
|
||||
"predecessor": {
|
||||
"kind": "release",
|
||||
"patchId": "device-manager-release-v6-20260822-035",
|
||||
"artifactSha256": "193faabe930e2b3f212f8eb45288e39f850ec714528b28881095be654baf9a80"
|
||||
},
|
||||
"controlCorePredecessor": {
|
||||
"patchId": "device-control-core-release-v2-20260822-038",
|
||||
"artifactSha256": "e2d062b82b022dba662522b5d6e192026ac964d78950d903295ca3cbbc95ab28"
|
||||
},
|
||||
"edgeChannelPredecessor": {
|
||||
"patchId": "device-edge-core-channel-upgrade-v4-20260812-023",
|
||||
"artifactSha256": "c10d5b6b7d55ab239f85b6c8130e34ce9f84985e3b46e6e5534733156c7982fc"
|
||||
},
|
||||
"service": "device-manager",
|
||||
"publicIngress": "reverse-proxy-only",
|
||||
"deviceCoreManagementApi": "file-token-authenticated",
|
||||
"launcherTrust": "file-token-scoped-to-device-core-handoff",
|
||||
"edgeChannel": "preserve-active-v4-core-initiated-pinned-mtls",
|
||||
"edgeChannelIdentity": "reuse-runner-managed-host-local-private-key-public-certificate-export",
|
||||
"edgeChannelEgress": "preserve-dedicated-core-only-bridge-no-host-ingress-public-ipv4-tcp-443-only",
|
||||
"healthGate": "bounded-container-grace+core-contract+persistent-data",
|
||||
"commandTransport": "typed-service-ping-v1",
|
||||
"commandCatalog": "allowlisted-adapter-typed-commands-only",
|
||||
"credentialBoundary": "transient-core-memory-then-single-pinned-mtls-command-envelope-to-edge-never-persisted-never-logged-never-returned",
|
||||
"presentationPersistence": "runner-managed-host-data-bind",
|
||||
"presentationDataHostPath": "/volume1/docker/nodedc-device-plane/data/device-manager",
|
||||
"presentationDataContainerPath": "/var/lib/nodedc-device-manager",
|
||||
"presentationDataOwnership": "uid-1000-gid-1000-mode-0750",
|
||||
"presentationDataLifecycle": "preserve-across-manager-recreate-and-source-rollback",
|
||||
"presentationPath": "/var/lib/nodedc-device-manager/device-manager-presentation.json",
|
||||
"mediaRoot": "/var/lib/nodedc-device-manager/media",
|
||||
"defaultAccentHex": "#f5f5f5",
|
||||
"overviewLayout": "mission-core-landing-stage-v1",
|
||||
"faviconSet": "nodedc-adaptive-v1",
|
||||
"commandFormLayout": "aligned-control-row-v1",
|
||||
"secondaryEmptyTypography": "help-text-sm-v1",
|
||||
"infrastructureHostProjection": "ontology-backed-host-runtime-v1",
|
||||
"ontologyFoundation": "ontology-core-device-foundation-20260822-001",
|
||||
"ontologyCatalogHash": "229c61c02a790906",
|
||||
"assetBinding": "temporal-device-asset-binding-v1",
|
||||
"infrastructureRuntime": "host-endpoint-deployment-service-instance-v1",
|
||||
"healthEvidence": "ttl-observation-missing-not-unhealthy-v1",
|
||||
"interactiveShell": "disabled-pending-managed-session-boundary",
|
||||
"gelios": "untouched-legacy-only",
|
||||
"rollback": "restore-preapply-snapshot-preserve-manager-data"
|
||||
}
|
||||
@@ -11,11 +11,13 @@ const platformRoot = resolve(scriptDir, "../..");
|
||||
const devicePlaneRoot = platformRoot;
|
||||
const managerRoot = resolve(platformRoot, "apps/device-manager");
|
||||
const artifactDir = resolve(process.env.NODEDC_DEPLOY_ARTIFACT_DIR || resolve(scriptDir, "../deploy-artifacts"));
|
||||
const [patchId = "device-manager-release-v7-20260822-037", ...extra] = process.argv.slice(2);
|
||||
const [patchId = "device-manager-release-v8-20260822-039", ...extra] = process.argv.slice(2);
|
||||
if (extra.length || !/^[A-Za-z0-9._-]{1,96}$/.test(patchId)) throw new Error("usage: build-device-manager-control-plane-artifact.mjs [patch-id]");
|
||||
|
||||
const descriptorPath = patchId.startsWith("device-manager-release-v7-")
|
||||
? "deployment/device-manager-release-v7.json"
|
||||
const descriptorPath = patchId.startsWith("device-manager-release-v8-")
|
||||
? "deployment/device-manager-release-v8.json"
|
||||
: patchId.startsWith("device-manager-release-v7-")
|
||||
? "deployment/device-manager-release-v7.json"
|
||||
: patchId.startsWith("device-manager-release-v6-")
|
||||
? "deployment/device-manager-release-v6.json"
|
||||
: patchId.startsWith("device-manager-release-v5-")
|
||||
@@ -31,7 +33,8 @@ const isV4 = descriptorPath.endsWith("release-v4.json");
|
||||
const isV5 = descriptorPath.endsWith("release-v5.json");
|
||||
const isV6 = descriptorPath.endsWith("release-v6.json");
|
||||
const isV7 = descriptorPath.endsWith("release-v7.json");
|
||||
const isPersistent = isV4 || isV5 || isV6 || isV7;
|
||||
const isV8 = descriptorPath.endsWith("release-v8.json");
|
||||
const isPersistent = isV4 || isV5 || isV6 || isV7 || isV8;
|
||||
const isManagerOnly = isV3 || isPersistent;
|
||||
const composeSource = resolve(devicePlaneRoot, "docker-compose.device-manager.yml");
|
||||
const composeSourceSha256 = createHash("sha256").update(await readFile(composeSource)).digest("hex");
|
||||
@@ -170,7 +173,43 @@ try {
|
||||
: "restore-preapply-snapshot")
|
||||
);
|
||||
if (commonContractInvalid) throw new Error("device_manager_activation_successor_contract_mismatch");
|
||||
if (descriptorPath.endsWith("release-v7.json")) {
|
||||
if (descriptorPath.endsWith("release-v8.json")) {
|
||||
if (
|
||||
descriptor.schemaVersion !== "nodedc.device-plane.device-manager-release.v8"
|
||||
|| descriptor.predecessor?.kind !== "release"
|
||||
|| descriptor.predecessor?.patchId !== "device-manager-release-v6-20260822-035"
|
||||
|| descriptor.predecessor?.artifactSha256 !== "193faabe930e2b3f212f8eb45288e39f850ec714528b28881095be654baf9a80"
|
||||
|| descriptor.controlCorePredecessor?.patchId !== "device-control-core-release-v2-20260822-038"
|
||||
|| descriptor.controlCorePredecessor?.artifactSha256 !== "e2d062b82b022dba662522b5d6e192026ac964d78950d903295ca3cbbc95ab28"
|
||||
|| descriptor.edgeChannelPredecessor?.patchId !== "device-edge-core-channel-upgrade-v4-20260812-023"
|
||||
|| descriptor.edgeChannelPredecessor?.artifactSha256 !== "c10d5b6b7d55ab239f85b6c8130e34ce9f84985e3b46e6e5534733156c7982fc"
|
||||
|| descriptor.commandTransport !== "typed-service-ping-v1"
|
||||
|| descriptor.commandCatalog !== "allowlisted-adapter-typed-commands-only"
|
||||
|| descriptor.credentialBoundary !== "transient-core-memory-then-single-pinned-mtls-command-envelope-to-edge-never-persisted-never-logged-never-returned"
|
||||
|| descriptor.presentationPersistence !== "runner-managed-host-data-bind"
|
||||
|| descriptor.presentationDataHostPath !== "/volume1/docker/nodedc-device-plane/data/device-manager"
|
||||
|| descriptor.presentationDataContainerPath !== "/var/lib/nodedc-device-manager"
|
||||
|| descriptor.presentationDataOwnership !== "uid-1000-gid-1000-mode-0750"
|
||||
|| descriptor.presentationDataLifecycle !== "preserve-across-manager-recreate-and-source-rollback"
|
||||
|| descriptor.presentationPath !== "/var/lib/nodedc-device-manager/device-manager-presentation.json"
|
||||
|| descriptor.mediaRoot !== "/var/lib/nodedc-device-manager/media"
|
||||
|| descriptor.defaultAccentHex !== "#f5f5f5"
|
||||
|| descriptor.overviewLayout !== "mission-core-landing-stage-v1"
|
||||
|| descriptor.faviconSet !== "nodedc-adaptive-v1"
|
||||
|| descriptor.commandFormLayout !== "aligned-control-row-v1"
|
||||
|| descriptor.secondaryEmptyTypography !== "help-text-sm-v1"
|
||||
|| descriptor.infrastructureHostProjection !== "ontology-backed-host-runtime-v1"
|
||||
|| descriptor.ontologyFoundation !== "ontology-core-device-foundation-20260822-001"
|
||||
|| descriptor.ontologyCatalogHash !== "229c61c02a790906"
|
||||
|| descriptor.assetBinding !== "temporal-device-asset-binding-v1"
|
||||
|| descriptor.infrastructureRuntime !== "host-endpoint-deployment-service-instance-v1"
|
||||
|| descriptor.healthEvidence !== "ttl-observation-missing-not-unhealthy-v1"
|
||||
|| descriptor.interactiveShell !== "disabled-pending-managed-session-boundary"
|
||||
|| descriptor.rollback !== "restore-preapply-snapshot-preserve-manager-data"
|
||||
|| descriptor.gelios !== "untouched-legacy-only"
|
||||
) throw new Error("device_manager_v8_canonical_ontology_runtime_contract_mismatch");
|
||||
await validateFaviconBundle(payload, "device_manager_v8");
|
||||
} else if (descriptorPath.endsWith("release-v7.json")) {
|
||||
if (
|
||||
descriptor.schemaVersion !== "nodedc.device-plane.device-manager-release.v7"
|
||||
|| descriptor.predecessor?.kind !== "release"
|
||||
|
||||
@@ -637,6 +637,82 @@ class DeviceManagerControlPlaneArtifactsTest(unittest.TestCase):
|
||||
)
|
||||
)
|
||||
|
||||
def test_device_manager_release_v8_adds_canonical_ontology_runtime(self):
|
||||
patch_id = "device-manager-release-v8-unit-001"
|
||||
manifest, entries, names, result = self.assert_deterministic_artifact(
|
||||
"build-device-manager-control-plane-artifact.mjs",
|
||||
patch_id,
|
||||
RUNNER.DEVICE_PLANE_MANAGER_RELEASE_V8_ENTRIES,
|
||||
)
|
||||
self.assertEqual(manifest["component"], "device-plane")
|
||||
self.assertEqual(result["services"], ["device-manager"])
|
||||
self.assertFalse(
|
||||
any(
|
||||
name.startswith("payload/services/device-control-core/")
|
||||
for name in names
|
||||
)
|
||||
)
|
||||
self.assertFalse(any(name.startswith("payload/packages/") for name in names))
|
||||
self.assertFalse(any(name.endswith((".test.mjs", ".map")) for name in names))
|
||||
template = json.loads(
|
||||
(
|
||||
DEVICE_CORE_ROOT
|
||||
/ "deployment/device-manager-release-v8.json"
|
||||
).read_text(encoding="utf-8")
|
||||
)
|
||||
descriptor = {**template, "releaseId": patch_id}
|
||||
self.assertIs(
|
||||
RUNNER.validate_device_plane_manager_release_descriptor(
|
||||
descriptor,
|
||||
schema_version=(
|
||||
"nodedc.device-plane.device-manager-release.v8"
|
||||
),
|
||||
boundaries=(
|
||||
RUNNER.expected_device_plane_manager_release_v8_boundaries()
|
||||
),
|
||||
expected_release_id=patch_id,
|
||||
),
|
||||
descriptor,
|
||||
)
|
||||
self.assertEqual(
|
||||
descriptor["predecessor"],
|
||||
{
|
||||
"kind": "release",
|
||||
"patchId": "device-manager-release-v6-20260822-035",
|
||||
"artifactSha256": (
|
||||
"193faabe930e2b3f212f8eb45288e39f850ec714528b28881095be654baf9a80"
|
||||
),
|
||||
},
|
||||
)
|
||||
self.assertEqual(
|
||||
descriptor["controlCorePredecessor"],
|
||||
{
|
||||
"patchId": "device-control-core-release-v2-20260822-038",
|
||||
"artifactSha256": (
|
||||
"e2d062b82b022dba662522b5d6e192026ac964d78950d903295ca3cbbc95ab28"
|
||||
),
|
||||
},
|
||||
)
|
||||
self.assertEqual(
|
||||
descriptor["infrastructureHostProjection"],
|
||||
"ontology-backed-host-runtime-v1",
|
||||
)
|
||||
self.assertEqual(
|
||||
descriptor["ontologyFoundation"],
|
||||
"ontology-core-device-foundation-20260822-001",
|
||||
)
|
||||
self.assertEqual(descriptor["ontologyCatalogHash"], "229c61c02a790906")
|
||||
self.assertEqual(
|
||||
descriptor["healthEvidence"],
|
||||
"ttl-observation-missing-not-unhealthy-v1",
|
||||
)
|
||||
self.assertTrue(
|
||||
RUNNER.is_device_plane_manager_release_v8_slice(
|
||||
"device-plane",
|
||||
entries,
|
||||
)
|
||||
)
|
||||
|
||||
def test_historical_manager_builder_fails_closed_after_v4_compose(self):
|
||||
if self.historical_manager_compose_is_current():
|
||||
self.skipTest("historical Manager Compose is still current")
|
||||
|
||||
Reference in New Issue
Block a user