diff --git a/coverage.py b/coverage.py index 01ee7b5..9a52248 100755 --- a/coverage.py +++ b/coverage.py @@ -362,6 +362,21 @@ def main(): check=False, stdout=subprocess.PIPE, ).stdout.decode() + shfmt = subprocess.run( + [ + "shfmt", + "--posix", + "--binary-next-line", + "--case-indent", + "--indent", + "2", + "--simplify", + "-d", + "shared/test.sh", + ], + check=False, + stdout=subprocess.PIPE, + ).stdout.decode() argv = None match test: case "qemu": @@ -411,9 +426,11 @@ def main(): acc_time_per_test[name].append(walltime) print(separator, file=sys.stderr) print(f"duration: {walltime}", file=sys.stderr) - if proc.returncode != 0 or shellcheck != "": + if proc.returncode != 0 or shellcheck != "" or shfmt != "": if shellcheck != "": print(shellcheck) + if shfmt != "": + print(shfmt) failed.append(formated_test_name) print("result: FAILURE", file=sys.stderr) else: diff --git a/coverage.sh b/coverage.sh index e02cf35..5328ca4 100755 --- a/coverage.sh +++ b/coverage.sh @@ -7,45 +7,48 @@ set -eu : "${CMD:=perl -MDevel::Cover=-silent,-nogcov ./mmdebstrap}" case "$CMD" in - "mmdebstrap "*|mmdebstrap|*" mmdebstrap"|*" mmdebstrap "*) - MMSCRIPT="$(command -v mmdebstrap 2>/dev/null)";; - *) MMSCRIPT=./mmdebstrap;; + "mmdebstrap "* | mmdebstrap | *" mmdebstrap" | *" mmdebstrap "*) + MMSCRIPT="$(command -v mmdebstrap 2>/dev/null)" + ;; + *) MMSCRIPT=./mmdebstrap ;; esac if [ -e "$MMSCRIPT" ]; then - TMPFILE=$(mktemp) - perltidy < "$MMSCRIPT" > "$TMPFILE" - ret=0 - diff -u "$MMSCRIPT" "$TMPFILE" || ret=$? - if [ "$ret" -ne 0 ]; then - echo "perltidy failed" >&2 - rm "$TMPFILE" - exit 1 - fi - rm "$TMPFILE" + TMPFILE=$(mktemp) + perltidy <"$MMSCRIPT" >"$TMPFILE" + ret=0 + diff -u "$MMSCRIPT" "$TMPFILE" || ret=$? + if [ "$ret" -ne 0 ]; then + echo "perltidy failed" >&2 + rm "$TMPFILE" + exit 1 + fi + rm "$TMPFILE" - if [ "$(sed -e '/^__END__$/,$d' "$MMSCRIPT" | wc --max-line-length)" -gt 79 ]; then - echo "exceeded maximum line length of 79 characters" >&2 - exit 1 - fi + if [ "$(sed -e '/^__END__$/,$d' "$MMSCRIPT" | wc --max-line-length)" -gt 79 ]; then + echo "exceeded maximum line length of 79 characters" >&2 + exit 1 + fi - perlcritic --severity 4 --verbose 8 "$MMSCRIPT" + perlcritic --severity 4 --verbose 8 "$MMSCRIPT" - pod2man "$MMSCRIPT" >/dev/null + pod2man "$MMSCRIPT" >/dev/null fi for f in tarfilter coverage.py caching_proxy.py; do - [ -e "./$f" ] || continue - black --check "./$f" + [ -e "./$f" ] || continue + black --check "./$f" done shellcheck --exclude=SC2016 coverage.sh make_mirror.sh run_null.sh run_qemu.sh gpgvnoexpkeysig mmdebstrap-autopkgtest-build-qemu hooks/*/*.sh +shfmt --binary-next-line --case-indent --indent 2 --simplify -d coverage.sh make_mirror.sh run_null.sh run_qemu.sh mmdebstrap-autopkgtest-build-qemu gpgvnoexpkeysig + mirrordir="./shared/cache/debian" if [ ! -e "$mirrordir" ]; then - echo "run ./make_mirror.sh before running $0" >&2 - exit 1 + echo "run ./make_mirror.sh before running $0" >&2 + exit 1 fi # we use -f because the file might not exist @@ -56,14 +59,14 @@ rm -f shared/cover_db.img : "${RUN_MA_SAME_TESTS:=yes}" if [ "$HAVE_QEMU" = "yes" ]; then - # prepare image for cover_db - fallocate -l 64M shared/cover_db.img - /usr/sbin/mkfs.vfat shared/cover_db.img + # prepare image for cover_db + fallocate -l 64M shared/cover_db.img + /usr/sbin/mkfs.vfat shared/cover_db.img - if [ ! -e "./shared/cache/debian-$DEFAULT_DIST.ext4" ]; then - echo "./shared/cache/debian-$DEFAULT_DIST.ext4 does not exist" >&2 - exit 1 - fi + if [ ! -e "./shared/cache/debian-$DEFAULT_DIST.ext4" ]; then + echo "./shared/cache/debian-$DEFAULT_DIST.ext4 does not exist" >&2 + exit 1 + fi fi # choose the timestamp of the unstable Release file, so that we get @@ -82,10 +85,10 @@ export HAVE_QEMU HAVE_BINFMT RUN_MA_SAME_TESTS DEFAULT_DIST SOURCE_DATE_EPOCH CM ./coverage.py "$@" if [ -e shared/cover_db.img ]; then - # produce report inside the VM to make sure that the versions match or - # otherwise we might get: - # Can't read shared/cover_db/runs/1598213854.252.64287/cover.14 with Sereal: Sereal: Error: Bad Sereal header: Not a valid Sereal document. at offset 1 of input at srl_decoder.c line 600 at /usr/lib/x86_64-linux-gnu/perl5/5.30/Devel/Cover/DB/IO/Sereal.pm line 34, <$fh> chunk 1. - cat << END > shared/test.sh + # produce report inside the VM to make sure that the versions match or + # otherwise we might get: + # Can't read shared/cover_db/runs/1598213854.252.64287/cover.14 with Sereal: Sereal: Error: Bad Sereal header: Not a valid Sereal document. at offset 1 of input at srl_decoder.c line 600 at /usr/lib/x86_64-linux-gnu/perl5/5.30/Devel/Cover/DB/IO/Sereal.pm line 34, <$fh> chunk 1. + cat <shared/test.sh cover -nogcov -report html_basic cover_db >&2 mkdir -p report for f in common.js coverage.html cover.css css.js mmdebstrap--branch.html mmdebstrap--condition.html mmdebstrap.html mmdebstrap--subroutine.html standardista-table-sorting.js; do @@ -93,20 +96,20 @@ for f in common.js coverage.html cover.css css.js mmdebstrap--branch.html mmdebs done cover -delete cover_db >&2 END - if [ "$HAVE_QEMU" = "yes" ]; then - ./run_qemu.sh - else - ./run_null.sh - fi + if [ "$HAVE_QEMU" = "yes" ]; then + ./run_qemu.sh + else + ./run_null.sh + fi - echo - echo "open file://$(pwd)/shared/report/coverage.html in a browser" - echo + echo + echo "open file://$(pwd)/shared/report/coverage.html in a browser" + echo fi # check if the wiki has to be updated with pod2markdown output -if [ "${DEBEMAIL:-}" = "josch@debian.org" ]; then - bash -exc "diff -u <(curl --silent https://gitlab.mister-muffin.de/josch/mmdebstrap/wiki/raw/Home | dos2unix; echo) <(pod2markdown < mmdebstrap)" || : +if [ "${DEBEMAIL-}" = "josch@debian.org" ]; then + bash -exc "diff -u <(curl --silent https://gitlab.mister-muffin.de/josch/mmdebstrap/wiki/raw/Home | dos2unix; echo) <(pod2markdown < mmdebstrap)" || : fi rm -f shared/test.sh shared/tar1.txt shared/tar2.txt shared/pkglist.txt shared/doc-debian.tar.list shared/mmdebstrap shared/tarfilter shared/proxysolver diff --git a/gpgvnoexpkeysig b/gpgvnoexpkeysig index f528ee4..e31d499 100755 --- a/gpgvnoexpkeysig +++ b/gpgvnoexpkeysig @@ -28,23 +28,23 @@ set -eu find_gpgv_status_fd() { - while [ "$#" -gt 0 ]; do - if [ "$1" = '--status-fd' ]; then - echo "$2" - return 0 - fi - shift - done - # default fd is stdout - echo 1 + while [ "$#" -gt 0 ]; do + if [ "$1" = '--status-fd' ]; then + echo "$2" + return 0 + fi + shift + done + # default fd is stdout + echo 1 } GPGSTATUSFD="$(find_gpgv_status_fd "$@")" case $GPGSTATUSFD in - ''|*[!0-9]*) - echo "invalid --status-fd argument" >&2 - exit 1 - ;; + '' | *[!0-9]*) + echo "invalid --status-fd argument" >&2 + exit 1 + ;; esac # we need eval because we cannot redirect a variable fd diff --git a/make_mirror.sh b/make_mirror.sh index 7cc38d1..28e6c85 100755 --- a/make_mirror.sh +++ b/make_mirror.sh @@ -10,160 +10,160 @@ set -eu # the local repository. deletecache() { - dir="$1" - echo "running deletecache $dir">&2 - if [ ! -e "$dir" ]; then - return - fi - if [ ! -e "$dir/mmdebstrapcache" ]; then - echo "$dir cannot be the mmdebstrap cache" >&2 - return 1 - fi - # be very careful with removing the old directory - # experimental is pulled in with USE_HOST_APT_CONFIG=yes on debci - # when testing a package from experimental - for dist in oldstable stable testing unstable experimental; do - # deleting artifacts from test "debootstrap" - for variant in minbase buildd -; do - if [ -e "$dir/debian-$dist-$variant.tar" ]; then - rm "$dir/debian-$dist-$variant.tar" - else - echo "does not exist: $dir/debian-$dist-$variant.tar" >&2 - fi - done - # deleting artifacts from test "mmdebstrap" - for variant in essential apt minbase buildd - standard; do - for format in tar ext2 ext4 squashfs; do - if [ -e "$dir/mmdebstrap-$dist-$variant.$format" ]; then - # attempt to delete for all dists because DEFAULT_DIST might've been different the last time - rm "$dir/mmdebstrap-$dist-$variant.$format" - elif [ "$dist" = "$DEFAULT_DIST" ]; then - # only warn about non-existance when it's expected to exist - echo "does not exist: $dir/mmdebstrap-$dist-$variant.$format" >&2 - fi - done - done - if [ -e "$dir/debian/dists/$dist" ]; then - rm --one-file-system --recursive "$dir/debian/dists/$dist" - else - echo "does not exist: $dir/debian/dists/$dist" >&2 - fi - case "$dist" in oldstable|stable) - if [ -e "$dir/debian/dists/$dist-updates" ]; then - rm --one-file-system --recursive "$dir/debian/dists/$dist-updates" - else - echo "does not exist: $dir/debian/dists/$dist-updates" >&2 - fi - ;; - esac - case "$dist" in oldstable|stable) - if [ -e "$dir/debian-security/dists/$dist-security" ]; then - rm --one-file-system --recursive "$dir/debian-security/dists/$dist-security" - else - echo "does not exist: $dir/debian-security/dists/$dist-security" >&2 - fi - ;; - esac - done - for f in "$dir/debian-"*.ext4; do - if [ -e "$f" ]; then - rm --one-file-system "$f" - fi - done - # on i386 and amd64, the intel-microcode and amd64-microcode packages - # from non-free-firwame get pulled in because they are - # priority:standard with USE_HOST_APT_CONFIG=yes - for c in main non-free-firmware; do - if [ -e "$dir/debian/pool/$c" ]; then - rm --one-file-system --recursive "$dir/debian/pool/$c" - else - echo "does not exist: $dir/debian/pool/$c" >&2 - fi - done - if [ -e "$dir/debian-security/pool/updates/main" ]; then - rm --one-file-system --recursive "$dir/debian-security/pool/updates/main" - else - echo "does not exist: $dir/debian-security/pool/updates/main" >&2 - fi - for i in $(seq 1 6); do - if [ ! -e "$dir/debian$i" ]; then - continue - fi - rm "$dir/debian$i" - done - rm "$dir/mmdebstrapcache" - # remove all symlinks - find "$dir" -type l -delete + dir="$1" + echo "running deletecache $dir" >&2 + if [ ! -e "$dir" ]; then + return + fi + if [ ! -e "$dir/mmdebstrapcache" ]; then + echo "$dir cannot be the mmdebstrap cache" >&2 + return 1 + fi + # be very careful with removing the old directory + # experimental is pulled in with USE_HOST_APT_CONFIG=yes on debci + # when testing a package from experimental + for dist in oldstable stable testing unstable experimental; do + # deleting artifacts from test "debootstrap" + for variant in minbase buildd -; do + if [ -e "$dir/debian-$dist-$variant.tar" ]; then + rm "$dir/debian-$dist-$variant.tar" + else + echo "does not exist: $dir/debian-$dist-$variant.tar" >&2 + fi + done + # deleting artifacts from test "mmdebstrap" + for variant in essential apt minbase buildd - standard; do + for format in tar ext2 ext4 squashfs; do + if [ -e "$dir/mmdebstrap-$dist-$variant.$format" ]; then + # attempt to delete for all dists because DEFAULT_DIST might've been different the last time + rm "$dir/mmdebstrap-$dist-$variant.$format" + elif [ "$dist" = "$DEFAULT_DIST" ]; then + # only warn about non-existance when it's expected to exist + echo "does not exist: $dir/mmdebstrap-$dist-$variant.$format" >&2 + fi + done + done + if [ -e "$dir/debian/dists/$dist" ]; then + rm --one-file-system --recursive "$dir/debian/dists/$dist" + else + echo "does not exist: $dir/debian/dists/$dist" >&2 + fi + case "$dist" in oldstable | stable) + if [ -e "$dir/debian/dists/$dist-updates" ]; then + rm --one-file-system --recursive "$dir/debian/dists/$dist-updates" + else + echo "does not exist: $dir/debian/dists/$dist-updates" >&2 + fi + ;; + esac + case "$dist" in oldstable | stable) + if [ -e "$dir/debian-security/dists/$dist-security" ]; then + rm --one-file-system --recursive "$dir/debian-security/dists/$dist-security" + else + echo "does not exist: $dir/debian-security/dists/$dist-security" >&2 + fi + ;; + esac + done + for f in "$dir/debian-"*.ext4; do + if [ -e "$f" ]; then + rm --one-file-system "$f" + fi + done + # on i386 and amd64, the intel-microcode and amd64-microcode packages + # from non-free-firwame get pulled in because they are + # priority:standard with USE_HOST_APT_CONFIG=yes + for c in main non-free-firmware; do + if [ -e "$dir/debian/pool/$c" ]; then + rm --one-file-system --recursive "$dir/debian/pool/$c" + else + echo "does not exist: $dir/debian/pool/$c" >&2 + fi + done + if [ -e "$dir/debian-security/pool/updates/main" ]; then + rm --one-file-system --recursive "$dir/debian-security/pool/updates/main" + else + echo "does not exist: $dir/debian-security/pool/updates/main" >&2 + fi + for i in $(seq 1 6); do + if [ ! -e "$dir/debian$i" ]; then + continue + fi + rm "$dir/debian$i" + done + rm "$dir/mmdebstrapcache" + # remove all symlinks + find "$dir" -type l -delete - # now the rest should only be empty directories - if [ -e "$dir" ]; then - find "$dir" -depth -print0 | xargs -0 --no-run-if-empty rmdir - else - echo "does not exist: $dir" >&2 - fi + # now the rest should only be empty directories + if [ -e "$dir" ]; then + find "$dir" -depth -print0 | xargs -0 --no-run-if-empty rmdir + else + echo "does not exist: $dir" >&2 + fi } cleanup_newcachedir() { - echo "running cleanup_newcachedir" - deletecache "$newcachedir" + echo "running cleanup_newcachedir" + deletecache "$newcachedir" } cleanupapt() { - echo "running cleanupapt" >&2 - if [ ! -e "$rootdir" ]; then - return - fi - for f in \ - "$rootdir/var/cache/apt/archives/"*.deb \ - "$rootdir/var/cache/apt/archives/partial/"*.deb \ - "$rootdir/var/cache/apt/"*.bin \ - "$rootdir/var/lib/apt/lists/"* \ - "$rootdir/var/lib/dpkg/status" \ - "$rootdir/var/lib/dpkg/lock-frontend" \ - "$rootdir/var/lib/dpkg/lock" \ - "$rootdir/var/lib/apt/lists/lock" \ - "$rootdir/etc/apt/apt.conf" \ - "$rootdir/etc/apt/sources.list.d/"* \ - "$rootdir/etc/apt/preferences.d/"* \ - "$rootdir/etc/apt/sources.list" \ - "$rootdir/var/cache/apt/archives/lock"; do - if [ ! -e "$f" ]; then - echo "does not exist: $f" >&2 - continue - fi - if [ -d "$f" ]; then - rmdir "$f" - else - rm "$f" - fi - done - find "$rootdir" -depth -print0 | xargs -0 --no-run-if-empty rmdir + echo "running cleanupapt" >&2 + if [ ! -e "$rootdir" ]; then + return + fi + for f in \ + "$rootdir/var/cache/apt/archives/"*.deb \ + "$rootdir/var/cache/apt/archives/partial/"*.deb \ + "$rootdir/var/cache/apt/"*.bin \ + "$rootdir/var/lib/apt/lists/"* \ + "$rootdir/var/lib/dpkg/status" \ + "$rootdir/var/lib/dpkg/lock-frontend" \ + "$rootdir/var/lib/dpkg/lock" \ + "$rootdir/var/lib/apt/lists/lock" \ + "$rootdir/etc/apt/apt.conf" \ + "$rootdir/etc/apt/sources.list.d/"* \ + "$rootdir/etc/apt/preferences.d/"* \ + "$rootdir/etc/apt/sources.list" \ + "$rootdir/var/cache/apt/archives/lock"; do + if [ ! -e "$f" ]; then + echo "does not exist: $f" >&2 + continue + fi + if [ -d "$f" ]; then + rmdir "$f" + else + rm "$f" + fi + done + find "$rootdir" -depth -print0 | xargs -0 --no-run-if-empty rmdir } # note: this function uses brackets instead of curly braces, so that it's run # in its own process and we can handle traps independent from the outside update_cache() ( - dist="$1" - nativearch="$2" + dist="$1" + nativearch="$2" - # use a subdirectory of $newcachedir so that we can use - # hardlinks - rootdir="$newcachedir/apt" - mkdir -p "$rootdir" + # use a subdirectory of $newcachedir so that we can use + # hardlinks + rootdir="$newcachedir/apt" + mkdir -p "$rootdir" - # we only set this trap here and overwrite the previous trap, because - # the update_cache function is run as part of a pipe and thus in its - # own process which will EXIT after it finished - trap 'kill "$PROXYPID" || :;cleanupapt' EXIT INT TERM + # we only set this trap here and overwrite the previous trap, because + # the update_cache function is run as part of a pipe and thus in its + # own process which will EXIT after it finished + trap 'kill "$PROXYPID" || :;cleanupapt' EXIT INT TERM - for p in /etc/apt/apt.conf.d /etc/apt/sources.list.d /etc/apt/preferences.d /var/cache/apt/archives /var/lib/apt/lists/partial /var/lib/dpkg; do - mkdir -p "$rootdir/$p" - done + for p in /etc/apt/apt.conf.d /etc/apt/sources.list.d /etc/apt/preferences.d /var/cache/apt/archives /var/lib/apt/lists/partial /var/lib/dpkg; do + mkdir -p "$rootdir/$p" + done - # read sources.list content from stdin - cat > "$rootdir/etc/apt/sources.list" + # read sources.list content from stdin + cat >"$rootdir/etc/apt/sources.list" - cat << END > "$rootdir/etc/apt/apt.conf" + cat <"$rootdir/etc/apt/apt.conf" Apt::Architecture "$nativearch"; Apt::Architectures "$nativearch"; Dir::Etc "$rootdir/etc/apt"; @@ -177,125 +177,125 @@ Dir::Etc::TrustedParts "/etc/apt/trusted.gpg.d"; Acquire::http::Proxy "http://127.0.0.1:8080/"; END - : > "$rootdir/var/lib/dpkg/status" + : >"$rootdir/var/lib/dpkg/status" - if [ "$dist" = "$DEFAULT_DIST" ] && [ "$nativearch" = "$HOSTARCH" ] && [ "$USE_HOST_APT_CONFIG" = "yes" ]; then - # we append sources and settings instead of overwriting after - # an empty line - for f in /etc/apt/sources.list /etc/apt/sources.list.d/*; do - [ -e "$f" ] || continue - [ -e "$rootdir/$f" ] && echo >> "$rootdir/$f" - # Filter out file:// repositories as they are added - # to each mmdebstrap call verbatim by - # debian/tests/copy_host_apt_config - # Also filter out all mirrors that are not of suite - # $DEFAULT_DIST, except experimental if the suite - # is unstable. This prevents packages from - # unstable entering a testing mirror. - if [ "$dist" = unstable ]; then - grep -v ' file://' "$f" \ - | grep -E " (unstable|experimental) " \ - >> "$rootdir/$f" || : - else - grep -v ' file://' "$f" \ - | grep " $DEFAULT_DIST " \ - >> "$rootdir/$f" || : - fi - done - for f in /etc/apt/preferences.d/*; do - [ -e "$f" ] || continue - [ -e "$rootdir/$f" ] && echo >> "$rootdir/$f" - cat "$f" >> "$rootdir/$f" - done - fi + if [ "$dist" = "$DEFAULT_DIST" ] && [ "$nativearch" = "$HOSTARCH" ] && [ "$USE_HOST_APT_CONFIG" = "yes" ]; then + # we append sources and settings instead of overwriting after + # an empty line + for f in /etc/apt/sources.list /etc/apt/sources.list.d/*; do + [ -e "$f" ] || continue + [ -e "$rootdir/$f" ] && echo >>"$rootdir/$f" + # Filter out file:// repositories as they are added + # to each mmdebstrap call verbatim by + # debian/tests/copy_host_apt_config + # Also filter out all mirrors that are not of suite + # $DEFAULT_DIST, except experimental if the suite + # is unstable. This prevents packages from + # unstable entering a testing mirror. + if [ "$dist" = unstable ]; then + grep -v ' file://' "$f" \ + | grep -E " (unstable|experimental) " \ + >>"$rootdir/$f" || : + else + grep -v ' file://' "$f" \ + | grep " $DEFAULT_DIST " \ + >>"$rootdir/$f" || : + fi + done + for f in /etc/apt/preferences.d/*; do + [ -e "$f" ] || continue + [ -e "$rootdir/$f" ] && echo >>"$rootdir/$f" + cat "$f" >>"$rootdir/$f" + done + fi - echo "creating mirror for $dist" >&2 - for f in /etc/apt/sources.list /etc/apt/sources.list.d/* /etc/apt/preferences.d/*; do - [ -e "$rootdir/$f" ] || continue - echo "contents of $f:" >&2 - cat "$rootdir/$f" >&2 - done + echo "creating mirror for $dist" >&2 + for f in /etc/apt/sources.list /etc/apt/sources.list.d/* /etc/apt/preferences.d/*; do + [ -e "$rootdir/$f" ] || continue + echo "contents of $f:" >&2 + cat "$rootdir/$f" >&2 + done - APT_CONFIG="$rootdir/etc/apt/apt.conf" apt-get update --error-on=any + APT_CONFIG="$rootdir/etc/apt/apt.conf" apt-get update --error-on=any - pkgs=$(APT_CONFIG="$rootdir/etc/apt/apt.conf" apt-get indextargets \ - --format '$(FILENAME)' 'Created-By: Packages' "Architecture: $nativearch" \ - | xargs --delimiter='\n' /usr/lib/apt/apt-helper cat-file \ - | grep-dctrl --no-field-names --show-field=Package --exact-match \ - \( --field=Essential yes --or --field=Priority required \ - --or --field=Priority important --or --field=Priority standard \ - \)) + pkgs=$(APT_CONFIG="$rootdir/etc/apt/apt.conf" apt-get indextargets \ + --format '$(FILENAME)' 'Created-By: Packages' "Architecture: $nativearch" \ + | xargs --delimiter='\n' /usr/lib/apt/apt-helper cat-file \ + | grep-dctrl --no-field-names --show-field=Package --exact-match \ + \( --field=Essential yes --or --field=Priority required \ + --or --field=Priority important --or --field=Priority standard \ + \)) - pkgs="$pkgs build-essential busybox gpg eatmydata fakechroot fakeroot" + pkgs="$pkgs build-essential busybox gpg eatmydata fakechroot fakeroot" - # we need usr-is-merged to simulate debootstrap behaviour for all dists - # starting from Debian 12 (Bullseye) - case "$dist" in - oldstable) : ;; - *) pkgs="$pkgs usr-is-merged usrmerge" ;; - esac + # we need usr-is-merged to simulate debootstrap behaviour for all dists + # starting from Debian 12 (Bullseye) + case "$dist" in + oldstable) : ;; + *) pkgs="$pkgs usr-is-merged usrmerge" ;; + esac - # shellcheck disable=SC2086 - APT_CONFIG="$rootdir/etc/apt/apt.conf" apt-get --yes install $pkgs \ - || APT_CONFIG="$rootdir/etc/apt/apt.conf" apt-get --yes install \ - -oDebug::pkgProblemResolver=true -oDebug::pkgDepCache::Marker=1 \ - -oDebug::pkgDepCache::AutoInstall=1 \ - $pkgs + # shellcheck disable=SC2086 + APT_CONFIG="$rootdir/etc/apt/apt.conf" apt-get --yes install $pkgs \ + || APT_CONFIG="$rootdir/etc/apt/apt.conf" apt-get --yes install \ + -oDebug::pkgProblemResolver=true -oDebug::pkgDepCache::Marker=1 \ + -oDebug::pkgDepCache::AutoInstall=1 \ + $pkgs - rm "$rootdir/var/cache/apt/archives/lock" - rmdir "$rootdir/var/cache/apt/archives/partial" - APT_CONFIG="$rootdir/etc/apt/apt.conf" apt-get --option Dir::Etc::SourceList=/dev/null update - APT_CONFIG="$rootdir/etc/apt/apt.conf" apt-get clean + rm "$rootdir/var/cache/apt/archives/lock" + rmdir "$rootdir/var/cache/apt/archives/partial" + APT_CONFIG="$rootdir/etc/apt/apt.conf" apt-get --option Dir::Etc::SourceList=/dev/null update + APT_CONFIG="$rootdir/etc/apt/apt.conf" apt-get clean - cleanupapt + cleanupapt - # this function is run in its own process, so we unset all traps before - # returning - trap "-" EXIT INT TERM + # this function is run in its own process, so we unset all traps before + # returning + trap "-" EXIT INT TERM ) check_proxy_running() { - if timeout 1 bash -c 'exec 3<>/dev/tcp/127.0.0.1/8080 && printf "GET http://deb.debian.org/debian/dists/'"$DEFAULT_DIST"'/InRelease HTTP/1.1\nHost: deb.debian.org\n\n" >&3 && grep "Suite: '"$DEFAULT_DIST"'" <&3 >/dev/null' 2>/dev/null; then - return 0 - elif timeout 1 env http_proxy="http://127.0.0.1:8080/" wget --quiet -O - "http://deb.debian.org/debian/dists/$DEFAULT_DIST/InRelease" | grep "Suite: $DEFAULT_DIST" >/dev/null; then - return 0 - elif timeout 1 curl --proxy "http://127.0.0.1:8080/" --silent "http://deb.debian.org/debian/dists/$DEFAULT_DIST/InRelease" | grep "Suite: $DEFAULT_DIST" >/dev/null; then - return 0 - fi - return 1 + if timeout 1 bash -c 'exec 3<>/dev/tcp/127.0.0.1/8080 && printf "GET http://deb.debian.org/debian/dists/'"$DEFAULT_DIST"'/InRelease HTTP/1.1\nHost: deb.debian.org\n\n" >&3 && grep "Suite: '"$DEFAULT_DIST"'" <&3 >/dev/null' 2>/dev/null; then + return 0 + elif timeout 1 env http_proxy="http://127.0.0.1:8080/" wget --quiet -O - "http://deb.debian.org/debian/dists/$DEFAULT_DIST/InRelease" | grep "Suite: $DEFAULT_DIST" >/dev/null; then + return 0 + elif timeout 1 curl --proxy "http://127.0.0.1:8080/" --silent "http://deb.debian.org/debian/dists/$DEFAULT_DIST/InRelease" | grep "Suite: $DEFAULT_DIST" >/dev/null; then + return 0 + fi + return 1 } if [ -e "./shared/cache.A" ] && [ -e "./shared/cache.B" ]; then - echo "both ./shared/cache.A and ./shared/cache.B exist" >&2 - echo "was a former run of the script aborted?" >&2 - if [ -e ./shared/cache ]; then - echo "cache symlink points to $(readlink ./shared/cache)" >&2 - case "$(readlink ./shared/cache)" in - cache.A) - echo "removing ./shared/cache.B" >&2 - rm -r ./shared/cache.B - ;; - cache.B) - echo "removing ./shared/cache.A" >&2 - rm -r ./shared/cache.A - ;; - *) - echo "unexpected" >&2 - exit 1 - ;; - esac - else - echo "./shared/cache doesn't exist" >&2 - exit 1 - fi + echo "both ./shared/cache.A and ./shared/cache.B exist" >&2 + echo "was a former run of the script aborted?" >&2 + if [ -e ./shared/cache ]; then + echo "cache symlink points to $(readlink ./shared/cache)" >&2 + case "$(readlink ./shared/cache)" in + cache.A) + echo "removing ./shared/cache.B" >&2 + rm -r ./shared/cache.B + ;; + cache.B) + echo "removing ./shared/cache.A" >&2 + rm -r ./shared/cache.A + ;; + *) + echo "unexpected" >&2 + exit 1 + ;; + esac + else + echo "./shared/cache doesn't exist" >&2 + exit 1 + fi fi if [ -e "./shared/cache.A" ]; then - oldcache=cache.A - newcache=cache.B + oldcache=cache.A + newcache=cache.B else - oldcache=cache.B - newcache=cache.A + oldcache=cache.B + newcache=cache.A fi oldcachedir="./shared/$oldcache" @@ -319,12 +319,18 @@ components=main : "${FORCE_UPDATE:=no}" if [ "$FORCE_UPDATE" != "yes" ] && [ -e "$oldmirrordir/dists/$DEFAULT_DIST/InRelease" ]; then - http_code=$(curl --output /dev/null --silent --location --head --time-cond "$oldmirrordir/dists/$DEFAULT_DIST/InRelease" --write-out '%{http_code}' "$mirror/dists/$DEFAULT_DIST/InRelease") - case "$http_code" in - 200) ;; # need update - 304) echo up-to-date; exit 0;; - *) echo "unexpected status: $http_code"; exit 1;; - esac + http_code=$(curl --output /dev/null --silent --location --head --time-cond "$oldmirrordir/dists/$DEFAULT_DIST/InRelease" --write-out '%{http_code}' "$mirror/dists/$DEFAULT_DIST/InRelease") + case "$http_code" in + 200) ;; # need update + 304) + echo up-to-date + exit 0 + ;; + *) + echo "unexpected status: $http_code" + exit 1 + ;; + esac fi ./caching_proxy.py "$oldcachedir" "$newcachedir" & @@ -332,13 +338,13 @@ PROXYPID=$! trap 'kill "$PROXYPID" || :' EXIT INT TERM for i in $(seq 10); do - check_proxy_running && break - sleep 1 + check_proxy_running && break + sleep 1 done if [ ! -s "$newmirrordir/dists/$DEFAULT_DIST/InRelease" ]; then - echo "failed to start proxy" >&2 - kill $PROXYPID - exit 1 + echo "failed to start proxy" >&2 + kill $PROXYPID + exit 1 fi trap 'kill "$PROXYPID" || :;cleanup_newcachedir' EXIT INT TERM @@ -349,9 +355,9 @@ touch "$newcachedir/mmdebstrapcache" HOSTARCH=$(dpkg --print-architecture) arches="$HOSTARCH" if [ "$HOSTARCH" = amd64 ]; then - arches="$arches arm64 i386" + arches="$arches arm64 i386" elif [ "$HOSTARCH" = arm64 ]; then - arches="$arches amd64 armhf" + arches="$arches amd64 armhf" fi # we need the split_inline_sig() function @@ -359,43 +365,43 @@ fi . /usr/share/debootstrap/functions for dist in oldstable stable testing unstable; do - for nativearch in $arches; do - # non-host architectures are only downloaded for $DEFAULT_DIST - if [ "$nativearch" != "$HOSTARCH" ] && [ "$DEFAULT_DIST" != "$dist" ]; then - continue - fi - # if ONLY_DEFAULT_DIST is set, only download DEFAULT_DIST - if [ "$ONLY_DEFAULT_DIST" = "yes" ] && [ "$DEFAULT_DIST" != "$dist" ]; then - continue - fi - if [ "$ONLY_HOSTARCH" = "yes" ] && [ "$nativearch" != "$HOSTARCH" ]; then - continue - fi - # we need a first pass without updates and security patches - # because otherwise, old package versions needed by - # debootstrap will not get included - echo "deb [arch=$nativearch] $mirror $dist $components" | update_cache "$dist" "$nativearch" - # we need to include the base mirror again or otherwise - # packages like build-essential will be missing - case "$dist" in oldstable|stable) - cat << END | update_cache "$dist" "$nativearch" + for nativearch in $arches; do + # non-host architectures are only downloaded for $DEFAULT_DIST + if [ "$nativearch" != "$HOSTARCH" ] && [ "$DEFAULT_DIST" != "$dist" ]; then + continue + fi + # if ONLY_DEFAULT_DIST is set, only download DEFAULT_DIST + if [ "$ONLY_DEFAULT_DIST" = "yes" ] && [ "$DEFAULT_DIST" != "$dist" ]; then + continue + fi + if [ "$ONLY_HOSTARCH" = "yes" ] && [ "$nativearch" != "$HOSTARCH" ]; then + continue + fi + # we need a first pass without updates and security patches + # because otherwise, old package versions needed by + # debootstrap will not get included + echo "deb [arch=$nativearch] $mirror $dist $components" | update_cache "$dist" "$nativearch" + # we need to include the base mirror again or otherwise + # packages like build-essential will be missing + case "$dist" in oldstable | stable) + cat <&2 - continue - fi - rm "$f" - done - rmdir "$tmpdir" + if [ -z "$tmpdir" ]; then + return + fi + if [ ! -e "$tmpdir" ]; then + return + fi + for f in "$tmpdir/worker.sh" "$tmpdir/mmdebstrap.service"; do + if [ ! -e "$f" ]; then + echo "does not exist: $f" >&2 + continue + fi + rm "$f" + done + rmdir "$tmpdir" } SOURCE_DATE_EPOCH="$(date --date="$(grep-dctrl -s Date -n '' "$newmirrordir/dists/$DEFAULT_DIST/Release")" +%s)" export SOURCE_DATE_EPOCH if [ "$HAVE_QEMU" = "yes" ]; then - # we use the caching proxy again when building the qemu image - # - we can re-use the packages that were already downloaded earlier - # - we make sure that the qemu image uses the same Release file even - # if a mirror push happened between now and earlier - # - we avoid polluting the mirror with the additional packages by - # using --readonly - ./caching_proxy.py --readonly "$oldcachedir" "$newcachedir" & - PROXYPID=$! + # we use the caching proxy again when building the qemu image + # - we can re-use the packages that were already downloaded earlier + # - we make sure that the qemu image uses the same Release file even + # if a mirror push happened between now and earlier + # - we avoid polluting the mirror with the additional packages by + # using --readonly + ./caching_proxy.py --readonly "$oldcachedir" "$newcachedir" & + PROXYPID=$! - for i in $(seq 10); do - check_proxy_running && break - sleep 1 - done - if [ ! -s "$newmirrordir/dists/$DEFAULT_DIST/InRelease" ]; then - echo "failed to start proxy" >&2 - kill $PROXYPID - exit 1 - fi + for i in $(seq 10); do + check_proxy_running && break + sleep 1 + done + if [ ! -s "$newmirrordir/dists/$DEFAULT_DIST/InRelease" ]; then + echo "failed to start proxy" >&2 + kill $PROXYPID + exit 1 + fi - tmpdir="$(mktemp -d)" - trap 'kill "$PROXYPID" || :;cleanuptmpdir; cleanup_newcachedir' EXIT INT TERM + tmpdir="$(mktemp -d)" + trap 'kill "$PROXYPID" || :;cleanuptmpdir; cleanup_newcachedir' EXIT INT TERM - pkgs=perl-doc,systemd-sysv,perl,arch-test,fakechroot,fakeroot,mount,uidmap,qemu-user-binfmt,dpkg-dev,mini-httpd,libdevel-cover-perl,libtemplate-perl,debootstrap,procps,apt-cudf,aspcud,python3,libcap2-bin,gpg,debootstrap,distro-info-data,iproute2,ubuntu-keyring,apt-utils,squashfs-tools-ng,genext2fs,linux-image-generic,passwd,e2fsprogs,uuid-runtime - if [ ! -e ./mmdebstrap ]; then - pkgs="$pkgs,mmdebstrap" - fi - arches=$HOSTARCH - if [ "$RUN_MA_SAME_TESTS" = "yes" ]; then - case "$HOSTARCH" in - amd64) - arches=amd64,arm64 - pkgs="$pkgs,libfakechroot:arm64,libfakeroot:arm64" - ;; - arm64) - arches=arm64,amd64 - pkgs="$pkgs,libfakechroot:amd64,libfakeroot:amd64" - ;; - esac - fi + pkgs=perl-doc,systemd-sysv,perl,arch-test,fakechroot,fakeroot,mount,uidmap,qemu-user-binfmt,dpkg-dev,mini-httpd,libdevel-cover-perl,libtemplate-perl,debootstrap,procps,apt-cudf,aspcud,python3,libcap2-bin,gpg,debootstrap,distro-info-data,iproute2,ubuntu-keyring,apt-utils,squashfs-tools-ng,genext2fs,linux-image-generic,passwd,e2fsprogs,uuid-runtime + if [ ! -e ./mmdebstrap ]; then + pkgs="$pkgs,mmdebstrap" + fi + arches=$HOSTARCH + if [ "$RUN_MA_SAME_TESTS" = "yes" ]; then + case "$HOSTARCH" in + amd64) + arches=amd64,arm64 + pkgs="$pkgs,libfakechroot:arm64,libfakeroot:arm64" + ;; + arm64) + arches=arm64,amd64 + pkgs="$pkgs,libfakechroot:amd64,libfakeroot:amd64" + ;; + esac + fi - cat << END > "$tmpdir/mmdebstrap.service" + cat <"$tmpdir/mmdebstrap.service" [Unit] Description=mmdebstrap worker script @@ -482,15 +488,15 @@ ExecStart=/worker.sh [Install] WantedBy=multi-user.target END - # here is something crazy: - # as we run mmdebstrap, the process ends up being run by different users with - # different privileges (real or fake). But for being able to collect - # Devel::Cover data, they must all share a single directory. The only way that - # I found to make this work is to mount the database directory with a - # filesystem that doesn't support ownership information at all and a umask that - # gives read/write access to everybody. - # https://github.com/pjcj/Devel--Cover/issues/223 - cat << 'END' > "$tmpdir/worker.sh" + # here is something crazy: + # as we run mmdebstrap, the process ends up being run by different users with + # different privileges (real or fake). But for being able to collect + # Devel::Cover data, they must all share a single directory. The only way that + # I found to make this work is to mount the database directory with a + # filesystem that doesn't support ownership information at all and a umask that + # gives read/write access to everybody. + # https://github.com/pjcj/Devel--Cover/issues/223 + cat <<'END' >"$tmpdir/worker.sh" #!/bin/sh echo 'root:root' | chpasswd mount -t 9p -o trans=virtio,access=any,msize=128k mmdebstrap /mnt @@ -530,37 +536,37 @@ handler () { umount /mnt systemctl poweroff END - chmod +x "$tmpdir/worker.sh" - if [ -z ${DISK_SIZE+x} ]; then - DISK_SIZE=10G - fi - # set PATH to pick up the correct mmdebstrap variant - env PATH="$(dirname "$(realpath --canonicalize-existing "$CMD")"):$PATH" \ - debvm-create --skip=usrmerge,systemdnetwork \ - --size="$DISK_SIZE" --release="$DEFAULT_DIST" \ - --output="$newcachedir/debian-$DEFAULT_DIST.ext4" -- \ - --architectures="$arches" --include="$pkgs" \ - --setup-hook='echo "Acquire::http::Proxy \"http://127.0.0.1:8080/\";" > "$1/etc/apt/apt.conf.d/00proxy"' \ - --hook-dir=/usr/share/mmdebstrap/hooks/maybe-merged-usr \ - --customize-hook='rm "$1/etc/apt/apt.conf.d/00proxy"' \ - --customize-hook='mkdir -p "$1/etc/systemd/system/multi-user.target.wants"' \ - --customize-hook='ln -s ../mmdebstrap.service "$1/etc/systemd/system/multi-user.target.wants/mmdebstrap.service"' \ - --customize-hook='touch "$1/mmdebstrap-testenv"' \ - --customize-hook='copy-in "'"$tmpdir"'/mmdebstrap.service" /etc/systemd/system/' \ - --customize-hook='copy-in "'"$tmpdir"'/worker.sh" /' \ - --customize-hook='echo 127.0.0.1 localhost > "$1/etc/hosts"' \ - --customize-hook='printf "START=1\nDAEMON_OPTS=\"-h 127.0.0.1 -p 80 -u nobody -dd /mnt/cache -i /var/run/mini-httpd.pid -T UTF-8\"\n" > "$1/etc/default/mini-httpd"' \ - --customize-hook='touch "$1/etc/systemd/system/tmp.mount"' \ - "$mirror" + chmod +x "$tmpdir/worker.sh" + if [ -z ${DISK_SIZE+x} ]; then + DISK_SIZE=10G + fi + # set PATH to pick up the correct mmdebstrap variant + env PATH="$(dirname "$(realpath --canonicalize-existing "$CMD")"):$PATH" \ + debvm-create --skip=usrmerge,systemdnetwork \ + --size="$DISK_SIZE" --release="$DEFAULT_DIST" \ + --output="$newcachedir/debian-$DEFAULT_DIST.ext4" -- \ + --architectures="$arches" --include="$pkgs" \ + --setup-hook='echo "Acquire::http::Proxy \"http://127.0.0.1:8080/\";" > "$1/etc/apt/apt.conf.d/00proxy"' \ + --hook-dir=/usr/share/mmdebstrap/hooks/maybe-merged-usr \ + --customize-hook='rm "$1/etc/apt/apt.conf.d/00proxy"' \ + --customize-hook='mkdir -p "$1/etc/systemd/system/multi-user.target.wants"' \ + --customize-hook='ln -s ../mmdebstrap.service "$1/etc/systemd/system/multi-user.target.wants/mmdebstrap.service"' \ + --customize-hook='touch "$1/mmdebstrap-testenv"' \ + --customize-hook='copy-in "'"$tmpdir"'/mmdebstrap.service" /etc/systemd/system/' \ + --customize-hook='copy-in "'"$tmpdir"'/worker.sh" /' \ + --customize-hook='echo 127.0.0.1 localhost > "$1/etc/hosts"' \ + --customize-hook='printf "START=1\nDAEMON_OPTS=\"-h 127.0.0.1 -p 80 -u nobody -dd /mnt/cache -i /var/run/mini-httpd.pid -T UTF-8\"\n" > "$1/etc/default/mini-httpd"' \ + --customize-hook='touch "$1/etc/systemd/system/tmp.mount"' \ + "$mirror" - kill $PROXYPID - cleanuptmpdir - trap "cleanup_newcachedir" EXIT INT TERM + kill $PROXYPID + cleanuptmpdir + trap "cleanup_newcachedir" EXIT INT TERM fi # delete possibly leftover symlink if [ -e ./shared/cache.tmp ]; then - rm ./shared/cache.tmp + rm ./shared/cache.tmp fi # now atomically switch the symlink to point to the other directory ln -s $newcache ./shared/cache.tmp diff --git a/mmdebstrap-autopkgtest-build-qemu b/mmdebstrap-autopkgtest-build-qemu index 76af46b..c817b55 100755 --- a/mmdebstrap-autopkgtest-build-qemu +++ b/mmdebstrap-autopkgtest-build-qemu @@ -127,15 +127,15 @@ POD2MAN set -eu die() { - echo "$*" 1>&2 - exit 1 + echo "$*" 1>&2 + exit 1 } usage() { - die "usage: $0 [--architecture=|--apt-proxy=|--keyring=|--mirror=|--script=|--size=] --boot=efi " + die "usage: $0 [--architecture=|--apt-proxy=|--keyring=|--mirror=|--script=|--size=] --boot=efi " } usage_error() { - echo "error: $*" 1>&2 - usage + echo "error: $*" 1>&2 + usage } BOOT=auto @@ -151,164 +151,164 @@ SCRIPT= export AUTOPKGTEST_BUILD_QEMU=1 opt_boot() { - BOOT="$1" + BOOT="$1" } opt_architecture() { - ARCHITECTURE="$1" + ARCHITECTURE="$1" } opt_arch() { - ARCHITECTURE="$1" + ARCHITECTURE="$1" } opt_apt_proxy() { - # consumed by setup-testbed - export AUTOPKGTEST_APT_PROXY="$1" - # consumed by mmdebstrap - if test "$1" = DIRECT; then - unset http_proxy - else - export http_proxy="$1" - fi + # consumed by setup-testbed + export AUTOPKGTEST_APT_PROXY="$1" + # consumed by mmdebstrap + if test "$1" = DIRECT; then + unset http_proxy + else + export http_proxy="$1" + fi } opt_keyring() { - KEYRING="$1" + KEYRING="$1" } opt_mirror() { - # consumed by setup-testbed - export MIRROR="$1" + # consumed by setup-testbed + export MIRROR="$1" } opt_script() { - test -f "$1" || die "passed script '$1' does not refer to a file" - SCRIPT="$1" + test -f "$1" || die "passed script '$1' does not refer to a file" + SCRIPT="$1" } opt_size() { - SIZE="$1" + SIZE="$1" } positional=1 positional_1() { - # consumed by setup-testbed - export RELEASE="$1" + # consumed by setup-testbed + export RELEASE="$1" } positional_2() { - IMAGE="$1" + IMAGE="$1" } positional_3() { opt_mirror "$@"; } positional_4() { opt_architecture "$@"; } positional_5() { opt_script "$@"; } positional_6() { opt_size "$@"; } positional_7() { - die "too many positional options" + die "too many positional options" } while test "$#" -gt 0; do - case "$1" in - --architecture=*|--arch=*|--boot=*|--keyring=*|--mirror=*|--script=*|--size=*) - optname="${1%%=*}" - "opt_${optname#--}" "${1#*=}" - ;; - --apt-proxy=*) - opt_apt_proxy "${1#*=}" - ;; - --architecture|--arch|--boot|--keyring|--mirror|--script|--size) - test "$#" -ge 2 || usage_error "missing argument for $1" - "opt_${1#--}" "$2" - shift - ;; - --apt-proxy) - test "$#" -ge 2 || usage_error "missing argument for $1" - opt_apt_proxy "$2" - shift - ;; - --efi) - opt_boot efi - ;; - --*) - usage_error "unrecognized argument $1" - ;; - *) - "positional_$positional" "$1" - positional=$((positional + 1)) - ;; - esac - shift + case "$1" in + --architecture=* | --arch=* | --boot=* | --keyring=* | --mirror=* | --script=* | --size=*) + optname="${1%%=*}" + "opt_${optname#--}" "${1#*=}" + ;; + --apt-proxy=*) + opt_apt_proxy "${1#*=}" + ;; + --architecture | --arch | --boot | --keyring | --mirror | --script | --size) + test "$#" -ge 2 || usage_error "missing argument for $1" + "opt_${1#--}" "$2" + shift + ;; + --apt-proxy) + test "$#" -ge 2 || usage_error "missing argument for $1" + opt_apt_proxy "$2" + shift + ;; + --efi) + opt_boot efi + ;; + --*) + usage_error "unrecognized argument $1" + ;; + *) + "positional_$positional" "$1" + positional=$((positional + 1)) + ;; + esac + shift done test -z "$RELEASE" -o -z "$IMAGE" && usage_error "missing positional arguments" -test "$BOOT" = efi || - die "this tool does not support boot modes other than efi" +test "$BOOT" = efi \ + || die "this tool does not support boot modes other than efi" case "$ARCHITECTURE" in - amd64) - EFIIMG=bootx64.efi - QEMUARCH=x86_64 - VMFPKG=ovmf - LINUXIMAGE=linux-image-amd64 - ;; - arm64) - EFIIMG=bootaa64.efi - QEMUARCH=aarch64 - VMFPKG=qemu-efi-aarch64 - LINUXIMAGE=linux-image-arm64 - ;; - armhf) - EFIIMG=bootarm.efi - QEMUARCH=arm - VMFPKG=qemu-efi-arm - LINUXIMAGE=linux-image-armmp - ;; - i386) - EFIIMG=bootia32.efi - QEMUARCH=i386 - VMFPKG=ovmf-ia32 - LINUXIMAGE=linux-image-686-pae - ;; - riscv64) - EFIIMG=bootriscv64.efi - QEMUARCH=riscv64 - VMFPKG= - LINUXIMAGE=linux-image-riscv64 - ;; - *) - die "unsupported architecture: $ARCHITECTURE" - ;; + amd64) + EFIIMG=bootx64.efi + QEMUARCH=x86_64 + VMFPKG=ovmf + LINUXIMAGE=linux-image-amd64 + ;; + arm64) + EFIIMG=bootaa64.efi + QEMUARCH=aarch64 + VMFPKG=qemu-efi-aarch64 + LINUXIMAGE=linux-image-arm64 + ;; + armhf) + EFIIMG=bootarm.efi + QEMUARCH=arm + VMFPKG=qemu-efi-arm + LINUXIMAGE=linux-image-armmp + ;; + i386) + EFIIMG=bootia32.efi + QEMUARCH=i386 + VMFPKG=ovmf-ia32 + LINUXIMAGE=linux-image-686-pae + ;; + riscv64) + EFIIMG=bootriscv64.efi + QEMUARCH=riscv64 + VMFPKG= + LINUXIMAGE=linux-image-riscv64 + ;; + *) + die "unsupported architecture: $ARCHITECTURE" + ;; esac if test "$(dpkg-query -f '${db:Status-Status}' -W binutils-multiarch)" = installed; then - GNU_PREFIX= - BINUTILS= + GNU_PREFIX= + BINUTILS= else - GNU_ARCHITECTURE="$(dpkg-architecture "-a$ARCHITECTURE" -qDEB_HOST_GNU_TYPE)" - GNU_PREFIX="$GNU_ARCHITECTURE-" - GNU_SUFFIX="-$(echo "$GNU_ARCHITECTURE" | tr _ -)" - BINUTILS=", binutils$GNU_SUFFIX | binutils-multiarch" + GNU_ARCHITECTURE="$(dpkg-architecture "-a$ARCHITECTURE" -qDEB_HOST_GNU_TYPE)" + GNU_PREFIX="$GNU_ARCHITECTURE-" + GNU_SUFFIX="-$(echo "$GNU_ARCHITECTURE" | tr _ -)" + BINUTILS=", binutils$GNU_SUFFIX | binutils-multiarch" fi arches=" $(dpkg --print-architecture) $(dpkg --print-foreign-architectures | tr '\n' ' ') " case $arches in - *" $ARCHITECTURE "*) : ;; # nothing to do - *) die "enable $ARCHITECTURE by running: sudo dpkg --add-architecture $ARCHITECTURE && sudo apt update" ;; + *" $ARCHITECTURE "*) : ;; # nothing to do + *) die "enable $ARCHITECTURE by running: sudo dpkg --add-architecture $ARCHITECTURE && sudo apt update" ;; esac -test "$(dpkg-query -f '${db:Status-Status}' -W "dpkg-dev")" = installed || - die "please install dpkg-dev" +test "$(dpkg-query -f '${db:Status-Status}' -W "dpkg-dev")" = installed \ + || die "please install dpkg-dev" -dpkg-checkbuilddeps -d "autopkgtest, dosfstools, e2fsprogs, fdisk, mount, mtools, passwd, uidmap, libarchive13, systemd-boot-efi:$ARCHITECTURE $BINUTILS" /dev/null || - die "please install the required packages listed above" +dpkg-checkbuilddeps -d "autopkgtest, dosfstools, e2fsprogs, fdisk, mount, mtools, passwd, uidmap, libarchive13, systemd-boot-efi:$ARCHITECTURE $BINUTILS" /dev/null \ + || die "please install the required packages listed above" BOOTSTUB="/usr/lib/systemd/boot/efi/linux${EFIIMG#boot}.stub" WORKDIR= cleanup() { - test -n "$WORKDIR" && rm -Rf "$WORKDIR" + test -n "$WORKDIR" && rm -Rf "$WORKDIR" } trap cleanup EXIT INT TERM QUIT WORKDIR=$(mktemp -d) -FAT_OFFSET_SECTORS=$((1024*2)) -FAT_SIZE_SECTORS=$((1024*254)) +FAT_OFFSET_SECTORS=$((1024 * 2)) +FAT_SIZE_SECTORS=$((1024 * 254)) # The image is raw and not in qcow2 format because: # - faster run-time as the "qemu-image convert" step is not needed @@ -321,44 +321,45 @@ FAT_SIZE_SECTORS=$((1024*254)) # custom options like compression set -- \ - --mode=unshare \ - --format=tar \ - --variant=important \ - --architecture="$ARCHITECTURE" + --mode=unshare \ + --format=tar \ + --variant=important \ + --architecture="$ARCHITECTURE" -case $MIRROR in http://snapshot.debian.org/archive/*|https://snapshot.debian.org/archive/*) - set -- "$@" --aptopt='Acquire::Check-Valid-Until "false"';; +case $MIRROR in http://snapshot.debian.org/archive/* | https://snapshot.debian.org/archive/*) + set -- "$@" --aptopt='Acquire::Check-Valid-Until "false"' + ;; esac EXT_FEATURES= if test "$RELEASE" = jessie; then - set -- "$@" --keyring=/usr/share/keyrings/debian-archive-removed-keys.gpg - set -- "$@" --aptopt='Apt::Key::gpgvcommand "/usr/libexec/mmdebstrap/gpgvnoexpkeysig"' - set -- "$@" --hook-dir=/usr/share/mmdebstrap/hooks/jessie-or-older - EXT_FEATURES="^metadata_csum,^metadata_csum_seed,^orphan_file" + set -- "$@" --keyring=/usr/share/keyrings/debian-archive-removed-keys.gpg + set -- "$@" --aptopt='Apt::Key::gpgvcommand "/usr/libexec/mmdebstrap/gpgvnoexpkeysig"' + set -- "$@" --hook-dir=/usr/share/mmdebstrap/hooks/jessie-or-older + EXT_FEATURES="^metadata_csum,^metadata_csum_seed,^orphan_file" fi set -- "$@" \ - "--include=init,$LINUXIMAGE,python3" \ - '--customize-hook=echo host >"$1/etc/hostname"' \ - '--customize-hook=echo 127.0.0.1 localhost host >"$1/etc/hosts"' \ - '--customize-hook=passwd --root "$1" --delete root' \ - '--customize-hook=useradd --root "$1" --home-dir /home/user --create-home user' \ - '--customize-hook=passwd --root "$1" --delete user' \ - '--customize-hook=/usr/share/autopkgtest/setup-commands/setup-testbed' + "--include=init,$LINUXIMAGE,python3" \ + '--customize-hook=echo host >"$1/etc/hostname"' \ + '--customize-hook=echo 127.0.0.1 localhost host >"$1/etc/hosts"' \ + '--customize-hook=passwd --root "$1" --delete root' \ + '--customize-hook=useradd --root "$1" --home-dir /home/user --create-home user' \ + '--customize-hook=passwd --root "$1" --delete user' \ + '--customize-hook=/usr/share/autopkgtest/setup-commands/setup-testbed' if test -n "$SCRIPT"; then - set -- "$@" \ - "--customize-hook=upload '$SCRIPT' /userscript" \ - "--chrooted-customize-hook=sh /userscript" \ - '--customize-hook=rm -f "$1/userscript"' + set -- "$@" \ + "--customize-hook=upload '$SCRIPT' /userscript" \ + "--chrooted-customize-hook=sh /userscript" \ + '--customize-hook=rm -f "$1/userscript"' fi set -- "$@" \ - "--customize-hook=download vmlinuz '$WORKDIR/kernel'" \ - "--customize-hook=download initrd.img '$WORKDIR/initrd'" \ - "$RELEASE" \ - - + "--customize-hook=download vmlinuz '$WORKDIR/kernel'" \ + "--customize-hook=download initrd.img '$WORKDIR/initrd'" \ + "$RELEASE" \ + - test -n "$MIRROR" && set -- "$@" "$MIRROR" test -n "$KEYRING" && set -- "$@" "--keyring=$KEYRING" @@ -368,45 +369,44 @@ echo "+ mmdebstrap $*" >&2 # shellcheck disable=SC3040 set -o pipefail mmdebstrap "$@" | { - set -- -t ext4 -L autopkgtestvm -d - - if test -n "$EXT_FEATURES"; then - set -- "$@" -O "$EXT_FEATURES" - fi - EXTOPTS="offset=$(( (FAT_OFFSET_SECTORS + FAT_SIZE_SECTORS) * 512))" - if test -n "${SOURCE_DATE_EPOCH:-}"; then - uuid="$(uuidgen --sha1 --namespace="$(uuidgen --sha1 --namespace='@dns' --name mister-muffin.de)" --name "$SOURCE_DATE_EPOCH")" - set -- "$@" -U "$uuid" - EXTOPTS="$EXTOPTS,hash_seed=$uuid" - fi - set -- "$@" -E "$EXTOPTS" "$IMAGE" "$SIZE" - echo "+ mke2fs $*" >&2 - /sbin/mke2fs "$@" + set -- -t ext4 -L autopkgtestvm -d - + if test -n "$EXT_FEATURES"; then + set -- "$@" -O "$EXT_FEATURES" + fi + EXTOPTS="offset=$(((FAT_OFFSET_SECTORS + FAT_SIZE_SECTORS) * 512))" + if test -n "${SOURCE_DATE_EPOCH-}"; then + uuid="$(uuidgen --sha1 --namespace="$(uuidgen --sha1 --namespace='@dns' --name mister-muffin.de)" --name "$SOURCE_DATE_EPOCH")" + set -- "$@" -U "$uuid" + EXTOPTS="$EXTOPTS,hash_seed=$uuid" + fi + set -- "$@" -E "$EXTOPTS" "$IMAGE" "$SIZE" + echo "+ mke2fs $*" >&2 + /sbin/mke2fs "$@" } - -echo "root=LABEL=autopkgtestvm rw console=ttyS0" > "$WORKDIR/cmdline" +echo "root=LABEL=autopkgtestvm rw console=ttyS0" >"$WORKDIR/cmdline" align_size() { - echo "$(( ($1) + ($2) - 1 - (($1) + ($2) - 1) % ($2) ))" + echo "$((($1) + ($2) - 1 - (($1) + ($2) - 1) % ($2)))" } alignment=$("${GNU_PREFIX}objdump" -p "$BOOTSTUB" | sed 's/^SectionAlignment\s\+\([0-9]\)/0x/;t;d') test -z "$alignment" && die "failed to discover the alignment of the efi stub" echo "determined efi vma alignment as $alignment" -test "$RELEASE" = jessie -a "$((alignment))" -lt "$((1024*1024))" && { - echo "increasing efi vma alignment for jessie" - alignment=$((1024*1024)) +test "$RELEASE" = jessie -a "$((alignment))" -lt "$((1024 * 1024))" && { + echo "increasing efi vma alignment for jessie" + alignment=$((1024 * 1024)) } lastoffset=0 # shellcheck disable=SC2034 # unused variables serve documentation -lastoffset="$("${GNU_PREFIX}objdump" -h "$BOOTSTUB" | - while read -r idx name size vma lma fileoff algn behind; do - test -z "$behind" -a "${algn#"2**"}" != "$algn" || continue - offset=$(( 0x$vma + 0x$size )) - test "$offset" -gt "$lastoffset" || continue - lastoffset="$offset" - echo "$lastoffset" - done | tail -n1)" +lastoffset="$("${GNU_PREFIX}objdump" -h "$BOOTSTUB" \ + | while read -r idx name size vma lma fileoff algn behind; do + test -z "$behind" -a "${algn#"2**"}" != "$algn" || continue + offset=$((0x$vma + 0x$size)) + test "$offset" -gt "$lastoffset" || continue + lastoffset="$offset" + echo "$lastoffset" + done | tail -n1)" lastoffset=$(align_size "$lastoffset" "$alignment") echo "determined minimum efi vma offset as $lastoffset" @@ -419,15 +419,15 @@ linux_offset=$((cmdline_offset + cmdline_size)) initrd_offset=$((linux_offset + linux_size)) SOURCE_DATE_EPOCH=0 \ - "${GNU_PREFIX}objcopy" \ - --enable-deterministic-archives \ - --add-section .cmdline="$WORKDIR/cmdline" \ - --change-section-vma .cmdline="$(printf 0x%x "$cmdline_offset")" \ - --add-section .linux="$WORKDIR/kernel" \ - --change-section-vma .linux="$(printf 0x%x "$linux_offset")" \ - --add-section .initrd="$WORKDIR/initrd" \ - --change-section-vma .initrd="$(printf 0x%x "$initrd_offset")" \ - "$BOOTSTUB" "$WORKDIR/efiimg" + "${GNU_PREFIX}objcopy" \ + --enable-deterministic-archives \ + --add-section .cmdline="$WORKDIR/cmdline" \ + --change-section-vma .cmdline="$(printf 0x%x "$cmdline_offset")" \ + --add-section .linux="$WORKDIR/kernel" \ + --change-section-vma .linux="$(printf 0x%x "$linux_offset")" \ + --add-section .initrd="$WORKDIR/initrd" \ + --change-section-vma .initrd="$(printf 0x%x "$initrd_offset")" \ + "$BOOTSTUB" "$WORKDIR/efiimg" rm -f "$WORKDIR/kernel" "$WORKDIR/initrd" @@ -438,7 +438,7 @@ mcopy -i "$WORKDIR/fat" "$WORKDIR/efiimg" "::EFI/BOOT/$EFIIMG" rm -f "$WORKDIR/efiimg" -truncate --size="+$((34*512))" "$IMAGE" +truncate --size="+$((34 * 512))" "$IMAGE" /sbin/sfdisk "$IMAGE" <&2 + echo "I: you might need to install a package providing qemu-system-$QEMUARCH to use this image with autopkgtest-virt-qemu" >&2 fi if test -n "$VMFPKG" && test "$(dpkg-query -f '${db:Status-Status}' -W "$VMFPKG")" != installed; then - echo "I: you might need to install $VMFPKG to use this image with autopkgtest-virt-qemu" >&2 + echo "I: you might need to install $VMFPKG to use this image with autopkgtest-virt-qemu" >&2 fi echo "I: SUCCESS! Your new image can be found here: $IMAGE" >&2 diff --git a/run_null.sh b/run_null.sh index 17b42fa..6b6e83a 100755 --- a/run_null.sh +++ b/run_null.sh @@ -4,17 +4,17 @@ set -eu SUDO= while [ "$#" -gt 0 ]; do - key="$1" - case "$key" in - SUDO) - SUDO=sudo - ;; - *) - echo "Unknown argument: $key" - exit 1 - ;; - esac - shift + key="$1" + case "$key" in + SUDO) + SUDO=sudo + ;; + *) + echo "Unknown argument: $key" + exit 1 + ;; + esac + shift done # - Run command with fds 3 and 4 closed so that whatever test.sh does it @@ -26,15 +26,24 @@ done # - Read fd 3 and let the group exit with that value # - Redirect fd 4 to stdout ret=0 -{ { { { - ret=0; - ( exec 3>&- 4>&-; env --chdir=./shared $SUDO sh -x ./test.sh 2>&1) || ret=$?; - echo $ret >&3; - } | tee shared/output.txt >&4; - } 3>&1; - } | { read -r xs; exit "$xs"; } +{ + { + { + { + ret=0 + ( + exec 3>&- 4>&- + env --chdir=./shared $SUDO sh -x ./test.sh 2>&1 + ) || ret=$? + echo $ret >&3 + } | tee shared/output.txt >&4 + } 3>&1 + } | { + read -r xs + exit "$xs" + } } 4>&1 || ret=$? if [ "$ret" -ne 0 ]; then - echo "test.sh failed" - exit 1 + echo "test.sh failed" + exit 1 fi diff --git a/run_qemu.sh b/run_qemu.sh index a51493b..426aeeb 100755 --- a/run_qemu.sh +++ b/run_qemu.sh @@ -8,65 +8,65 @@ set -eu tmpdir="$(mktemp -d)" cleanup() { - rv=$? - rm -f "$tmpdir/log" - [ -e "$tmpdir" ] && rmdir "$tmpdir" - if [ -e shared/output.txt ]; then - res="$(cat shared/exitstatus.txt)" - if [ "$res" != "0" ]; then - # this might possibly overwrite another non-zero rv - rv=1 - fi - fi - exit $rv + rv=$? + rm -f "$tmpdir/log" + [ -e "$tmpdir" ] && rmdir "$tmpdir" + if [ -e shared/output.txt ]; then + res="$(cat shared/exitstatus.txt)" + if [ "$res" != "0" ]; then + # this might possibly overwrite another non-zero rv + rv=1 + fi + fi + exit $rv } trap cleanup INT TERM EXIT -echo 1 > shared/exitstatus.txt +echo 1 >shared/exitstatus.txt if [ -e shared/output.txt ]; then - rm shared/output.txt + rm shared/output.txt fi touch shared/output.txt setpriv --pdeathsig TERM tail -f shared/output.txt & set -- timeout --foreground 40m \ - debvm-run --image="$(realpath "$cachedir")/debian-$DEFAULT_DIST.ext4" \ - -- + debvm-run --image="$(realpath "$cachedir")/debian-$DEFAULT_DIST.ext4" \ + -- cpuname=$(lscpu | awk '/Model name:/ {print $3}' | tr '\n' '+') ncpu=$(lscpu | awk '/Core\(s\) per socket:/ {print $4}' | tr '\n' '+') if [ "$cpuname" = "Cortex-A53+Cortex-A73+" ] && [ "$ncpu" = "2+4+" ]; then - # crude detection of the big.LITTLE heterogeneous setup of cores on the - # amlogic a311d bananapi - # - # https://lists.nongnu.org/archive/html/qemu-devel/2020-10/msg08494.html - # https://gitlab.com/qemu-project/qemu/-/issues/239 - # https://segments.zhan.science/posts/kvm_on_pinehone_pro/#trouble-with-heterogeneous-architecture - set -- taskset --cpu-list 2,3,4,5 "$@" -smp 4 + # crude detection of the big.LITTLE heterogeneous setup of cores on the + # amlogic a311d bananapi + # + # https://lists.nongnu.org/archive/html/qemu-devel/2020-10/msg08494.html + # https://gitlab.com/qemu-project/qemu/-/issues/239 + # https://segments.zhan.science/posts/kvm_on_pinehone_pro/#trouble-with-heterogeneous-architecture + set -- taskset --cpu-list 2,3,4,5 "$@" -smp 4 fi set -- "$@" -nic none -m 4G -snapshot if [ "$MMDEBSTRAP_TESTS_DEBUG" = "no" ]; then - # to connect to serial use: - # minicom -D 'unix#/tmp/ttyS0' - # or this (quit with ctrl+q): - # socat stdin,raw,echo=0,escape=0x11 unix-connect:/tmp/ttyS0 - set -- "$@" \ - -monitor unix:/tmp/monitor,server,nowait \ - -serial unix:/tmp/ttyS0,server,nowait \ - -serial unix:/tmp/ttyS1,server,nowait + # to connect to serial use: + # minicom -D 'unix#/tmp/ttyS0' + # or this (quit with ctrl+q): + # socat stdin,raw,echo=0,escape=0x11 unix-connect:/tmp/ttyS0 + set -- "$@" \ + -monitor unix:/tmp/monitor,server,nowait \ + -serial unix:/tmp/ttyS0,server,nowait \ + -serial unix:/tmp/ttyS1,server,nowait fi set -- "$@" -virtfs local,id=mmdebstrap,path="$(pwd)/shared",security_model=none,mount_tag=mmdebstrap ret=0 if [ "$MMDEBSTRAP_TESTS_DEBUG" = "no" ]; then - "$@" >"$tmpdir/log" 2>&1 || ret=$? + "$@" >"$tmpdir/log" 2>&1 || ret=$? else - "$@" 2>&1 | tee "$tmpdir/log" || ret=$? + "$@" 2>&1 | tee "$tmpdir/log" || ret=$? fi if [ "$ret" -ne 0 ]; then - cat "$tmpdir/log" - exit $ret + cat "$tmpdir/log" + exit $ret fi diff --git a/tests/apt-patterns b/tests/apt-patterns index a4f03e2..89526d5 100644 --- a/tests/apt-patterns +++ b/tests/apt-patterns @@ -3,6 +3,6 @@ set -eu export LC_ALL=C.UTF-8 trap "rm -f /tmp/debian-chroot.tar" EXIT INT TERM {{ CMD }} --mode={{ MODE }} --variant=essential \ - --include '?or(?exact-name(dummy-does-not-exist),?exact-name(apt))' \ - {{ DIST }} /tmp/debian-chroot.tar {{ MIRROR }} + --include '?or(?exact-name(dummy-does-not-exist),?exact-name(apt))' \ + {{ DIST }} /tmp/debian-chroot.tar {{ MIRROR }} tar -tf /tmp/debian-chroot.tar | sort | diff -u tar1.txt - diff --git a/tests/apt-patterns-custom b/tests/apt-patterns-custom index bd78ed1..c00fd23 100644 --- a/tests/apt-patterns-custom +++ b/tests/apt-patterns-custom @@ -3,7 +3,10 @@ set -eu export LC_ALL=C.UTF-8 trap "rm -f /tmp/debian-chroot.tar" EXIT INT TERM {{ CMD }} --mode={{ MODE }} --variant=custom \ - --include '?narrow(?archive(^{{ DIST }}$),?essential)' \ - --include apt \ - {{ DIST }} /tmp/debian-chroot.tar {{ MIRROR }} -{ tar -tf /tmp/debian-chroot.tar; echo ./var/lib/apt/extended_states; } | sort | diff -u tar1.txt - + --include '?narrow(?archive(^{{ DIST }}$),?essential)' \ + --include apt \ + {{ DIST }} /tmp/debian-chroot.tar {{ MIRROR }} +{ + tar -tf /tmp/debian-chroot.tar + echo ./var/lib/apt/extended_states +} | sort | diff -u tar1.txt - diff --git a/tests/aptopt b/tests/aptopt index c757c30..68fe713 100644 --- a/tests/aptopt +++ b/tests/aptopt @@ -2,7 +2,7 @@ set -eu export LC_ALL=C.UTF-8 trap "rm -rf /tmp/debian-chroot; rm -f /tmp/config" EXIT INT TERM -echo 'Acquire::Languages "none";' > /tmp/config +echo 'Acquire::Languages "none";' >/tmp/config {{ CMD }} --mode=root --variant=apt --aptopt='Acquire::Check-Valid-Until "false"' --aptopt=/tmp/config {{ DIST }} /tmp/debian-chroot {{ MIRROR }} printf 'Acquire::Check-Valid-Until "false";\nAcquire::Languages "none";\n' | cmp /tmp/debian-chroot/etc/apt/apt.conf.d/99mmdebstrap - rm /tmp/debian-chroot/etc/apt/apt.conf.d/99mmdebstrap diff --git a/tests/arm64-without-qemu-support b/tests/arm64-without-qemu-support index 77c4b20..3fe5444 100644 --- a/tests/arm64-without-qemu-support +++ b/tests/arm64-without-qemu-support @@ -2,8 +2,8 @@ set -eu export LC_ALL=C.UTF-8 if [ ! -e /mmdebstrap-testenv ]; then - echo "this test modifies the system and should only be run inside a container" >&2 - exit 1 + echo "this test modifies the system and should only be run inside a container" >&2 + exit 1 fi apt-get remove --yes qemu-user-binfmt binfmt-support qemu-user # the following is not necessary anymore since systemd-binfmt @@ -13,6 +13,6 @@ apt-get remove --yes qemu-user-binfmt binfmt-support qemu-user ret=0 {{ CMD }} --mode={{ MODE }} --variant=apt --architectures=arm64 {{ DIST }} /tmp/debian-chroot.tar {{ MIRROR }} || ret=$? if [ "$ret" = 0 ]; then - echo expected failure but got exit $ret >&2 - exit 1 + echo expected failure but got exit $ret >&2 + exit 1 fi diff --git a/tests/as-debootstrap-unshare-wrapper b/tests/as-debootstrap-unshare-wrapper index b3f7a44..34fdf1c 100644 --- a/tests/as-debootstrap-unshare-wrapper +++ b/tests/as-debootstrap-unshare-wrapper @@ -5,14 +5,14 @@ export SOURCE_DATE_EPOCH={{ SOURCE_DATE_EPOCH }} prefix= if [ "$(id -u)" -eq 0 ] && [ "{{ MODE }}" != "root" ] && [ "{{ MODE }}" != "auto" ]; then - if ! id "${SUDO_USER:-user}" >/dev/null 2>&1; then - if [ ! -e /mmdebstrap-testenv ]; then - echo "this test modifies the system and should only be run inside a container" >&2 - exit 1 - fi - useradd --home-dir "/home/${SUDO_USER:-user}" --create-home "${SUDO_USER:-user}" - fi - prefix="runuser -u ${SUDO_USER:-user} --" + if ! id "${SUDO_USER:-user}" >/dev/null 2>&1; then + if [ ! -e /mmdebstrap-testenv ]; then + echo "this test modifies the system and should only be run inside a container" >&2 + exit 1 + fi + useradd --home-dir "/home/${SUDO_USER:-user}" --create-home "${SUDO_USER:-user}" + fi + prefix="runuser -u ${SUDO_USER:-user} --" fi # debootstrap uses apt-config to figure out whether the system running it has @@ -30,16 +30,16 @@ fi AUTOPROXY= eval "$(apt-config shell AUTOPROXY Acquire::http::Proxy-Auto-Detect)" if [ -n "$AUTOPROXY" ] && [ -x "$AUTOPROXY" ] && [ -e /tmp/.auto-apt-proxy-0 ]; then - TMP_APT_CONFIG=$(mktemp) - echo "Dir \"/dev/null\";" > "$TMP_APT_CONFIG" - chmod 644 "$TMP_APT_CONFIG" + TMP_APT_CONFIG=$(mktemp) + echo 'Dir "/dev/null";' >"$TMP_APT_CONFIG" + chmod 644 "$TMP_APT_CONFIG" fi $prefix {{ CMD }} --variant=custom --mode={{ MODE }} \ - --setup-hook='env '"${AUTOPROXY:+APT_CONFIG='$TMP_APT_CONFIG'}"' debootstrap --variant={{ VARIANT }} unstable "$1" {{ MIRROR }}' \ - - /tmp/debian-mm.tar {{ MIRROR }} + --setup-hook='env '"${AUTOPROXY:+APT_CONFIG='$TMP_APT_CONFIG'}"' debootstrap --variant={{ VARIANT }} unstable "$1" {{ MIRROR }}' \ + - /tmp/debian-mm.tar {{ MIRROR }} if [ -n "$AUTOPROXY" ] && [ -x "$AUTOPROXY" ] && [ -e /tmp/.auto-apt-proxy-0 ]; then - rm "$TMP_APT_CONFIG" + rm "$TMP_APT_CONFIG" fi mkdir /tmp/debian-mm @@ -62,21 +62,21 @@ rm /tmp/debian-debootstrap/var/cache/apt/archives/*.deb rm /tmp/debian-debootstrap/var/cache/ldconfig/aux-cache # remove logs rm /tmp/debian-debootstrap/var/log/dpkg.log \ - /tmp/debian-debootstrap/var/log/bootstrap.log \ - /tmp/debian-debootstrap/var/log/alternatives.log \ - /tmp/debian-mm/var/log/bootstrap.log + /tmp/debian-debootstrap/var/log/bootstrap.log \ + /tmp/debian-debootstrap/var/log/alternatives.log \ + /tmp/debian-mm/var/log/bootstrap.log # clear out /run except for /run/lock find /tmp/debian-debootstrap/run/ -mindepth 1 -maxdepth 1 ! -name lock -print0 | xargs --no-run-if-empty -0 rm -r # debootstrap doesn't clean apt rm /tmp/debian-debootstrap/var/lib/apt/lists/127.0.0.1_debian_dists_unstable_main_binary-{{ HOSTARCH }}_Packages \ - /tmp/debian-debootstrap/var/lib/apt/lists/127.0.0.1_debian_dists_unstable_InRelease \ - /tmp/debian-debootstrap/var/lib/apt/lists/127.0.0.1_debian_dists_unstable_Release \ - /tmp/debian-debootstrap/var/lib/apt/lists/127.0.0.1_debian_dists_unstable_Release.gpg + /tmp/debian-debootstrap/var/lib/apt/lists/127.0.0.1_debian_dists_unstable_InRelease \ + /tmp/debian-debootstrap/var/lib/apt/lists/127.0.0.1_debian_dists_unstable_Release \ + /tmp/debian-debootstrap/var/lib/apt/lists/127.0.0.1_debian_dists_unstable_Release.gpg if [ -e /tmp/debian-debootstrap/etc/machine-id ]; then - rm /tmp/debian-debootstrap/etc/machine-id /tmp/debian-mm/etc/machine-id + rm /tmp/debian-debootstrap/etc/machine-id /tmp/debian-mm/etc/machine-id fi rm /tmp/debian-mm/var/cache/apt/archives/lock rm /tmp/debian-mm/var/lib/apt/lists/lock @@ -85,24 +85,24 @@ rm /tmp/debian-mm/var/lib/dpkg/arch # also needed for users that are created by systemd-sysusers before systemd 252 # https://github.com/systemd/systemd/pull/24534 for f in shadow shadow-; do - if [ ! -e /tmp/debian-debootstrap/etc/$f ]; then - continue - fi - if ! cmp /tmp/debian-debootstrap/etc/$f /tmp/debian-mm/etc/$f >&2; then - echo patching /etc/$f >&2 - awk -v FS=: -v OFS=: -v SDE={{ SOURCE_DATE_EPOCH }} '{ print $1,$2,int(SDE/60/60/24),$4,$5,$6,$7,$8,$9 }' < /tmp/debian-mm/etc/$f > /tmp/debian-mm/etc/$f.bak - cat /tmp/debian-mm/etc/$f.bak > /tmp/debian-mm/etc/$f - rm /tmp/debian-mm/etc/$f.bak - else - echo no difference for /etc/$f >&2 - fi + if [ ! -e /tmp/debian-debootstrap/etc/$f ]; then + continue + fi + if ! cmp /tmp/debian-debootstrap/etc/$f /tmp/debian-mm/etc/$f >&2; then + echo patching /etc/$f >&2 + awk -v FS=: -v OFS=: -v SDE={{ SOURCE_DATE_EPOCH }} '{ print $1,$2,int(SDE/60/60/24),$4,$5,$6,$7,$8,$9 }' /tmp/debian-mm/etc/$f.bak + cat /tmp/debian-mm/etc/$f.bak >/tmp/debian-mm/etc/$f + rm /tmp/debian-mm/etc/$f.bak + else + echo no difference for /etc/$f >&2 + fi done # isc-dhcp-client postinst doesn't create this file in debootstrap run with # unshared wrapper. The responsible postinst snippet was automatically added # by dh_apparmor since isc-dhcp-client 4.4.3-P1-1.1 if [ -e /tmp/debian-debootstrap/etc/apparmor.d/local/sbin.dhclient ] && [ ! -s /tmp/debian-debootstrap/etc/apparmor.d/local/sbin.dhclient ]; then - echo /sbin/setcap > /tmp/debian-debootstrap/etc/apparmor.d/local/sbin.dhclient + echo /sbin/setcap >/tmp/debian-debootstrap/etc/apparmor.d/local/sbin.dhclient fi # check if the file content differs @@ -111,17 +111,17 @@ diff --unified --no-dereference --recursive /tmp/debian-debootstrap /tmp/debian- # check permissions, ownership, symlink targets, modification times using tar # mtimes of directories created by mmdebstrap will differ, thus we equalize them first for d in etc/apt/preferences.d/ etc/apt/sources.list.d/ etc/dpkg/dpkg.cfg.d/ var/log/apt/; do - touch --date="@{{ SOURCE_DATE_EPOCH }}" /tmp/debian-debootstrap/$d /tmp/debian-mm/$d + touch --date="@{{ SOURCE_DATE_EPOCH }}" /tmp/debian-debootstrap/$d /tmp/debian-mm/$d done # debootstrap never ran apt -- fixing permissions for d in ./var/lib/apt/lists/partial ./var/cache/apt/archives/partial; do - chroot /tmp/debian-debootstrap chmod 0700 $d - chroot /tmp/debian-debootstrap chown _apt:root $d + chroot /tmp/debian-debootstrap chmod 0700 $d + chroot /tmp/debian-debootstrap chown _apt:root $d done tar -C /tmp/debian-debootstrap --numeric-owner --xattrs --xattrs-include='*' --sort=name --clamp-mtime --mtime="$(date --utc --date=@{{ SOURCE_DATE_EPOCH }} --iso-8601=seconds)" -cf /tmp/root1.tar . tar -C /tmp/debian-mm --numeric-owner --xattrs --xattrs-include='*' --sort=name --clamp-mtime --mtime="$(date --utc --date=@{{ SOURCE_DATE_EPOCH }} --iso-8601=seconds)" -cf /tmp/root2.tar . -tar --full-time --verbose -tf /tmp/root1.tar > /tmp/root1.tar.list -tar --full-time --verbose -tf /tmp/root2.tar > /tmp/root2.tar.list +tar --full-time --verbose -tf /tmp/root1.tar >/tmp/root1.tar.list +tar --full-time --verbose -tf /tmp/root2.tar >/tmp/root2.tar.list # despite SOURCE_DATE_EPOCH and --clamp-mtime, the timestamps in the tarball # will slightly differ from each other in the sub-second precision (last # decimals) so the tarballs will not be identical, so we use diff to compare diff --git a/tests/ascii-armored-keys b/tests/ascii-armored-keys index 518991c..cb312fb 100644 --- a/tests/ascii-armored-keys +++ b/tests/ascii-armored-keys @@ -2,19 +2,19 @@ set -eu export LC_ALL=C.UTF-8 if [ ! -e /mmdebstrap-testenv ]; then - echo "this test modifies the system and should only be run inside a container" >&2 - exit 1 + echo "this test modifies the system and should only be run inside a container" >&2 + exit 1 fi for f in /etc/apt/trusted.gpg.d/*.gpg /etc/apt/trusted.gpg.d/*.asc; do - [ -e "$f" ] || continue - rm "$f" + [ -e "$f" ] || continue + rm "$f" done rmdir /etc/apt/trusted.gpg.d mkdir /etc/apt/trusted.gpg.d for f in /usr/share/keyrings/*.gpg; do - name=$(basename "$f" .gpg) - gpg --no-default-keyring --keyring="/usr/share/keyrings/$name.gpg" --armor --output="/etc/apt/trusted.gpg.d/$name.asc" --export - rm "/usr/share/keyrings/$name.gpg" + name=$(basename "$f" .gpg) + gpg --no-default-keyring --keyring="/usr/share/keyrings/$name.gpg" --armor --output="/etc/apt/trusted.gpg.d/$name.asc" --export + rm "/usr/share/keyrings/$name.gpg" done {{ CMD }} --mode=root --variant=apt {{ DIST }} /tmp/debian-chroot.tar {{ MIRROR }} tar -tf /tmp/debian-chroot.tar | sort | diff -u tar1.txt - diff --git a/tests/aspcud-apt-solver b/tests/aspcud-apt-solver index 24ab3f8..28a6299 100644 --- a/tests/aspcud-apt-solver +++ b/tests/aspcud-apt-solver @@ -3,9 +3,12 @@ set -eu export LC_ALL=C.UTF-8 trap "rm -f /tmp/debian-chroot.tar" EXIT INT TERM {{ CMD }} --mode={{ MODE }} --variant=custom \ - --include "$(tr '\n' ',' < pkglist.txt)" \ - --aptopt='APT::Solver "aspcud"' \ - {{ DIST }} /tmp/debian-chroot.tar {{ MIRROR }} -{ tar -tf /tmp/debian-chroot.tar; echo ./var/lib/apt/extended_states; } | sort \ - | grep -v '^./etc/apt/apt.conf.d/99mmdebstrap$' \ - | diff -u tar1.txt - + --include "$(tr '\n' ',' /dev/null 2>&1; then - if [ ! -e /mmdebstrap-testenv ]; then - echo "this test modifies the system and should only be run inside a container" >&2 - exit 1 - fi - useradd --home-dir "/home/${SUDO_USER:-user}" --create-home "${SUDO_USER:-user}" - fi - prefix="runuser -u ${SUDO_USER:-user} --" + if ! id "${SUDO_USER:-user}" >/dev/null 2>&1; then + if [ ! -e /mmdebstrap-testenv ]; then + echo "this test modifies the system and should only be run inside a container" >&2 + exit 1 + fi + useradd --home-dir "/home/${SUDO_USER:-user}" --create-home "${SUDO_USER:-user}" + fi + prefix="runuser -u ${SUDO_USER:-user} --" fi $prefix {{ CMD }} --mode={{ MODE }} --variant=apt {{ DIST }} /tmp/debian-chroot.tar.gz {{ MIRROR }} diff --git a/tests/auto-mode-without-unshare-capabilities b/tests/auto-mode-without-unshare-capabilities index 17244b8..d7352f8 100644 --- a/tests/auto-mode-without-unshare-capabilities +++ b/tests/auto-mode-without-unshare-capabilities @@ -2,12 +2,12 @@ set -eu export LC_ALL=C.UTF-8 if [ ! -e /mmdebstrap-testenv ]; then - echo "this test modifies the system and should only be run inside a container" >&2 - exit 1 + echo "this test modifies the system and should only be run inside a container" >&2 + exit 1 fi useradd --home-dir /home/user --create-home user if [ -e /proc/sys/kernel/unprivileged_userns_clone ] && [ "$(sysctl -n kernel.unprivileged_userns_clone)" = "1" ]; then - sysctl -w kernel.unprivileged_userns_clone=0 + sysctl -w kernel.unprivileged_userns_clone=0 fi runuser -u user -- {{ CMD }} --mode=auto --variant=apt {{ DIST }} /tmp/debian-chroot.tar.gz {{ MIRROR }} tar -tf /tmp/debian-chroot.tar.gz | sort | diff -u tar1.txt - diff --git a/tests/automatic-mirror-from-suite b/tests/automatic-mirror-from-suite index 7cff5a6..b5061b7 100644 --- a/tests/automatic-mirror-from-suite +++ b/tests/automatic-mirror-from-suite @@ -2,10 +2,10 @@ set -eu export LC_ALL=C.UTF-8 if [ ! -e /mmdebstrap-testenv ]; then - echo "this test modifies the system and should only be run inside a container" >&2 - exit 1 + echo "this test modifies the system and should only be run inside a container" >&2 + exit 1 fi -cat << HOSTS >> /etc/hosts +cat <>/etc/hosts 127.0.0.1 deb.debian.org 127.0.0.1 security.debian.org HOSTS diff --git a/tests/check-against-debootstrap-dist b/tests/check-against-debootstrap-dist index 40e5798..c12123e 100644 --- a/tests/check-against-debootstrap-dist +++ b/tests/check-against-debootstrap-dist @@ -11,10 +11,10 @@ echo "SOURCE_DATE_EPOCH=$SOURCE_DATE_EPOCH" # https://bugs.debian.org/969631 # we cannot use useradd because passwd is not Essential:yes {{ CMD }} --variant={{ VARIANT }} --mode={{ MODE }} \ - --essential-hook='[ {{ DIST }} = oldstable ] && [ {{ VARIANT }} = - ] && echo _apt:*:100:65534::/nonexistent:/usr/sbin/nologin >> "$1"/etc/passwd || :' \ - "$(if [ {{ DIST }} = oldstable ]; then echo --merged-usr; else echo --hook-dir=./hooks/merged-usr; fi)" \ - "$(case {{ DIST }} in oldstable) echo --include=e2fsprogs,mount,tzdata,gcc-9-base;; stable) echo --include=e2fsprogs,mount,tzdata;; *) echo --include=base-files ;; esac )" \ - {{ DIST }} /tmp/debian-{{ DIST }}-mm.tar {{ MIRROR }} + --essential-hook='[ {{ DIST }} = oldstable ] && [ {{ VARIANT }} = - ] && echo _apt:*:100:65534::/nonexistent:/usr/sbin/nologin >> "$1"/etc/passwd || :' \ + "$(if [ {{ DIST }} = oldstable ]; then echo --merged-usr; else echo --hook-dir=./hooks/merged-usr; fi)" \ + "$(case {{ DIST }} in oldstable) echo --include=e2fsprogs,mount,tzdata,gcc-9-base ;; stable) echo --include=e2fsprogs,mount,tzdata ;; *) echo --include=base-files ;; esac)" \ + {{ DIST }} /tmp/debian-{{ DIST }}-mm.tar {{ MIRROR }} mkdir /tmp/debian-{{ DIST }}-mm tar --xattrs --xattrs-include='*' -C /tmp/debian-{{ DIST }}-mm -xf /tmp/debian-{{ DIST }}-mm.tar @@ -30,27 +30,27 @@ tar -C /tmp/debian-{{ DIST }}-mm -cf /tmp/dev2.tar ./dev ret=0 cmp /tmp/dev1.tar /tmp/dev2.tar >&2 || ret=$? if [ "$ret" -ne 0 ]; then - if type diffoscope >/dev/null; then - diffoscope /tmp/dev1.tar /tmp/dev2.tar - exit 1 - else - echo "no diffoscope installed" >&2 - fi - if type base64 >/dev/null; then - base64 /tmp/dev1.tar - base64 /tmp/dev2.tar - exit 1 - else - echo "no base64 installed" >&2 - fi - if type xxd >/dev/null; then - xxd /tmp/dev1.tar - xxd /tmp/dev2.tar - exit 1 - else - echo "no xxd installed" >&2 - fi - exit 1 + if type diffoscope >/dev/null; then + diffoscope /tmp/dev1.tar /tmp/dev2.tar + exit 1 + else + echo "no diffoscope installed" >&2 + fi + if type base64 >/dev/null; then + base64 /tmp/dev1.tar + base64 /tmp/dev2.tar + exit 1 + else + echo "no base64 installed" >&2 + fi + if type xxd >/dev/null; then + xxd /tmp/dev1.tar + xxd /tmp/dev2.tar + exit 1 + else + echo "no xxd installed" >&2 + fi + exit 1 fi rm /tmp/dev1.tar /tmp/dev2.tar rm -r /tmp/debian-{{ DIST }}-debootstrap/dev /tmp/debian-{{ DIST }}-mm/dev @@ -61,17 +61,17 @@ rm /tmp/debian-{{ DIST }}-debootstrap/var/cache/apt/archives/*.deb rm /tmp/debian-{{ DIST }}-debootstrap/var/cache/ldconfig/aux-cache # remove logs rm /tmp/debian-{{ DIST }}-debootstrap/var/log/dpkg.log \ - /tmp/debian-{{ DIST }}-debootstrap/var/log/bootstrap.log \ - /tmp/debian-{{ DIST }}-debootstrap/var/log/alternatives.log + /tmp/debian-{{ DIST }}-debootstrap/var/log/bootstrap.log \ + /tmp/debian-{{ DIST }}-debootstrap/var/log/alternatives.log # remove *-old files rm /tmp/debian-{{ DIST }}-debootstrap/var/cache/debconf/config.dat-old \ - /tmp/debian-{{ DIST }}-mm/var/cache/debconf/config.dat-old + /tmp/debian-{{ DIST }}-mm/var/cache/debconf/config.dat-old rm /tmp/debian-{{ DIST }}-debootstrap/var/cache/debconf/templates.dat-old \ - /tmp/debian-{{ DIST }}-mm/var/cache/debconf/templates.dat-old + /tmp/debian-{{ DIST }}-mm/var/cache/debconf/templates.dat-old rm /tmp/debian-{{ DIST }}-debootstrap/var/lib/dpkg/status-old \ - /tmp/debian-{{ DIST }}-mm/var/lib/dpkg/status-old + /tmp/debian-{{ DIST }}-mm/var/lib/dpkg/status-old rm -f /tmp/debian-{{ DIST }}-debootstrap/var/lib/dpkg/diversions-old \ - /tmp/debian-{{ DIST }}-mm/var/lib/dpkg/diversions-old + /tmp/debian-{{ DIST }}-mm/var/lib/dpkg/diversions-old # remove dpkg files rm /tmp/debian-{{ DIST }}-debootstrap/var/lib/dpkg/available rm /tmp/debian-{{ DIST }}-debootstrap/var/lib/dpkg/cmethopt @@ -79,49 +79,49 @@ rm /tmp/debian-{{ DIST }}-debootstrap/var/lib/dpkg/cmethopt rm /tmp/debian-{{ DIST }}-mm/var/lib/dpkg/arch # since we installed packages directly from the .deb files, Priorities differ # thus we first check for equality and then remove the files -chroot /tmp/debian-{{ DIST }}-debootstrap dpkg --list > /tmp/dpkg1 -chroot /tmp/debian-{{ DIST }}-mm dpkg --list > /tmp/dpkg2 +chroot /tmp/debian-{{ DIST }}-debootstrap dpkg --list >/tmp/dpkg1 +chroot /tmp/debian-{{ DIST }}-mm dpkg --list >/tmp/dpkg2 diff -u /tmp/dpkg1 /tmp/dpkg2 >&2 rm /tmp/dpkg1 /tmp/dpkg2 -grep -v '^Priority: ' /tmp/debian-{{ DIST }}-debootstrap/var/lib/dpkg/status > /tmp/status1 -grep -v '^Priority: ' /tmp/debian-{{ DIST }}-mm/var/lib/dpkg/status > /tmp/status2 +grep -v '^Priority: ' /tmp/debian-{{ DIST }}-debootstrap/var/lib/dpkg/status >/tmp/status1 +grep -v '^Priority: ' /tmp/debian-{{ DIST }}-mm/var/lib/dpkg/status >/tmp/status2 diff -u /tmp/status1 /tmp/status2 >&2 rm /tmp/status1 /tmp/status2 rm /tmp/debian-{{ DIST }}-debootstrap/var/lib/dpkg/status /tmp/debian-{{ DIST }}-mm/var/lib/dpkg/status # debootstrap exposes the hosts's kernel version if [ -e /tmp/debian-{{ DIST }}-debootstrap/etc/apt/apt.conf.d/01autoremove-kernels ]; then - rm /tmp/debian-{{ DIST }}-debootstrap/etc/apt/apt.conf.d/01autoremove-kernels + rm /tmp/debian-{{ DIST }}-debootstrap/etc/apt/apt.conf.d/01autoremove-kernels fi if [ -e /tmp/debian-{{ DIST }}-mm/etc/apt/apt.conf.d/01autoremove-kernels ]; then - rm /tmp/debian-{{ DIST }}-mm/etc/apt/apt.conf.d/01autoremove-kernels + rm /tmp/debian-{{ DIST }}-mm/etc/apt/apt.conf.d/01autoremove-kernels fi # clear out /run except for /run/lock find /tmp/debian-{{ DIST }}-debootstrap/run/ -mindepth 1 -maxdepth 1 ! -name lock -print0 | xargs --no-run-if-empty -0 rm -r # debootstrap doesn't clean apt rm /tmp/debian-{{ DIST }}-debootstrap/var/lib/apt/lists/127.0.0.1_debian_dists_{{ DIST }}_main_binary-{{ HOSTARCH }}_Packages \ - /tmp/debian-{{ DIST }}-debootstrap/var/lib/apt/lists/127.0.0.1_debian_dists_{{ DIST }}_InRelease \ - /tmp/debian-{{ DIST }}-debootstrap/var/lib/apt/lists/127.0.0.1_debian_dists_{{ DIST }}_Release \ - /tmp/debian-{{ DIST }}-debootstrap/var/lib/apt/lists/127.0.0.1_debian_dists_{{ DIST }}_Release.gpg + /tmp/debian-{{ DIST }}-debootstrap/var/lib/apt/lists/127.0.0.1_debian_dists_{{ DIST }}_InRelease \ + /tmp/debian-{{ DIST }}-debootstrap/var/lib/apt/lists/127.0.0.1_debian_dists_{{ DIST }}_Release \ + /tmp/debian-{{ DIST }}-debootstrap/var/lib/apt/lists/127.0.0.1_debian_dists_{{ DIST }}_Release.gpg if [ "{{ VARIANT }}" = "-" ]; then - rm /tmp/debian-{{ DIST }}-debootstrap/etc/machine-id - rm /tmp/debian-{{ DIST }}-mm/etc/machine-id - rm /tmp/debian-{{ DIST }}-debootstrap/var/lib/systemd/catalog/database - rm /tmp/debian-{{ DIST }}-mm/var/lib/systemd/catalog/database + rm /tmp/debian-{{ DIST }}-debootstrap/etc/machine-id + rm /tmp/debian-{{ DIST }}-mm/etc/machine-id + rm /tmp/debian-{{ DIST }}-debootstrap/var/lib/systemd/catalog/database + rm /tmp/debian-{{ DIST }}-mm/var/lib/systemd/catalog/database - cap=$(chroot /tmp/debian-{{ DIST }}-debootstrap /sbin/getcap /bin/ping) - expected="/bin/ping cap_net_raw=ep" - if [ "$cap" != "$expected" ]; then - echo "expected bin/ping to have capabilities $expected" >&2 - echo "but debootstrap produced: $cap" >&2 - exit 1 - fi - cap=$(chroot /tmp/debian-{{ DIST }}-mm /sbin/getcap /bin/ping) - if [ "$cap" != "$expected" ]; then - echo "expected bin/ping to have capabilities $expected" >&2 - echo "but mmdebstrap produced: $cap" >&2 - exit 1 - fi + cap=$(chroot /tmp/debian-{{ DIST }}-debootstrap /sbin/getcap /bin/ping) + expected="/bin/ping cap_net_raw=ep" + if [ "$cap" != "$expected" ]; then + echo "expected bin/ping to have capabilities $expected" >&2 + echo "but debootstrap produced: $cap" >&2 + exit 1 + fi + cap=$(chroot /tmp/debian-{{ DIST }}-mm /sbin/getcap /bin/ping) + if [ "$cap" != "$expected" ]; then + echo "expected bin/ping to have capabilities $expected" >&2 + echo "but mmdebstrap produced: $cap" >&2 + exit 1 + fi fi rm /tmp/debian-{{ DIST }}-mm/var/cache/apt/archives/lock rm /tmp/debian-{{ DIST }}-mm/var/lib/apt/extended_states @@ -130,97 +130,100 @@ rm /tmp/debian-{{ DIST }}-mm/var/lib/apt/lists/lock # the list of shells might be sorted wrongly # /var/lib/dpkg/triggers/File might be sorted wrongly for f in "/var/lib/dpkg/triggers/File" "/etc/shells"; do - f1="/tmp/debian-{{ DIST }}-debootstrap/$f" - f2="/tmp/debian-{{ DIST }}-mm/$f" - # both chroots must have the file - if [ ! -e "$f1" ] || [ ! -e "$f2" ]; then - continue - fi - # the file must be different - if cmp "$f1" "$f2" >&2; then - continue - fi - # then sort both - sort -o "$f1" "$f1" - sort -o "$f2" "$f2" + f1="/tmp/debian-{{ DIST }}-debootstrap/$f" + f2="/tmp/debian-{{ DIST }}-mm/$f" + # both chroots must have the file + if [ ! -e "$f1" ] || [ ! -e "$f2" ]; then + continue + fi + # the file must be different + if cmp "$f1" "$f2" >&2; then + continue + fi + # then sort both + sort -o "$f1" "$f1" + sort -o "$f2" "$f2" done # Because of unreproducible uids (#969631) we created the _apt user ourselves # and because passwd is not Essential:yes we didn't use useradd. But newer # versions of adduser and shadow will create a different /etc/shadow if [ "{{ VARIANT }}" = "-" ] && [ "{{ DIST}}" = oldstable ]; then - for f in shadow shadow-; do - if grep -q '^_apt:!:' /tmp/debian-{{ DIST }}-debootstrap/etc/$f; then - sed -i 's/^_apt:\*:\([^:]\+\):0:99999:7:::$/_apt:!:\1::::::/' /tmp/debian-{{ DIST }}-mm/etc/$f - fi - done + for f in shadow shadow-; do + if grep -q '^_apt:!:' /tmp/debian-{{ DIST }}-debootstrap/etc/$f; then + sed -i 's/^_apt:\*:\([^:]\+\):0:99999:7:::$/_apt:!:\1::::::/' /tmp/debian-{{ DIST }}-mm/etc/$f + fi + done fi for log in faillog lastlog; do - f1="/tmp/debian-{{ DIST }}-debootstrap/var/log/$log" - f2="/tmp/debian-{{ DIST }}-mm/var/log/$log" - # skip cmp if file is absent in both chroots - if [ ! -e "$f1" ] && [ ! -e "$f2" ]; then - continue - fi - if ! cmp "$f1" "$f2" >&2;then - # if the files differ, make sure they are all zeroes - cmp -n "$(stat -c %s "$f1")" "$f1" /dev/zero >&2 - cmp -n "$(stat -c %s "$f2")" "$f2" /dev/zero >&2 - # then delete them - rm "$f1" "$f2" - fi + f1="/tmp/debian-{{ DIST }}-debootstrap/var/log/$log" + f2="/tmp/debian-{{ DIST }}-mm/var/log/$log" + # skip cmp if file is absent in both chroots + if [ ! -e "$f1" ] && [ ! -e "$f2" ]; then + continue + fi + if ! cmp "$f1" "$f2" >&2; then + # if the files differ, make sure they are all zeroes + cmp -n "$(stat -c %s "$f1")" "$f1" /dev/zero >&2 + cmp -n "$(stat -c %s "$f2")" "$f2" /dev/zero >&2 + # then delete them + rm "$f1" "$f2" + fi done if [ "{{ VARIANT }}" = "-" ]; then - # the order in which systemd and cron get installed differ and thus the order - # of lines in /etc/group and /etc/gshadow differs - for f in group group- gshadow gshadow-; do - for d in mm debootstrap; do - sort /tmp/debian-{{ DIST }}-$d/etc/$f > /tmp/debian-{{ DIST }}-$d/etc/$f.bak - mv /tmp/debian-{{ DIST }}-$d/etc/$f.bak /tmp/debian-{{ DIST }}-$d/etc/$f - done - done - # the order in which systemd and passwd get installed differ and thus - # the order of lines in /etc/shadow and /etc/shadow- differs - for f in shadow shadow-; do - for d in mm debootstrap; do - sort /tmp/debian-{{ DIST }}-$d/etc/$f > /tmp/debian-{{ DIST }}-$d/etc/$f.bak - mv /tmp/debian-{{ DIST }}-$d/etc/$f.bak /tmp/debian-{{ DIST }}-$d/etc/$f - done - done - # and since the order was different, ignore the *- files - for f in shadow- passwd-; do - for d in mm debootstrap; do - rm /tmp/debian-{{ DIST }}-$d/etc/$f - done - done + # the order in which systemd and cron get installed differ and thus the order + # of lines in /etc/group and /etc/gshadow differs + for f in group group- gshadow gshadow-; do + for d in mm debootstrap; do + sort /tmp/debian-{{ DIST }}-$d/etc/$f >/tmp/debian-{{ DIST }}-$d/etc/$f.bak + mv /tmp/debian-{{ DIST }}-$d/etc/$f.bak /tmp/debian-{{ DIST }}-$d/etc/$f + done + done + # the order in which systemd and passwd get installed differ and thus + # the order of lines in /etc/shadow and /etc/shadow- differs + for f in shadow shadow-; do + for d in mm debootstrap; do + sort /tmp/debian-{{ DIST }}-$d/etc/$f >/tmp/debian-{{ DIST }}-$d/etc/$f.bak + mv /tmp/debian-{{ DIST }}-$d/etc/$f.bak /tmp/debian-{{ DIST }}-$d/etc/$f + done + done + # and since the order was different, ignore the *- files + for f in shadow- passwd-; do + for d in mm debootstrap; do + rm /tmp/debian-{{ DIST }}-$d/etc/$f + done + done fi # since debootstrap 1.0.133 there is no tzdata in the buildd variant and thus # debootstrap creates its own /etc/localtime if [ "{{ VARIANT }}" = "buildd" ] && [ "{{ DIST }}" != "stable" ] && [ "{{ DIST }}" != "oldstable" ]; then - [ "$(readlink /tmp/debian-{{ DIST }}-debootstrap/etc/localtime)" = /usr/share/zoneinfo/UTC ] - rm /tmp/debian-{{ DIST }}-debootstrap/etc/localtime + [ "$(readlink /tmp/debian-{{ DIST }}-debootstrap/etc/localtime)" = /usr/share/zoneinfo/UTC ] + rm /tmp/debian-{{ DIST }}-debootstrap/etc/localtime fi # starting with systemd 255 upstream dropped splitusr support and depending on # the installation order, symlink targets are prefixed with /usr or not # See #1060000 and #1054137 -case {{ DIST }} in testing|unstable) - for f in multi-user.target.wants/e2scrub_reap.service timers.target.wants/apt-daily-upgrade.timer timers.target.wants/apt-daily.timer timers.target.wants/e2scrub_all.timer; do - for d in mm debootstrap; do - [ -L "/tmp/debian-{{ DIST }}-$d/etc/systemd/system/$f" ] || continue - oldlink="$(readlink "/tmp/debian-{{ DIST }}-$d/etc/systemd/system/$f")" - case $oldlink in - /usr/*) : ;; - /*) oldlink="/usr$oldlink" ;; - *) echo unexpected >&2; exit 1 ;; - esac - ln -sf "$oldlink" "/tmp/debian-{{ DIST }}-$d/etc/systemd/system/$f" - done - done - ;; +case {{ DIST }} in testing | unstable) + for f in multi-user.target.wants/e2scrub_reap.service timers.target.wants/apt-daily-upgrade.timer timers.target.wants/apt-daily.timer timers.target.wants/e2scrub_all.timer; do + for d in mm debootstrap; do + [ -L "/tmp/debian-{{ DIST }}-$d/etc/systemd/system/$f" ] || continue + oldlink="$(readlink "/tmp/debian-{{ DIST }}-$d/etc/systemd/system/$f")" + case $oldlink in + /usr/*) : ;; + /*) oldlink="/usr$oldlink" ;; + *) + echo unexpected >&2 + exit 1 + ;; + esac + ln -sf "$oldlink" "/tmp/debian-{{ DIST }}-$d/etc/systemd/system/$f" + done + done + ;; esac # check if the file content differs @@ -231,14 +234,14 @@ diff --unified --no-dereference --recursive /tmp/debian-{{ DIST }}-debootstrap / find /tmp/debian-{{ DIST }}-debootstrap /tmp/debian-{{ DIST }}-mm -type d -print0 | xargs -0 touch --date="@{{ SOURCE_DATE_EPOCH }}" # debootstrap never ran apt -- fixing permissions for d in ./var/lib/apt/lists/partial ./var/cache/apt/archives/partial; do - unmergedPATH="$PATH$(if [ "{{ DIST }}" = oldstable ]; then echo :/bin:/sbin; fi)" - PATH="$unmergedPATH" chroot /tmp/debian-{{ DIST }}-debootstrap chmod 0700 $d - PATH="$unmergedPATH" chroot /tmp/debian-{{ DIST }}-debootstrap chown "$(id -u _apt):root" $d + unmergedPATH="$PATH$(if [ "{{ DIST }}" = oldstable ]; then echo :/bin:/sbin; fi)" + PATH="$unmergedPATH" chroot /tmp/debian-{{ DIST }}-debootstrap chmod 0700 $d + PATH="$unmergedPATH" chroot /tmp/debian-{{ DIST }}-debootstrap chown "$(id -u _apt):root" $d done tar -C /tmp/debian-{{ DIST }}-debootstrap --numeric-owner --sort=name --clamp-mtime --mtime="$(date --utc --date=@{{ SOURCE_DATE_EPOCH }} --iso-8601=seconds)" -cf /tmp/root1.tar . tar -C /tmp/debian-{{ DIST }}-mm --numeric-owner --sort=name --clamp-mtime --mtime="$(date --utc --date=@{{ SOURCE_DATE_EPOCH }} --iso-8601=seconds)" -cf /tmp/root2.tar . -tar --full-time --verbose -tf /tmp/root1.tar > /tmp/root1.tar.list -tar --full-time --verbose -tf /tmp/root2.tar > /tmp/root2.tar.list +tar --full-time --verbose -tf /tmp/root1.tar >/tmp/root1.tar.list +tar --full-time --verbose -tf /tmp/root2.tar >/tmp/root2.tar.list diff -u /tmp/root1.tar.list /tmp/root2.tar.list >&2 rm /tmp/root1.tar /tmp/root2.tar /tmp/root1.tar.list /tmp/root2.tar.list diff --git a/tests/check-for-bit-by-bit-identical-format-output b/tests/check-for-bit-by-bit-identical-format-output index 6cbab90..6c9bba6 100644 --- a/tests/check-for-bit-by-bit-identical-format-output +++ b/tests/check-for-bit-by-bit-identical-format-output @@ -5,23 +5,23 @@ export SOURCE_DATE_EPOCH={{ SOURCE_DATE_EPOCH }} trap "rm -f /tmp/debian-chroot-{{ MODE }}.{{ FORMAT }}" EXIT INT TERM -case {{ MODE }} in unshare|fakechroot) : ;; *) exit 1;; esac +case {{ MODE }} in unshare | fakechroot) : ;; *) exit 1 ;; esac prefix= if [ "$(id -u)" -eq 0 ] && [ "{{ MODE }}" != "root" ] && [ "{{ MODE }}" != "auto" ]; then - if ! id "${SUDO_USER:-user}" >/dev/null 2>&1; then - if [ ! -e /mmdebstrap-testenv ]; then - echo "this test modifies the system and should only be run inside a container" >&2 - exit 1 - fi - useradd --home-dir "/home/${SUDO_USER:-user}" --create-home "${SUDO_USER:-user}" - fi - prefix="runuser -u ${SUDO_USER:-user} --" + if ! id "${SUDO_USER:-user}" >/dev/null 2>&1; then + if [ ! -e /mmdebstrap-testenv ]; then + echo "this test modifies the system and should only be run inside a container" >&2 + exit 1 + fi + useradd --home-dir "/home/${SUDO_USER:-user}" --create-home "${SUDO_USER:-user}" + fi + prefix="runuser -u ${SUDO_USER:-user} --" fi $prefix {{ CMD }} --mode={{ MODE }} --variant={{ VARIANT }} {{ DIST }} /tmp/debian-chroot-{{ MODE }}.{{ FORMAT }} {{ MIRROR }} cmp ./cache/mmdebstrap-{{ DIST }}-{{ VARIANT }}.{{ FORMAT }} /tmp/debian-chroot-{{ MODE }}.{{ FORMAT }} \ - || diffoscope ./cache/mmdebstrap-{{ DIST }}-{{ VARIANT }}.{{ FORMAT }} /tmp/debian-chroot-{{ MODE }}.{{ FORMAT }} + || diffoscope ./cache/mmdebstrap-{{ DIST }}-{{ VARIANT }}.{{ FORMAT }} /tmp/debian-chroot-{{ MODE }}.{{ FORMAT }} # we cannot test chrootless mode here, because mmdebstrap relies on the # usrmerge package to set up merged-/usr and that doesn't work in chrootless diff --git a/tests/chrootless b/tests/chrootless index 77490c3..4a2548b 100644 --- a/tests/chrootless +++ b/tests/chrootless @@ -6,11 +6,11 @@ trap "rm -f /tmp/chrootless.tar /tmp/root.tar" EXIT INT TERM # we need --hook-dir=./hooks/merged-usr because usrmerge does not understand # DPKG_ROOT for INCLUDE in '' 'apt' 'apt,build-essential' 'systemd-sysv'; do - for MODE in root chrootless; do - {{ CMD }} --mode=$MODE --variant={{ VARIANT }} --hook-dir=./hooks/merged-usr \ - ${INCLUDE:+--include="$INCLUDE"} --skip=check/chrootless \ - {{ DIST }} "/tmp/$MODE.tar" {{ MIRROR }} - done - cmp /tmp/root.tar /tmp/chrootless.tar || diffoscope /tmp/root.tar /tmp/chrootless.tar - rm /tmp/chrootless.tar /tmp/root.tar + for MODE in root chrootless; do + {{ CMD }} --mode=$MODE --variant={{ VARIANT }} --hook-dir=./hooks/merged-usr \ + ${INCLUDE:+--include="$INCLUDE"} --skip=check/chrootless \ + {{ DIST }} "/tmp/$MODE.tar" {{ MIRROR }} + done + cmp /tmp/root.tar /tmp/chrootless.tar || diffoscope /tmp/root.tar /tmp/chrootless.tar + rm /tmp/chrootless.tar /tmp/root.tar done diff --git a/tests/chrootless-fakeroot b/tests/chrootless-fakeroot index 8821fa6..cbddc21 100644 --- a/tests/chrootless-fakeroot +++ b/tests/chrootless-fakeroot @@ -8,14 +8,14 @@ trap "rm -f /tmp/chrootless.tar /tmp/root.tar" EXIT INT TERM prefix= if [ "$(id -u)" -eq 0 ] && [ "{{ MODE }}" != "root" ] && [ "{{ MODE }}" != "auto" ]; then - if ! id "${SUDO_USER:-user}" >/dev/null 2>&1; then - if [ ! -e /mmdebstrap-testenv ]; then - echo "this test modifies the system and should only be run inside a container" >&2 - exit 1 - fi - useradd --home-dir "/home/${SUDO_USER:-user}" --create-home "${SUDO_USER:-user}" - fi - prefix="runuser -u ${SUDO_USER:-user} --" + if ! id "${SUDO_USER:-user}" >/dev/null 2>&1; then + if [ ! -e /mmdebstrap-testenv ]; then + echo "this test modifies the system and should only be run inside a container" >&2 + exit 1 + fi + useradd --home-dir "/home/${SUDO_USER:-user}" --create-home "${SUDO_USER:-user}" + fi + prefix="runuser -u ${SUDO_USER:-user} --" fi MMTARFILTER= @@ -28,16 +28,16 @@ MMTARFILTER= # be preserved under fakeroot # this applies to 'z' lines in files in /usr/lib/tmpfiles.d/ for INCLUDE in '' 'apt' 'apt,build-essential' 'systemd-sysv'; do - {{ CMD }} --variant={{ VARIANT }} --hook-dir=./hooks/merged-usr \ - ${INCLUDE:+--include="$INCLUDE"} \ - {{ DIST }} - {{ MIRROR }} \ - | "$MMTARFILTER" --path-exclude="/var/log/journal" --path-exclude="/etc/credstore*" \ - >/tmp/root.tar - $prefix fakeroot {{ CMD }} --mode={{ MODE }} --variant={{ VARIANT }} --hook-dir=./hooks/merged-usr \ - ${INCLUDE:+--include="$INCLUDE"} \ - {{ DIST }} - {{ MIRROR }} \ - | "$MMTARFILTER" --path-exclude="/var/log/journal" --path-exclude="/etc/credstore*" \ - > /tmp/chrootless.tar - cmp /tmp/root.tar /tmp/chrootless.tar || diffoscope /tmp/root.tar /tmp/chrootless.tar - rm /tmp/chrootless.tar /tmp/root.tar + {{ CMD }} --variant={{ VARIANT }} --hook-dir=./hooks/merged-usr \ + ${INCLUDE:+--include="$INCLUDE"} \ + {{ DIST }} - {{ MIRROR }} \ + | "$MMTARFILTER" --path-exclude="/var/log/journal" --path-exclude="/etc/credstore*" \ + >/tmp/root.tar + $prefix fakeroot {{ CMD }} --mode={{ MODE }} --variant={{ VARIANT }} --hook-dir=./hooks/merged-usr \ + ${INCLUDE:+--include="$INCLUDE"} \ + {{ DIST }} - {{ MIRROR }} \ + | "$MMTARFILTER" --path-exclude="/var/log/journal" --path-exclude="/etc/credstore*" \ + >/tmp/chrootless.tar + cmp /tmp/root.tar /tmp/chrootless.tar || diffoscope /tmp/root.tar /tmp/chrootless.tar + rm /tmp/chrootless.tar /tmp/root.tar done diff --git a/tests/chrootless-foreign b/tests/chrootless-foreign index 03203d0..0317f12 100644 --- a/tests/chrootless-foreign +++ b/tests/chrootless-foreign @@ -4,29 +4,28 @@ export LC_ALL=C.UTF-8 export SOURCE_DATE_EPOCH={{ SOURCE_DATE_EPOCH }} trap "rm -f /tmp/chrootless.tar /tmp/root.tar" EXIT INT TERM if [ ! -e /mmdebstrap-testenv ]; then - echo "this test modifies the system and should only be run inside a container" >&2 - exit 1 + echo "this test modifies the system and should only be run inside a container" >&2 + exit 1 fi deb2qemu() { - case "$1" in - amd64) echo x86_64;; - arm64) echo aarch64;; - armel|armhf) echo arm;; - ppc64el) echo ppc64le;; - *) echo "$1";; - esac + case "$1" in + amd64) echo x86_64 ;; + arm64) echo aarch64 ;; + armel | armhf) echo arm ;; + ppc64el) echo ppc64le ;; + *) echo "$1" ;; + esac } if [ "$(dpkg --print-architecture)" = "arm64" ]; then - arch=amd64 + arch=amd64 else - arch=arm64 + arch=arm64 fi [ "$(id -u)" -eq 0 ] [ -e "/proc/sys/fs/binfmt_misc/qemu-$(deb2qemu "$arch")" ] - # we need --hook-dir=./hooks/merged-usr because usrmerge does not understand # DPKG_ROOT # @@ -36,33 +35,32 @@ fi # its own architecture as the native architecture, see #825385 and #1020533 # So we are not testing the installation of apt,build-essential here. for INCLUDE in '' 'apt' 'systemd-sysv'; do - echo 1 > "/proc/sys/fs/binfmt_misc/qemu-$(deb2qemu "$arch")" - arch-test "$arch" - {{ CMD }} --mode=root --architecture="$arch" --variant={{ VARIANT }} \ - --hook-dir=./hooks/merged-usr ${INCLUDE:+--include="$INCLUDE"} \ - {{ DIST }} "/tmp/root.tar" {{ MIRROR }} - echo 0 > "/proc/sys/fs/binfmt_misc/qemu-$(deb2qemu "$arch")" - arch-test "$arch" && exit 1 - {{ CMD }} --mode=chrootless --architecture="$arch" --variant={{ VARIANT }} \ - --hook-dir=./hooks/merged-usr ${INCLUDE:+--include="$INCLUDE"} \ - --skip=check/chrootless {{ DIST }} "/tmp/chrootless.tar" {{ MIRROR }} - # when creating a foreign architecture chroot, the tarballs are not - # bit-by-bit identical but contain a few remaining differences: - # - # * /etc/ld.so.cache -- hard problem, must be solved in glibc upstream - # * /var/lib/dpkg/triggers -- #990712 - # * /var/cache/debconf/*.dat-old -- needs investigation - for tar in root chrootless; do - <"/tmp/$tar.tar" \ - ./tarfilter \ - --path-exclude=/var/cache/debconf/config.dat-old \ - --path-exclude=/var/cache/debconf/templates.dat-old \ - --path-exclude=/etc/ld.so.cache \ - --path-exclude=/var/lib/dpkg/triggers/File \ - --path-exclude=/var/lib/dpkg/triggers/ldconfig \ - > "/tmp/$tar.tar.tmp" - mv "/tmp/$tar.tar.tmp" "/tmp/$tar.tar" - done - cmp /tmp/root.tar /tmp/chrootless.tar || diffoscope /tmp/root.tar /tmp/chrootless.tar - rm /tmp/chrootless.tar /tmp/root.tar + echo 1 >"/proc/sys/fs/binfmt_misc/qemu-$(deb2qemu "$arch")" + arch-test "$arch" + {{ CMD }} --mode=root --architecture="$arch" --variant={{ VARIANT }} \ + --hook-dir=./hooks/merged-usr ${INCLUDE:+--include="$INCLUDE"} \ + {{ DIST }} "/tmp/root.tar" {{ MIRROR }} + echo 0 >"/proc/sys/fs/binfmt_misc/qemu-$(deb2qemu "$arch")" + arch-test "$arch" && exit 1 + {{ CMD }} --mode=chrootless --architecture="$arch" --variant={{ VARIANT }} \ + --hook-dir=./hooks/merged-usr ${INCLUDE:+--include="$INCLUDE"} \ + --skip=check/chrootless {{ DIST }} "/tmp/chrootless.tar" {{ MIRROR }} + # when creating a foreign architecture chroot, the tarballs are not + # bit-by-bit identical but contain a few remaining differences: + # + # * /etc/ld.so.cache -- hard problem, must be solved in glibc upstream + # * /var/lib/dpkg/triggers -- #990712 + # * /var/cache/debconf/*.dat-old -- needs investigation + for tar in root chrootless; do + ./tarfilter <"/tmp/$tar.tar" \ + --path-exclude=/var/cache/debconf/config.dat-old \ + --path-exclude=/var/cache/debconf/templates.dat-old \ + --path-exclude=/etc/ld.so.cache \ + --path-exclude=/var/lib/dpkg/triggers/File \ + --path-exclude=/var/lib/dpkg/triggers/ldconfig \ + >"/tmp/$tar.tar.tmp" + mv "/tmp/$tar.tar.tmp" "/tmp/$tar.tar" + done + cmp /tmp/root.tar /tmp/chrootless.tar || diffoscope /tmp/root.tar /tmp/chrootless.tar + rm /tmp/chrootless.tar /tmp/root.tar done diff --git a/tests/compare-output-with-pre-seeded-var-cache-apt-archives b/tests/compare-output-with-pre-seeded-var-cache-apt-archives index f0e132c..025052f 100644 --- a/tests/compare-output-with-pre-seeded-var-cache-apt-archives +++ b/tests/compare-output-with-pre-seeded-var-cache-apt-archives @@ -7,21 +7,21 @@ set -eu export LC_ALL=C.UTF-8 export SOURCE_DATE_EPOCH={{ SOURCE_DATE_EPOCH }} if [ ! -e /mmdebstrap-testenv ]; then - echo "this test requires the cache directory to be mounted on /mnt and should only be run inside a container" >&2 - exit 1 + echo "this test requires the cache directory to be mounted on /mnt and should only be run inside a container" >&2 + exit 1 fi tmpdir=$(mktemp -d) trap 'rm -f "$tmpdir"/*.deb /tmp/orig.tar /tmp/test1.tar /tmp/test2.tar; rmdir "$tmpdir"' EXIT INT TERM include="--include=doc-debian" if [ "{{ VARIANT }}" = "custom" ]; then - include="$include,base-files,base-passwd,coreutils,dash,diffutils,dpkg,libc-bin,sed" + include="$include,base-files,base-passwd,coreutils,dash,diffutils,dpkg,libc-bin,sed" fi {{ CMD }} $include --mode={{ MODE }} --variant={{ VARIANT }} \ - --setup-hook='mkdir -p "$1"/var/cache/apt/archives/partial' \ - --setup-hook='touch "$1"/var/cache/apt/archives/lock' \ - --setup-hook='chmod 0640 "$1"/var/cache/apt/archives/lock' \ - {{ DIST }} - {{ MIRROR }} > /tmp/orig.tar + --setup-hook='mkdir -p "$1"/var/cache/apt/archives/partial' \ + --setup-hook='touch "$1"/var/cache/apt/archives/lock' \ + --setup-hook='chmod 0640 "$1"/var/cache/apt/archives/lock' \ + {{ DIST }} - {{ MIRROR }} >/tmp/orig.tar # somehow, when trying to create a tarball from the 9p mount, tar throws the # following error: tar: ./doc-debian_6.4_all.deb: File shrank by 132942 bytes; padding with zeros # to reproduce, try: tar --directory /mnt/cache/debian/pool/main/d/doc-debian/ --create --file - . | tar --directory /tmp/ --extract --file - @@ -30,15 +30,15 @@ fi # another reason to copy the files into a new directory is, that we can use shell globs cp /mnt/cache/debian/pool/main/b/busybox/busybox_*"_{{ HOSTARCH }}.deb" /mnt/cache/debian/pool/main/a/apt/apt_*"_{{ HOSTARCH }}.deb" "$tmpdir" {{ CMD }} $include --mode={{ MODE }} --variant={{ VARIANT }} \ - --setup-hook='mkdir -p "$1"/var/cache/apt/archives/partial' \ - --setup-hook='sync-in "'"$tmpdir"'" /var/cache/apt/archives/partial' \ - {{ DIST }} - {{ MIRROR }} > /tmp/test1.tar + --setup-hook='mkdir -p "$1"/var/cache/apt/archives/partial' \ + --setup-hook='sync-in "'"$tmpdir"'" /var/cache/apt/archives/partial' \ + {{ DIST }} - {{ MIRROR }} >/tmp/test1.tar cmp /tmp/orig.tar /tmp/test1.tar {{ CMD }} $include --mode={{ MODE }} --variant={{ VARIANT }} \ - --customize-hook='touch "$1"/var/cache/apt/archives/partial' \ - --setup-hook='mkdir -p "$1"/var/cache/apt/archives/' \ - --setup-hook='sync-in "'"$tmpdir"'" /var/cache/apt/archives/' \ - --setup-hook='chmod 0755 "$1"/var/cache/apt/archives/' \ - --customize-hook='find "'"$tmpdir"'" -type f -exec md5sum "{}" \; | sed "s|"'"$tmpdir"'"|$1/var/cache/apt/archives|" | md5sum --check' \ - {{ DIST }} - {{ MIRROR }} > /tmp/test2.tar + --customize-hook='touch "$1"/var/cache/apt/archives/partial' \ + --setup-hook='mkdir -p "$1"/var/cache/apt/archives/' \ + --setup-hook='sync-in "'"$tmpdir"'" /var/cache/apt/archives/' \ + --setup-hook='chmod 0755 "$1"/var/cache/apt/archives/' \ + --customize-hook='find "'"$tmpdir"'" -type f -exec md5sum "{}" \; | sed "s|"'"$tmpdir"'"|$1/var/cache/apt/archives|" | md5sum --check' \ + {{ DIST }} - {{ MIRROR }} >/tmp/test2.tar cmp /tmp/orig.tar /tmp/test2.tar diff --git a/tests/copy-mirror b/tests/copy-mirror index 1903925..4397604 100644 --- a/tests/copy-mirror +++ b/tests/copy-mirror @@ -2,8 +2,8 @@ set -eu export LC_ALL=C.UTF-8 if [ ! -e /mmdebstrap-testenv ]; then - echo "this test requires the cache directory to be mounted on /mnt and should only be run inside a container" >&2 - exit 1 + echo "this test requires the cache directory to be mounted on /mnt and should only be run inside a container" >&2 + exit 1 fi {{ CMD }} --mode={{ MODE }} --variant=apt {{ DIST }} /tmp/debian-chroot.tar "deb copy:///mnt/cache/debian {{ DIST }} main" tar -tf /tmp/debian-chroot.tar | sort | diff -u tar1.txt - diff --git a/tests/create-directory b/tests/create-directory index 2d5461b..8e32d96 100644 --- a/tests/create-directory +++ b/tests/create-directory @@ -5,5 +5,5 @@ export LC_ALL=C.UTF-8 trap "rm -rf /tmp/debian-chroot" EXIT INT TERM {{ CMD }} --mode=root --variant=apt {{ DIST }} /tmp/debian-chroot {{ MIRROR }} -chroot /tmp/debian-chroot dpkg-query --showformat '${binary:Package}\n' --show > pkglist.txt -tar -C /tmp/debian-chroot --one-file-system -c . | tar -t | sort > tar1.txt +chroot /tmp/debian-chroot dpkg-query --showformat '${binary:Package}\n' --show >pkglist.txt +tar -C /tmp/debian-chroot --one-file-system -c . | tar -t | sort >tar1.txt diff --git a/tests/create-directory-dry-run b/tests/create-directory-dry-run index 03226e4..9f06f37 100644 --- a/tests/create-directory-dry-run +++ b/tests/create-directory-dry-run @@ -2,10 +2,10 @@ set -eu export LC_ALL=C.UTF-8 {{ CMD }} --mode={{ MODE }} --dry-run --variant=apt \ - --setup-hook="exit 1" \ - --essential-hook="exit 1" \ - --customize-hook="exit 1" \ - {{ DIST }} /tmp/debian-chroot {{ MIRROR }} + --setup-hook="exit 1" \ + --essential-hook="exit 1" \ + --customize-hook="exit 1" \ + {{ DIST }} /tmp/debian-chroot {{ MIRROR }} rm /tmp/debian-chroot/dev/console rm /tmp/debian-chroot/dev/fd rm /tmp/debian-chroot/dev/full diff --git a/tests/create-foreign-tarball b/tests/create-foreign-tarball index bf8f13a..880b584 100644 --- a/tests/create-foreign-tarball +++ b/tests/create-foreign-tarball @@ -4,74 +4,75 @@ export LC_ALL=C.UTF-8 prefix= if [ "$(id -u)" -eq 0 ] && [ "{{ MODE }}" != "root" ] && [ "{{ MODE }}" != "auto" ]; then - if ! id "${SUDO_USER:-user}" >/dev/null 2>&1; then - if [ ! -e /mmdebstrap-testenv ]; then - echo "this test modifies the system and should only be run inside a container" >&2 - exit 1 - fi - useradd --home-dir "/home/${SUDO_USER:-user}" --create-home "${SUDO_USER:-user}" - fi - prefix="runuser -u ${SUDO_USER:-user} --" + if ! id "${SUDO_USER:-user}" >/dev/null 2>&1; then + if [ ! -e /mmdebstrap-testenv ]; then + echo "this test modifies the system and should only be run inside a container" >&2 + exit 1 + fi + useradd --home-dir "/home/${SUDO_USER:-user}" --create-home "${SUDO_USER:-user}" + fi + prefix="runuser -u ${SUDO_USER:-user} --" fi case "$(dpkg --print-architecture)" in - arm64) - native_arch=arm64 - native_gnu=aarch64-linux-gnu - foreign_arch=amd64 - foreign_gnu=x86_64-linux-gnu - ;; - amd64) - native_arch=amd64 - native_gnu=x86_64-linux-gnu - foreign_arch=arm64 - foreign_gnu=aarch64-linux-gnu - ;; - *) - echo "unsupported native architecture" >&2 - exit 1 - ;; + arm64) + native_arch=arm64 + native_gnu=aarch64-linux-gnu + foreign_arch=amd64 + foreign_gnu=x86_64-linux-gnu + ;; + amd64) + native_arch=amd64 + native_gnu=x86_64-linux-gnu + foreign_arch=arm64 + foreign_gnu=aarch64-linux-gnu + ;; + *) + echo "unsupported native architecture" >&2 + exit 1 + ;; esac [ "{{ MODE }}" = "fakechroot" ] && prefix="$prefix fakechroot fakeroot" $prefix {{ CMD }} --mode={{ MODE }} --variant=apt --architectures="$foreign_arch" \ - {{ DIST }} /tmp/debian-chroot.tar {{ MIRROR }} + {{ DIST }} /tmp/debian-chroot.tar {{ MIRROR }} # we ignore differences between architectures by ignoring some files # and renaming others -{ tar -tf /tmp/debian-chroot.tar \ - | grep -v '^\./usr/bin/i386$' \ - | grep -v '^\./usr/bin/x86_64$' \ - | grep -v '^\./lib64$' \ - | grep -v '^\./usr/lib64/$' \ - | grep -v '^\./usr/lib64/ld-linux-x86-64\.so\.2$' \ - | grep -v '^\./usr/lib/ld-linux-aarch64\.so\.1$' \ - | grep -v "^\\./usr/lib/$foreign_gnu/ld-linux-aarch64\\.so\\.1$" \ - | grep -v "^\\./usr/lib/$foreign_gnu/ld-linux-x86-64\\.so\\.2$" \ - | grep -v "^\\./usr/lib/$foreign_gnu/perl/5\\.[0-9][.0-9]\\+/.*\\.ph$" \ - | grep -v "^\\./usr/lib/$foreign_gnu/libmvec\\.so\\.1$" \ - | grep -v "^\\./usr/share/doc/[^/]\\+/changelog\\(\\.Debian\\)\\?\\.$foreign_arch\\.gz$" \ - | grep -v '^\./usr/share/man/man8/i386\.8\.gz$' \ - | grep -v '^\./usr/share/man/man8/x86_64\.8\.gz$' \ - | sed "s/$foreign_gnu/$native_gnu/" \ - | sed "s/$foreign_arch/$native_arch/"; -} | sort > /tmp/tar2.txt -{ < tar1.txt \ - grep -v '^\./usr/bin/i386$' \ - | grep -v '^\./usr/bin/x86_64$' \ - | grep -v '^\./lib32$' \ - | grep -v '^\./lib64$' \ - | grep -v '^\./libx32$' \ - | grep -v '^\./usr/lib32/$' \ - | grep -v '^\./usr/libx32/$' \ - | grep -v '^\./usr/lib64/$' \ - | grep -v '^\./usr/lib64/ld-linux-x86-64\.so\.2$' \ - | grep -v '^\./usr/lib/ld-linux-aarch64\.so\.1$' \ - | grep -v "^\\./usr/lib/$native_gnu/ld-linux-x86-64\\.so\\.2$" \ - | grep -v "^\\./usr/lib/$native_gnu/ld-linux-aarch64\\.so\\.1$" \ - | grep -v "^\\./usr/lib/$native_gnu/libmvec\\.so\\.1$" \ - | grep -v "^\\./usr/lib/$native_gnu/perl/5\\.[0-9][.0-9]\\+/.*\\.ph$" \ - | grep -v "^\\./usr/share/doc/[^/]\\+/changelog\\(\\.Debian\\)\\?\\.$native_arch\\.gz$" \ - | grep -v '^\./usr/share/man/man8/i386\.8\.gz$' \ - | grep -v '^\./usr/share/man/man8/x86_64\.8\.gz$'; +{ + tar -tf /tmp/debian-chroot.tar \ + | grep -v '^\./usr/bin/i386$' \ + | grep -v '^\./usr/bin/x86_64$' \ + | grep -v '^\./lib64$' \ + | grep -v '^\./usr/lib64/$' \ + | grep -v '^\./usr/lib64/ld-linux-x86-64\.so\.2$' \ + | grep -v '^\./usr/lib/ld-linux-aarch64\.so\.1$' \ + | grep -v "^\\./usr/lib/$foreign_gnu/ld-linux-aarch64\\.so\\.1$" \ + | grep -v "^\\./usr/lib/$foreign_gnu/ld-linux-x86-64\\.so\\.2$" \ + | grep -v "^\\./usr/lib/$foreign_gnu/perl/5\\.[0-9][.0-9]\\+/.*\\.ph$" \ + | grep -v "^\\./usr/lib/$foreign_gnu/libmvec\\.so\\.1$" \ + | grep -v "^\\./usr/share/doc/[^/]\\+/changelog\\(\\.Debian\\)\\?\\.$foreign_arch\\.gz$" \ + | grep -v '^\./usr/share/man/man8/i386\.8\.gz$' \ + | grep -v '^\./usr/share/man/man8/x86_64\.8\.gz$' \ + | sed "s/$foreign_gnu/$native_gnu/" \ + | sed "s/$foreign_arch/$native_arch/" +} | sort >/tmp/tar2.txt +{ + grep &2 rm /tmp/debian-chroot.tar /tmp/tar2.txt diff --git a/tests/create-gzip-compressed-tarball b/tests/create-gzip-compressed-tarball index 1492df2..e5abe56 100644 --- a/tests/create-gzip-compressed-tarball +++ b/tests/create-gzip-compressed-tarball @@ -4,14 +4,14 @@ export LC_ALL=C.UTF-8 prefix= if [ "$(id -u)" -eq 0 ] && [ "{{ MODE }}" != "root" ] && [ "{{ MODE }}" != "auto" ]; then - if ! id "${SUDO_USER:-user}" >/dev/null 2>&1; then - if [ ! -e /mmdebstrap-testenv ]; then - echo "this test modifies the system and should only be run inside a container" >&2 - exit 1 - fi - useradd --home-dir "/home/${SUDO_USER:-user}" --create-home "${SUDO_USER:-user}" - fi - prefix="runuser -u ${SUDO_USER:-user} --" + if ! id "${SUDO_USER:-user}" >/dev/null 2>&1; then + if [ ! -e /mmdebstrap-testenv ]; then + echo "this test modifies the system and should only be run inside a container" >&2 + exit 1 + fi + useradd --home-dir "/home/${SUDO_USER:-user}" --create-home "${SUDO_USER:-user}" + fi + prefix="runuser -u ${SUDO_USER:-user} --" fi $prefix {{ CMD }} --mode={{ MODE }} --variant=apt {{ DIST }} /tmp/debian-chroot.tar.gz {{ MIRROR }} diff --git a/tests/create-tarball-dry-run b/tests/create-tarball-dry-run index f4c5fe2..158d7f4 100644 --- a/tests/create-tarball-dry-run +++ b/tests/create-tarball-dry-run @@ -8,20 +8,20 @@ export LC_ALL=C.UTF-8 prefix= include=, if [ "$(id -u)" -eq 0 ] && [ "{{ MODE }}" != root ] && [ "{{ MODE }}" != auto ]; then - if ! id "${SUDO_USER:-user}" >/dev/null 2>&1; then - if [ ! -e /mmdebstrap-testenv ]; then - echo "this test modifies the system and should only be run inside a container" >&2 - exit 1 - fi - useradd --home-dir "/home/${SUDO_USER:-user}" --create-home "${SUDO_USER:-user}" - fi - prefix="runuser -u ${SUDO_USER:-user} --" - if [ "{{ VARIANT }}" = extract ] || [ "{{ VARIANT }}" = custom ]; then - include="$(tr '\n' ',' < pkglist.txt)" - fi + if ! id "${SUDO_USER:-user}" >/dev/null 2>&1; then + if [ ! -e /mmdebstrap-testenv ]; then + echo "this test modifies the system and should only be run inside a container" >&2 + exit 1 + fi + useradd --home-dir "/home/${SUDO_USER:-user}" --create-home "${SUDO_USER:-user}" + fi + prefix="runuser -u ${SUDO_USER:-user} --" + if [ "{{ VARIANT }}" = extract ] || [ "{{ VARIANT }}" = custom ]; then + include="$(tr '\n' ',' &2 - exit 1 + echo "/tmp/debian-chroot.tar must not be created with --dry-run" >&2 + exit 1 fi diff --git a/tests/create-tarball-with-tmp-mounted-nodev b/tests/create-tarball-with-tmp-mounted-nodev index 61ff320..9247f0e 100644 --- a/tests/create-tarball-with-tmp-mounted-nodev +++ b/tests/create-tarball-with-tmp-mounted-nodev @@ -2,8 +2,8 @@ set -eu export LC_ALL=C.UTF-8 if [ ! -e /mmdebstrap-testenv ]; then - echo "this test modifies the system and should only be run inside a container" >&2 - exit 1 + echo "this test modifies the system and should only be run inside a container" >&2 + exit 1 fi mount -t tmpfs -o nodev,nosuid,size=400M tmpfs /tmp # use --customize-hook to exercise the mounting/unmounting code of block devices in root mode diff --git a/tests/custom-tmpdir b/tests/custom-tmpdir index bfd3651..a0dbb2c 100644 --- a/tests/custom-tmpdir +++ b/tests/custom-tmpdir @@ -6,27 +6,27 @@ export LC_ALL=C.UTF-8 [ {{ MODE }} = "unshare" ] if ! id "${SUDO_USER:-user}" >/dev/null 2>&1; then - if [ ! -e /mmdebstrap-testenv ]; then - echo "this test modifies the system and should only be run inside a container" >&2 - exit 1 - fi - useradd --home-dir "/home/${SUDO_USER:-user}" --create-home "${SUDO_USER:-user}" + if [ ! -e /mmdebstrap-testenv ]; then + echo "this test modifies the system and should only be run inside a container" >&2 + exit 1 + fi + useradd --home-dir "/home/${SUDO_USER:-user}" --create-home "${SUDO_USER:-user}" fi prefix="runuser -u ${SUDO_USER:-user} --" # https://www.etalabs.net/sh_tricks.html -quote () { printf %s\\n "$1" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/'/" ; } +quote() { printf %s\\n "$1" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/'/"; } homedir=$($prefix sh -c 'cd && pwd') # apt:test/integration/test-apt-key -TMPDIR_ADD="This is fü\$\$ing cràzy, \$(apt -v)\$!" +TMPDIR_ADD='This is fü$$ing cràzy, $(apt -v)$!' $prefix mkdir "$homedir/$TMPDIR_ADD" # make sure the unshared user can traverse into the TMPDIR chmod 711 "$homedir" # set permissions and sticky bit like the real /tmp chmod 1777 "$homedir/$TMPDIR_ADD" $prefix env TMPDIR="$homedir/$TMPDIR_ADD" {{ CMD }} --mode={{ MODE }} --variant=apt \ - --setup-hook='case "$1" in '"$(quote "$homedir/$TMPDIR_ADD/mmdebstrap.")"'??????????) exit 0;; *) echo "$1"; exit 1;; esac' \ - {{ DIST }} /tmp/debian-chroot.tar {{ MIRROR }} + --setup-hook='case "$1" in '"$(quote "$homedir/$TMPDIR_ADD/mmdebstrap.")"'??????????) exit 0;; *) echo "$1"; exit 1;; esac' \ + {{ DIST }} /tmp/debian-chroot.tar {{ MIRROR }} tar -tf /tmp/debian-chroot.tar | sort | diff -u tar1.txt - # use rmdir as a quick check that nothing is remaining in TMPDIR $prefix rmdir "$homedir/$TMPDIR_ADD" diff --git a/tests/customize-hook b/tests/customize-hook index 6437eac..1be7f32 100644 --- a/tests/customize-hook +++ b/tests/customize-hook @@ -2,7 +2,7 @@ set -eu export LC_ALL=C.UTF-8 trap "rm -rf /tmp/debian-chroot; rm -f /tmp/customize.sh" EXIT INT TERM -cat << 'SCRIPT' > /tmp/customize.sh +cat <<'SCRIPT' >/tmp/customize.sh #!/bin/sh chroot "$1" whoami > "$1/output2" chroot "$1" pwd >> "$1/output2" diff --git a/tests/cwd-directory-not-accessible-by-unshared-user b/tests/cwd-directory-not-accessible-by-unshared-user index 859cf6b..a1717ca 100644 --- a/tests/cwd-directory-not-accessible-by-unshared-user +++ b/tests/cwd-directory-not-accessible-by-unshared-user @@ -6,11 +6,11 @@ export LC_ALL=C.UTF-8 [ {{ MODE }} = "unshare" ] if ! id "${SUDO_USER:-user}" >/dev/null 2>&1; then - if [ ! -e /mmdebstrap-testenv ]; then - echo "this test modifies the system and should only be run inside a container" >&2 - exit 1 - fi - useradd --home-dir "/home/${SUDO_USER:-user}" --create-home "${SUDO_USER:-user}" + if [ ! -e /mmdebstrap-testenv ]; then + echo "this test modifies the system and should only be run inside a container" >&2 + exit 1 + fi + useradd --home-dir "/home/${SUDO_USER:-user}" --create-home "${SUDO_USER:-user}" fi prefix="runuser -u ${SUDO_USER:-user} --" @@ -19,11 +19,11 @@ chmod 700 /tmp/debian-chroot chown "${SUDO_USER:-user}:${SUDO_USER:-user}" /tmp/debian-chroot set -- env --chdir=/tmp/debian-chroot if [ "{{ CMD }}" = "./mmdebstrap" ]; then - set -- "$@" "$(realpath --canonicalize-existing ./mmdebstrap)" + set -- "$@" "$(realpath --canonicalize-existing ./mmdebstrap)" elif [ "{{ CMD }}" = "perl -MDevel::Cover=-silent,-nogcov ./mmdebstrap" ]; then - set -- "$@" perl -MDevel::Cover=-silent,-nogcov "$(realpath --canonicalize-existing ./mmdebstrap)" + set -- "$@" perl -MDevel::Cover=-silent,-nogcov "$(realpath --canonicalize-existing ./mmdebstrap)" else - set -- "$@" {{ CMD }} + set -- "$@" {{ CMD }} fi $prefix "$@" --mode={{ MODE }} --variant=apt {{ DIST }} /tmp/debian-chroot.tar {{ MIRROR }} tar -tf /tmp/debian-chroot.tar | sort | diff -u tar1.txt - diff --git a/tests/deb822-1-2 b/tests/deb822-1-2 index 1459117..ac38110 100644 --- a/tests/deb822-1-2 +++ b/tests/deb822-1-2 @@ -2,30 +2,30 @@ set -eu export LC_ALL=C.UTF-8 trap "rm -rf /tmp/debian-chroot; rm -f /tmp/sources.list /tmp/deb822.sources" EXIT INT TERM -cat << SOURCES > /tmp/deb822.sources +cat </tmp/deb822.sources Types: deb URIs: {{ MIRROR }}1 Suites: {{ DIST }} Components: main SOURCES -echo "deb {{ MIRROR }}2 {{ DIST }} main" > /tmp/sources.list +echo "deb {{ MIRROR }}2 {{ DIST }} main" >/tmp/sources.list echo "deb {{ MIRROR }}3 {{ DIST }} main" \ - | {{ CMD }} --mode={{ MODE }} --variant=apt {{ DIST }} \ - /tmp/debian-chroot \ - /tmp/deb822.sources \ - {{ MIRROR }}4 \ - - \ - "deb {{ MIRROR }}5 {{ DIST }} main" \ - {{ MIRROR }}6 \ - /tmp/sources.list + | {{ CMD }} --mode={{ MODE }} --variant=apt {{ DIST }} \ + /tmp/debian-chroot \ + /tmp/deb822.sources \ + {{ MIRROR }}4 \ + - \ + "deb {{ MIRROR }}5 {{ DIST }} main" \ + {{ MIRROR }}6 \ + /tmp/sources.list test ! -e /tmp/debian-chroot/etc/apt/sources.list -cat << SOURCES | cmp /tmp/debian-chroot/etc/apt/sources.list.d/0000deb822.sources - +cat < /tmp/deb822 +cat </tmp/deb822 Types: deb URIs: {{ MIRROR }}1 Suites: {{ DIST }} Components: main SOURCES -echo "deb {{ MIRROR }}2 {{ DIST }} main" > /tmp/sources -cat << SOURCES | {{ CMD }} --mode={{ MODE }} --variant=apt {{ DIST }} \ - /tmp/debian-chroot \ - /tmp/deb822 \ - - \ - /tmp/sources +echo "deb {{ MIRROR }}2 {{ DIST }} main" >/tmp/sources +cat < "./cache/debian-{{ DIST }}-{{ VARIANT }}.tar" +tar --sort=name --mtime=@$SOURCE_DATE_EPOCH --clamp-mtime --numeric-owner --one-file-system --xattrs -C "$tmpdir" -c . >"./cache/debian-{{ DIST }}-{{ VARIANT }}.tar" rm -r "$tmpdir" diff --git a/tests/debug b/tests/debug index bce3fd2..6d5109b 100644 --- a/tests/debug +++ b/tests/debug @@ -7,9 +7,9 @@ trap "rm -f /tmp/debian-chroot.tar" EXIT INT TERM # we use variant standard in verbose mode to see the maximum number of packages # that was chosen in case of USE_HOST_APT_CONFIG=yes -case {{ VARIANT }} in standard) : ;; *) exit 1;; esac +case {{ VARIANT }} in standard) : ;; *) exit 1 ;; esac {{ CMD }} --variant={{ VARIANT }} --debug {{ DIST }} /tmp/debian-chroot.tar {{ MIRROR }} cmp ./cache/mmdebstrap-{{ DIST }}-{{ VARIANT }}.tar /tmp/debian-chroot.tar \ - || diffoscope ./cache/mmdebstrap-{{ DIST }}-{{ VARIANT }}.tar /tmp/debian-chroot.tar + || diffoscope ./cache/mmdebstrap-{{ DIST }}-{{ VARIANT }}.tar /tmp/debian-chroot.tar diff --git a/tests/dev-ptmx b/tests/dev-ptmx index 5eb7bd0..ca1cde0 100644 --- a/tests/dev-ptmx +++ b/tests/dev-ptmx @@ -3,24 +3,24 @@ set -eu export LC_ALL=C.UTF-8 if [ {{ MODE }} != unshare ] && [ {{ MODE }} != root ]; then - echo "test requires root or unshare mode" >&2 - exit 1 + echo "test requires root or unshare mode" >&2 + exit 1 fi prefix= if [ "$(id -u)" -eq 0 ] && [ "{{ MODE }}" != "root" ] && [ "{{ MODE }}" != "auto" ]; then - if ! id "${SUDO_USER:-user}" >/dev/null 2>&1; then - if [ ! -e /mmdebstrap-testenv ]; then - echo "this test modifies the system and should only be run inside a container" >&2 - exit 1 - fi - useradd --home-dir "/home/${SUDO_USER:-user}" --create-home "${SUDO_USER:-user}" - fi - prefix="runuser -u ${SUDO_USER:-user} --" + if ! id "${SUDO_USER:-user}" >/dev/null 2>&1; then + if [ ! -e /mmdebstrap-testenv ]; then + echo "this test modifies the system and should only be run inside a container" >&2 + exit 1 + fi + useradd --home-dir "/home/${SUDO_USER:-user}" --create-home "${SUDO_USER:-user}" + fi + prefix="runuser -u ${SUDO_USER:-user} --" fi # this mimics what apt does in apt-pkg/deb/dpkgpm.cc/pkgDPkgPM::StartPtyMagic() -cat > /tmp/test.c << 'END' +cat >/tmp/test.c <<'END' #define _GNU_SOURCE #include @@ -141,9 +141,9 @@ grep 'Can not write log' /tmp/log && fail=1 grep 'posix_openpt' /tmp/log && fail=1 grep 'No such file or directory' /tmp/log && fail=1 if [ $fail -eq 1 ]; then - echo "apt failed to write log:" >&2 - cat /tmp/log >&2 - exit 1 + echo "apt failed to write log:" >&2 + cat /tmp/log >&2 + exit 1 fi rm /tmp/test.c /tmp/log diff --git a/tests/directory-ending-in-tar b/tests/directory-ending-in-tar index b44e35a..78bc55a 100644 --- a/tests/directory-ending-in-tar +++ b/tests/directory-ending-in-tar @@ -6,7 +6,7 @@ trap "rm -rf /tmp/debian-chroot.tar" EXIT INT TERM {{ CMD }} --mode={{ MODE }} --variant=apt --format=directory {{ DIST }} /tmp/debian-chroot.tar {{ MIRROR }} ftype=$(stat -c %F /tmp/debian-chroot.tar) if [ "$ftype" != directory ]; then - echo "expected directory but got: $ftype" >&2 - exit 1 + echo "expected directory but got: $ftype" >&2 + exit 1 fi tar -C /tmp/debian-chroot.tar --one-file-system -c . | tar -t | sort | diff -u tar1.txt - diff --git a/tests/dist-using-codename b/tests/dist-using-codename index 96d8929..0165e1f 100644 --- a/tests/dist-using-codename +++ b/tests/dist-using-codename @@ -8,6 +8,6 @@ trap "rm -f InRelease; rm -rf /tmp/debian-chroot.tar /tmp/expected" EXIT INT TER /usr/lib/apt/apt-helper download-file "{{ MIRROR }}/dists/{{ DIST }}/InRelease" InRelease codename=$(awk '/^Codename: / { print $2; }' InRelease) {{ CMD }} --mode={{ MODE }} --variant=apt "$codename" /tmp/debian-chroot.tar {{ MIRROR }} -echo "deb {{ MIRROR }} $codename main" > /tmp/expected +echo "deb {{ MIRROR }} $codename main" >/tmp/expected tar --to-stdout --extract --file /tmp/debian-chroot.tar ./etc/apt/sources.list \ - | diff -u /tmp/expected - + | diff -u /tmp/expected - diff --git a/tests/dpkgopt b/tests/dpkgopt index 1a41da4..60b56ca 100644 --- a/tests/dpkgopt +++ b/tests/dpkgopt @@ -2,9 +2,13 @@ set -eu export LC_ALL=C.UTF-8 trap "rm -rf /tmp/debian-chroot; rm -f /tmp/config" EXIT INT TERM -echo no-pager > /tmp/config +echo no-pager >/tmp/config {{ CMD }} --mode=root --variant=apt --dpkgopt="path-exclude=/usr/share/doc/*" --dpkgopt=/tmp/config --dpkgopt="path-include=/usr/share/doc/dpkg/copyright" {{ DIST }} /tmp/debian-chroot {{ MIRROR }} printf 'path-exclude=/usr/share/doc/*\nno-pager\npath-include=/usr/share/doc/dpkg/copyright\n' | cmp /tmp/debian-chroot/etc/dpkg/dpkg.cfg.d/99mmdebstrap - rm /tmp/debian-chroot/etc/dpkg/dpkg.cfg.d/99mmdebstrap -tar -C /tmp/debian-chroot --one-file-system -c . | tar -t | sort > tar2.txt -{ grep -v '^./usr/share/doc/.' tar1.txt; echo ./usr/share/doc/dpkg/; echo ./usr/share/doc/dpkg/copyright; } | sort | diff -u - tar2.txt +tar -C /tmp/debian-chroot --one-file-system -c . | tar -t | sort >tar2.txt +{ + grep -v '^./usr/share/doc/.' tar1.txt + echo ./usr/share/doc/dpkg/ + echo ./usr/share/doc/dpkg/copyright +} | sort | diff -u - tar2.txt diff --git a/tests/eatmydata-via-hook-dir b/tests/eatmydata-via-hook-dir index b554508..552dcdd 100644 --- a/tests/eatmydata-via-hook-dir +++ b/tests/eatmydata-via-hook-dir @@ -1,7 +1,7 @@ #!/bin/sh set -eu export LC_ALL=C.UTF-8 -cat << SCRIPT > /tmp/checkeatmydata.sh +cat <