refactor(worker): externalize runtime registries
This commit is contained in:
@@ -5,8 +5,6 @@ import re
|
||||
from pathlib import Path
|
||||
from typing import cast
|
||||
|
||||
from k1link.observatory import portable_lab_v1_local_runners as local_runners
|
||||
|
||||
REPOSITORY_ROOT = Path(__file__).resolve().parents[1]
|
||||
ARTIFACT_ROOT = (
|
||||
REPOSITORY_ROOT / "experiments" / "perception" / "worker" / "observatory_portable"
|
||||
@@ -23,6 +21,14 @@ AUTHORITY = {
|
||||
"navigation_or_safety_accepted": False,
|
||||
"production_accepted": False,
|
||||
}
|
||||
DOCKER_SOCKET = "/var/run/docker.sock"
|
||||
DEFINITIONS_CONTAINER_PATH = (
|
||||
"/run/nodedc/registries/observatory-portable-run-definitions.json"
|
||||
)
|
||||
RUNTIME_REGISTRY_CONTAINER_PATH = (
|
||||
"/run/nodedc/registries/observatory-worker-runtime-candidates.json"
|
||||
)
|
||||
LAB_V1_RECEIPT_CONTAINER_PATH = "/release/lab-v1-worker-installation-receipt.json"
|
||||
|
||||
|
||||
def _document(path: Path) -> dict[str, object]:
|
||||
@@ -45,8 +51,11 @@ def test_agent_dockerfile_is_offline_commit_bound_and_model_free() -> None:
|
||||
assert 'ENTRYPOINT ["python3", "-m", "k1link.observatory.m49_worker_container_main"]' in payload
|
||||
assert "CMD []" in payload
|
||||
assert "COPY src/k1link ./src/k1link" in payload
|
||||
assert "COPY config ./config" in payload
|
||||
assert "COPY config" not in payload
|
||||
assert "COPY . ." not in payload
|
||||
assert "mkdir -p /run/nodedc/registries" in payload
|
||||
assert "chmod 0555 /run/nodedc /run/nodedc/registries" in payload
|
||||
assert 'com.nodedc.runtime-registries="external-read-only"' in payload
|
||||
assert re.search(r"(?im)^\s*(?:run\s+)?(?:apt|apk|yum|dnf|pip|uv)\b", payload) is None
|
||||
assert "curl " not in payload.lower()
|
||||
assert "wget " not in payload.lower()
|
||||
@@ -85,7 +94,6 @@ def test_build_context_is_only_repo_source_configuration_and_artifact_contract()
|
||||
paths = [cast(str, row["path"]) for row in entries]
|
||||
assert paths == [
|
||||
"src/k1link",
|
||||
"config",
|
||||
"experiments/perception/worker/observatory_portable/Dockerfile.worker-006-agent",
|
||||
"experiments/perception/worker/observatory_portable/worker-006-agent-build-context.json",
|
||||
]
|
||||
@@ -97,19 +105,41 @@ def test_build_context_is_only_repo_source_configuration_and_artifact_contract()
|
||||
for token in ("model", "weight", "session", "credential", "runtime")
|
||||
)
|
||||
|
||||
required = cast(list[str], document["required_configuration"])
|
||||
assert required == [
|
||||
"config/observatory-portable-run-definitions.json",
|
||||
"config/observatory-worker-runtime-candidates.json",
|
||||
"config/perception/m49-tgs-portable-v2.json",
|
||||
"config/perception/lab-v1-eomt-ddrnet-portable-v2.json",
|
||||
assert document["embedded_configuration"] == []
|
||||
assert "required_configuration" not in document
|
||||
external_runtime_files = cast(
|
||||
list[dict[str, object]], document["external_runtime_files"]
|
||||
)
|
||||
assert external_runtime_files == [
|
||||
{
|
||||
"role": "portable-run-definition-registry",
|
||||
"environment_variable": "MISSIONCORE_OBSERVATORY_WORKER_DEFINITIONS_FILE",
|
||||
"container_path": DEFINITIONS_CONTAINER_PATH,
|
||||
"binding": "exact-read-only-regular-file",
|
||||
"identity_owner": "post-image runtime installation",
|
||||
"baked_into_image": False,
|
||||
},
|
||||
{
|
||||
"role": "portable-worker-runtime-registry",
|
||||
"environment_variable": (
|
||||
"MISSIONCORE_OBSERVATORY_WORKER_RUNTIME_REGISTRY_FILE"
|
||||
),
|
||||
"container_path": RUNTIME_REGISTRY_CONTAINER_PATH,
|
||||
"binding": "exact-read-only-regular-file",
|
||||
"identity_owner": "post-image runtime installation",
|
||||
"baked_into_image": False,
|
||||
},
|
||||
]
|
||||
assert all((REPOSITORY_ROOT / relative).is_file() for relative in required)
|
||||
runtime = cast(dict[str, object], document["runtime"])
|
||||
assert runtime["entrypoint"] == ENTRYPOINT
|
||||
assert runtime["composition_module"] == "k1link.observatory.m49_worker_service"
|
||||
assert runtime["configuration_baked_into_image"] is False
|
||||
assert runtime["runtime_registries_baked_into_image"] is False
|
||||
assert runtime["models_baked_into_image"] is False
|
||||
assert runtime["executor_releases_baked_into_image"] is False
|
||||
forbidden = cast(list[str], document["forbidden_context"])
|
||||
assert "run-definition registries" in forbidden
|
||||
assert "runtime-candidate registries" in forbidden
|
||||
|
||||
|
||||
def test_install_plan_requires_offline_build_hardening_smoke_and_unfilled_receipt() -> None:
|
||||
@@ -162,6 +192,7 @@ def test_install_plan_requires_offline_build_hardening_smoke_and_unfilled_receip
|
||||
assert labels["org.opencontainers.image.revision"] == "<source-revision>"
|
||||
assert labels["com.nodedc.base-image.sha256"] == BASE_SHA256
|
||||
assert labels["com.nodedc.models"] == "external"
|
||||
assert labels["com.nodedc.runtime-registries"] == "external-read-only"
|
||||
smoke = cast(dict[str, object], acceptance["smoke"])
|
||||
assert smoke["network"] == "none"
|
||||
assert smoke["read_only_rootfs"] is True
|
||||
@@ -174,16 +205,40 @@ def test_install_plan_requires_offline_build_hardening_smoke_and_unfilled_receip
|
||||
"MISSIONCORE_OBSERVATORY_WORKER_BASE_URL": "http://127.0.0.1:18080",
|
||||
"MISSIONCORE_OBSERVATORY_WORKER_TOKEN_FILE": "/run/secrets/observatory-worker.token",
|
||||
"MISSIONCORE_OBSERVATORY_WORKER_WORK_ROOT": "/work",
|
||||
"MISSIONCORE_OBSERVATORY_WORKER_DEFINITIONS_FILE": (
|
||||
"/opt/nodedc/mission-core/config/observatory-portable-run-definitions.json"
|
||||
),
|
||||
"MISSIONCORE_OBSERVATORY_WORKER_DEFINITIONS_FILE": DEFINITIONS_CONTAINER_PATH,
|
||||
"MISSIONCORE_OBSERVATORY_WORKER_RUNTIME_REGISTRY_FILE": (
|
||||
"/opt/nodedc/mission-core/config/observatory-worker-runtime-candidates.json"
|
||||
RUNTIME_REGISTRY_CONTAINER_PATH
|
||||
),
|
||||
"MISSIONCORE_OBSERVATORY_M49_INSTALLATION_RECEIPT_FILE": (
|
||||
"/release/worker-installation-receipt.json"
|
||||
),
|
||||
"MISSIONCORE_OBSERVATORY_LAB_V1_INSTALLATION_RECEIPT_FILE": (
|
||||
LAB_V1_RECEIPT_CONTAINER_PATH
|
||||
),
|
||||
}
|
||||
registry_files = cast(dict[str, object], runtime["runtime_registry_files"])
|
||||
assert registry_files["binding"] == "individual read-only bind files"
|
||||
assert registry_files["identity_timing"] == (
|
||||
"filled and verified after coordinator image build"
|
||||
)
|
||||
assert registry_files["included_in_coordinator_image_or_image_receipt"] is False
|
||||
registry_rows = cast(list[dict[str, object]], registry_files["required"])
|
||||
assert [row["container_path"] for row in registry_rows] == [
|
||||
DEFINITIONS_CONTAINER_PATH,
|
||||
RUNTIME_REGISTRY_CONTAINER_PATH,
|
||||
]
|
||||
assert all(
|
||||
row["host_path"] is None
|
||||
and row["byte_length"] is None
|
||||
and row["sha256"] is None
|
||||
and row["mode"] == "read-only"
|
||||
for row in registry_rows
|
||||
)
|
||||
registry_preflight = cast(list[str], registry_files["required_preflight"])
|
||||
assert any("after the coordinator image identity exists" in row for row in registry_preflight)
|
||||
assert any("symbolic-link" in row for row in registry_preflight)
|
||||
assert any("read-only file" in row for row in registry_preflight)
|
||||
assert any("inside the coordinator image" in row for row in registry_preflight)
|
||||
user = cast(dict[str, object], runtime["user"])
|
||||
assert (user["uid"], user["gid"]) == (0, 0)
|
||||
assert cast(str, user["reason"]).strip()
|
||||
@@ -205,8 +260,8 @@ def test_install_plan_requires_offline_build_hardening_smoke_and_unfilled_receip
|
||||
socket_mount = cast(dict[str, object], docker_control["socket_mount"])
|
||||
assert socket_mount == {
|
||||
"type": "bind",
|
||||
"host_path": str(local_runners._DOCKER_SOCKET),
|
||||
"container_path": str(local_runners._DOCKER_SOCKET),
|
||||
"host_path": DOCKER_SOCKET,
|
||||
"container_path": DOCKER_SOCKET,
|
||||
"mode": "read-write",
|
||||
"exception_to_read_only_mount_policy": True,
|
||||
}
|
||||
@@ -219,11 +274,18 @@ def test_install_plan_requires_offline_build_hardening_smoke_and_unfilled_receip
|
||||
"force-delete exact created container ID",
|
||||
]
|
||||
fences = cast(dict[str, object], docker_control["sibling_runtime_fences"])
|
||||
assert fences["exact_image_sha256s"] == {
|
||||
"eomt": local_runners._EOMT_IMAGE_SHA256,
|
||||
"ddrnet": local_runners._DDRNET_IMAGE_SHA256,
|
||||
assert "exact_image_sha256s" not in fences
|
||||
assert fences["component_image_identity"] == {
|
||||
"source": LAB_V1_RECEIPT_CONTAINER_PATH,
|
||||
"schema_version": (
|
||||
"missioncore.observatory-portable-lab-v1-worker-installation-ready-"
|
||||
"receipt/v1"
|
||||
),
|
||||
"fields": "component_installations.<eomt-or-ddrnet>.image_sha256",
|
||||
"image_kind": "derived adapter image",
|
||||
"base_image_ids_are_component_ids": False,
|
||||
"queued_job_override_allowed": False,
|
||||
}
|
||||
assert local_runners._EOMT_IMAGE_SHA256 == BASE_SHA256
|
||||
assert "queued job" in cast(str, fences["commands_and_entrypoints"])
|
||||
assert "exact Worker-host asset roots" in cast(str, fences["bind_sources"])
|
||||
assert fences["network"] == "none"
|
||||
@@ -254,15 +316,32 @@ def test_install_plan_requires_offline_build_hardening_smoke_and_unfilled_receip
|
||||
external = cast(dict[str, object], runtime["external_assets"])
|
||||
assert external["baked_into_agent_image"] is False
|
||||
assert external["queued_jobs_may_select_paths_or_commands"] is False
|
||||
mounts = cast(list[dict[str, object]], runtime["mounts"])
|
||||
registry_mounts = [
|
||||
row
|
||||
for row in mounts
|
||||
if cast(str, row["container_path"]).startswith("/run/nodedc/registries/")
|
||||
]
|
||||
assert registry_mounts == [
|
||||
{
|
||||
"container_path": DEFINITIONS_CONTAINER_PATH,
|
||||
"mode": "read-only",
|
||||
"purpose": "exact external portable RunDefinition registry file",
|
||||
},
|
||||
{
|
||||
"container_path": RUNTIME_REGISTRY_CONTAINER_PATH,
|
||||
"mode": "read-only",
|
||||
"purpose": "exact external portable runtime candidate registry file",
|
||||
},
|
||||
]
|
||||
lab_v1_input = cast(dict[str, object], runtime["lab_v1_runner_installation_input"])
|
||||
assert lab_v1_input == {
|
||||
"state": "loader-contract-not-yet-defined",
|
||||
"environment_variable": None,
|
||||
"container_path": None,
|
||||
"reason": (
|
||||
"the current local runner module defines an in-memory sealed installation "
|
||||
"receipt but no environment loader or installed receipt path"
|
||||
),
|
||||
"state": "external-installed-receipt-required",
|
||||
"environment_variable": "MISSIONCORE_OBSERVATORY_LAB_V1_INSTALLATION_RECEIPT_FILE",
|
||||
"container_path": LAB_V1_RECEIPT_CONTAINER_PATH,
|
||||
"mode": "read-only",
|
||||
"owns_component_image_identities": True,
|
||||
"queued_jobs_may_override_component_images": False,
|
||||
}
|
||||
|
||||
receipt = cast(dict[str, object], document["receipt_skeleton"])
|
||||
@@ -274,4 +353,5 @@ def test_install_plan_requires_offline_build_hardening_smoke_and_unfilled_receip
|
||||
image = cast(dict[str, object], receipt["image"])
|
||||
assert image == {"tag": None, "id": None, "size_bytes": None}
|
||||
assert receipt["models_baked_into_image"] is False
|
||||
assert receipt["runtime_registries_baked_into_image"] is False
|
||||
assert receipt["authority"] == AUTHORITY
|
||||
|
||||
Reference in New Issue
Block a user