IQ.Pilot Release Commit @ bec7652
This commit is contained in:
71
iqpilot/system/proprietary_runtime/SConscript
Normal file
71
iqpilot/system/proprietary_runtime/SConscript
Normal file
@@ -0,0 +1,71 @@
|
||||
# Copyright © IQ.Lvbs, apart of Project Teal Lvbs, All Rights Reserved, licensed under https://konn3kt.com/tos
|
||||
import os
|
||||
import sysconfig
|
||||
|
||||
Import('env', 'common')
|
||||
|
||||
_PRIVATE_ROOT_RAW = os.environ.get("IQPILOT_PROPRIETARY_RUNTIME_SOURCE_ROOT", "").strip()
|
||||
_REQUIRE_PRIVATE_SOURCE = os.environ.get("IQPILOT_BUILD_PROPRIETARY_RUNTIME", "") == "1"
|
||||
_ALLOW_HOST_RUNTIME = os.environ.get("IQPILOT_BUILD_HOST_RUNTIME", "") == "1"
|
||||
_BUILD_NATIVE_RUNTIME = env["PLATFORM"] != "darwin" or _ALLOW_HOST_RUNTIME
|
||||
|
||||
if _PRIVATE_ROOT_RAW:
|
||||
from pathlib import Path
|
||||
_PRIVATE_ROOT = Path(_PRIVATE_ROOT_RAW).resolve()
|
||||
_PRIVATE_SOURCES = {
|
||||
name: _PRIVATE_ROOT / name
|
||||
for name in ("runner.cc", "bundle_common.cc", "bundle_common.h", "verified_import.cc")
|
||||
}
|
||||
else:
|
||||
_PRIVATE_ROOT = None
|
||||
_PRIVATE_SOURCES = {}
|
||||
|
||||
|
||||
def _private_sources_ready() -> bool:
|
||||
if _PRIVATE_ROOT is None:
|
||||
if _REQUIRE_PRIVATE_SOURCE:
|
||||
raise FileNotFoundError(
|
||||
"IQPILOT_PROPRIETARY_RUNTIME_SOURCE_ROOT is not set"
|
||||
)
|
||||
print(env.PrettyNote('SKIP', "proprietary runtime native build — no private source root configured"))
|
||||
return False
|
||||
|
||||
missing = [str(path) for path in _PRIVATE_SOURCES.values() if not path.exists()]
|
||||
if not missing:
|
||||
return True
|
||||
|
||||
if _REQUIRE_PRIVATE_SOURCE:
|
||||
raise FileNotFoundError(
|
||||
"missing proprietary runtime source files:\n" + "\n".join(missing)
|
||||
)
|
||||
print(env.PrettyNote('SKIP', f"proprietary runtime native build — private source unavailable at {_PRIVATE_ROOT}"))
|
||||
return False
|
||||
|
||||
|
||||
runner = None
|
||||
verified_import = None
|
||||
|
||||
if not _BUILD_NATIVE_RUNTIME:
|
||||
print(env.PrettyNote('SKIP', "proprietary runtime host build on darwin (IQPILOT_BUILD_HOST_RUNTIME=1 to override)"))
|
||||
elif _private_sources_ready():
|
||||
runner = env.Program(
|
||||
'iqpilot_bundle_runner',
|
||||
[str(_PRIVATE_SOURCES["runner.cc"]), str(_PRIVATE_SOURCES["bundle_common.cc"])],
|
||||
LIBS=common + ['json11', 'crypto', 'pthread'],
|
||||
)
|
||||
|
||||
python_module_env = env.Clone()
|
||||
python_module_env["SHLIBPREFIX"] = ""
|
||||
python_module_env["SHLIBSUFFIX"] = ".so"
|
||||
python_module_env.Append(CPPPATH=[sysconfig.get_paths()["include"], str(_PRIVATE_ROOT)])
|
||||
python_module_env["LINKFLAGS"] = [flag for flag in python_module_env["LINKFLAGS"] if flag != "-Wl,--no-undefined"]
|
||||
if python_module_env["PLATFORM"] == "darwin":
|
||||
python_module_env.Append(LINKFLAGS=["-undefined", "dynamic_lookup"])
|
||||
|
||||
verified_import = python_module_env.SharedLibrary(
|
||||
'_verified_import',
|
||||
[str(_PRIVATE_SOURCES["verified_import.cc"]), str(_PRIVATE_SOURCES["bundle_common.cc"])],
|
||||
LIBS=common + ['json11', 'crypto', 'pthread'],
|
||||
)
|
||||
|
||||
Export('runner', 'verified_import')
|
||||
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": "4ae9a2ad76345019633c2fcf9698f48089576c9b7c009078a732e2a7c36006e4",
|
||||
"size": 1418
|
||||
},
|
||||
{
|
||||
"mode": 420,
|
||||
"path": "/usr/lib/systemd/system/ble-transportd.service",
|
||||
"relative_to": "absolute",
|
||||
"sha256": "dfb9e18320e264c847efc01a2d58ee1850a83c49ed614527eafa7634de4ac51a",
|
||||
"size": 1500
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
dmb/R9bZCCHK8J72JIgm8TMY7nBVVo1exmvFIodw0LSFVcGZGDrZNB74xhQTAXgzAgeYVdFQyXs0qdwpvQa2Aw==
|
||||
@@ -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