fix(admin-config-tool): pin xceadmin's python3 to meson's own resolution

Both meson-build.sh (venv creation) and meson-install.sh (wrapper
shebang) resolved python3 independently at run time (bare `python3 -m
venv` / `command -v python3`) -- correct as long as invoked inside
nix develop/build, but nothing prevented a stray non-nix system
python3 earlier on PATH from shadowing it.

meson.build now resolves python3 once via import('python').
find_installation('python3') -- same mechanism as find_program('go')/
capnp/packcc elsewhere in this build, printed at `meson setup` time
as "Program python3 found: YES (/nix/store/...)" -- and threads that
exact resolved path into both scripts as an explicit argument instead
of a fresh lookup.

Verified: meson setup prints the pinned python3, xceadmin target
rebuilds clean (165/165 passed), and the built venv's own python3
resolves through to that exact nix store path.
This commit is contained in:
Rongsong Shen 2026-07-22 13:07:23 +00:00
parent d5330fc976
commit db2b5f17f0
3 changed files with 28 additions and 10 deletions

View file

@ -19,7 +19,9 @@ set -euo pipefail
SOURCE_DIR="$1" # .../src/xceadmin (meson.current_source_dir())
BUILD_DIR="$2" # .../xceadmin (meson.current_build_dir())
REPO_ROOT="$3" # real repo root (contains ha/, src/)
STAMP_FILE="$4"
PYTHON="$4" # meson's resolved python3 (import('python').find_installation()),
# NOT a bare `python3` PATH lookup -- see meson.build's comment
STAMP_FILE="$5"
SRC_DIR="$REPO_ROOT/src"
@ -50,9 +52,9 @@ cp "$SRC_DIR/schema/controller.capnp" "$SCHEMA_DST/controller.capnp"
cp "$SRC_DIR/schema/c.capnp" "$SCHEMA_DST/c.capnp"
cp "$SRC_DIR/configs/schema/"*.schema.json "$SCHEMA_DST/json/"
echo "=== xceadmin (meson): pinned install into build-dir venv ==="
echo "=== xceadmin (meson): pinned install into build-dir venv (python: $PYTHON) ==="
rm -rf "$VENV_DIR"
python3 -m venv --system-site-packages "$VENV_DIR"
"$PYTHON" -m venv --system-site-packages "$VENV_DIR"
"$VENV_DIR/bin/pip" install "$WORK_DIR" --quiet
echo "=== xceadmin (meson): running tests ==="

View file

@ -9,15 +9,18 @@
#
# Instead: copy just the xceadmin/xcecommon package dirs (pure files, no
# shebang) into $out, and hand-write a wrapper whose shebang and PYTHONPATH
# are resolved against *this* install script's own environment (python3
# and the nix-provided pycapnp/pyyaml/jsonschema/click site-packages come
# from nativeBuildInputs, same as every other phase of this derivation) --
# every path baked in below is a real /nix/store path, so nix's reference
# scanner picks each one up as a proper runtime dependency of $out.
# are resolved against *this* install script's own environment (python3 --
# passed in as $1, meson's own resolved interpreter (import('python').
# find_installation()) from meson.build, not a fresh `command -v python3`
# lookup here -- and the nix-provided pycapnp/pyyaml/jsonschema/click
# site-packages come from nativeBuildInputs, same as every other phase of
# this derivation) -- every path baked in below is a real /nix/store path,
# so nix's reference scanner picks each one up as a proper runtime
# dependency of $out.
set -euo pipefail
PYTHON="$1"
DESTDIR_PREFIX="$MESON_INSTALL_DESTDIR_PREFIX"
PYTHON="$(command -v python3)"
VENV_SITE_GLOB=("$MESON_BUILD_ROOT"/xceadmin/.venv/lib/python3.*/site-packages)
VENV_SITE="${VENV_SITE_GLOB[0]}"

View file

@ -12,6 +12,18 @@
# standalone, but no longer xce-build.sh's OWN xceadmin implementation
# -- see tools/xce-build.sh, which now just calls this same target).
# Resolved once via meson's own dependency machinery (same pattern as
# find_program('go')/capnp/packcc elsewhere in this build, printed as
# "Program python3 found: YES (/nix/store/...)" at `meson setup` time) and
# threaded explicitly into both scripts below -- NOT left to each script's
# own `python3 -m venv`/`command -v python3` PATH lookup at run time. A bare
# PATH lookup would happen to match nix's python3 when invoked correctly
# (inside `nix develop` / a nix build sandbox), but nothing would catch a
# stray non-nix system python3 shadowing it earlier on PATH -- pinning the
# exact interpreter meson already found makes that impossible, not just
# unlikely.
python3_prog = import('python').find_installation('python3')
xceadmin_stamp = custom_target('xceadmin',
output: 'xceadmin-build.stamp',
# No meaningful per-file `input:` list: meson-build.sh copies the whole
@ -26,6 +38,7 @@ xceadmin_stamp = custom_target('xceadmin',
meson.current_source_dir(),
meson.current_build_dir(),
meson.current_source_dir() / '..' / '..', # repo root (contains ha/, src/)
python3_prog.full_path(),
'@OUTPUT@',
],
build_by_default: true,
@ -37,4 +50,4 @@ xceadmin_stamp = custom_target('xceadmin',
# (ninja install always depends on build_by_default targets first) so the
# build-dir venv it copies from already exists. See meson-install.sh for
# why this isn't a plain `cp` of that venv.
meson.add_install_script('meson-install.sh')
meson.add_install_script('meson-install.sh', python3_prog.full_path())