IQ.Pilot Prebuilt Release @ 27f668a
This commit is contained in:
16
iqpilot/system/proprietary_runtime/__init__.py
Normal file
16
iqpilot/system/proprietary_runtime/__init__.py
Normal file
@@ -0,0 +1,16 @@
|
||||
import os
|
||||
|
||||
from iqpilot.common.basedir import BASEDIR
|
||||
|
||||
|
||||
os.environ.setdefault("OPENPILOT_BASEDIR", BASEDIR)
|
||||
os.environ.setdefault("IQPILOT_PROPRIETARY_ROOT", os.path.join(BASEDIR, ".iqpilot", "bundles"))
|
||||
|
||||
# _verified_import.so ships ONLY in the signed rootfs runtime. It MUST be prepended so a
|
||||
# repo-side _verified_import.py can never shadow the signed native module via __path__
|
||||
# order. runtime_paths.py lives in the repo copy and still resolves from the fall-through.
|
||||
_ROOTFS_PKG = "/usr/libexec/iqpilot/python/openpilot/system/proprietary_runtime"
|
||||
if os.path.isdir(_ROOTFS_PKG):
|
||||
if _ROOTFS_PKG in __path__:
|
||||
__path__.remove(_ROOTFS_PKG)
|
||||
__path__.insert(0, _ROOTFS_PKG)
|
||||
54
iqpilot/system/proprietary_runtime/install_verified_runtime.sh
Executable file
54
iqpilot/system/proprietary_runtime/install_verified_runtime.sh
Executable file
@@ -0,0 +1,54 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
|
||||
RUNTIME_ROOT="${IQPILOT_VERIFIED_RUNTIME_ROOT:-/usr/libexec/iqpilot}"
|
||||
PYTHON_ROOT="${RUNTIME_ROOT}/python"
|
||||
TARGET_EXT_DIR="${PYTHON_ROOT}/openpilot/system/proprietary_runtime"
|
||||
MANIFEST_SRC="${ROOT}/iqpilot/system/proprietary_runtime/rootfs_integrity.json"
|
||||
MANIFEST_SIG_SRC="${ROOT}/iqpilot/system/proprietary_runtime/rootfs_integrity.json.sig"
|
||||
|
||||
RUNNER_SRC="${ROOT}/iqpilot/system/proprietary_runtime/iqpilot_bundle_runner"
|
||||
EXT_SRC="${ROOT}/iqpilot/system/proprietary_runtime/_verified_import.so"
|
||||
STUB_ROOT="${ROOT}/iqpilot/system/proprietary_runtime/rootfs_python"
|
||||
|
||||
if [ ! -x "${RUNNER_SRC}" ]; then
|
||||
echo "missing runner: ${RUNNER_SRC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "${EXT_SRC}" ]; then
|
||||
# No locally-built _verified_import.so staged in the tree. This is the NORMAL prebuilt/release case:
|
||||
# the .so is gitignored and ships baked into the OS image at /usr/libexec/iqpilot, so there is
|
||||
# nothing to install from /data. Quietly no-op and let the OS-baked verified runtime be used.
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ ! -f "${MANIFEST_SRC}" ] || [ ! -f "${MANIFEST_SIG_SRC}" ]; then
|
||||
if [ -n "${IQPILOT_SIGNING_KEY:-}" ]; then
|
||||
"${ROOT}/.venv/bin/python" \
|
||||
"${ROOT}/scripts/iqpilot/build_proprietary_runtime_manifest.py" \
|
||||
--repo-root "${ROOT}" \
|
||||
--output "${MANIFEST_SRC}"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -f "${MANIFEST_SRC}" ] || [ ! -f "${MANIFEST_SIG_SRC}" ]; then
|
||||
echo "missing rootfs runtime integrity manifest or signature"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sudo mount -o remount,rw /
|
||||
trap 'sudo mount -o remount,ro /' EXIT
|
||||
|
||||
sudo mkdir -p "${RUNTIME_ROOT}" "${TARGET_EXT_DIR}"
|
||||
sudo install -m 0755 "${RUNNER_SRC}" "${RUNTIME_ROOT}/iqpilot_bundle_runner"
|
||||
sudo install -m 0755 "${EXT_SRC}" "${TARGET_EXT_DIR}/_verified_import.so"
|
||||
sudo install -m 0644 "${MANIFEST_SRC}" "${RUNTIME_ROOT}/runtime_integrity.json"
|
||||
sudo install -m 0644 "${MANIFEST_SIG_SRC}" "${RUNTIME_ROOT}/runtime_integrity.json.sig"
|
||||
sudo install -m 0644 "${STUB_ROOT}/openpilot/__init__.py" "${PYTHON_ROOT}/openpilot/__init__.py"
|
||||
sudo mkdir -p "${PYTHON_ROOT}/openpilot/system"
|
||||
sudo install -m 0644 "${STUB_ROOT}/openpilot/system/__init__.py" "${PYTHON_ROOT}/openpilot/system/__init__.py"
|
||||
sudo install -m 0644 "${STUB_ROOT}/openpilot/system/proprietary_runtime/__init__.py" "${TARGET_EXT_DIR}/__init__.py"
|
||||
|
||||
echo "installed verified runtime to ${RUNTIME_ROOT}"
|
||||
BIN
iqpilot/system/proprietary_runtime/iqpilot_bundle_runner
Executable file
BIN
iqpilot/system/proprietary_runtime/iqpilot_bundle_runner
Executable file
Binary file not shown.
53
iqpilot/system/proprietary_runtime/rootfs_integrity.json
Normal file
53
iqpilot/system/proprietary_runtime/rootfs_integrity.json
Normal file
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"entries": [
|
||||
{
|
||||
"mode": 493,
|
||||
"path": "iqpilot_bundle_runner",
|
||||
"relative_to": "runtime_root",
|
||||
"sha256": "13af5da8a783b2f2e20464187e468a2acb58fbbf03340ced6f9b8a69874fe7ed",
|
||||
"size": 134160
|
||||
},
|
||||
{
|
||||
"mode": 420,
|
||||
"path": "python/openpilot/__init__.py",
|
||||
"relative_to": "runtime_root",
|
||||
"sha256": "acff7d771dbec2a17c97ea2de7c0a86f12f1119616932ddb09e7c670bf2eed25",
|
||||
"size": 580
|
||||
},
|
||||
{
|
||||
"mode": 420,
|
||||
"path": "python/openpilot/system/__init__.py",
|
||||
"relative_to": "runtime_root",
|
||||
"sha256": "399977f784cfb3a5e1c1d2f4e75619214c37ec2b4127802f0b739ab8e768ce82",
|
||||
"size": 602
|
||||
},
|
||||
{
|
||||
"mode": 420,
|
||||
"path": "python/openpilot/system/proprietary_runtime/__init__.py",
|
||||
"relative_to": "runtime_root",
|
||||
"sha256": "3243b0edf306e17fe860e0c2a64fc2354be0d72ad12b613eea1dfeb426bb522b",
|
||||
"size": 742
|
||||
},
|
||||
{
|
||||
"mode": 493,
|
||||
"path": "python/openpilot/system/proprietary_runtime/_verified_import.so",
|
||||
"relative_to": "runtime_root",
|
||||
"sha256": "cd8cf31c11742d4f2079b398a9dec9e6df60f5a79dfe42c1d6888614bd8e500b",
|
||||
"size": 200416
|
||||
},
|
||||
{
|
||||
"mode": 420,
|
||||
"path": "/usr/lib/systemd/system/hephaestusd.service",
|
||||
"relative_to": "absolute",
|
||||
"sha256": "3b70e8873c7eb813e70798300b76c153dddda9947c1301cbba7e103962461fa2",
|
||||
"size": 1627
|
||||
},
|
||||
{
|
||||
"mode": 420,
|
||||
"path": "/usr/lib/systemd/system/ble-transportd.service",
|
||||
"relative_to": "absolute",
|
||||
"sha256": "6b5bf61ebfebffe3d125bb766c13c391b83e8feda04b89f47de2725c6fe186e3",
|
||||
"size": 1907
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
exS3jBbVETgFQtzbRGWymtflNgeWLbjHvcMVsKs5NrwpmMdx9sWpcZ2FO/pB6RQaCniXGDwT7GhjvGxpfrP5Cg==
|
||||
@@ -0,0 +1,23 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def _resolve_source_pkg() -> Path:
|
||||
raw_root = os.environ.get("IQPILOT_SOURCE_ROOT") or os.environ.get("OPENPILOT_SOURCE_ROOT") or "/data/openpilot/iqpilot"
|
||||
source_root = Path(raw_root)
|
||||
if source_root.name == "openpilot":
|
||||
return source_root
|
||||
return source_root / "openpilot"
|
||||
|
||||
|
||||
def _extend_package_path() -> None:
|
||||
source_pkg = _resolve_source_pkg()
|
||||
if source_pkg.is_dir():
|
||||
pkg_path = str(source_pkg)
|
||||
if pkg_path not in __path__:
|
||||
__path__.append(pkg_path)
|
||||
|
||||
|
||||
_extend_package_path()
|
||||
@@ -0,0 +1,23 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def _resolve_source_pkg() -> Path:
|
||||
raw_root = os.environ.get("IQPILOT_SOURCE_ROOT") or os.environ.get("OPENPILOT_SOURCE_ROOT") or "/data/openpilot/iqpilot"
|
||||
source_root = Path(raw_root)
|
||||
if source_root.name == "openpilot":
|
||||
return source_root / "system"
|
||||
return source_root / "openpilot" / "system"
|
||||
|
||||
|
||||
def _extend_package_path() -> None:
|
||||
source_pkg = _resolve_source_pkg()
|
||||
if source_pkg.is_dir():
|
||||
pkg_path = str(source_pkg)
|
||||
if pkg_path not in __path__:
|
||||
__path__.append(pkg_path)
|
||||
|
||||
|
||||
_extend_package_path()
|
||||
@@ -0,0 +1,27 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from ._verified_import import import_verified_module
|
||||
|
||||
|
||||
def _resolve_source_pkg() -> Path:
|
||||
raw_root = os.environ.get("IQPILOT_SOURCE_ROOT") or os.environ.get("OPENPILOT_SOURCE_ROOT") or "/data/openpilot/iqpilot"
|
||||
source_root = Path(raw_root)
|
||||
if source_root.name == "openpilot":
|
||||
return source_root / "system" / "proprietary_runtime"
|
||||
return source_root / "openpilot" / "system" / "proprietary_runtime"
|
||||
|
||||
|
||||
def _extend_package_path() -> None:
|
||||
source_pkg = _resolve_source_pkg()
|
||||
if source_pkg.is_dir():
|
||||
pkg_path = str(source_pkg)
|
||||
if pkg_path not in __path__:
|
||||
__path__.append(pkg_path)
|
||||
|
||||
|
||||
_extend_package_path()
|
||||
|
||||
__all__ = ["import_verified_module"]
|
||||
32
iqpilot/system/proprietary_runtime/runtime_paths.py
Normal file
32
iqpilot/system/proprietary_runtime/runtime_paths.py
Normal file
@@ -0,0 +1,32 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
VERIFIED_RUNTIME_ROOT = Path("/usr/libexec/iqpilot")
|
||||
VERIFIED_RUNNER_PATH = VERIFIED_RUNTIME_ROOT / "iqpilot_bundle_runner"
|
||||
VERIFIED_PYTHON_ROOT = VERIFIED_RUNTIME_ROOT / "python"
|
||||
FALLBACK_RUNNER_PATH = Path("/data/openpilot/iqpilot/system/proprietary_runtime/iqpilot_bundle_runner")
|
||||
DEFAULT_SOURCE_ROOT = Path("/data/openpilot/iqpilot")
|
||||
|
||||
|
||||
def verified_runtime_present() -> bool:
|
||||
return VERIFIED_RUNNER_PATH.is_file() and os.access(VERIFIED_RUNNER_PATH, os.X_OK)
|
||||
|
||||
|
||||
def preferred_runner_path() -> Path:
|
||||
if verified_runtime_present():
|
||||
return VERIFIED_RUNNER_PATH
|
||||
if os.getenv("IQPILOT_ALLOW_DEV_FALLBACKS") == "1" and FALLBACK_RUNNER_PATH.is_file():
|
||||
return FALLBACK_RUNNER_PATH
|
||||
return VERIFIED_RUNNER_PATH
|
||||
|
||||
|
||||
def preferred_pythonpath(existing: str = "") -> str:
|
||||
parts: list[str] = []
|
||||
if VERIFIED_PYTHON_ROOT.is_dir():
|
||||
parts.append(str(VERIFIED_PYTHON_ROOT))
|
||||
if existing:
|
||||
parts.append(existing)
|
||||
return ":".join(parts)
|
||||
@@ -0,0 +1,35 @@
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
from iqpilot.common.basedir import BASEDIR
|
||||
|
||||
|
||||
def _runtime_paths(env):
|
||||
result = subprocess.run(
|
||||
[
|
||||
sys.executable,
|
||||
"-c",
|
||||
"import os; import iqpilot.system.proprietary_runtime; print(os.environ['OPENPILOT_BASEDIR']); "
|
||||
+ "print(os.environ['IQPILOT_PROPRIETARY_ROOT'])",
|
||||
],
|
||||
env=env,
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
return result.stdout.splitlines()
|
||||
|
||||
|
||||
def test_basedir_contract():
|
||||
env = os.environ.copy()
|
||||
env.pop("OPENPILOT_BASEDIR", None)
|
||||
env.pop("IQPILOT_PROPRIETARY_ROOT", None)
|
||||
assert _runtime_paths(env) == [BASEDIR, os.path.join(BASEDIR, ".iqpilot", "bundles")]
|
||||
|
||||
|
||||
def test_explicit_basedir_is_preserved(tmp_path):
|
||||
env = os.environ.copy()
|
||||
env["OPENPILOT_BASEDIR"] = str(tmp_path)
|
||||
env["IQPILOT_PROPRIETARY_ROOT"] = str(tmp_path / "bundles")
|
||||
assert _runtime_paths(env) == [str(tmp_path), str(tmp_path / "bundles")]
|
||||
Reference in New Issue
Block a user