diff options
| author | Doan Luu Duc Tai <doan@luuduct.ai> | 2026-11-01 07:13:45 -0600 |
|---|---|---|
| committer | Doan Luu Duc Tai <doan@luuduct.ai> | 2026-11-01 07:13:45 -0600 |
| commit | 9349a2de648e241da8e00ba7ae25cb2a877ff3e9 (patch) | |
| tree | 2fea913ee0aaff4370877f4a91c911db2fe37592 /infra/guix/test-bootstrap.sh | |
| parent | 5b89c370d5974f057306a52089f14c337565fd1d (diff) | |
feat(guix): carry prebuilt runtime and recover preserved state
Diffstat (limited to 'infra/guix/test-bootstrap.sh')
| -rw-r--r-- | infra/guix/test-bootstrap.sh | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/infra/guix/test-bootstrap.sh b/infra/guix/test-bootstrap.sh new file mode 100644 index 0000000..470ebeb --- /dev/null +++ b/infra/guix/test-bootstrap.sh @@ -0,0 +1,118 @@ +#!/bin/sh +# Copyright (C) 2026 Doan Luu Duc Tai <doan@luuduct.ai> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +set -eu +umask 077 +ROOT=$(CDPATH= cd -- "$(dirname -- "$0")/../.." && pwd) +command -v bwrap >/dev/null || { echo 'Bootstrap tests require bubblewrap.' >&2; exit 1; } +STAGE=$(mktemp -d) +trap 'chmod -R u+w "$STAGE"; rm -rf -- "$STAGE"' EXIT HUP INT TERM +mkdir -p "$STAGE/capsule" "$STAGE/pack/gnu/store/00000000000000000000000000000000-tool/bin" \ + "$STAGE/pack/gnu/store/11111111111111111111111111111111-profile/bin" "$STAGE/pack/etc" +cp "$ROOT/infra/guix/bootstrap.sh" "$STAGE/capsule/bootstrap" +printf '%s\n' '#!/bin/sh' 'printf "%s\n" canonical-tool' > "$STAGE/pack/gnu/store/00000000000000000000000000000000-tool/bin/tool" +chmod 755 "$STAGE/pack/gnu/store/00000000000000000000000000000000-tool/bin/tool" +ln -s /gnu/store/00000000000000000000000000000000-tool/bin/tool "$STAGE/pack/gnu/store/11111111111111111111111111111111-profile/bin/tool" +ln -s /gnu/store/11111111111111111111111111111111-profile/bin "$STAGE/pack/bin" +printf '%s\n' 'Must stay inside pack.' > "$STAGE/pack/etc/pack-sentinel" +tar -czf "$STAGE/capsule/runtime.tar.gz" -C "$STAGE/pack" . +(cd "$STAGE/capsule" && sha256sum bootstrap runtime.tar.gz > SHA256SUMS) +cp -a "$STAGE/capsule" "$STAGE/tampered" +printf '%s\n' 'tamper' >> "$STAGE/tampered/runtime.tar.gz" +cp -a "$STAGE/capsule" "$STAGE/next" +mkdir "$STAGE/pack/gnu/store/22222222222222222222222222222222-next" +printf '%s\n' 'Second closure.' > "$STAGE/pack/gnu/store/22222222222222222222222222222222-next/value" +tar -czf "$STAGE/next/runtime.tar.gz" -C "$STAGE/pack" . +(cd "$STAGE/next" && sha256sum bootstrap runtime.tar.gz > SHA256SUMS) +bwrap --unshare-user --uid 0 --gid 0 --unshare-pid --cap-add CAP_DAC_OVERRIDE \ + --tmpfs / --ro-bind /usr /usr \ + --symlink usr/bin /bin --symlink usr/lib /lib --symlink usr/lib /lib64 \ + --ro-bind "$STAGE/capsule" /capsule --ro-bind "$STAGE/next" /next \ + --ro-bind "$STAGE/tampered" /tampered --proc /proc --dev /dev --tmpfs /tmp \ + --chdir / /bin/sh -eu <<'TEST' +fail() { printf '%s\n' "$1" >&2; exit 1; } +reject() { if sh "$1/bootstrap"; then fail "$2"; fi; } +TOOL=/gnu/store/00000000000000000000000000000000-tool/bin/tool +PROFILE=/gnu/store/11111111111111111111111111111111-profile +mkdir /etc +printf '%s\n' 'Host configuration.' > /etc/host-sentinel +[ ! -e /gnu ] && [ ! -e /var/guix ] +if sh /capsule/bootstrap extra; then fail 'Accepted bootstrap arguments.'; fi +reject /tampered 'Accepted altered runtime.' +[ ! -e /gnu ] +sh /capsule/bootstrap > /tmp/bootstrap-first.log & +FIRST=$! +sh /capsule/bootstrap +wait "$FIRST" +DIGEST=$(sha256sum /capsule/runtime.tar.gz) +DIGEST=${DIGEST%% *} +[ "$(cat "/gnu/.stack-runtimes/$DIGEST")" = "$DIGEST" ] +[ -z "$(find /gnu/store -mindepth 1 ! -user 0 -print -quit)" ] +[ -z "$(find /gnu/store -mindepth 1 ! -type l -perm /222 -print -quit)" ] +[ "$("$PROFILE/bin/tool")" = canonical-tool ] +[ "$(readlink "$PROFILE/bin/tool")" = "$TOOL" ] +[ "$(readlink /bin)" = usr/bin ] +[ "$(cat /etc/host-sentinel)" = 'Host configuration.' ] +[ ! -e /etc/pack-sentinel ] +INODE=$(stat -c %i "/gnu/.stack-runtimes/$DIGEST") +sh /capsule/bootstrap +[ "$(stat -c %i "/gnu/.stack-runtimes/$DIGEST")" = "$INODE" ] +rm "/gnu/.stack-runtimes/$DIGEST" +chmod -R u+w "$PROFILE" +rm -rf "$PROFILE" +sh /capsule/bootstrap +[ "$("$PROFILE/bin/tool")" = canonical-tool ] +[ -f "/gnu/.stack-runtimes/$DIGEST" ] +[ -z "$(find /gnu -maxdepth 1 -name '.stack-stage.*' -print -quit)" ] +sh /next/bootstrap +[ "$("$PROFILE/bin/tool")" = canonical-tool ] +[ "$(cat /gnu/store/22222222222222222222222222222222-next/value)" = 'Second closure.' ] +[ -f "/gnu/.stack-runtimes/$DIGEST" ] +rm "/gnu/.stack-runtimes/$DIGEST" +chmod u+w "$TOOL" +printf '%s\n' 'conflicting content' >> "$TOOL" +chmod a-w "$TOOL" +reject /capsule 'Overwrote conflicting store entry.' +[ ! -e "/gnu/.stack-runtimes/$DIGEST" ] +[ -z "$(find /gnu -maxdepth 1 -name '.stack-stage.*' -print -quit)" ] +tail -n 1 "$TOOL" | grep -Fx 'conflicting content' +chmod -R u+w /gnu +rm -rf /gnu +mkdir -p /var/guix +reject /capsule 'Accepted managed Guix installation.' +[ ! -e /gnu ] +rm -rf /var/guix +mkdir -p /gnu/store +printf '%s\n' 'Foreign store.' > /gnu/store/sentinel +reject /capsule 'Accepted foreign store.' +[ "$(cat /gnu/store/sentinel)" = 'Foreign store.' ] +rm -rf /gnu +mkdir /outside +ln -s /outside /gnu +reject /capsule 'Accepted symlink /gnu.' +[ -z "$(find /outside -mindepth 1 -print -quit)" ] +rm /gnu +mkdir -p /gnu/.stack-runtimes +chmod 755 /gnu /gnu/.stack-runtimes +ln -s /outside /gnu/store +reject /capsule 'Accepted symlink store.' +[ -z "$(find /outside -mindepth 1 -print -quit)" ] +rm /gnu/store +chmod 777 /gnu/.stack-runtimes +reject /capsule 'Accepted writable ownership metadata.' +[ ! -e /gnu/store ] +printf '%s\n' 'Canonical bootstrap, retry, idempotency, preservation and refusal checks passed.' +TEST |
