fix(simulation): inspect namespace through netlink

This commit is contained in:
DCCONSTRUCTIONS 2026-07-24 18:29:52 +03:00
parent 01ec12263a
commit b4e3b3b735
1 changed files with 29 additions and 8 deletions

View File

@ -5,6 +5,7 @@ import hashlib
import os import os
import re import re
import shutil import shutil
import socket
import sys import sys
import time import time
from datetime import UTC, datetime from datetime import UTC, datetime
@ -79,18 +80,38 @@ def main() -> int:
parser.error(f"the lifecycle harness requires WSL distribution {EXPECTED_DISTRO}") parser.error(f"the lifecycle harness requires WSL distribution {EXPECTED_DISTRO}")
paths = StockRoverTargetPaths.from_d_root(args.d_root) paths = StockRoverTargetPaths.from_d_root(args.d_root)
evidence_root = paths.d_root / "artifacts/s1/lifecycle" / args.run_id
evidence_root.mkdir(mode=0o700, parents=True, exist_ok=False)
lifecycle_profile_path = args.lifecycle_profile.expanduser().resolve() lifecycle_profile_path = args.lifecycle_profile.expanduser().resolve()
s0_profile_path = args.s0_profile.expanduser().resolve() s0_profile_path = args.s0_profile.expanduser().resolve()
try:
lifecycle_profile = load_stock_rover_lifecycle_profile(lifecycle_profile_path) lifecycle_profile = load_stock_rover_lifecycle_profile(lifecycle_profile_path)
guard = S0WorkerGuard(s0_profile_path) guard = S0WorkerGuard(s0_profile_path)
_preflight(paths, guard.profile) _preflight(paths, guard.profile)
interface_names = _loopback_only_interfaces()
except Exception as exc:
write_json_atomic(
evidence_root / "result.json",
{
"schema_version": "missioncore.s1b-stock-rover-result/v1",
"verdict": "fail",
"phase": "preflight",
"detail": f"{type(exc).__name__}: {exc}",
"run_id": args.run_id,
"mission_core_commit": args.mission_core_commit,
"network_scope": "loopback-only-netns-required",
"actuator_authority": False,
"direct_actuator_setpoints_allowed": False,
"finished_at_utc": _utc_now(),
},
)
_write_digest_index(evidence_root)
print("verdict=fail")
print(f"evidence_root={evidence_root}")
return 1
artifact_runs_root = paths.d_root / "artifacts/s1/runs" artifact_runs_root = paths.d_root / "artifacts/s1/runs"
runtime_runs_root = paths.d_root / "runtime/s1/runs" runtime_runs_root = paths.d_root / "runtime/s1/runs"
evidence_root = paths.d_root / "artifacts/s1/lifecycle" / args.run_id
evidence_root.mkdir(mode=0o700, parents=True, exist_ok=False)
interface_names = _loopback_only_interfaces()
write_json_atomic( write_json_atomic(
evidence_root / "network.json", evidence_root / "network.json",
{ {
@ -239,7 +260,7 @@ def _preflight(paths: StockRoverTargetPaths, profile: S0Profile) -> None:
def _loopback_only_interfaces() -> tuple[str, ...]: def _loopback_only_interfaces() -> tuple[str, ...]:
interfaces = tuple(sorted(path.name for path in Path("/sys/class/net").iterdir())) interfaces = tuple(sorted(name for _, name in socket.if_nameindex()))
if interfaces != ("lo",): if interfaces != ("lo",):
raise RuntimeError(f"S1B must run in a loopback-only namespace; observed {interfaces}") raise RuntimeError(f"S1B must run in a loopback-only namespace; observed {interfaces}")
return interfaces return interfaces