feat(deploy): add typed command transport releases

This commit is contained in:
Codex
2026-08-12 22:57:20 +03:00
parent 4b73a15765
commit 3ea2133bcd
10 changed files with 1028 additions and 75 deletions
+417 -27
View File
@@ -246,6 +246,9 @@ DEVICE_PLANE_MANAGER_CONTROL_PLANE_REL = (
DEVICE_PLANE_MANAGER_RELEASE_V2_REL = (
"deployment/device-manager-release-v2.json"
)
DEVICE_PLANE_MANAGER_RELEASE_V3_REL = (
"deployment/device-manager-release-v3.json"
)
DEVICE_PLANE_MANAGER_COMPOSE_REL = "docker-compose.device-manager.yml"
DEVICE_PLANE_EDGE_CORE_CHANNEL_BOOTSTRAP_REL = (
"deployment/device-edge-core-channel-bootstrap-v1.json"
@@ -262,6 +265,9 @@ DEVICE_PLANE_EDGE_CORE_CHANNEL_UPGRADE_V4_REL = (
DEVICE_PLANE_CONTROL_CORE_RELEASE_REL = (
"deployment/device-control-core-release-v1.json"
)
DEVICE_PLANE_CONTROL_CORE_RELEASE_V2_REL = (
"deployment/device-control-core-release-v2.json"
)
DEVICE_PLANE_EDGE_CORE_CHANNEL_COMPOSE_REL = (
"docker-compose.device-edge-core-channel.yml"
)
@@ -323,12 +329,33 @@ DEVICE_PLANE_CONTROL_CORE_RELEASE_ENTRIES = (
"services/device-control-core",
DEVICE_PLANE_CONTROL_CORE_RELEASE_REL,
)
DEVICE_PLANE_CONTROL_CORE_RELEASE_V2_ENTRIES = (
".dockerignore",
"package.json",
"package-lock.json",
"packages/device-protocol-contract",
"packages/device-edge-channel-contract",
"services/device-control-core",
DEVICE_PLANE_CONTROL_CORE_RELEASE_V2_REL,
)
DEVICE_PLANE_CONTROL_CORE_RELEASE_FIRST_PREDECESSOR_PATCH_ID = (
"device-edge-core-channel-upgrade-v4-20260812-023"
)
DEVICE_PLANE_CONTROL_CORE_RELEASE_FIRST_PREDECESSOR_ARTIFACT_SHA256 = (
"c10d5b6b7d55ab239f85b6c8130e34ce9f84985e3b46e6e5534733156c7982fc"
)
DEVICE_PLANE_MANAGER_RELEASE_V3_CONTROL_CORE_PREDECESSOR_PATCH_ID = (
"device-control-core-release-v2-20260812-025"
)
DEVICE_PLANE_MANAGER_RELEASE_V3_CONTROL_CORE_PREDECESSOR_ARTIFACT_SHA256 = (
"c61b1f0de1bae23de0caa7289036865ea419ff5705611416f736ca929d1592db"
)
DEVICE_PLANE_MANAGER_RELEASE_V3_EDGE_CHANNEL_PREDECESSOR_PATCH_ID = (
"device-edge-core-channel-upgrade-v4-20260812-023"
)
DEVICE_PLANE_MANAGER_RELEASE_V3_EDGE_CHANNEL_PREDECESSOR_ARTIFACT_SHA256 = (
"c10d5b6b7d55ab239f85b6c8130e34ce9f84985e3b46e6e5534733156c7982fc"
)
DEVICE_PLANE_EDGE_CORE_CHANNEL_BOOTSTRAP_PREDECESSOR_PATCH_ID = (
"device-edge-core-channel-bootstrap-20260812-018"
)
@@ -460,6 +487,11 @@ DEVICE_PLANE_MANAGER_RELEASE_V2_ENTRIES = (
"services/device-manager",
DEVICE_PLANE_MANAGER_RELEASE_V2_REL,
)
DEVICE_PLANE_MANAGER_RELEASE_V3_ENTRIES = (
DEVICE_PLANE_MANAGER_COMPOSE_REL,
"services/device-manager",
DEVICE_PLANE_MANAGER_RELEASE_V3_REL,
)
DEVICE_PLANE_MANAGER_RECONCILIATION_REL = (
"deployment/device-manager-control-plane-reconciliation-v1.json"
)
@@ -3889,11 +3921,13 @@ def allowed_payload_path(component, rel):
DEVICE_PLANE_MANAGER_FAILED_CONTROL_PLANE_REL,
DEVICE_PLANE_MANAGER_CONTROL_PLANE_REL,
DEVICE_PLANE_MANAGER_RELEASE_V2_REL,
DEVICE_PLANE_MANAGER_RELEASE_V3_REL,
DEVICE_PLANE_EDGE_CORE_CHANNEL_BOOTSTRAP_REL,
DEVICE_PLANE_EDGE_CORE_CHANNEL_UPGRADE_REL,
DEVICE_PLANE_EDGE_CORE_CHANNEL_UPGRADE_V2_REL,
DEVICE_PLANE_EDGE_CORE_CHANNEL_UPGRADE_V4_REL,
DEVICE_PLANE_CONTROL_CORE_RELEASE_REL,
DEVICE_PLANE_CONTROL_CORE_RELEASE_V2_REL,
DEVICE_PLANE_MANAGER_RECONCILIATION_REL,
DEVICE_PLANE_MANAGER_V2_RECONCILIATION_REL,
"packages/device-protocol-contract",
@@ -9459,6 +9493,7 @@ def is_device_plane_manager_control_plane_slice(component, entries):
DEVICE_PLANE_MANAGER_CONTROL_PLANE_ENTRIES,
DEVICE_PLANE_MANAGER_RELEASE_V1_SUCCESSOR_ENTRIES,
DEVICE_PLANE_MANAGER_RELEASE_V2_ENTRIES,
DEVICE_PLANE_MANAGER_RELEASE_V3_ENTRIES,
)
)
@@ -9471,6 +9506,14 @@ def is_device_plane_manager_release_v2_slice(component, entries):
)
def is_device_plane_manager_release_v3_slice(component, entries):
return (
component == "device-plane"
and entries is not None
and tuple(entries) == DEVICE_PLANE_MANAGER_RELEASE_V3_ENTRIES
)
def is_device_plane_edge_core_channel_bootstrap_slice(component, entries):
return (
component == "device-plane"
@@ -9516,7 +9559,18 @@ def is_device_plane_control_core_release_slice(component, entries):
return (
component == "device-plane"
and entries is not None
and tuple(entries) == DEVICE_PLANE_CONTROL_CORE_RELEASE_ENTRIES
and tuple(entries) in (
DEVICE_PLANE_CONTROL_CORE_RELEASE_ENTRIES,
DEVICE_PLANE_CONTROL_CORE_RELEASE_V2_ENTRIES,
)
)
def is_device_plane_control_core_release_v2_slice(component, entries):
return (
component == "device-plane"
and entries is not None
and tuple(entries) == DEVICE_PLANE_CONTROL_CORE_RELEASE_V2_ENTRIES
)
@@ -9605,6 +9659,49 @@ def expected_device_plane_manager_release_v2_boundaries():
}
def expected_device_plane_manager_release_v3_boundaries():
return {
"controlCorePredecessor": {
"patchId": (
DEVICE_PLANE_MANAGER_RELEASE_V3_CONTROL_CORE_PREDECESSOR_PATCH_ID
),
"artifactSha256": (
DEVICE_PLANE_MANAGER_RELEASE_V3_CONTROL_CORE_PREDECESSOR_ARTIFACT_SHA256
),
},
"edgeChannelPredecessor": {
"patchId": (
DEVICE_PLANE_MANAGER_RELEASE_V3_EDGE_CHANNEL_PREDECESSOR_PATCH_ID
),
"artifactSha256": (
DEVICE_PLANE_MANAGER_RELEASE_V3_EDGE_CHANNEL_PREDECESSOR_ARTIFACT_SHA256
),
},
"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",
"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"
),
"gelios": "untouched-legacy-only",
"rollback": "restore-preapply-snapshot",
}
def expected_device_plane_manager_release_boundaries():
# Compatibility name for the current release builder/tests. Immutable v1
# predecessors always use expected_device_plane_manager_release_v1_boundaries.
@@ -9823,10 +9920,12 @@ def expected_device_plane_edge_core_channel_upgrade_v4_descriptor(
def expected_device_plane_control_core_release_descriptor(
release_id,
predecessor,
*,
schema_version="v1",
):
return {
descriptor = {
"schemaVersion": (
"nodedc.device-plane.device-control-core-release.v1"
f"nodedc.device-plane.device-control-core-release.{schema_version}"
),
"releaseId": release_id,
"action": "upgrade",
@@ -9847,8 +9946,16 @@ def expected_device_plane_control_core_release_descriptor(
],
"publicIngress": "none-on-synology",
"edgeRegistrations": "preserved",
"commandTransport": "disabled",
"gelios": "untouched",
"commandTransport": (
"typed-service-ping-v1"
if schema_version == "v2"
else "disabled"
),
"gelios": (
"untouched-legacy-only"
if schema_version == "v2"
else "untouched"
),
"preservedServices": [
"device-manager",
"device-gateway",
@@ -9861,6 +9968,15 @@ def expected_device_plane_control_core_release_descriptor(
),
"rollback": "restore-preapply-source-and-core-runtime",
}
if schema_version == "v2":
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"
)
return descriptor
def expected_device_plane_manager_failed_control_plane_descriptor():
@@ -10145,6 +10261,22 @@ def validate_device_plane_manager_release_v2_payload(
)
def validate_device_plane_manager_release_v3_payload(
payload_dir,
*,
expected_release_id=None,
):
return validate_device_plane_manager_release_payload_contract(
payload_dir,
descriptor_rel=DEVICE_PLANE_MANAGER_RELEASE_V3_REL,
schema_version="nodedc.device-plane.device-manager-release.v3",
boundaries=expected_device_plane_manager_release_v3_boundaries(),
compose_sha256=DEVICE_PLANE_MANAGER_RELEASE_V1_COMPOSE_SHA256,
edge_channel=False,
expected_release_id=expected_release_id,
)
def validate_device_plane_manager_release_payload(
payload_dir,
*,
@@ -10152,9 +10284,18 @@ def validate_device_plane_manager_release_payload(
):
v1 = payload_dir / DEVICE_PLANE_MANAGER_CONTROL_PLANE_REL
v2 = payload_dir / DEVICE_PLANE_MANAGER_RELEASE_V2_REL
present = [path for path in (v1, v2) if path.exists() or path.is_symlink()]
v3 = payload_dir / DEVICE_PLANE_MANAGER_RELEASE_V3_REL
present = [
path for path in (v1, v2, v3)
if path.exists() or path.is_symlink()
]
if len(present) != 1:
die("Device Manager release descriptor cardinality mismatch")
if present[0] == v3:
return validate_device_plane_manager_release_v3_payload(
payload_dir,
expected_release_id=expected_release_id,
)
if present[0] == v2:
return validate_device_plane_manager_release_v2_payload(
payload_dir,
@@ -10285,8 +10426,14 @@ def validate_device_plane_control_core_release_payload(
*,
expected_release_id=None,
):
v1 = payload_dir / DEVICE_PLANE_CONTROL_CORE_RELEASE_REL
v2 = payload_dir / DEVICE_PLANE_CONTROL_CORE_RELEASE_V2_REL
present = [path for path in (v1, v2) if path.exists() or path.is_symlink()]
if len(present) != 1:
die("Device Control Core release descriptor cardinality mismatch")
schema_version = "v2" if present[0] == v2 else "v1"
descriptor = read_strict_json(
payload_dir / DEVICE_PLANE_CONTROL_CORE_RELEASE_REL,
present[0],
"Device Control Core release descriptor",
max_bytes=16 * 1024,
)
@@ -10326,7 +10473,7 @@ def validate_device_plane_control_core_release_payload(
if (
not isinstance(release_id, str)
or not re.fullmatch(
r"device-control-core-release-[A-Za-z0-9._-]{1,67}",
r"device-control-core-release(?:-v2)?-[A-Za-z0-9._-]{1,67}",
release_id,
)
or (
@@ -10338,6 +10485,7 @@ def validate_device_plane_control_core_release_payload(
!= expected_device_plane_control_core_release_descriptor(
release_id,
predecessor,
schema_version=schema_version,
)
):
die("Device Control Core release descriptor mismatch")
@@ -10419,6 +10567,7 @@ def installed_device_plane_manager_compose_sha256():
root = DEVICE_PLANE_ROOT
v1 = root / DEVICE_PLANE_MANAGER_CONTROL_PLANE_REL
v2 = root / DEVICE_PLANE_MANAGER_RELEASE_V2_REL
v3 = root / DEVICE_PLANE_MANAGER_RELEASE_V3_REL
# A successful v2 overlay intentionally leaves the immutable v1 release
# descriptor as predecessor evidence. Prefer the highest installed
@@ -10426,6 +10575,19 @@ def installed_device_plane_manager_compose_sha256():
# the generation-specific Compose digest. During a failed v2 apply,
# rollback removes the candidate-only v2 descriptor before rebuilding the
# restored v1 runtime, so the same lookup follows the restored source.
if v3.exists() or v3.is_symlink():
descriptor = read_strict_json(
v3,
"installed Device Manager release v3 descriptor",
max_bytes=16 * 1024,
)
validate_device_plane_manager_release_descriptor(
descriptor,
schema_version="nodedc.device-plane.device-manager-release.v3",
boundaries=expected_device_plane_manager_release_v3_boundaries(),
)
return DEVICE_PLANE_MANAGER_RELEASE_V1_COMPOSE_SHA256
if v2.exists() or v2.is_symlink():
descriptor = read_strict_json(
v2,
@@ -11926,6 +12088,152 @@ def validate_device_plane_manager_reconciliation_evidence(payload_dir):
}
def validate_device_plane_manager_v3_active_baseline(descriptor):
if descriptor.get("schemaVersion") != (
"nodedc.device-plane.device-manager-release.v3"
):
return None
def successful_applied_artifact(reference, label):
patch_id = reference["patchId"]
artifact_sha256 = reference["artifactSha256"]
artifact_name = f"nodedc-device-plane-{patch_id}.tgz"
artifact = APPLIED_DIR / artifact_name
if (
not artifact.is_file()
or artifact.is_symlink()
or sha256_file(artifact) != artifact_sha256
):
die(f"Device Manager v3 {label} applied artifact mismatch")
records = [
row for row in load_state(STATE_FILE)
if row.get("id") == patch_id
and row.get("sha256") == artifact_sha256
]
if (
len(records) != 1
or records[0].get("status") != "ok"
or records[0].get("component") != "device-plane"
or records[0].get("artifact") != artifact_name
):
die(f"Device Manager v3 {label} applied journal mismatch")
backup_id = records[0].get("backup_id")
backup = BACKUPS_DIR / backup_id if isinstance(backup_id, str) else None
if (
backup is None
or safe_name(backup_id) != backup_id
or not backup.is_dir()
or backup.is_symlink()
):
die(f"Device Manager v3 {label} backup is unsafe")
return artifact
core_reference = descriptor["controlCorePredecessor"]
edge_reference = descriptor["edgeChannelPredecessor"]
core_artifact = successful_applied_artifact(
core_reference,
"Device Control Core predecessor",
)
edge_artifact = successful_applied_artifact(
edge_reference,
"Device Edge channel predecessor",
)
with tempfile.TemporaryDirectory(
prefix="device-manager-v3-core-baseline-",
dir=TMP_DIR,
) as directory:
core_manifest, core_entries, core_payload = load_artifact(
core_artifact,
Path(directory),
)
if (
core_manifest.get("id") != core_reference["patchId"]
or core_manifest.get("component") != "device-plane"
or core_manifest.get("type") != "app-overlay"
or tuple(core_entries) != DEVICE_PLANE_CONTROL_CORE_RELEASE_V2_ENTRIES
):
die("Device Manager v3 Device Control Core predecessor type mismatch")
expected_core_descriptor = (
validate_device_plane_control_core_release_payload(
core_payload,
expected_release_id=core_reference["patchId"],
)
)
installed_core_descriptor = read_strict_json(
DEVICE_PLANE_ROOT / DEVICE_PLANE_CONTROL_CORE_RELEASE_V2_REL,
"installed Device Manager v3 Device Control Core predecessor",
max_bytes=16 * 1024,
)
if installed_core_descriptor != expected_core_descriptor:
die("Device Manager v3 Device Control Core predecessor is not current")
expected_core_source = collect_exact_files(
core_payload,
DEVICE_PLANE_CONTROL_CORE_RELEASE_V2_ENTRIES,
"Device Manager v3 Device Control Core predecessor source",
)
actual_core_source = collect_exact_files(
DEVICE_PLANE_ROOT,
DEVICE_PLANE_CONTROL_CORE_RELEASE_V2_ENTRIES,
"installed Device Manager v3 Device Control Core predecessor source",
)
if actual_core_source != expected_core_source:
die("installed Device Manager v3 Device Control Core source drift detected")
with tempfile.TemporaryDirectory(
prefix="device-manager-v3-edge-baseline-",
dir=TMP_DIR,
) as directory:
edge_manifest, edge_entries, edge_payload = load_artifact(
edge_artifact,
Path(directory),
)
if (
edge_manifest.get("id") != edge_reference["patchId"]
or edge_manifest.get("component") != "device-plane"
or edge_manifest.get("type") != "app-overlay"
or tuple(edge_entries)
!= DEVICE_PLANE_EDGE_CORE_CHANNEL_UPGRADE_V4_ENTRIES
):
die("Device Manager v3 Device Edge channel predecessor type mismatch")
expected_edge_descriptor = (
validate_device_plane_edge_core_channel_upgrade_v4_payload(
edge_payload,
expected_transition_id=edge_reference["patchId"],
)
)
installed_edge_descriptor = read_strict_json(
DEVICE_PLANE_ROOT / DEVICE_PLANE_EDGE_CORE_CHANNEL_UPGRADE_V4_REL,
"installed Device Manager v3 Device Edge channel predecessor",
max_bytes=16 * 1024,
)
if installed_edge_descriptor != expected_edge_descriptor:
die("Device Manager v3 Device Edge channel predecessor is not current")
expected_base_compose_sha256 = sha256_file(
edge_payload / "docker-compose.device-plane.yml"
)
installed_base_compose = DEVICE_PLANE_ROOT / "docker-compose.device-plane.yml"
if (
installed_base_compose.is_symlink()
or not installed_base_compose.is_file()
or sha256_file(installed_base_compose) != expected_base_compose_sha256
):
die("installed Device Manager v3 Device Edge topology drift detected")
identity_state = inspect_device_edge_channel_core_identity_state()
if identity_state != "valid-reuse-at-apply":
die("Device Manager v3 requires the valid active Edge identity")
validate_device_manager_control_plane_runtime(
require_edge_channel=True,
core_network_mode="private-egress",
)
return {
"controlCoreArtifact": core_artifact,
"edgeChannelArtifact": edge_artifact,
"identityState": identity_state,
}
def validate_device_plane_manager_activation_predecessor(payload_dir):
descriptor = validate_device_plane_manager_release_payload(
payload_dir
@@ -12033,6 +12341,7 @@ def validate_device_plane_manager_activation_predecessor(payload_dir):
DEVICE_PLANE_MANAGER_CONTROL_PLANE_ENTRIES,
DEVICE_PLANE_MANAGER_RELEASE_V1_SUCCESSOR_ENTRIES,
DEVICE_PLANE_MANAGER_RELEASE_V2_ENTRIES,
DEVICE_PLANE_MANAGER_RELEASE_V3_ENTRIES,
)
):
die("Device Manager release predecessor type mismatch")
@@ -12042,11 +12351,14 @@ def validate_device_plane_manager_activation_predecessor(payload_dir):
expected_release_id=patch_id,
)
)
predecessor_descriptor_rel = (
DEVICE_PLANE_MANAGER_RELEASE_V2_REL
if tuple(predecessor_entries)
== DEVICE_PLANE_MANAGER_RELEASE_V2_ENTRIES
else DEVICE_PLANE_MANAGER_CONTROL_PLANE_REL
predecessor_descriptor_rel = {
DEVICE_PLANE_MANAGER_RELEASE_V2_ENTRIES:
DEVICE_PLANE_MANAGER_RELEASE_V2_REL,
DEVICE_PLANE_MANAGER_RELEASE_V3_ENTRIES:
DEVICE_PLANE_MANAGER_RELEASE_V3_REL,
}.get(
tuple(predecessor_entries),
DEVICE_PLANE_MANAGER_CONTROL_PLANE_REL,
)
installed_descriptor = read_strict_json(
root / predecessor_descriptor_rel,
@@ -12062,6 +12374,11 @@ def validate_device_plane_manager_activation_predecessor(payload_dir):
):
healthcheck_compose_service("device-plane", service)
runtime = {"accepted": True}
v3_baseline = validate_device_plane_manager_v3_active_baseline(
descriptor
)
if v3_baseline is not None:
runtime["v3Baseline"] = v3_baseline
mode = "active-manager-forward-upgrade"
return {
"mode": mode,
@@ -16086,6 +16403,9 @@ def component_services(component, entries=None):
if is_device_plane_control_core_release_slice(component, entries):
return ("device-control-core",)
if is_device_plane_manager_release_v3_slice(component, entries):
return ("device-manager",)
if is_device_plane_edge_core_channel_bootstrap_slice(component, entries):
return ("device-control-core",)
@@ -16683,6 +17003,18 @@ def component_builds(component, entries=None):
),
),)
if is_device_plane_manager_release_v3_slice(component, entries):
return ((
DEVICE_PLANE_ROOT / "services/device-manager",
(
"build",
"--no-cache",
"-t",
DEVICE_PLANE_MANAGER_IMAGE,
".",
),
),)
if is_device_plane_manager_control_plane_slice(component, entries):
return (
(
@@ -20427,7 +20759,15 @@ def plan_artifact(artifact):
print("device_control_core_discovery_ingest=enabled:authenticated")
else:
print("device_gateway_public_ingress=disabled")
print("device_gateway_command_transport=disabled")
if (
device_plane_manager_activation_preflight is not None
and device_plane_manager_activation_preflight["descriptor"].get(
"commandTransport"
) == "typed-service-ping-v1"
):
print("device_gateway_command_transport=typed-service-ping-v1")
else:
print("device_gateway_command_transport=disabled")
print("gelios=untouched")
if device_plane_foundation_recovery_preflight is not None:
print(
@@ -20589,15 +20929,36 @@ def plan_artifact(artifact):
)
print(
"device_plane_runtime_mutation="
"build+recreate:device-control-core,device-manager"
+ (
"build+recreate:device-manager"
if device_plane_manager_activation_preflight["descriptor"].get(
"schemaVersion"
) == "nodedc.device-plane.device-manager-release.v3"
else "build+recreate:device-control-core,device-manager"
)
)
print(
"device_plane_runtime_services="
"preserved:device-gateway,device-postgres,"
"device-backhaul-target"
+ (
"preserved:device-control-core,device-gateway,"
"device-postgres,device-backhaul-target"
if device_plane_manager_activation_preflight["descriptor"].get(
"schemaVersion"
) == "nodedc.device-plane.device-manager-release.v3"
else "preserved:device-gateway,device-postgres,"
"device-backhaul-target"
)
)
print("device_manager_health_gate=bounded-grace+contract")
print("device_manager_public_route=unchanged:absent")
if device_plane_manager_activation_preflight["descriptor"].get(
"commandTransport"
) == "typed-service-ping-v1":
print("device_manager_public_route=unchanged:active")
print("device_edge_channel_commands=typed-service-ping-v1")
print("device_command_credential=transient-core-memory-only")
print("gelios=untouched:legacy-only")
else:
print("device_manager_public_route=unchanged:absent")
print("device_gateway_tcp_9921=preserved:loopback-only")
print(
"device_plane_rollback="
@@ -20637,11 +20998,14 @@ def plan_artifact(artifact):
print("device_edge_channel=preserved:core-initiated:pinned-mtls:registered-edges-only")
print("device_edge_channel_networks=preserved:device-plane-private,device-plane-egress")
print("device_edge_channel_registrations=preserved")
print("device_edge_channel_commands=disabled")
print(
"device_edge_channel_commands="
f"{descriptor['commandTransport']}"
)
print("device_manager=preserved:active")
print("device_manager_public_route=unchanged:active")
print("device_gateway_tcp_9921=preserved:loopback-only")
print("gelios=untouched")
print(f"gelios={descriptor['gelios']}")
print("device_plane_rollback=source+preapply-core-runtime")
if device_plane_edge_core_channel_preflight is not None:
print(
@@ -22571,7 +22935,12 @@ def component_healthchecks(component, entries=None, services=None):
},
},)
if is_device_plane_manager_control_plane_slice(component, entries):
return ({
command_transport = (
"typed-service-ping-v1"
if is_device_plane_manager_release_v3_slice(component, entries)
else "disabled"
)
checks = ({
"url": "http://127.0.0.1:18120/healthz",
"expected_json": {
"ok": True,
@@ -22579,9 +22948,21 @@ def component_healthchecks(component, entries=None, services=None):
"database": "ready",
"discoveryIngest": "enabled",
"managementApi": "enabled",
"commandTransport": "disabled",
"commandTransport": command_transport,
},
},)
if is_device_plane_manager_release_v3_slice(component, entries):
checks += ({
"url": "http://127.0.0.1:18080/healthz",
"headers": {"Host": "device.nodedc.ru"},
"expected_json": {
"ok": True,
"service": "nodedc-device-manager",
"authRequired": True,
"deviceCoreConfigured": True,
},
},)
return checks
if (
is_device_plane_control_core_release_slice(component, entries)
or is_device_plane_edge_core_channel_bootstrap_slice(
@@ -22597,7 +22978,14 @@ def component_healthchecks(component, entries=None, services=None):
"database": "ready",
"discoveryIngest": "enabled",
"managementApi": "enabled",
"commandTransport": "disabled",
"commandTransport": (
"typed-service-ping-v1"
if is_device_plane_control_core_release_v2_slice(
component,
entries,
)
else "disabled"
),
},
},)
if is_device_plane_b2_discovery_rollback_recovery_slice(
@@ -23319,10 +23707,12 @@ def run_healthchecks(component, entries=None, services=None):
assert_loopback_tcp_port_open(9921)
return
if is_device_plane_manager_control_plane_slice(component, entries):
if tuple(services or ()) != (
"device-control-core",
"device-manager",
):
expected_services = (
("device-manager",)
if is_device_plane_manager_release_v3_slice(component, entries)
else ("device-control-core", "device-manager")
)
if tuple(services or ()) != expected_services:
die("Device Manager control-plane service set mismatch")
for service in services:
healthcheck_compose_service_with_grace(