fix(simulation): inspect namespace through netlink
This commit is contained in:
parent
01ec12263a
commit
b4e3b3b735
|
|
@ -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()
|
||||||
lifecycle_profile = load_stock_rover_lifecycle_profile(lifecycle_profile_path)
|
try:
|
||||||
guard = S0WorkerGuard(s0_profile_path)
|
lifecycle_profile = load_stock_rover_lifecycle_profile(lifecycle_profile_path)
|
||||||
_preflight(paths, guard.profile)
|
guard = S0WorkerGuard(s0_profile_path)
|
||||||
|
_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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue