mirror of
https://github.com/cozystack/cozystack.git
synced 2026-11-09 14:02:56 +09:00
Nightly and the rc gate still booted the management nodes as QEMU guests, the substrate the merge-gating lanes left behind. On it the tenant Kubernetes suites have missed their node-join deadline on most nights since 2026-10-02, each failure spends the whole deadline, and the job reaches its timeout before the alphabetically later suites run. Over the same days those suites passed on every PR run that selected them, where the nodes are Talos containers and a tenant worker sits one virtualization level shallower. Both lanes now use the PR lanes' container substrate. Nightly's e2e no longer waits for the nocloud disk, which it does not boot; the disk is still built and published. A manual e2e-tag dispatch against a tag that predates the container lane fails early and names the ref to dispatch from instead. DRBD, the replicated StorageClass and the Cozystack Talos node image lose their last e2e coverage with this. The docs and comments that pointed at nightly and the rc gate as that coverage now say so. Assisted-by: LLM Signed-off-by: Aleksei Sviridkin <f@lex.la>
155 lines
7.3 KiB
Bash
155 lines
7.3 KiB
Bash
#!/usr/bin/env bats
|
|
# Tests for hack/collect-images.sh, which lists the images the e2e sandbox's
|
|
# Talos nodes hold. Its image-refs.txt feeds the runtime multi-arch audit, so
|
|
# it must name every pulled image by the digest the node resolved, and must not
|
|
# be written at all when a node could not be read.
|
|
#
|
|
# talosctl is a stub: it prints the `images ls` table held in
|
|
# $MOCK_TALOS/<node>-<namespace>, or fails for a node listed in $MOCK_TALOS/down.
|
|
#
|
|
# Harness note: the unit lane runs this file under Bats. The bodies stay POSIX
|
|
# sh (no `run`, no [[ ]]; each @test a shell function under `set -eu`), so
|
|
# hack/cozytest.sh can still run it under dash by hand.
|
|
#
|
|
# Run with: bats hack/collect-images_test.bats
|
|
|
|
load test_helper
|
|
|
|
_stub_talos() {
|
|
MOCK_TALOS="$1"
|
|
export MOCK_TALOS
|
|
mkdir -p "$MOCK_TALOS/bin"
|
|
: >"$MOCK_TALOS/down"
|
|
cat >"$MOCK_TALOS/bin/talosctl" <<'EOF'
|
|
#!/bin/sh
|
|
set -eu
|
|
node="$2"
|
|
ns=cri
|
|
[ "$6" = --namespace ] && ns="$7"
|
|
if grep -qxF "$node" "$MOCK_TALOS/down"; then echo "rpc error: connection refused" >&2; exit 1; fi
|
|
printf 'NODE IMAGE DIGEST SIZE LABELS CREATED\n'
|
|
[ -f "$MOCK_TALOS/$node-$ns" ] && cat "$MOCK_TALOS/$node-$ns"
|
|
exit 0
|
|
EOF
|
|
chmod +x "$MOCK_TALOS/bin/talosctl"
|
|
}
|
|
|
|
D1="sha256:$(printf '1%.0s' $(seq 1 64))"
|
|
D2="sha256:$(printf '2%.0s' $(seq 1 64))"
|
|
D3="sha256:$(printf '3%.0s' $(seq 1 64))"
|
|
|
|
@test "image-refs.txt names every image a node holds by the digest it resolved" {
|
|
tmp=$(mktemp -d)
|
|
_stub_talos "$tmp/talos"
|
|
n=192.168.123.11
|
|
{
|
|
printf '%s ghcr.io/cozy/api:v1 %s 1MB x now\n' "$n" "$D1"
|
|
printf '%s ghcr.io/cozy/api@%s %s 1MB x now\n' "$n" "$D1" "$D1"
|
|
printf '%s docker.io/library/busybox@%s %s 1MB x now\n' "$n" "$D2" "$D2"
|
|
# An image ID alias, not a pull: it names no repository.
|
|
printf '%s %s %s 1MB x now\n' "$n" "$D3" "$D3"
|
|
} >"$MOCK_TALOS/$n-cri"
|
|
printf '%s registry.example:5000/etcd:v3 %s 1MB x now\n' 192.168.123.12 "$D3" >"$MOCK_TALOS/192.168.123.12-system"
|
|
cp hack/collect-images.sh "$tmp/"
|
|
(cd "$tmp" && PATH="$MOCK_TALOS/bin:$PATH" sh ./collect-images.sh)
|
|
printf '%s\n' "docker.io/library/busybox@$D2" "ghcr.io/cozy/api@$D1" "registry.example:5000/etcd@$D3" | diff - "$tmp/image-refs.txt"
|
|
grep -q "^$D1 ghcr.io/cozy/api:v1\$" "$tmp/images.txt"
|
|
rm -rf "$tmp"
|
|
}
|
|
|
|
@test "a node that cannot be read leaves no image-refs.txt behind" {
|
|
tmp=$(mktemp -d)
|
|
_stub_talos "$tmp/talos"
|
|
printf '%s ghcr.io/cozy/api:v1 %s 1MB x now\n' 192.168.123.11 "$D1" >"$MOCK_TALOS/192.168.123.11-cri"
|
|
echo 192.168.123.13 >"$MOCK_TALOS/down"
|
|
cp hack/collect-images.sh "$tmp/"
|
|
# A partial list would audit only the nodes that answered.
|
|
echo stale >"$tmp/image-refs.txt"
|
|
(cd "$tmp" && PATH="$MOCK_TALOS/bin:$PATH" sh ./collect-images.sh) 2>"$tmp/err"
|
|
[ ! -e "$tmp/image-refs.txt" ]
|
|
grep -q 'image-refs.txt not written' "$tmp/err"
|
|
grep -q "ghcr.io/cozy/api:v1" "$tmp/images.txt"
|
|
rm -rf "$tmp"
|
|
}
|
|
|
|
@test "e2e-tag audits what the nodes pulled, fails only a pre-release, and tears down regardless" {
|
|
wf=.github/workflows/e2e-tag.yaml
|
|
names=$(yq -r '.jobs.e2e.steps[].name' "$wf")
|
|
c=$(echo "$names" | grep -nx 'Collect images list' | cut -d: -f1)
|
|
a=$(echo "$names" | grep -nx 'Audit pulled images are multi-arch' | cut -d: -f1)
|
|
t=$(echo "$names" | grep -nx 'Tear down sandbox' | cut -d: -f1)
|
|
[ -n "$c" ] && [ -n "$a" ] && [ -n "$t" ] && [ "$c" -lt "$a" ] && [ "$a" -lt "$t" ]
|
|
step='.jobs.e2e.steps[] | select(.name == "Audit pulled images are multi-arch")'
|
|
[ "$(yq -r "$step | .if" "$wf")" = 'always()' ]
|
|
run=$(yq -r "$step | .run" "$wf")
|
|
echo "$run" | grep -q 'hack/verify-multiarch.sh .*--refs-file'
|
|
# A stable tag's run reports; a pre-release's fails.
|
|
echo "$run" | grep -qF '*-*)'
|
|
[ "$(yq -r '.jobs.e2e.steps[] | select(.name == "Tear down sandbox") | .if' "$wf")" = 'always()' ]
|
|
yq -r '.jobs.e2e.steps[] | select(.name == "Upload image list") | .with.path' "$wf" | grep -q 'image-refs.txt'
|
|
yq -r '.jobs.e2e.steps[] | select(.name == "Upload image list") | .with.path' "$wf" | grep -q 'multiarch-audit.txt'
|
|
}
|
|
|
|
@test "e2e-tag refuses a tree that predates the container lane and names the ref to dispatch from" {
|
|
run=$(yq -r '.jobs.e2e.steps[] | select(.name == "Require a container-lane tree") | .run' .github/workflows/e2e-tag.yaml)
|
|
tmp=$(mktemp -d)
|
|
mkdir -p "$tmp/old" "$tmp/new/hack"
|
|
touch "$tmp/new/hack/e2e-compose.yaml"
|
|
printf '%s\n' "$run" >"$tmp/step.sh"
|
|
(cd "$tmp/new" && TAG=v1.7.0-alpha.3 bash -e "$tmp/step.sh")
|
|
rc=0
|
|
(cd "$tmp/old" && TAG=v1.6.3 bash -e "$tmp/step.sh") >"$tmp/out" 2>&1 || rc=$?
|
|
[ "$rc" -ne 0 ]
|
|
grep -qF '::error title=e2e-tag::v1.6.3 predates the container lane' "$tmp/out"
|
|
grep -qF -- '--ref v1.6.3' "$tmp/out"
|
|
rm -rf "$tmp"
|
|
}
|
|
|
|
@test "the e2e audit skips a tree that predates it and fails a pre-release tree that has it" {
|
|
# The step runs in the checkout of the tag under test. An rc cut before the
|
|
# audit existed has neither the script nor image-refs.txt, and failing its e2e
|
|
# for that would block re-validating it from main.
|
|
run=$(yq -r '.jobs.e2e.steps[] | select(.name == "Audit pulled images are multi-arch") | .run' .github/workflows/e2e-tag.yaml)
|
|
tmp=$(mktemp -d)
|
|
mkdir -p "$tmp/old" "$tmp/new/hack" "$tmp/new/_out" "$tmp/bin"
|
|
printf '%s\n' "$run" >"$tmp/step.sh"
|
|
# The step installs skopeo and jq when they are missing; neither case here
|
|
# reaches a registry, so stubs keep it off apt-get.
|
|
printf '#!/bin/sh\nexit 0\n' >"$tmp/bin/skopeo"
|
|
printf '#!/bin/sh\nexit 0\n' >"$tmp/bin/jq"
|
|
chmod +x "$tmp/bin/skopeo" "$tmp/bin/jq"
|
|
# cd "/tmp/$SANDBOX_NAME" must land in the fixture, wherever mktemp put it.
|
|
rc=0
|
|
PATH="$tmp/bin:$PATH" SANDBOX_NAME="..$tmp/old" TAG=v9.9.9-rc.1 bash -e "$tmp/step.sh" >"$tmp/out" 2>&1 || rc=$?
|
|
[ "$rc" -eq 0 ]
|
|
grep -q '::warning.*predates the multi-arch audit' "$tmp/out"
|
|
|
|
# A tree that has the audit but no image list: the collection failed.
|
|
cp hack/verify-multiarch.sh "$tmp/new/hack/"
|
|
cp hack/multiarch-allowlist "$tmp/new/hack/"
|
|
mkdir -p "$tmp/new/hack/lib" && cp hack/lib/image-refs.sh "$tmp/new/hack/lib/"
|
|
rc=0
|
|
PATH="$tmp/bin:$PATH" SANDBOX_NAME="..$tmp/new" TAG=v9.9.9-rc.1 bash -e "$tmp/step.sh" >"$tmp/out" 2>&1 || rc=$?
|
|
[ "$rc" -ne 0 ]
|
|
grep -q "refs file '_out/image-refs.txt' does not exist" "$tmp/out"
|
|
# A stable tag only warns, and says the audit did not run.
|
|
PATH="$tmp/bin:$PATH" SANDBOX_NAME="..$tmp/new" TAG=v9.9.9 bash -e "$tmp/step.sh" >"$tmp/out" 2>&1
|
|
grep -q '::warning title=multi-arch audit::the multi-arch audit did not run' "$tmp/out"
|
|
|
|
# A single-arch image: a pre-release fails, a stable tag warns that the
|
|
# images are not all indexes. Real jq reads the stub's manifest.
|
|
mkdir -p "$tmp/bin-single"
|
|
printf '#!/bin/sh\necho %s\n' "'{\"schemaVersion\":2,\"config\":{}}'" >"$tmp/bin-single/skopeo"
|
|
chmod +x "$tmp/bin-single/skopeo"
|
|
printf 'example.test/x@sha256:%s\n' "$(printf 'a%.0s' $(seq 1 64))" >"$tmp/new/_out/image-refs.txt"
|
|
rc=0
|
|
PATH="$tmp/bin-single:$PATH" SANDBOX_NAME="..$tmp/new" TAG=v9.9.9-rc.1 bash -e "$tmp/step.sh" >"$tmp/out" 2>&1 || rc=$?
|
|
[ "$rc" -ne 0 ]
|
|
grep -q 'example.test/x@sha256:a*: single-platform manifest' "$tmp/out"
|
|
rc=0
|
|
PATH="$tmp/bin-single:$PATH" SANDBOX_NAME="..$tmp/new" TAG=v9.9.9 bash -e "$tmp/step.sh" >"$tmp/out" 2>&1 || rc=$?
|
|
[ "$rc" -eq 0 ]
|
|
grep -q '::warning title=multi-arch audit::some images pulled by e2e are not amd64+arm64 indexes or could not be checked' "$tmp/out"
|
|
rm -rf "$tmp"
|
|
}
|