Show why a deb-install image build or container start failed

The deb-install suite sent the output of its runtime image build and of
its container start to /dev/null, so a registry timeout or a container
that was never created surfaced only as "runtime build failed" with the
cause thrown away. The dns-resolver suite already captured that output
and printed it on failure.

Move its capture helpers into testing/lib/image-build.sh and use them in
both suites, so a failed build or start in deb-install prints what docker
said. The dns-resolver change is a move only. Also correct the
deb-install header, which still described the package build it no longer
does itself.
This commit is contained in:
Johnathan Corgan
2026-09-19 13:30:33 +00:00
parent db254f6d44
commit 217bea3086
3 changed files with 56 additions and 37 deletions
+12 -7
View File
@@ -1,10 +1,10 @@
#!/bin/bash
# Test the fips Debian package install path across target distros.
#
# Each scenario builds (or reuses) the .deb in a cached Debian 12
# cargo-deb image, boots a systemd container with TUN access for the
# target distro, installs the .deb via `apt
# install ./fips_*.deb`, waits for fips.service + fips-dns.service
# Each scenario takes the .deb from --deb, or builds (or reuses) it
# through packaging/debian/build-deb-container.sh, boots a systemd
# container with TUN access for the target distro, installs the .deb
# via `apt install ./fips_*.deb`, waits for fips.service + fips-dns.service
# to come up, and verifies that `dig @127.0.0.53 AAAA <npub>.fips`
# returns a non-empty AAAA answer through the resolver backend that
# fips-dns-setup configured. Then exercises fips-gateway against the
@@ -31,6 +31,8 @@ set -uo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
# shellcheck source=SCRIPTDIR/../lib/systemd-container.sh
source "$SCRIPT_DIR/../lib/systemd-container.sh"
# shellcheck source=SCRIPTDIR/../lib/image-build.sh
source "$SCRIPT_DIR/../lib/image-build.sh"
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
CACHE_DIR="$SCRIPT_DIR/.cache"
DEB_CACHE_DIR="$CACHE_DIR/deb"
@@ -77,10 +79,12 @@ cleanup_container() {
docker rm -f "$name" >/dev/null 2>&1 || true
}
# Build an image from an inline Dockerfile.
build_image() {
local tag="$1"
shift
echo "$@" | docker build -t "$tag" -f - "$REPO_ROOT" >/dev/null 2>&1
echo "$@" | run_quiet "docker build -t $tag" \
docker build -t "$tag" -f - "$REPO_ROOT"
}
# Start the scenario's systemd container. Not privileged: see
@@ -94,7 +98,8 @@ build_image() {
start_systemd_container_with_tun() {
local name="$1" image="$2"
cleanup_container "$name"
docker run -d --name "$name" \
run_quiet "docker run $name (with tun)" \
docker run -d --name "$name" \
--label com.corganlabs.fips-ci=1 \
"${SYSTEMD_CAPS[@]}" \
--cgroupns=host \
@@ -102,7 +107,7 @@ start_systemd_container_with_tun() {
--sysctl net.ipv6.conf.all.forwarding=1 \
-v /sys/fs/cgroup:/sys/fs/cgroup:rw \
--tmpfs /run --tmpfs /run/lock \
"$image" >/dev/null 2>&1 || return
"$image" || return
check_isolation "$name"
return
}
+2 -30
View File
@@ -31,6 +31,8 @@ set -uo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
# shellcheck source=SCRIPTDIR/../lib/systemd-container.sh
source "$SCRIPT_DIR/../lib/systemd-container.sh"
# shellcheck source=SCRIPTDIR/../lib/image-build.sh
source "$SCRIPT_DIR/../lib/image-build.sh"
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
SETUP_SCRIPT="$REPO_ROOT/packaging/common/fips-dns-setup"
TEARDOWN_SCRIPT="$REPO_ROOT/packaging/common/fips-dns-teardown"
@@ -67,36 +69,6 @@ cleanup_container() {
docker rm -f "$name" >/dev/null 2>&1 || true
}
# Emit a captured output file to stderr, delimited and labelled with the
# command it came from. Callers use this only on failure: a command that
# succeeds leaves no trace, so the suite stays quiet when it is green.
dump_output() {
local label="$1" file="$2"
{
echo " --- $label failed; captured output follows ---"
if [ -s "$file" ]; then
cat "$file"
else
echo " (no output)"
fi
echo " --- end captured output ---"
} >&2
}
# Run a command with both streams captured. Discard the capture on success;
# on failure emit it, so the reason a build or a container start died is not
# thrown away. Stdin is inherited, so a caller may pipe into it.
run_quiet() {
local label="$1"
shift
local out rc=0
out=$(mktemp)
"$@" >"$out" 2>&1 || rc=$?
[ "$rc" -eq 0 ] || dump_output "$label" "$out"
rm -f "$out"
return "$rc"
}
# Build an image from an inline Dockerfile.
build_image() {
local tag="$1"
+42
View File
@@ -0,0 +1,42 @@
#!/bin/bash
# Shared helpers for building test images and starting test containers.
#
# Source this file to get dump_output() and run_quiet():
# source "$SCRIPT_DIR/../lib/image-build.sh"
# echo "$dockerfile" | run_quiet "docker build -t $tag" \
# docker build -t "$tag" -f - "$REPO_ROOT"
#
# A build or a container start that fails for a reason outside the project,
# such as a registry timeout, is indistinguishable from one the project caused
# unless its output survives. These helpers keep a command quiet when it
# succeeds and print everything it said when it fails.
# Emit a captured output file to stderr, delimited and labelled with the
# command it came from. Callers use this only on failure: a command that
# succeeds leaves no trace, so the suite stays quiet when it is green.
dump_output() {
local label="$1" file="$2"
{
echo " --- $label failed; captured output follows ---"
if [ -s "$file" ]; then
cat "$file"
else
echo " (no output)"
fi
echo " --- end captured output ---"
} >&2
}
# Run a command with both streams captured. Discard the capture on success;
# on failure emit it, so the reason a build or a container start died is not
# thrown away. Stdin is inherited, so a caller may pipe into it.
run_quiet() {
local label="$1"
shift
local out rc=0
out=$(mktemp)
"$@" >"$out" 2>&1 || rc=$?
[ "$rc" -eq 0 ] || dump_output "$label" "$out"
rm -f "$out"
return "$rc"
}