Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ci: diff back-to-back built images #250

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions .github/workflows/test-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,43 @@ jobs:
name: vm-results-${{matrix.host_release}}-${{matrix.release}}-${{matrix.debootstrap}}
if-no-files-found: error
path: tests/results/

b2b-diff:
needs: build-debian
# We want a working shell, qemu, python and docker. Specific version should not matter (much).
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Download built deb
uses: actions/download-artifact@v3
with:
name: deb-unstable

- run: ./tests/gha-b2b-diff.sh run
name: "Build VM image twice"
env:
HOST_RELEASE: unstable
RELEASE: trixie
DEBOOTSTRAP: debootstrap

- run: ./tests/gha-b2b-diff.sh test
name: "Diff built images"
env:
RELEASE: unstable

- name: Setup tmate session
if: ${{ failure() }}
uses: mxschmitt/action-tmate@v3
timeout-minutes: 45
with:
limit-access-to-actor: true

- name: Archive VM test results
uses: actions/upload-artifact@v3
with:
name: b2b-diff
if-no-files-found: error
path: diff.txt

36 changes: 36 additions & 0 deletions tests/b2b-known-differences
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# installation log files

Check failure on line 1 in tests/b2b-known-differences

View workflow job for this annotation

GitHub Actions / shellcheck test scripts

