From bf2c816e63c2cf115a6506da3d88d2aa628a25eb Mon Sep 17 00:00:00 2001 From: Pedro Henrique Penna Date: Thu, 12 Nov 2026 04:29:38 -0800 Subject: [PATCH] guest: delete the Alpine one-shot container helpers SL7.8b deleted the old layered init, whose container launcher was the only caller of the Alpine one-shot container helpers: nvx-container-launch ran a workload's container through nvx-container-enter, which staged Alpine's musl loader and setpriv in the container's root. The shell /init now runs only nvx-init for a layered root, or the managed agent with its own root, so nothing runs them any more. Delete guest/alpine/nvx-container-enter and nvx-container-launch, and so guest/alpine, which held nothing else, with every inventory that names them or the directory: - build.py no longer installs them in the Alpine initramfs, nor lists guest/alpine among the Alpine guest's customization files; - the Alpine guest's source directories are guest/common alone, as Azure Linux's are, in build_constants.py and in the guest_sources of SOURCE-MANIFEST.json, which release.py checks against them; - release.py's source-tree check no longer requires the entry helper; - the Alpine artifacts' CI cache key no longer hashes guest/alpine; - check-quality's ShellCheck and shfmt lists, and their copies in the setup guide, no longer name them; - the project structure no longer describes guest/alpine, nor, since SL7.8b deleted the init agent, an agent among guest/common's scripts. Tests: the fixture manifest of test_nvx_tools.py's release tests drops guest/alpine from the Alpine guest_sources, and the CI change-detection test drops its case of guest/alpine/nvx-container-enter, a deleted file; its guest/common/init case still covers the guests' inputs. Part of #1123 (SL7.8c). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../actions/build-guest-artifacts/action.yml | 2 +- .github/actions/check-quality/action.yml | 6 +- SOURCE-MANIFEST.json | 1 - doc/project-structure.md | 8 +- doc/setup.md | 9 +- guest/alpine/nvx-container-enter | 83 ------------------- guest/alpine/nvx-container-launch | 19 ----- scripts/nvx_tools/build.py | 27 +----- scripts/nvx_tools/build_constants.py | 6 +- scripts/nvx_tools/release.py | 4 - scripts/test_nvx_tools.py | 2 - 11 files changed, 11 insertions(+), 156 deletions(-) delete mode 100644 guest/alpine/nvx-container-enter delete mode 100644 guest/alpine/nvx-container-launch diff --git a/.github/actions/build-guest-artifacts/action.yml b/.github/actions/build-guest-artifacts/action.yml index bb2ed0018..9e58cefea 100644 --- a/.github/actions/build-guest-artifacts/action.yml +++ b/.github/actions/build-guest-artifacts/action.yml @@ -136,7 +136,7 @@ runs: AZURELINUX_VERSION: ${{ steps.guest-versions.outputs.azurelinux-version }} KERNEL_INPUT_HASH: ${{ hashFiles('SOURCE-MANIFEST.json', 'kernel/config-microvm', 'kernel/config-microvm.derived', 'kernel/patches/**', 'docker/Dockerfile', '.dockerignore', 'scripts/nvx_tools/build.py', 'scripts/nvx_tools/build_config.py', 'scripts/nvx_tools/build_constants.py', 'scripts/nvx_tools/kconfig.py', 'scripts/nvx_tools/kernel_config.py', 'scripts/nvx_tools/kernel_features.py') }} DEBUG_KERNEL_INPUT_HASH: ${{ hashFiles('SOURCE-MANIFEST.json', 'kernel/config-microvm', 'kernel/config-microvm-debug', 'kernel/patches/**', 'docker/Dockerfile', '.dockerignore', 'scripts/nvx_tools/build.py', 'scripts/nvx_tools/build_config.py', 'scripts/nvx_tools/build_constants.py', 'scripts/nvx_tools/kconfig.py', 'scripts/nvx_tools/kernel_config.py', 'scripts/nvx_tools/kernel_features.py') }} - ALPINE_INPUT_HASH: ${{ hashFiles('SOURCE-MANIFEST.json', 'guest/common/**', 'guest/alpine/**', 'docker/Dockerfile', '.dockerignore', 'scripts/nvx_tools/build.py', 'scripts/nvx_tools/build_config.py', 'scripts/nvx_tools/build_constants.py', 'scripts/nvx_tools/common.py', 'scripts/nvx_tools/elf.py', 'scripts/nvx_tools/guest_binaries.py', 'scripts/nvx_tools/guests.py') }} + ALPINE_INPUT_HASH: ${{ hashFiles('SOURCE-MANIFEST.json', 'guest/common/**', 'docker/Dockerfile', '.dockerignore', 'scripts/nvx_tools/build.py', 'scripts/nvx_tools/build_config.py', 'scripts/nvx_tools/build_constants.py', 'scripts/nvx_tools/common.py', 'scripts/nvx_tools/elf.py', 'scripts/nvx_tools/guest_binaries.py', 'scripts/nvx_tools/guests.py') }} UBUNTU_INPUT_HASH: ${{ hashFiles('SOURCE-MANIFEST.json', 'guest/common/**', 'guest/ubuntu/**', 'ubuntu/**', 'docker/Dockerfile', '.dockerignore', 'scripts/nvx_tools/build.py', 'scripts/nvx_tools/build_config.py', 'scripts/nvx_tools/build_constants.py', 'scripts/nvx_tools/common.py', 'scripts/nvx_tools/elf.py', 'scripts/nvx_tools/guest_binaries.py', 'scripts/nvx_tools/guests.py', 'scripts/nvx_tools/ubuntu.py') }} AZURELINUX_INPUT_HASH: ${{ hashFiles('SOURCE-MANIFEST.json', 'guest/common/**', 'azurelinux/**', 'docker/Dockerfile', '.dockerignore', 'scripts/nvx_tools/azurelinux.py', 'scripts/nvx_tools/build.py', 'scripts/nvx_tools/build_config.py', 'scripts/nvx_tools/build_constants.py', 'scripts/nvx_tools/common.py', 'scripts/nvx_tools/elf.py', 'scripts/nvx_tools/guest_binaries.py', 'scripts/nvx_tools/guests.py') }} run: | diff --git a/.github/actions/check-quality/action.yml b/.github/actions/check-quality/action.yml index 6c1f9b148..1608a9621 100644 --- a/.github/actions/check-quality/action.yml +++ b/.github/actions/check-quality/action.yml @@ -40,8 +40,7 @@ runs: python -m ruff check scripts .github/specula python -m compileall -q .github/specula ${SHELLCHECK} --shell=sh \ - guest/common/init guest/alpine/nvx-container-enter \ - guest/alpine/nvx-container-launch \ + guest/common/init \ guest/common/nvx-hostmount guest/common/nvx-identity-probe \ guest/common/nvx-sandbox-smoke guest/common/nvx-snapshot \ guest/common/nvx-virtio-restore-probe \ @@ -53,8 +52,7 @@ runs: python -m pyright --pythonplatform Windows python -m ruff format --check scripts .github/specula ${SHFMT} -d -ln posix -i 4 -ci \ - guest/common/init guest/alpine/nvx-container-enter \ - guest/alpine/nvx-container-launch \ + guest/common/init \ guest/common/nvx-hostmount guest/common/nvx-identity-probe \ guest/common/nvx-sandbox-smoke guest/common/nvx-snapshot \ guest/common/nvx-virtio-restore-probe \ diff --git a/SOURCE-MANIFEST.json b/SOURCE-MANIFEST.json index 8b5ddb656..ba5654d49 100644 --- a/SOURCE-MANIFEST.json +++ b/SOURCE-MANIFEST.json @@ -38,7 +38,6 @@ "minirootfs_sha256": "41f73e3cf5fa919b8aa5ca6b30dc48f0da2720776d7423e2a7748211456fe081", "guest_sources": [ "guest/common", - "guest/alpine", "nvx-rs", "rust-toolchain.toml" ], diff --git a/doc/project-structure.md b/doc/project-structure.md index bf0907ccc..a0be6cbf6 100644 --- a/doc/project-structure.md +++ b/doc/project-structure.md @@ -57,8 +57,7 @@ nvx/ | `-- copilot-instructions.md Repository-wide Copilot instructions |-- .vscode/settings.json Shared VS Code settings |-- guest/ Guest-owned scripts -| |-- common/ Shared init, agent, snapshot, and probe scripts -| |-- alpine/ Alpine-control container entry scripts +| |-- common/ Shared init, snapshot, and probe scripts | `-- ubuntu/ Ubuntu interactive-shell startup policy |-- ubuntu/ | `-- packages.lock.json Exact supplemental Ubuntu binary package closure @@ -234,10 +233,7 @@ starts an initramfs program named by `nvx_exec=`, `nvx-init` for a layered root, workload named by `nvx_entrypoint=`, a virtio restore probe for benchmark profiling, or the interactive shell. On an interactive boot, `init` prints a stable distribution boot marker for Alpine and Azure Linux, and -`guest/ubuntu/nvx-bashrc` prints Ubuntu's. `guest/alpine` contains -the container launch and entry scripts that only the Alpine initramfs installs; -the entry script stages Alpine's musl loader and `setpriv` inside the -workload's root. +`guest/ubuntu/nvx-bashrc` prints Ubuntu's. The remaining common helpers handle shutdown, virtio-fs mounting, snapshot preparation, and the guest side of the time ABI. The Rust guest binaries diff --git a/doc/setup.md b/doc/setup.md index 56cda6a83..543cccc88 100644 --- a/doc/setup.md +++ b/doc/setup.md @@ -216,8 +216,7 @@ Run all lint and formatting checks before submitting a change: ```bash python3 -m ruff check scripts .github/specula shellcheck --shell=sh \ - guest/common/init guest/alpine/nvx-container-enter \ - guest/alpine/nvx-container-launch \ + guest/common/init \ guest/common/nvx-hostmount guest/common/nvx-identity-probe \ guest/common/nvx-sandbox-smoke \ guest/common/nvx-snapshot guest/common/nvx-virtio-restore-probe \ @@ -228,8 +227,7 @@ python3 -m pyright --pythonplatform Linux python3 -m pyright --pythonplatform Windows python3 -m ruff format --check scripts .github/specula shfmt -d -ln posix -i 4 -ci \ - guest/common/init guest/alpine/nvx-container-enter \ - guest/alpine/nvx-container-launch \ + guest/common/init \ guest/common/nvx-hostmount guest/common/nvx-identity-probe \ guest/common/nvx-sandbox-smoke \ guest/common/nvx-snapshot guest/common/nvx-virtio-restore-probe \ @@ -273,8 +271,7 @@ Apply the configured Python and POSIX shell formatters with: ```bash python3 -m ruff format scripts .github/specula shfmt -w -ln posix -i 4 -ci \ - guest/common/init guest/alpine/nvx-container-enter \ - guest/alpine/nvx-container-launch \ + guest/common/init \ guest/common/nvx-hostmount guest/common/nvx-identity-probe \ guest/common/nvx-sandbox-smoke \ guest/common/nvx-snapshot guest/common/nvx-virtio-restore-probe \ diff --git a/guest/alpine/nvx-container-enter b/guest/alpine/nvx-container-enter deleted file mode 100644 index 34aca9ae0..000000000 --- a/guest/alpine/nvx-container-enter +++ /dev/null @@ -1,83 +0,0 @@ -#!/bin/sh -set -eu - -rootfs=$1 -hostname_value=$2 -workload_uid=$3 -workload_gid=$4 -workload_name=$5 -workload_home=$6 -shift 6 -tools=$rootfs/.nvx-agent - -mount --make-rprivate / -rm -rf "$tools" -mkdir -p \ - "$tools" \ - "$rootfs/dev/pts" \ - "$rootfs/dev/shm" \ - "$rootfs/proc" \ - "$rootfs/sys" -mount -t tmpfs -o mode=755,nosuid,nodev tmpfs "$tools" -cp /lib/ld-musl-x86_64.so.1 "$tools/ld-musl-x86_64.so.1" -cp /bin/setpriv "$tools/setpriv" -cp -L /usr/lib/libcap-ng.so.0 "$tools/libcap-ng.so.0" -cp -L /usr/lib/libeconf.so.0 "$tools/libeconf.so.0" -chmod 0555 "$tools"/* -mount -o remount,ro,nosuid,nodev "$tools" -mount -t proc -o nosuid,nodev,noexec proc "$rootfs/proc" -mount -t sysfs -o ro,nosuid,nodev,noexec sysfs "$rootfs/sys" -mount -t tmpfs -o mode=755,nosuid tmpfs "$rootfs/dev" -mkdir -p "$rootfs/dev/pts" "$rootfs/dev/shm" -mount -t devpts -o newinstance,ptmxmode=0666,mode=0620 devpts "$rootfs/dev/pts" -mount -t tmpfs -o mode=1777,nosuid,nodev tmpfs "$rootfs/dev/shm" - -workload_machine_id=/run/nvx/workload-machine-id -[ -f "$workload_machine_id" ] && [ ! -L "$workload_machine_id" ] || exit 125 -if [ -L "$rootfs/etc" ] || { [ -e "$rootfs/etc" ] && [ ! -d "$rootfs/etc" ]; }; then - exit 125 -fi -mkdir -p "$rootfs/etc" -rm -f "$rootfs/etc/machine-id" -: >"$rootfs/etc/machine-id" -mount --bind "$workload_machine_id" "$rootfs/etc/machine-id" -mount -o remount,bind,ro,nosuid,nodev "$rootfs/etc/machine-id" - -# Workloads read the time ABI discontinuity state at the guest's path. No -# path component may be an image symlink, which would redirect the mount. -time_state=$rootfs -for component in run nvx time; do - time_state=$time_state/$component - if [ -L "$time_state" ] || { [ -e "$time_state" ] && [ ! -d "$time_state" ]; }; then - exit 125 - fi - mkdir -p "$time_state" -done -mount --bind /run/nvx/time "$time_state" -mount -o remount,bind,ro,nosuid,nodev,noexec "$time_state" - -mknod -m 666 "$rootfs/dev/null" c 1 3 -mknod -m 666 "$rootfs/dev/zero" c 1 5 -mknod -m 666 "$rootfs/dev/full" c 1 7 -mknod -m 666 "$rootfs/dev/random" c 1 8 -mknod -m 666 "$rootfs/dev/urandom" c 1 9 -mknod -m 666 "$rootfs/dev/tty" c 5 0 -ln -s pts/ptmx "$rootfs/dev/ptmx" -ln -s /proc/self/fd "$rootfs/dev/fd" -ln -s /proc/self/fd/0 "$rootfs/dev/stdin" -ln -s /proc/self/fd/1 "$rootfs/dev/stdout" -ln -s /proc/self/fd/2 "$rootfs/dev/stderr" - -hostname "$hostname_value" -export HOME="$workload_home" USER="$workload_name" LOGNAME="$workload_name" -exec chroot "$rootfs" /.nvx-agent/ld-musl-x86_64.so.1 \ - --library-path /.nvx-agent \ - /.nvx-agent/setpriv \ - --reuid "$workload_uid" \ - --regid "$workload_gid" \ - --clear-groups \ - --no-new-privs \ - --bounding-set=-all \ - --inh-caps=-all \ - --ambient-caps=-all \ - "$@" diff --git a/guest/alpine/nvx-container-launch b/guest/alpine/nvx-container-launch deleted file mode 100644 index 878793928..000000000 --- a/guest/alpine/nvx-container-launch +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh -set -eu - -barrier=$1 -rootfs=$2 -hostname_value=$3 -workload_uid=$4 -workload_gid=$5 -workload_name=$6 -workload_home=$7 -shift 7 - -IFS= read -r start <"$barrier" -[ "$start" = start ] || exit 125 - -exec unshare --mount --pid --uts --fork --kill-child \ - /sbin/nvx-container-enter \ - "$rootfs" "$hostname_value" "$workload_uid" "$workload_gid" \ - "$workload_name" "$workload_home" "$@" diff --git a/scripts/nvx_tools/build.py b/scripts/nvx_tools/build.py index 3d320b631..b642b028d 100644 --- a/scripts/nvx_tools/build.py +++ b/scripts/nvx_tools/build.py @@ -792,23 +792,7 @@ def _install_guest_files( root / "sbin" / "nvx-virtio-restore-probe", ), ] - if descriptor.sandbox_control: - alpine = BuildConstants.REPO_ROOT / AlpineBuildConstants.GUEST_DIRECTORY - scripts.extend( - [ - ( - "nvx-container-enter", - alpine / "nvx-container-enter", - root / "sbin" / "nvx-container-enter", - ), - ( - "nvx-container-launch", - alpine / "nvx-container-launch", - root / "sbin" / "nvx-container-launch", - ), - ] - ) - else: + if not descriptor.sandbox_control: scripts.append( ( "nvx-bashrc", @@ -889,14 +873,7 @@ def _guest_customization_files(descriptor: GuestDescriptor) -> tuple[Path, ...]: ) if path.is_file() ) - alpine = tuple( - path - for path in sorted( - (BuildConstants.REPO_ROOT / AlpineBuildConstants.GUEST_DIRECTORY).iterdir() - ) - if path.is_file() - ) - return (*common, *alpine, *guest_binary_source_files()) + return (*common, *guest_binary_source_files()) def build_initramfs(config: InitramfsBuildConfig) -> None: diff --git a/scripts/nvx_tools/build_constants.py b/scripts/nvx_tools/build_constants.py index 98b51133b..327c608e0 100644 --- a/scripts/nvx_tools/build_constants.py +++ b/scripts/nvx_tools/build_constants.py @@ -200,11 +200,7 @@ class GuestRustBuildConstants: class AlpineBuildConstants: GUEST_NAME: Final = "alpine" - GUEST_DIRECTORY: Final = Path("guest") / GUEST_NAME - GUEST_SOURCE_DIRECTORIES: Final = ( - BuildConstants.COMMON_GUEST_DIRECTORY, - GUEST_DIRECTORY, - ) + GUEST_SOURCE_DIRECTORIES: Final = (BuildConstants.COMMON_GUEST_DIRECTORY,) DISTRIBUTION: Final = "Alpine Linux" VERSION: Final = "3.24.1" BRANCH: Final = "v3.24" diff --git a/scripts/nvx_tools/release.py b/scripts/nvx_tools/release.py index acdcefb3a..ecf5c186b 100644 --- a/scripts/nvx_tools/release.py +++ b/scripts/nvx_tools/release.py @@ -1643,10 +1643,6 @@ def verify_source_tree() -> None: / "0002-microvm-hvc-xe9.patch": "xe9 HVC patch", BuildConstants.REPO_ROOT / "kernel" / "COPYING-LINUX": "Linux copyright notice", BuildConstants.REPO_ROOT / "guest" / "common" / "init": "common guest init", - BuildConstants.REPO_ROOT - / "guest" - / "alpine" - / "nvx-container-enter": "Alpine sandbox container helper", UbuntuBuildConstants.PACKAGE_LOCK: "Ubuntu supplemental package lock", OpenVMMBuildConstants.DIRECTORY / "Cargo.toml": "initialized OpenVMM submodule", } diff --git a/scripts/test_nvx_tools.py b/scripts/test_nvx_tools.py index e4d41ff37..664881ade 100644 --- a/scripts/test_nvx_tools.py +++ b/scripts/test_nvx_tools.py @@ -808,7 +808,6 @@ def _write_release_fixture( "minirootfs_sha256": AlpineBuildConstants.MINIROOTFS_SHA256, "guest_sources": [ "guest/common", - "guest/alpine", *GuestRustBuildConstants.SOURCE_PATHS, ], "package_manifests": ["build/initramfs.cpio.gz.packages.json"], @@ -7511,7 +7510,6 @@ def select(*outputs: str) -> ci.CiChanges: (("kernel/config-microvm",), microvm_and_benchmarks, None), (("kernel/patches/0001-example.patch",), microvm_and_benchmarks, None), (("guest/common/init",), microvm_and_benchmarks, None), - (("guest/alpine/nvx-container-enter",), microvm_and_benchmarks, None), ( (".github/actions/build-guest-artifacts/action.yml",), microvm_and_benchmarks,