mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-10-15 04:18:05 +00:00
Set the supported ONNX installer skip policy inside the cleared build sandbox so optional CUDA downloads do not abort offline lifecycle scripts. Keep CPU binaries, network containment, and all grading checks intact. Strengthen command construction and real Bubblewrap lifecycle coverage. Targeted tests: 114 passed, 15 skipped. Full core and real containment validation deferred to hosted CI with maintainer approval.
137 lines
4.9 KiB
Python
137 lines
4.9 KiB
Python
"""Build a candidate without exposing the trusted evaluator or host environment."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import json
|
|
import os
|
|
from pathlib import Path, PurePosixPath
|
|
|
|
from .process_control import run_checked
|
|
from .proposer_sandbox import SANDBOX_PATH, bwrap_base_args, preflight_bubblewrap, real_directory
|
|
|
|
|
|
REGISTRY = "https://registry.npmjs.org/"
|
|
LOCKFILES = ("package-lock.json", "gitnexus/package-lock.json")
|
|
|
|
|
|
def require_registry_only_install(repo: Path) -> None:
|
|
"""Fail unless the online install can only fetch from the public npm registry.
|
|
|
|
The download phase has network, and npm fetches every lockfile ``resolved``
|
|
URL. A candidate must not steer it at other hosts (loopback, private
|
|
networks, cloud metadata) through its lockfiles or an npm config file.
|
|
"""
|
|
|
|
for config in (".npmrc", "gitnexus/.npmrc"):
|
|
if os.path.lexists(repo / config):
|
|
raise ValueError(f"release candidate must not ship npm configuration: {config}")
|
|
for lockfile in LOCKFILES:
|
|
try:
|
|
packages = json.loads((repo / lockfile).read_text())["packages"]
|
|
except (OSError, ValueError, KeyError, TypeError) as exc:
|
|
raise ValueError(f"release candidate lockfile is unreadable: {lockfile}") from exc
|
|
if not isinstance(packages, dict):
|
|
raise ValueError(f"release candidate lockfile is malformed: {lockfile}")
|
|
root = PurePosixPath(lockfile).parent
|
|
for name, entry in packages.items():
|
|
resolved = entry.get("resolved") if isinstance(entry, dict) else None
|
|
if resolved is None or (isinstance(resolved, str) and resolved.startswith(REGISTRY)):
|
|
continue
|
|
# Workspace links stay inside the checkout and fetch nothing.
|
|
target = PurePosixPath(os.path.normpath(root / resolved)) if isinstance(resolved, str) else None
|
|
if (
|
|
entry.get("link") is True
|
|
and target is not None
|
|
and not target.is_absolute()
|
|
and ".." not in target.parts
|
|
):
|
|
continue
|
|
raise ValueError(f"release candidate lockfile {lockfile} resolves {name!r} outside {REGISTRY}")
|
|
|
|
|
|
def build_candidate(repo: Path) -> None:
|
|
"""Install dependencies with network, then run lifecycle scripts without it.
|
|
|
|
Only the checkout, minus git metadata, is writable in either phase.
|
|
"""
|
|
repo = real_directory(repo, label="release candidate")
|
|
# Host git later runs in this checkout (e.g. actions/checkout cleanup), so
|
|
# lifecycle scripts must not plant git config such as core.fsmonitor.
|
|
git_dir = repo / ".git"
|
|
git_mask = ["--ro-bind", str(git_dir), "/workspace/.git"] if os.path.lexists(git_dir) else []
|
|
require_registry_only_install(repo)
|
|
bwrap = preflight_bubblewrap()
|
|
|
|
def sandboxed(script: list[str], *, offline: bool) -> list[str]:
|
|
return [
|
|
str(bwrap),
|
|
*bwrap_base_args(unshare_network=offline, cap_drop_all=True),
|
|
"--tmpfs",
|
|
"/tmp",
|
|
"--dir",
|
|
"/home/build",
|
|
"--bind",
|
|
str(repo),
|
|
"/workspace",
|
|
*git_mask,
|
|
"--clearenv",
|
|
"--setenv",
|
|
"PATH",
|
|
SANDBOX_PATH,
|
|
"--setenv",
|
|
"HOME",
|
|
"/home/build",
|
|
# CPU binaries ship in the npm package. Optional CUDA downloads
|
|
# cannot run during the network-isolated lifecycle phase.
|
|
"--setenv",
|
|
"ONNXRUNTIME_NODE_INSTALL",
|
|
"skip",
|
|
"--chdir",
|
|
"/workspace",
|
|
"--",
|
|
"/bin/bash",
|
|
"--noprofile",
|
|
"--norc",
|
|
"-c",
|
|
"\n".join(["set -euo pipefail", *script]),
|
|
]
|
|
|
|
# Locked downloads need the network but run no package code. Every
|
|
# lifecycle script (dependency installs, prepare, build) then runs with no
|
|
# network, so candidate-controlled code cannot reach host-local services.
|
|
# No host home, evaluator checkout, GitHub command files or tokens are mounted.
|
|
run_checked(
|
|
sandboxed(
|
|
[
|
|
"npm ci --ignore-scripts --audit=false --fund=false",
|
|
"npm ci --prefix gitnexus --ignore-scripts --audit=false --fund=false",
|
|
],
|
|
offline=False,
|
|
),
|
|
timeout=1200,
|
|
env={},
|
|
)
|
|
run_checked(
|
|
sandboxed(
|
|
[
|
|
"npm rebuild --foreground-scripts",
|
|
"npm rebuild --prefix gitnexus --foreground-scripts",
|
|
"npm run build --prefix gitnexus",
|
|
"mkdir -p gitnexus-shared/node_modules",
|
|
],
|
|
offline=True,
|
|
),
|
|
timeout=1200,
|
|
env={},
|
|
)
|
|
|
|
|
|
def main() -> None:
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
parser.add_argument("--repo", required=True, type=Path)
|
|
build_candidate(parser.parse_args().repo)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|