[shellcheck] reported by reviewdog 🐶 Tips depend on target shell and yours is unknown. Add a shebang or a 'shell' directive. [SC2148](https://github.com/koalaman/shellcheck/wiki/SC2148) Raw Output: tests/b2b-known-differences:1:1:error:Tips depend on target shell and yours is unknown. Add a shebang or a 'shell' directive. [SC2148](https://github.com/koalaman/shellcheck/wiki/SC2148)
/var/log/*

Check warning on line 2 in tests/b2b-known-differences

View workflow job for this annotation

GitHub Actions / shellcheck test scripts

[shellcheck] reported by reviewdog 🐶 This is a glob used as a command name. Was it supposed to be in ${..}, array, or is it missing quoting? [SC2211](https://github.com/koalaman/shellcheck/wiki/SC2211) Raw Output: tests/b2b-known-differences:2:1:warning:This is a glob used as a command name. Was it supposed to be in ${..}, array, or is it missing quoting? [SC2211](https://github.com/koalaman/shellcheck/wiki/SC2211)
# device files cannot be compared by diff
/dev/console
/dev/full
/dev/null
/dev/ptmx
/dev/random
/dev/tty
/dev/urandom
/dev/zero
# postfix - unknown reason for difference
/etc/aliases.db
# ssh keys are generated randomly
/etc/ssh/ssh_host_*key*

Check warning on line 15 in tests/b2b-known-differences

View workflow job for this annotation

GitHub Actions / shellcheck test scripts

[shellcheck] reported by reviewdog 🐶 This is a glob used as a command name. Was it supposed to be in ${..}, array, or is it missing quoting? [SC2211](https://github.com/koalaman/shellcheck/wiki/SC2211) Raw Output: tests/b2b-known-differences:15:1:warning:This is a glob used as a command name. Was it supposed to be in ${..}, array, or is it missing quoting? [SC2211](https://github.com/koalaman/shellcheck/wiki/SC2211)
# ssl certificates generated by ssl-cert
/etc/ssl/certs/ssl-cert-snakeoil.pem
/etc/ssl/private/ssl-cert-snakeoil.key
/etc/ssl/certs/*.0

Check warning on line 19 in tests/b2b-known-differences

View workflow job for this annotation

GitHub Actions / shellcheck test scripts

[shellcheck] reported by reviewdog 🐶 This is a glob used as a command name. Was it supposed to be in ${..}, array, or is it missing quoting? [SC2211](https://github.com/koalaman/shellcheck/wiki/SC2211) Raw Output: tests/b2b-known-differences:19:1:warning:This is a glob used as a command name. Was it supposed to be in ${..}, array, or is it missing quoting? [SC2211](https://github.com/koalaman/shellcheck/wiki/SC2211)
# kernel initrd images are generated during install and embed timestamp?
/boot/initrd.img-*

Check warning on line 21 in tests/b2b-known-differences

View workflow job for this annotation

GitHub Actions / shellcheck test scripts

[shellcheck] reported by reviewdog 🐶 This is a glob used as a command name. Was it supposed to be in ${..}, array, or is it missing quoting? [SC2211](https://github.com/koalaman/shellcheck/wiki/SC2211) Raw Output: tests/b2b-known-differences:21:1:warning:This is a glob used as a command name. Was it supposed to be in ${..}, array, or is it missing quoting? [SC2211](https://github.com/koalaman/shellcheck/wiki/SC2211)
# generated by dbus during install. TODO: delete?
/var/lib/dbus/machine-id
/etc/machine-id
# root password hash is randomized
/etc/shadow
# embed creation timestamp
/etc/mdadm/mdadm.conf
/etc/lvm/backup/vg0
# embed root partition UUID
/etc/fstab
/boot/grub/grub.cfg
# bug?
/etc/debootstrap/config
# TBD: why?
/var/cache/ldconfig/aux-cache
37 changes: 37 additions & 0 deletions tests/docker-test-b2b.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Diff two built VM images for unaccounted differences.

set -eu -o pipefail

if [ "$#" -ne 2 ]; then
echo "$0: Invalid arguments" >&2
echo "Expect: $0 IMG1 IMG2" >&2
exit 1
fi
IMG1="$1"
IMG2="$2"

set -x

MNTDIR1=$(mktemp -d)
MNTDIR2=$(mktemp -d)

# Assumes root partition is at 4MB offset.
mount -oloop,offset=4194304 "$IMG1" "$MNTDIR1"
mount -oloop,offset=4194304 "$IMG2" "$MNTDIR2"

set +x

while read -r pattern; do
if [ -n "$pattern" ]; then
echo "Removing known difference before diffing: $pattern"
rm -rfv "$MNTDIR1"$pattern "$MNTDIR2"$pattern

Check warning on line 30 in tests/docker-test-b2b.sh

View workflow job for this annotation

GitHub Actions / shellcheck test scripts

[shellcheck] reported by reviewdog 🐶 Double quote to prevent globbing and word splitting. [SC2086](https://github.com/koalaman/shellcheck/wiki/SC2086) Raw Output: tests/docker-test-b2b.sh:30:23:info:Double quote to prevent globbing and word splitting. [SC2086](https://github.com/koalaman/shellcheck/wiki/SC2086)

Check warning on line 30 in tests/docker-test-b2b.sh

View workflow job for this annotation

GitHub Actions / shellcheck test scripts

[shellcheck] reported by reviewdog 🐶 Double quote to prevent globbing and word splitting. [SC2086](https://github.com/koalaman/shellcheck/wiki/SC2086) Raw Output: tests/docker-test-b2b.sh:30:42:info:Double quote to prevent globbing and word splitting. [SC2086](https://github.com/koalaman/shellcheck/wiki/SC2086)

Check failure on line 30 in tests/docker-test-b2b.sh

View workflow job for this annotation

GitHub Actions / shellcheck test scripts

[shellcheck (suggestion)] reported by reviewdog 🐶 Raw Output: tests/docker-test-b2b.sh:30:- rm -rfv "$MNTDIR1"$pattern "$MNTDIR2"$pattern tests/docker-test-b2b.sh:30:+ rm -rfv "$MNTDIR1""$pattern" "$MNTDIR2""$pattern"
fi
done < <(grep -v '^#' ./tests/b2b-known-differences)

set -x
exec diff -Nru \
--no-dereference \
"$MNTDIR1" "$MNTDIR2" | tee diff.txt
78 changes: 78 additions & 0 deletions tests/gha-b2b-diff.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Install an already built grml-debootstrap.deb in docker and use it to
# build two test VM images, with the same configuration. Then diff the
# two images for unaccounted differences.

set -eu -o pipefail

usage() {
echo "Usage: $0 run"
echo " then: $0 test"
echo "WARNING: $0 is potentially dangerous and may destroy the host system and/or any data."
exit 0
}

if [ "${1:-}" == "--help" ] || [ "${1:-}" == "help" ]; then
usage
fi

if [ -z "${1:-}" ]; then
echo "$0: unknown parameters, see --help" >&2
exit 1
fi

set -x

if [ ! -d ./tests ]; then
echo "$0: Started from incorrect working directory" >&2
exit 1
fi

# Debian version to install using grml-debootstrap
RELEASE="${RELEASE:-bookworm}"
HOST_RELEASE="${HOST_RELEASE:-unstable}"

# debootstrap to use, default empty (let grml-debootstrap decide)
DEBOOTSTRAP="${DEBOOTSTRAP:-}"

build_image() {
# we need to run in privileged mode to be able to use loop devices
docker run --privileged --rm -i \
-v "$(pwd)":/code \
-e TERM="$TERM" \
-e DEBOOTSTRAP="$DEBOOTSTRAP" \
-w /code \
debian:"$HOST_RELEASE" \
bash -c './tests/docker-install-deb.sh '"$DEB_NAME"' && ./tests/docker-build-vm.sh '"$(id -u)"' '"/code/$1"' '"$RELEASE"
}

if [ "$1" == "run" ]; then
# Debian version on which grml-debootstrap will *run*
HOST_RELEASE="${HOST_RELEASE:-bookworm}"

DEB_NAME=$(ls ./grml-debootstrap*.deb || true)
if [ -z "$DEB_NAME" ]; then
echo "$0: No grml-debootstrap*.deb found, aborting" >&2
exit 1
fi

build_image qemu-1.img
build_image qemu-2.img

elif [ "$1" == "test" ]; then
exec docker run --privileged --rm -i \
-v "$(pwd)":/code \
-e TERM="$TERM" \
-e DEBOOTSTRAP="$DEBOOTSTRAP" \
-w /code \
debian:"$HOST_RELEASE" \
./tests/docker-test-b2b.sh qemu-1.img qemu-2.img

else
echo "$0: unknown parameters, see --help" >&2
exit 1
fi

# EOF
Loading