From 017c2c018d3bb4aea5bfa54404e6b5f7b20d9381 Mon Sep 17 00:00:00 2001 From: O6lvl4 Date: Sun, 27 Sep 2026 23:20:25 +0900 Subject: [PATCH] Ship a Linux binary that starts on glibc 2.31 and needs no libssl The Linux release was linked on the Ubuntu 24.04 runner, so it asked for glibc 2.39 and libssl.so.3 and did not start on Debian 12, Ubuntu 22.04 or the python:*-slim images: most containers an agent runs in. - reqwest without its default features: TLS is rustls only - scripts/build-linux.sh builds in Debian bullseye, with the pinned Almide built from its tag there, and refuses a result past glibc 2.31 or one linking OpenSSL - release.yml builds Linux with it; the integration suite still runs the result on the runner - ci.yml checks that no OpenSSL is linked on Linux - README: the glibc floor Closes #35 Co-Authored-By: Claude Opus 5.5 (1M context) --- .github/workflows/ci.yml | 8 +++++++ .github/workflows/release.yml | 10 +++++++++ README.ja.md | 2 +- README.md | 2 +- README.zh-CN.md | 2 +- almide.toml | 2 +- scripts/build-linux.sh | 42 +++++++++++++++++++++++++++++++++++ 7 files changed, 64 insertions(+), 4 deletions(-) create mode 100755 scripts/build-linux.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 43242d6..fc63c55 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -76,6 +76,14 @@ jobs: run: .tools/almide/almide check src/main.almd - name: Build run: .tools/almide/almide build src/main.almd -o target/porta + # TLS is rustls only (reqwest without its default features), so the Linux + # binary needs no libssl.so.3 from whatever image it lands in (#35). A + # dependency that turns native-tls back on shows up here. + - name: No OpenSSL linked + if: runner.os == 'Linux' + run: | + ldd target/porta + ! ldd target/porta | grep -E 'libssl|libcrypto' - name: Test run: .tools/almide/almide test --ci # The memory ceiling is a cgroup v2 scope asked of the systemd user diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 24aa1f8..18a479f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -39,9 +39,19 @@ jobs: python-version: "3.12" - uses: dtolnay/rust-toolchain@stable - name: Install pinned Almide + if: runner.os == 'macOS' run: bash scripts/install-almide.sh - name: Build + if: runner.os == 'macOS' run: .tools/almide/almide build src/main.almd -o target/porta + # Linux builds in Debian bullseye, not on the runner: a binary linked on + # Ubuntu 24.04 asks for glibc 2.39 and does not start on Debian 12, + # Ubuntu 22.04 or the python:*-slim images, which is most containers an + # agent runs in (#35). The script refuses a result past glibc 2.31 or one + # linking OpenSSL. + - name: Build (Debian bullseye, glibc 2.31) + if: runner.os == 'Linux' + run: bash scripts/build-linux.sh target/porta # A binary nobody checked is worse than no binary: the same suite that # gates a commit gates a release, on the machine that produced the file. - name: Verify the binary that will ship diff --git a/README.ja.md b/README.ja.md index b7b31da..4b3b37d 100644 --- a/README.ja.md +++ b/README.ja.md @@ -46,7 +46,7 @@ curl -fsSL https://raw.githubusercontent.com/almide/porta/main/scripts/install.s | 環境 | 方法 | |---|---| -| macOS (Apple silicon)、Linux (x86-64, arm64) | 上のスクリプト。SHA-256 を検証し、`cosign` があれば Sigstore 署名も検証 | +| macOS (Apple silicon)、Linux (x86-64, arm64。glibc 2.31 以降:Debian 11、Ubuntu 20.04 以降) | 上のスクリプト。SHA-256 を検証し、`cosign` があれば Sigstore 署名も検証 | | Debian、Ubuntu | [リリース](https://github.com/almide/porta/releases)の `sudo apt install ./porta__amd64.deb`。Ubuntu 23.10 以降では namespace に必要な AppArmor プロファイルも読み込む | | それ以外の方法で入れた Ubuntu | 一度だけ `sudo porta setup` で同じプロファイルを入れる | | GitHub Actions | `- uses: almide/porta@v0.6.16` の後、どのステップでも `porta run …` | diff --git a/README.md b/README.md index 43c9a7e..ed5f321 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ curl -fsSL https://raw.githubusercontent.com/almide/porta/main/scripts/install.s | Where | How | |---|---| -| macOS (Apple silicon), Linux (x86-64, arm64) | the script above: checks the SHA-256, and the Sigstore signature where `cosign` is installed | +| macOS (Apple silicon), Linux (x86-64, arm64; glibc 2.31+: Debian 11, Ubuntu 20.04 and later) | the script above: checks the SHA-256, and the Sigstore signature where `cosign` is installed | | Debian, Ubuntu | `sudo apt install ./porta__amd64.deb` from a [release](https://github.com/almide/porta/releases); on Ubuntu 23.10+ it also loads the AppArmor profile porta's namespaces need | | Ubuntu, installed any other way | `sudo porta setup` once, for the same profile | | GitHub Actions | `- uses: almide/porta@v0.6.16`, then `porta run …` in any step | diff --git a/README.zh-CN.md b/README.zh-CN.md index d9ac93c..25a30fa 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -45,7 +45,7 @@ curl -fsSL https://raw.githubusercontent.com/almide/porta/main/scripts/install.s | 平台 | 方法 | |---|---| -| macOS (Apple silicon)、Linux (x86-64, arm64) | 上面的脚本:校验 SHA-256,安装了 `cosign` 时还会校验 Sigstore 签名 | +| macOS (Apple silicon)、Linux (x86-64, arm64;glibc 2.31+:Debian 11、Ubuntu 20.04 及以上) | 上面的脚本:校验 SHA-256,安装了 `cosign` 时还会校验 Sigstore 签名 | | Debian、Ubuntu | 从 [release](https://github.com/almide/porta/releases) 下载后 `sudo apt install ./porta__amd64.deb`;在 Ubuntu 23.10+ 上还会加载命名空间所需的 AppArmor 配置 | | 以其他方式安装的 Ubuntu | 运行一次 `sudo porta setup`,加载同样的配置 | | GitHub Actions | `- uses: almide/porta@v0.6.16`,之后任意步骤中都可 `porta run …` | diff --git a/almide.toml b/almide.toml index e5adf37..592520f 100644 --- a/almide.toml +++ b/almide.toml @@ -8,7 +8,7 @@ allow = ["FS.read", "FS.write", "IO", "Env", "Time", "Net"] [native-deps] wasmtime = "47.0.3" wasmtime-wasi = { version = "47.0.3", features = ["p3"] } -reqwest = { version = "0.12.28", features = ["blocking", "rustls-tls"] } +reqwest = { version = "0.12.28", default-features = false, features = ["blocking", "rustls-tls"] } serde_json = "1" sha2 = "0.10" jsonschema = { version = "=0.56.0", default-features = false } diff --git a/scripts/build-linux.sh b/scripts/build-linux.sh new file mode 100755 index 0000000..6223f65 --- /dev/null +++ b/scripts/build-linux.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +# Builds the Linux porta that ships: inside Debian bullseye, so the binary asks for +# nothing newer than glibc 2.31 and runs on Debian 11 and later, Ubuntu 20.04 and later, +# and the python:*-slim images (#35). A binary built on the runner itself (Ubuntu 24.04) +# needed glibc 2.39 and did not start on bookworm. +# +# scripts/build-linux.sh [OUT] (default: target/porta) +# +# The pinned Almide is built from its tag in the same container, because its own Linux +# release needs glibc 2.39 too. The result is checked before it is handed back: no glibc +# symbol past 2.31, and no libssl or libcrypto (porta speaks TLS through rustls only). +set -euo pipefail + +cd "$(dirname "${BASH_SOURCE[0]}")/.." +out="${1:-target/porta}" +tag="${ALMIDE_RELEASE_TAG:-$(sed -n 's/^tag="\${ALMIDE_RELEASE_TAG:-\(.*\)}"$/\1/p' scripts/install-almide.sh)}" +[ -n "$tag" ] || { echo "no pinned Almide tag in scripts/install-almide.sh" >&2; exit 2; } +image="${PORTA_LINUX_BUILD_IMAGE:-rust:1-bullseye}" +mkdir -p "$(dirname "$out")" .tools/linux-build + +# As the caller's user, so what lands in target/ can be stripped and packaged after. +docker run --rm --user "$(id -u):$(id -g)" -e HOME=/tmp -v "$PWD:/src" -w /src \ + -e ALMIDE_TAG="$tag" -e OUT="$out" -e CARGO_HOME=/src/.tools/linux-build/cargo \ + ${CARGO_BUILD_JOBS:+-e CARGO_BUILD_JOBS="$CARGO_BUILD_JOBS"} "$image" bash -euo pipefail -c ' + almide=/src/.tools/linux-build/almide-$ALMIDE_TAG + if [ ! -x "$almide" ]; then + git init -q /tmp/almide && cd /tmp/almide + git remote add origin https://github.com/almide/almide + git fetch -q --depth 1 origin "refs/tags/$ALMIDE_TAG:refs/tags/$ALMIDE_TAG" + git checkout -q "$ALMIDE_TAG" + cargo build --release --locked --bin almide > /tmp/almide-build.log 2>&1 || { tail -30 /tmp/almide-build.log; exit 1; } + install -m 0755 target/release/almide "$almide" + cd /src + fi + "$almide" --version + "$almide" build src/main.almd -o "$OUT" + newest=$(objdump -T "$OUT" | grep -o "GLIBC_[0-9.]*" | sort -uV | tail -1) + echo "needs $newest" + [ "$(printf "%s\nGLIBC_2.31\n" "$newest" | sort -V | tail -1)" = GLIBC_2.31 ] || { echo "needs $newest, past bullseye" >&2; exit 1; } + if ldd "$OUT" | grep -E "libssl|libcrypto"; then echo "links OpenSSL; porta is rustls only" >&2; exit 1; fi + ' +echo "== built $out"