feat(lab): bind sealed component adapter images

This commit is contained in:
DCCONSTRUCTIONS
2026-08-31 19:19:47 +03:00
parent 35d99e40d5
commit 19c0bd70d0
4 changed files with 210 additions and 64 deletions
@@ -1,5 +1,6 @@
from __future__ import annotations
import hashlib
import json
from dataclasses import dataclass
from pathlib import Path
@@ -21,6 +22,7 @@ EOMT_IMAGE_SHA256 = "58df7489c3f2276f9591d500a012dee03e23d35543ce3c390b4c001e6bf
DDRNET_IMAGE_SHA256 = "591cb382c099eeb05e7ec16e2371e0b2da54d2bb5c49ec0f4ac88dbf72b0f0cd"
DEFINITION_SHA256 = "a" * 64
RELEASE_SHA256 = "b" * 64
REPOSITORY_ROOT = Path(__file__).resolve().parents[1]
@dataclass(frozen=True)
@@ -42,19 +44,21 @@ class _Plan:
def _assets(
component: local_runners.PortableLabV1Component,
) -> tuple[local_runners.PortableLabV1HostAsset, ...]:
identities = local_runners._EXPECTED_ASSET_IDENTITIES[component]
tree_assets = {"eomt-dependency-set", "k1-valid-fov-identity"}
targets = local_runners._EXPECTED_ASSET_TARGETS[component]
return tuple(
local_runners.PortableLabV1HostAsset(
asset_id=asset_id,
host_path=f"D:\\NDC_MISSIONCORE\\assets\\{asset_id}",
container_path=f"/opt/nodedc/assets/{asset_id}",
kind="tree" if asset_id in tree_assets else "file",
verification=("identity-sha256" if asset_id in tree_assets else "sha256"),
identity_sha256=identity,
byte_length=local_runners._EXPECTED_ASSET_LENGTHS.get(asset_id),
container_path=container_path,
kind="tree" if component == "eomt" else "file",
verification=("identity-sha256" if component == "eomt" else "sha256"),
identity_sha256=local_runners._EXPECTED_FIXED_ASSET_IDENTITIES.get(
asset_id,
hashlib.sha256(asset_id.encode()).hexdigest(),
),
byte_length=local_runners._EXPECTED_ASSET_LENGTHS.get(asset_id, 1_024),
)
for asset_id, identity in sorted(identities.items())
for asset_id, container_path in sorted(targets.items())
)
@@ -64,8 +68,8 @@ def _component(
return local_runners.PortableLabV1ComponentInstallation.seal(
component=component,
image_sha256=(EOMT_IMAGE_SHA256 if component == "eomt" else DDRNET_IMAGE_SHA256),
entrypoint=("/opt/nodedc/bin/portable-lab-v1-agent",),
command=(f"run-{component}",),
entrypoint=local_runners._EXPECTED_ENTRYPOINTS[component],
command=local_runners._EXPECTED_COMMANDS[component],
assets=_assets(component),
timeout_seconds=3600.0,
memory_bytes=16 * 1024**3,
@@ -148,8 +152,12 @@ def _docker_launch(tmp_path: Path) -> local_runners.PortableLabV1DockerLaunch:
return local_runners.PortableLabV1DockerLaunch(
component="eomt",
image_sha256=EOMT_IMAGE_SHA256,
entrypoint=("/opt/nodedc/bin/portable-lab-v1-agent",),
command=("run-eomt", "--request", "/run/nodedc/request.json"),
entrypoint=local_runners._EXPECTED_ENTRYPOINTS["eomt"],
command=(
"/opt/nodedc/adapter/run_portable_lab_v1_eomt_component.py",
"--request",
"/run/nodedc/request.json",
),
mounts=(
local_runners.PortableLabV1DockerMount(
host_path="D:\\NDC_MISSIONCORE\\runtime\\output",
@@ -522,10 +530,37 @@ def test_component_installation_rejects_wrong_worker006_asset_identity() -> None
local_runners.PortableLabV1ComponentInstallation.seal(
component="ddrnet",
image_sha256=DDRNET_IMAGE_SHA256,
entrypoint=("/opt/nodedc/bin/portable-lab-v1-agent",),
command=("run-ddrnet",),
entrypoint=local_runners._EXPECTED_ENTRYPOINTS["ddrnet"],
command=local_runners._EXPECTED_COMMANDS["ddrnet"],
assets=tuple(assets),
timeout_seconds=3600.0,
memory_bytes=16 * 1024**3,
nano_cpus=4_000_000_000,
)
def test_component_adapter_images_are_thin_offline_wrappers() -> None:
eomt = (
REPOSITORY_ROOT
/ "experiments/perception/worker/observatory_portable/"
"Dockerfile.lab-v1-eomt-adapter"
).read_text(encoding="utf-8")
ddrnet = (
REPOSITORY_ROOT
/ "experiments/perception/worker/observatory_portable/"
"Dockerfile.lab-v1-ddrnet-adapter"
).read_text(encoding="utf-8")
assert "FROM nvcr.io/nvidia/tritonserver:26.06-py3@sha256:" in eomt
assert "FROM ndc/mission-core-lab-v1-goose:sg3.2.0-cu117-v1" in ddrnet
assert "COPY portable_lab_v1_component_adapter.py" in eomt
assert "COPY portable_lab_v1_component_adapter.py" in ddrnet
assert 'ENTRYPOINT ["python3"]' in eomt
assert 'ENTRYPOINT ["conda", "run", "--no-capture-output"' in ddrnet
for dockerfile in (eomt, ddrnet):
assert "apt-get" not in dockerfile
assert "pip install" not in dockerfile
assert "curl " not in dockerfile
assert "wget " not in dockerfile
assert "NODEDC_SHARED_ADAPTER_SHA256" in dockerfile
assert "NODEDC_COMPONENT_ADAPTER_SHA256" in dockerfile