Quellcode durchsuchen

ci: unpack bubblewrap without package transaction

Tianyi Cui vor 1 Monat
Ursprung
Commit
d7e0104a72
2 geänderte Dateien mit 43 neuen und 48 gelöschten Zeilen
  1. 13 48
      .github/workflows/ci.yml
  2. 30 0
      scripts/prepare-ci-bubblewrap.sh

+ 13 - 48
.github/workflows/ci.yml

@@ -277,23 +277,16 @@ jobs:
       # re-executing their bash calls under a real runner. ubuntu-latest has
       # no bubblewrap preinstalled and no built Landlock launcher, so without
       # this the confined executions fail closed (SANDBOX_UNAVAILABLE). The
-      # install retries after refreshing stale indexes and applies the Ubuntu
-      # 24.04 AppArmor userns knob. Bubblewrap preparation is independent of
-      # dependency installation and the build, so it runs beside both.
-      - name: Install and prepare built snapshot runtime and bubblewrap
+      # pinned Ubuntu payload is verified and extracted into the ephemeral
+      # runner instead of paying for a system package transaction. Bubblewrap
+      # preparation is independent of dependency installation and the build,
+      # so it runs beside both.
+      - name: Prepare built snapshot runtime and bubblewrap
         if: startsWith(matrix.lane, 'snapshot-')
         run: |
           pnpm install --frozen-lockfile &
           install_pid=$!
-          (
-            if ! sudo apt-get install -yq --no-install-recommends bubblewrap; then
-              echo "initial bubblewrap install failed; refreshing APT indexes and retrying"
-              sudo apt-get update -q
-              sudo apt-get install -yq --no-install-recommends bubblewrap
-            fi
-            sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 \
-              || echo "apparmor userns knob absent — the functional probe decides"
-          ) &
+          bash scripts/prepare-ci-bubblewrap.sh &
           sandbox_pid=$!
           install_status=0
           wait "$install_pid" || install_status=$?
@@ -356,19 +349,11 @@ jobs:
           restore-keys: |
             ${{ runner.os }}-node-${{ env.PRIMARY_NODE_VERSION }}-eslint-full-
 
-      - name: Install and prepare bubblewrap
+      - name: Install dependencies and prepare bubblewrap
         run: |
           pnpm install --frozen-lockfile &
           install_pid=$!
-          (
-            if ! sudo apt-get install -yq --no-install-recommends bubblewrap; then
-              echo "initial bubblewrap install failed; refreshing APT indexes and retrying"
-              sudo apt-get update -q
-              sudo apt-get install -yq --no-install-recommends bubblewrap
-            fi
-            sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 \
-              || echo "apparmor userns knob absent — the functional probe decides"
-          ) &
+          bash scripts/prepare-ci-bubblewrap.sh &
           sandbox_pid=$!
           install_status=0
           wait "$install_pid" || install_status=$?
@@ -473,20 +458,12 @@ jobs:
         if: matrix.primary_cpu != true
         run: pnpm install --frozen-lockfile
 
-      - name: Install and prepare bubblewrap
+      - name: Install dependencies and prepare bubblewrap
         if: matrix.primary_cpu == true
         run: |
           pnpm install --frozen-lockfile &
           install_pid=$!
-          (
-            if ! sudo apt-get install -yq --no-install-recommends bubblewrap; then
-              echo "initial bubblewrap install failed; refreshing APT indexes and retrying"
-              sudo apt-get update -q
-              sudo apt-get install -yq --no-install-recommends bubblewrap
-            fi
-            sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 \
-              || echo "apparmor userns knob absent — the functional probe decides"
-          ) &
+          bash scripts/prepare-ci-bubblewrap.sh &
           sandbox_pid=$!
           install_status=0
           wait "$install_pid" || install_status=$?
@@ -731,12 +708,8 @@ jobs:
       - name: Install (immutable)
         run: pnpm install --frozen-lockfile
 
-      - name: Install bubblewrap (unrestrict userns)
-        run: |
-          sudo apt-get update -q
-          sudo apt-get install -yq --no-install-recommends bubblewrap
-          sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 \
-            || echo "apparmor userns knob absent — the functional probe decides"
+      - name: Prepare bubblewrap (unrestrict userns)
+        run: bash scripts/prepare-ci-bubblewrap.sh
 
       - name: Run complete unsharded primary Node CI serially
         env:
@@ -1016,15 +989,7 @@ jobs:
         run: |
           pnpm install --frozen-lockfile &
           install_pid=$!
-          (
-            if ! sudo apt-get install -yq --no-install-recommends bubblewrap; then
-              echo "initial bubblewrap install failed; refreshing APT indexes and retrying"
-              sudo apt-get update -q
-              sudo apt-get install -yq --no-install-recommends bubblewrap
-            fi
-            sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 \
-              || echo "apparmor userns knob absent — the functional probe decides"
-          ) &
+          bash scripts/prepare-ci-bubblewrap.sh &
           sandbox_pid=$!
           install_status=0
           wait "$install_pid" || install_status=$?

+ 30 - 0
scripts/prepare-ci-bubblewrap.sh

@@ -0,0 +1,30 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+# Ubuntu's package transaction scans the hosted image's full dpkg database and
+# runs post-install hooks. CI needs only the signed-archive payload, so pin and
+# verify that payload before extracting it into the ephemeral runner directory.
+readonly BUBBLEWRAP_VERSION='0.9.0-1ubuntu0.1'
+readonly BUBBLEWRAP_SHA256='1b506492bd9c7fd0cdb4f02ac822f1d3e336b0aead5113c1239baf8db5db562a'
+readonly BUBBLEWRAP_URL="https://archive.ubuntu.com/ubuntu/pool/main/b/bubblewrap/bubblewrap_${BUBBLEWRAP_VERSION}_amd64.deb"
+
+: "${RUNNER_TEMP:?prepare-ci-bubblewrap requires RUNNER_TEMP}"
+: "${GITHUB_PATH:?prepare-ci-bubblewrap requires GITHUB_PATH}"
+
+if [[ "$(uname -s)" != 'Linux' || "$(uname -m)" != 'x86_64' ]]; then
+  echo 'prepare-ci-bubblewrap supports only Linux x86_64 hosted runners' >&2
+  exit 1
+fi
+
+archive="${RUNNER_TEMP}/bubblewrap_${BUBBLEWRAP_VERSION}_amd64.deb"
+root="${RUNNER_TEMP}/dsh-bubblewrap"
+
+curl --fail --silent --show-error --location --retry 3 --output "$archive" "$BUBBLEWRAP_URL"
+printf '%s  %s\n' "$BUBBLEWRAP_SHA256" "$archive" | sha256sum --check --status
+mkdir -p "$root"
+dpkg-deb --extract "$archive" "$root"
+printf '%s\n' "$root/usr/bin" >> "$GITHUB_PATH"
+
+sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 \
+  || echo 'apparmor userns knob absent — the functional probe decides'
+"$root/usr/bin/bwrap" --version