diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1a428c56..53f0d276 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -114,18 +114,8 @@ jobs: - run: | set -x - sudo apt-get update && \ - sudo apt-get install -y \ - apt-transport-https \ - ca-certificates \ - curl \ - gnupg - - curl -fsSL https://gvisor.dev/archive.key | sudo gpg --dearmor -o /usr/share/keyrings/gvisor-archive-keyring.gpg - echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/gvisor-archive-keyring.gpg] https://storage.googleapis.com/gvisor/releases release main" | sudo tee /etc/apt/sources.list.d/gvisor.list > /dev/null - - sudo apt-get update && sudo apt-get install -y runsc - sudo runsc install + bash scripts/installGvisor.sh + sudo /usr/local/bin/runsc install sudo systemctl restart docker docker info name: Install gVisor diff --git a/build/templates/installSandbox.yml b/build/templates/installSandbox.yml index 7d3ba0db..067da3a3 100644 --- a/build/templates/installSandbox.yml +++ b/build/templates/installSandbox.yml @@ -43,26 +43,15 @@ steps: - bash: | set -exo pipefail if command -v apt-get >/dev/null; then - sudo apt-get install -y apt-transport-https ca-certificates curl gnupg acl - curl -fsSL https://gvisor.dev/archive.key | sudo gpg --dearmor -o /usr/share/keyrings/gvisor-archive-keyring.gpg - echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/gvisor-archive-keyring.gpg] https://storage.googleapis.com/gvisor/releases release main" | sudo tee /etc/apt/sources.list.d/gvisor.list > /dev/null - sudo apt-get update - sudo apt-get install -y runsc - RUNSC=/usr/bin/runsc + sudo apt-get install -y ca-certificates curl acl tar bzip2 elif command -v tdnf >/dev/null; then sudo tdnf install -y ca-certificates curl moby-engine moby-cli moby-buildx util-linux acl tar bzip2 - INSTALL_DIR=$(mktemp -d "${AGENT_TEMPDIRECTORY:?}/tsperf-runsc.XXXXXX") - trap 'rm -f "$INSTALL_DIR/gvisor.tar.bz2" "$INSTALL_DIR/gvisor.tar.bz2.sha512"; rmdir "$INSTALL_DIR"' EXIT - URL="https://storage.googleapis.com/gvisor/releases/release/latest/$(uname -m)" - curl -fsSL "$URL/gvisor.tar.bz2" -o "$INSTALL_DIR/gvisor.tar.bz2" - curl -fsSL "$URL/gvisor.tar.bz2.sha512" -o "$INSTALL_DIR/gvisor.tar.bz2.sha512" - (cd "$INSTALL_DIR" && sha512sum --check gvisor.tar.bz2.sha512) - sudo tar -xjf "$INSTALL_DIR/gvisor.tar.bz2" -C /usr/local/bin --no-same-owner --no-same-permissions - RUNSC=/usr/local/bin/runsc else echo "Unsupported package manager for scenario sandbox installation" >&2 exit 1 fi + bash "$PIPELINE_WORKSPACE/typescript-benchmarking/scripts/installGvisor.sh" + RUNSC=/usr/local/bin/runsc docker buildx version sudo "$RUNSC" install sudo systemctl restart docker diff --git a/scripts/installGvisor.sh b/scripts/installGvisor.sh new file mode 100755 index 00000000..09b7fd71 --- /dev/null +++ b/scripts/installGvisor.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +# Installs a pinned gVisor release into /usr/local/bin for the scenario installer sandbox. +# Upstream's "latest" tarball, checksum, and apt index are replaced separately, so they can +# disagree while a release is being published. Pin a release and commit its checksums. +# To update, pick a release from https://gvisor.dev/docs/user_guide/install/ and use the +# checksums from its gvisor.tar.bz2.sha512 files. + +set -eo pipefail + +GVISOR_RELEASE=20261019.0 +ARCH=$(uname -m) +case "$ARCH" in + x86_64) GVISOR_SHA512=7cbc2aeeee809dcccfb40e612504a1b76f2c119790cee59e482f7b35428cccc4f71705e7e322442d07d1f7d29b5d9e72e31319fc3088d6dcbec9fc7c1f0d8881 ;; + aarch64) GVISOR_SHA512=6b14b582cd3185169df54275eed8721d94c9b40e6cb1533d0d0c46573271c6d2d03db586ea1caac46a45e805797f00b115bead9fb93636a1ffa69f2430958977 ;; + *) + echo "Unsupported architecture for gVisor" >&2 + exit 1 + ;; +esac + +INSTALL_DIR=$(mktemp -d "${RUNNER_TEMP:-${AGENT_TEMPDIRECTORY:-/tmp}}/tsperf-runsc.XXXXXX") +trap 'rm -f "$INSTALL_DIR/gvisor.tar.bz2"; rmdir "$INSTALL_DIR"' EXIT + +curl -fsSL --retry 3 "https://storage.googleapis.com/gvisor/releases/release/$GVISOR_RELEASE/$ARCH/gvisor.tar.bz2" \ + -o "$INSTALL_DIR/gvisor.tar.bz2" +echo "$GVISOR_SHA512 $INSTALL_DIR/gvisor.tar.bz2" | sha512sum --check +sudo tar -xjf "$INSTALL_DIR/gvisor.tar.bz2" -C /usr/local/bin --no-same-owner --no-same-permissions diff --git a/scripts/src/__tests__/scenarioSetup.test.ts b/scripts/src/__tests__/scenarioSetup.test.ts index faa51e25..e5a66b38 100644 --- a/scripts/src/__tests__/scenarioSetup.test.ts +++ b/scripts/src/__tests__/scenarioSetup.test.ts @@ -7,6 +7,7 @@ import { fileURLToPath } from "node:url"; import { afterEach, expect, test } from "vitest"; import { parse } from "yaml"; +const repoRoot = fileURLToPath(new URL("../../..", import.meta.url)); const commonScript = fileURLToPath(new URL("../../../cases/common.sh", import.meta.url)); const setupScript = fileURLToPath(new URL("../../setupScenario.sh", import.meta.url)); const benchmarkScript = fileURLToPath(new URL("../../runBenchmarkSandbox.sh", import.meta.url)); @@ -62,6 +63,9 @@ function runAzureLinuxSetup(env: Record = {}) { const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "typescript-benchmarking-azurelinux-")); tempDirs.push(tempDir); const commands = path.join(tempDir, "commands"); + const workspace = fs.mkdtempSync(path.join(os.tmpdir(), "typescript-benchmarking-workspace-")); + tempDirs.push(workspace); + fs.symlinkSync(repoRoot, path.join(workspace, "typescript-benchmarking")); const script = ` command() { if [ "$1" = "-v" ]; then @@ -79,13 +83,23 @@ sudo() { fi } curl() { - if [[ "$2" == */gvisor.tar.bz2.sha512 ]]; then - (cd "\${4%/*}" && sha512sum gvisor.tar.bz2) > "$4" - if [ "\${CORRUPT_DOWNLOAD:-}" = "true" ]; then - printf 'modified' >> "\${4%/*}/gvisor.tar.bz2" - fi + local out url + while [ $# -gt 0 ]; do + case "$1" in + -o) out=$2; shift ;; + https://*) url=$1 ;; + esac + shift + done + printf '%s\\n' "curl $url" >> "$COMMANDS" + printf '#!/bin/sh\\nexit 0\\n' > "$out" +} +# The stub download cannot match the pinned checksum, so accept it unless testing corruption. +sha512sum() { + if [ "\${CORRUPT_DOWNLOAD:-}" = "true" ]; then + builtin command sha512sum "$@" else - printf '#!/bin/sh\\nexit 0\\n' > "$4" + printf '%s\\n' "sha512sum $* $(cat)" >> "$COMMANDS" fi } docker() { @@ -94,12 +108,14 @@ docker() { return 37 fi } +export -f sudo curl sha512sum docker ${sandboxScript("Install scenario sandbox")} `; const result = spawnSync("bash", ["-c", script], { env: { ...process.env, AGENT_TEMPDIRECTORY: tempDir, + PIPELINE_WORKSPACE: workspace, COMMANDS: commands, ...env, }, @@ -115,6 +131,12 @@ test("Azure Linux installs and verifies gVisor before configuring Docker", () => expect(commands).toContain( "tdnf install -y ca-certificates curl moby-engine moby-cli moby-buildx util-linux acl tar bzip2", ); + expect(commands).toContain( + `curl https://storage.googleapis.com/gvisor/releases/release/20261019.0/${ + os.arch() === "arm64" ? "aarch64" : "x86_64" + }/gvisor.tar.bz2\n`, + ); + expect(commands).toMatch(/^sha512sum --check [0-9a-f]{128} {2}\S+\/gvisor\.tar\.bz2$/m); expect(commands).toContain("tar -xjf"); expect(commands).toContain("docker buildx version\n/usr/local/bin/runsc install\nsystemctl restart docker\n"); expect(commands).toContain("docker info");