myxce/src/xceadmin/meson.build
Rongsong Shen 68bc86bc59
build: make Go and Python builds fully offline (hermetic Nix build)
The Nix build previously fetched Go modules from goproxy.cn and Python
build deps from PyPI during the build phase, relying on network leaking
into the sandbox. This is non-reproducible and breaks whenever the
sandbox resolver is unreachable (e.g. pc13v's loopback dnsmasq).

Go:
- Vendor all three modules (frontend/apiserver, frontend/xcecli,
  autoscaler/providers/baidu/src/bcctool) and commit vendor/ trees.
- tools/go_build now builds with GOFLAGS=-mod=vendor and GOPROXY=off
  instead of GOPROXY=https://goproxy.cn.

Python (xceadmin):
- Add setuptools + wheel to xce.nix nativeBuildInputs.
- meson-build.sh installs with pip --no-build-isolation --no-index
  --no-deps so no PyPI access happens at build time.

xceadmin install script:
- Invoke meson-install.sh via find_program('bash') instead of relying
  on its #!/usr/bin/env bash shebang, which fails in the Nix install
  sandbox (no /usr/bin/env -> 'could not be run').

Cleanup:
- Drop now-unneeded cacert and impureEnvVars=[HOME] from xce.nix and
  xcecli.nix (they only existed to enable the impure network fetch).

Docs:
- README build guide: drop '--option sandbox false' from nix build /
  nix bundle commands, note the build is now hermetic, and document the
  go mod vendor + git add vendor/ maintenance workflow.

Verified: nix build .#xcecore, .#xcecore_debug, .#xcecli, and .#xce all
succeed with the sandbox enabled.
2026-09-03 12:38:49 +08:00

79 lines
4.3 KiB
Meson

# xceadmin (admin-config-tool): Python package, no C compilation.
#
# Unlike every other subdir here, there is no single build artifact for
# meson/ninja to track -- `pip install` produces a multi-file venv tree.
# custom_target()'s output is a stamp file representing "install +
# test succeeded", following the same pattern used to wrap non-native
# build systems (cargo, npm, etc.) inside meson elsewhere in the
# ecosystem. The real work happens in meson-build.sh, out-of-tree in
# this subdir's own build directory -- never writing into the live
# source checkout, unlike xce-build.sh's separate editable-install
# fast dev-loop path (`xce-build.sh xceadmin`, still available
# 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
# subdir tree regardless, so tracking a subset of .py files would only
# give false confidence about staleness detection. build_always_stale
# instead matches this project's existing convention (every
# xce-build.sh component does `rm -rf "$BUILD_DIR"` and rebuilds clean
# on every invocation) rather than relying on ninja's file-mtime cache.
command: [
find_program('bash'),
meson.current_source_dir() / 'meson-build.sh',
meson.current_source_dir(),
meson.current_build_dir(),
meson.current_source_dir() / '..' / '..', # repo root (contains ha/, src/)
python3_prog.full_path(),
'@OUTPUT@',
# build-time-versioning task 5.1: same resolved commit_id/build_time
# option values src/meson.build:30-31 (C) and apiserver/xcecli's
# meson.build (Go, via XCE_GIT_COMMIT/XCE_BUILD_TIME) already thread
# through -- passed here as two more positional args, matching this
# custom_target's existing positional (not env-var) style. Empty when
# unset (meson.options' default); meson-build.sh is responsible for the
# empty -> "unknown" fallback, same discipline as go_build's
# XCE_GIT_COMMIT/XCE_BUILD_TIME handling.
get_option('commit_id'),
get_option('build_time'),
# dirty-content-fingerprint task 5.1: third positional arg, same
# resolved-option-value style as commit_id/build_time above. Unlike
# those two, its meson-build.sh-side fallback on empty is a plain empty
# string, NOT "unknown" -- matching this feature's convention
# everywhere else (go_build's XCE_DIRTY_FINGERPRINT, the C daemons'
# dirty_fingerprint), not the original feature's commit_id/build_time
# convention.
get_option('dirty_fingerprint'),
],
build_by_default: true,
build_always_stale: true,
console: true,
)
# Installs a standalone $out/bin/xceadmin -- runs after xceadmin_stamp
# (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.
# Invoke the install script through an explicit bash (find_program('bash'),
# the same interpreter-pinning pattern the build-phase custom_target above
# already uses) rather than relying on the script's `#!/usr/bin/env bash`
# shebang. In the Nix install-phase sandbox there is no /usr/bin/env, so
# letting meson exec the script by shebang fails with "could not be run";
# handing meson a resolved bash + the script path sidesteps that entirely.
meson.add_install_script(find_program('bash'),
meson.current_source_dir() / 'meson-install.sh',
python3_prog.full_path())