95 lines
3.8 KiB
Python
95 lines
3.8 KiB
Python
"""Install only the bundled, hash-pinned Ubuntu K1 runtime; no network I/O."""
|
|
|
|
import hashlib
|
|
import json
|
|
import os
|
|
import shutil
|
|
import sys
|
|
import tempfile
|
|
import zipfile
|
|
from pathlib import Path, PurePosixPath
|
|
|
|
SHARE = Path("/usr/share/mission-core-node/k1")
|
|
ROOT = Path("/var/lib/mission-core-k1-runtime")
|
|
|
|
|
|
def members(archive):
|
|
for info in archive.infolist():
|
|
path = PurePosixPath(info.filename)
|
|
if (
|
|
path.is_absolute()
|
|
or ".." in path.parts
|
|
or (info.external_attr >> 16) & 0o170000 == 0o120000
|
|
or ".data" in path.parts
|
|
):
|
|
raise RuntimeError("Unsafe K1 runtime archive")
|
|
# Rerun's pinned wheel declares this one static package directory.
|
|
# We do not execute .pth files; bootstrap adds the exact directory.
|
|
if info.filename.endswith(".pth") and not (
|
|
info.filename == "rerun_sdk.pth" and archive.read(info) == b"rerun_sdk\n"
|
|
):
|
|
raise RuntimeError("Unreviewed K1 Python path hook")
|
|
# Distribution script/data relocation must be handled deliberately,
|
|
# never interpreted as an install hook by the operator's Python.
|
|
if any(part.endswith(".data") for part in path.parts):
|
|
raise RuntimeError("K1 wheel requires unsupported relocation")
|
|
yield info
|
|
|
|
|
|
def prepare():
|
|
if os.geteuid() != 0 or os.uname().machine != "x86_64" or sys.version_info[:2] != (3, 12):
|
|
raise RuntimeError("K1 runtime requires privileged Ubuntu amd64 Python 3.12 installation")
|
|
release = Path("/etc/os-release").read_text()
|
|
if "ID=ubuntu" not in release or 'VERSION_ID="24.04"' not in release:
|
|
raise RuntimeError("K1 runtime requires Ubuntu 24.04")
|
|
manifest = json.loads((SHARE / "bundle.json").read_text())
|
|
revision = manifest["revision"]
|
|
if not revision.isalnum():
|
|
raise RuntimeError("Invalid K1 runtime revision")
|
|
ROOT.mkdir(mode=0o755, exist_ok=True)
|
|
if ROOT.is_symlink() or ROOT.stat().st_uid != 0 or ROOT.stat().st_mode & 0o022:
|
|
raise RuntimeError("Unsafe K1 runtime root")
|
|
target = ROOT / revision
|
|
if target.is_symlink() or (ROOT / "active.path").is_symlink():
|
|
raise RuntimeError("Unsafe K1 runtime reference")
|
|
for item in manifest["wheels"]:
|
|
path = SHARE / item["name"]
|
|
if (
|
|
path.name != item["name"]
|
|
or path.is_symlink()
|
|
or hashlib.sha256(path.read_bytes()).hexdigest() != item["sha256"]
|
|
):
|
|
raise RuntimeError("K1 runtime checksum mismatch")
|
|
if not target.exists():
|
|
stage = Path(tempfile.mkdtemp(prefix=".k1-", dir=ROOT))
|
|
try:
|
|
for item in manifest["wheels"]:
|
|
with zipfile.ZipFile(SHARE / item["name"]) as archive:
|
|
archive.extractall(stage, members=members(archive))
|
|
for path in stage.rglob("*"):
|
|
path.chmod(0o755 if path.is_dir() else 0o644)
|
|
stage.chmod(0o755)
|
|
stage.rename(target)
|
|
finally:
|
|
if stage.exists():
|
|
shutil.rmtree(stage)
|
|
for item in manifest["wheels"]:
|
|
with zipfile.ZipFile(SHARE / item["name"]) as archive:
|
|
for info in members(archive):
|
|
path = target / info.filename
|
|
if path.is_symlink() or (
|
|
not info.is_dir() and path.read_bytes() != archive.read(info)
|
|
):
|
|
raise RuntimeError("Installed K1 runtime differs from bundled wheel")
|
|
fd, name = tempfile.mkstemp(prefix=".active-", dir=ROOT)
|
|
with os.fdopen(fd, "w") as stream:
|
|
os.fchmod(stream.fileno(), 0o644)
|
|
stream.write(str(target))
|
|
stream.flush()
|
|
os.fsync(stream.fileno())
|
|
os.replace(name, ROOT / "active.path")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
prepare()
|