fix(worker): bind claim migration to the imported transport module
This commit is contained in:
@@ -29,8 +29,8 @@ TARGETS = {
|
|||||||
"ndc-observatory-installed-lab-worker-agent": INSTALLED_PARENT_SHA,
|
"ndc-observatory-installed-lab-worker-agent": INSTALLED_PARENT_SHA,
|
||||||
"ndc-observatory-m49-worker-agent": M49_PARENT_SHA,
|
"ndc-observatory-m49-worker-agent": M49_PARENT_SHA,
|
||||||
}
|
}
|
||||||
SOURCE = "/opt/nodedc/mission-core/src/k1link/observatory/worker_http_transport.py"
|
SOURCE = "/opt/nodedc/installed-lab/src/k1link/observatory/worker_http_transport.py"
|
||||||
BEFORE_SHA = "fb67ae174c8da66f7d04022310be663b2735fff72966883aaa5b50fdbc3e89c7"
|
BEFORE_SHA = "c3d82ffd482a29b17c68d1fb5603e82924766abc0080137d3a0a6130f92ccdce"
|
||||||
OLD = b"missioncore.observatory-worker-claim-request/v2"
|
OLD = b"missioncore.observatory-worker-claim-request/v2"
|
||||||
NEW = b"missioncore.observatory-worker-claim-request/v3"
|
NEW = b"missioncore.observatory-worker-claim-request/v3"
|
||||||
PARENT_LABEL = "com.nodedc.claim-transport-parent.sha256"
|
PARENT_LABEL = "com.nodedc.claim-transport-parent.sha256"
|
||||||
@@ -115,6 +115,12 @@ with httpx.Client(base_url=os.environ["MISSIONCORE_OBSERVATORY_WORKER_BASE_URL"]
|
|||||||
print(json.dumps(response.json()))
|
print(json.dumps(response.json()))
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
IMPORTED_SOURCE = """import hashlib, json, pathlib
|
||||||
|
from k1link.observatory import worker_http_transport as transport
|
||||||
|
path = pathlib.Path(transport.__file__).resolve()
|
||||||
|
print(json.dumps({"path": str(path), "sha256": hashlib.sha256(path.read_bytes()).hexdigest()}))
|
||||||
|
"""
|
||||||
|
|
||||||
PROBE = """import json, os, pathlib, uuid
|
PROBE = """import json, os, pathlib, uuid
|
||||||
from k1link.observatory.worker_http_transport import ObservatoryWorkerHttpGateway
|
from k1link.observatory.worker_http_transport import ObservatoryWorkerHttpGateway
|
||||||
with ObservatoryWorkerHttpGateway(
|
with ObservatoryWorkerHttpGateway(
|
||||||
@@ -169,6 +175,9 @@ def plan(engine: Engine) -> dict:
|
|||||||
for name, parent in TARGETS.items():
|
for name, parent in TARGETS.items():
|
||||||
inspection = engine.inspect(name)
|
inspection = engine.inspect(name)
|
||||||
validate_target(name, inspection)
|
validate_target(name, inspection)
|
||||||
|
imported = engine.execute_json(name, IMPORTED_SOURCE)
|
||||||
|
if imported != {"path": SOURCE, "sha256": BEFORE_SHA}:
|
||||||
|
raise ValueError("loaded transport differs from the reviewed immutable source")
|
||||||
readiness = engine.execute_json(name, READINESS)
|
readiness = engine.execute_json(name, READINESS)
|
||||||
require_idle(readiness)
|
require_idle(readiness)
|
||||||
targets.append(
|
targets.append(
|
||||||
@@ -176,6 +185,7 @@ def plan(engine: Engine) -> dict:
|
|||||||
"name": name,
|
"name": name,
|
||||||
"container_id": inspection["Id"],
|
"container_id": inspection["Id"],
|
||||||
"parent_image_sha256": parent,
|
"parent_image_sha256": parent,
|
||||||
|
"imported_source": imported,
|
||||||
"create_body_sha256": sha(
|
"create_body_sha256": sha(
|
||||||
canonical(
|
canonical(
|
||||||
{
|
{
|
||||||
@@ -348,6 +358,10 @@ def apply(engine: Engine, expected_plan_sha: str, evidence: Path) -> dict:
|
|||||||
after = engine.inspect(name)
|
after = engine.inspect(name)
|
||||||
if not after["State"]["Running"] or after["RestartCount"] != 0:
|
if not after["State"]["Running"] or after["RestartCount"] != 0:
|
||||||
raise RuntimeError("replacement agent needs reconciliation; predecessor retained")
|
raise RuntimeError("replacement agent needs reconciliation; predecessor retained")
|
||||||
|
if engine.execute_json(name, IMPORTED_SOURCE) != {
|
||||||
|
"path": SOURCE, "sha256": image["source_sha256"],
|
||||||
|
}:
|
||||||
|
raise RuntimeError("replacement agent did not load the pinned transport module")
|
||||||
before_probe = engine.execute_json(name, READINESS)
|
before_probe = engine.execute_json(name, READINESS)
|
||||||
require_idle(before_probe)
|
require_idle(before_probe)
|
||||||
probe = engine.execute_json(name, PROBE)
|
probe = engine.execute_json(name, PROBE)
|
||||||
|
|||||||
@@ -81,6 +81,8 @@ def test_evidence_is_immutable_and_control_probe_cannot_claim_models(tmp_path: P
|
|||||||
assert "range(8)" in migration.PROBE
|
assert "range(8)" in migration.PROBE
|
||||||
compile(migration.PROBE, "control-probe", "exec")
|
compile(migration.PROBE, "control-probe", "exec")
|
||||||
compile(migration.READINESS, "readiness", "exec")
|
compile(migration.READINESS, "readiness", "exec")
|
||||||
|
compile(migration.IMPORTED_SOURCE, "imported-source", "exec")
|
||||||
|
assert "transport.__file__" in migration.IMPORTED_SOURCE
|
||||||
|
|
||||||
|
|
||||||
def test_transport_clone_retains_executor_configuration_and_rollback_snapshot() -> None:
|
def test_transport_clone_retains_executor_configuration_and_rollback_snapshot() -> None:
|
||||||
|
|||||||
Reference in New Issue
Block a user