Package: dkms Version: 2.8.1-5 Severity: normal Hi,
attached you can find 2 patches that aim on improving dkms-autopkgtest. It does not solve the issue of missing linux-headers-* - that should be addressed via autodep8. IMO tests using dkms-autopkgtest should primarily test whether the modules can be built against (all variants) of the current kernel to quickly notice regressions (aka build failures) caused by newer kernel headers. Parsing the autoinstall result from apt-get output and logs does not really work if the failure occurs while autopkgtest installs test dependencies because dkms-autopkgtest won't be run in that case. Neither does it work for multiple linux-headers-* packages being installed. Therefore the first patch adds the ability to disable autoinstall by creating the flag file /etc/dkms/no-autoinstall. Then the required packages can be installed without risking failures and dkms-autopkgtest can run the build and install steps separately, providing more verbose errors on failure. dkms-autopkgtest will loop over all available kernel headers (via existence of /lib/modules/*/build) and try to build and install the module for them, that should work even in a plain chroot. It will continue testing more headers even if one failed to collect as much information as possible. This should be used from autodep8 generated test instances like Test-Command: /usr/lib/dkms/dkms-autopkgtest Restrictions: needs-root, allow-stderr, superficial Depends: dkms, linux-headers-4kc-malta [mipsel], linux-headers-5kc-malta [mips64el mipsel], linux-headers-686 [i386], linux-headers-686-pae [i386], linux-headers-amd64 [amd64], linux-headers-arm64 [arm64], linux-headers-armmp [armhf], linux-headers-armmp-lpae [armhf], linux-headers-cloud-amd64 [amd64], linux-headers-cloud-arm64 [arm64], linux-headers-loongson-3 [mips64el mipsel], linux-headers-marvell [armel], linux-headers-octeon [mips64el mipsel], linux-headers-powerpc64le [ppc64el], linux-headers-rpi [armel], linux-headers-rt-686-pae [i386], linux-headers-rt-amd64 [amd64], linux-headers-rt-arm64 [arm64], linux-headers-rt-armmp [armhf], linux-headers-s390x [s390x], Features: test-name=dkms-autopkgtest Note there is no longer a Depends: @ to prevent the *-dkms package being installed together with linux-headers-* before dkms-autopkgtest gets the change to create the no-autoinstall flag file. (I'll file a separate bug about this against autodep8.) This seems to work well for Debian (tested on bbswitch-dkms), I don't know about the impact on Ubuntu. Andreas
>From cb233cf90bee2c8bc6bbeb3333808e0897d56b01 Mon Sep 17 00:00:00 2001 From: Andreas Beckmann <a...@debian.org> Date: Wed, 6 May 2020 15:28:10 +0200 Subject: [PATCH 1/3] use /etc/dkms/no-autoinstall as flag file to disable autoinstall --- debian/patches/no-autoinstall-flag-file.patch | 39 +++++++++++++++++++ debian/patches/series | 1 + 2 files changed, 40 insertions(+) create mode 100644 debian/patches/no-autoinstall-flag-file.patch diff --git a/debian/patches/no-autoinstall-flag-file.patch b/debian/patches/no-autoinstall-flag-file.patch new file mode 100644 index 0000000..7592764 --- /dev/null +++ b/debian/patches/no-autoinstall-flag-file.patch @@ -0,0 +1,39 @@ +Author: Andreas Beckmann <a...@debian.org> +Description: use /etc/dkms/no-autoinstall as flag file to disable autoinstall + intended use: autopkgtests should not fail while installing *-dkms + or linux-headers-* without detailed error reporting + instead they can run the invidiual steps with verbose error reporting + +--- a/dkms_autoinstaller ++++ b/dkms_autoinstaller +@@ -45,9 +45,13 @@ case "$1" in + else + kernel=`uname -r` + fi +- log_daemon_msg "$prog: running auto installation service for kernel $kernel" +- dkms autoinstall --kernelver $kernel +- log_end_msg $? ++ if [ -f /etc/dkms/no-autoinstall ]; then ++ log_daemon_msg "$prog: autoinstall for dkms modules has been disabled" ++ else ++ log_daemon_msg "$prog: running auto installation service for kernel $kernel" ++ dkms autoinstall --kernelver $kernel ++ log_end_msg $? ++ fi + ;; + stop|restart|force-reload|status|reload) + # There is no stop action, this and the 04 priority during stop is +--- a/dkms_common.postinst ++++ b/dkms_common.postinst +@@ -149,6 +149,11 @@ if [ -z "$NAME" ] || [ -z "$VERSION" ]; + exit 1 + fi + ++if [ -f /etc/dkms/no-autoinstall ]; then ++ echo "autoinstall for dkms modules has been disabled." ++ exit 0 ++fi ++ + # read framework configuration options + if [ -r /etc/dkms/framework.conf ]; then + . /etc/dkms/framework.conf diff --git a/debian/patches/series b/debian/patches/series index 4091394..eb51d12 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -1,2 +1,3 @@ verboselog.patch do-not-load-modules.patch +no-autoinstall-flag-file.patch -- 2.20.1
>From 7b336f51bcdc6d1e6c1c334b2b037e09443e7314 Mon Sep 17 00:00:00 2001 From: Andreas Beckmann <a...@debian.org> Date: Wed, 6 May 2020 16:50:46 +0200 Subject: [PATCH 2/3] improve dkms-autopkgtest * disable autoinstall mode before installing *-dkms packages * do not try to parse the autoinstall result from apt-get output and logs * run the build and install steps manually for better error reporting * test building the module for all installed linux headers --- debian/scripts/dkms-autopkgtest | 107 +++++++++++++++++++------------- 1 file changed, 65 insertions(+), 42 deletions(-) diff --git a/debian/scripts/dkms-autopkgtest b/debian/scripts/dkms-autopkgtest index eb4a00b..672b82c 100755 --- a/debian/scripts/dkms-autopkgtest +++ b/debian/scripts/dkms-autopkgtest @@ -4,70 +4,88 @@ # Copyright: (C) 2014 Canonical Ltd. set -eu +result=0 + run_pkg() { pkg="$1" - tmpfile=$(mktemp) - echo "I: removing binary package $pkg, to get clean state" + echo "I: Removing binary package $pkg, to get clean state" export DEBIAN_FRONTEND=noninteractive apt-get purge -yq $pkg </dev/null 2>&1 >/dev/null || true echo "I: Installing binary package $pkg" export DEBIAN_FRONTEND=noninteractive RC=0 - apt-get install -yq $pkg </dev/null 2>&1 >"$tmpfile" || RC=$? - cat "$tmpfile" + apt-get install -yq $pkg </dev/null 2>&1 || RC=$? + if [ "$RC" -ne 0 ]; then + echo "E: Package $pkg failed to install" >&2 + exit 1 + fi + + # Try and remove dkms to spot packages which miss a dkms dependency + dpkg --remove dkms || true if ! dkms_conf=$(dpkg -L $pkg | grep 'dkms.conf$'); then echo "I: Package $pkg has no dkms.conf, skipping" return fi - # Do not continue if dkms build was skipped due to BUILD_EXCLUSIVE - # directive - excluded=0 - grep -q "BUILD_EXCLUSIVE" "$tmpfile" && excluded=1 - rm "$tmpfile" - if [ "$excluded" -eq 1 ]; then - echo "I: Package $pkg excluded by BUILD_EXCLUSIVE directive, skipping" - return - fi - - # collect build logs as artifacts - if [ -d /var/lib/dkms ]; then - (cd /var/lib/dkms; find -name "make.log" -print0 | xargs -0 tar c) > "$ADT_ARTIFACTS/$pkg-make-logs.tar" - fi - - if [ "$RC" -ne 0 ]; then - echo "E: Package $pkg failed to install" >&2 - exit 1 - fi - echo "I: Testing binary package $pkg" dkms_pkg=$(bash -c ". $dkms_conf; echo \$PACKAGE_NAME" 2>/dev/null) dkms_ver=$(bash -c ". $dkms_conf; echo \$PACKAGE_VERSION" 2>/dev/null) - echo "I: Testing if $dkms_pkg modules are correctly installed" - dkmsstatus="$(dkms status $dkms_pkg)" - if [ -z "$dkmsstatus" ]; then - echo "E: dkms status output is empty!" >&2 - exit 1 - fi - echo "$dkmsstatus" + for k in /lib/modules/*/build + do + test -d "$k" || continue + kver="${k%/build}" + kver="${kver#/lib/modules/}" + + echo "I: Trying to build $dkms_pkg/$dkms_ver for $kver" + res=0 + dkms build -m "$dkms_pkg" -v "$dkms_ver" -k "$kver" || res=$? + + if [ "$res" = 9 ]; then + echo "I: $dkms_pkg/$dkms_ver is not supported on $kver (BUILD_EXCLUSIVE directive), skipping" + continue + fi + + if [ "$res" != 0 ]; then + echo "E: $dkms_pkg/$dkms_ver failed to build for $kver" >&2 + makelog="/var/lib/dkms/$dkms_pkg/$dkms_ver/build/make.log" + echo "========== $makelog ==========" >&2 + cat "$makelog" >&2 || true + echo "====================" >&2 + result=1 + continue + fi + + if ! dkms install -m "$dkms_pkg" -v "$dkms_ver" -k "$kver" ; then + echo "E: $dkms_pkg/$dkms_ver failed to install for $kver" >&2 + result=1 + continue + fi - if grep -q "Good news! Module version $dkms_ver" /var/log/apt/term.log; then - tail -n 50 /var/log/apt/term.log - if ! echo "$dkmsstatus" | grep -q "installed"; then + echo "I: Testing if $dkms_pkg modules are correctly installed" + dkmsstatus="$(dkms status $dkms_pkg -k $kver)" + echo "$dkmsstatus" + if [ -z "$dkmsstatus" ]; then + echo "E: dkms status output is empty!" >&2 + result=1 + continue + fi + + if ! echo "$dkmsstatus" | grep -q "installed$"; then echo "E: not installed" >&2 - exit 1 + result=1 + continue fi - exit 0 - fi - if ! echo "$dkmsstatus" | grep -q "installed$"; then - echo "E: not installed" >&2 - exit 1 + done + + # collect build logs as artifacts + if [ -d /var/lib/dkms ]; then + (cd /var/lib/dkms; find -name "make.log" -print0 | xargs -r -0 tar cv) > "$AUTOPKGTEST_ARTIFACTS/$pkg-make-logs.tar" fi # skip modprobing for now; this fails too often (needs particular @@ -83,8 +101,11 @@ run_pkg() { # done } -# Try and remove dkms to spot packages which miss a dkms dependency -dpkg --remove dkms || true +# Do not (fail to) build the modules upon linux-header-* and *-dkms package +# installation, which can cause apt-get to fail. We will do this later with +# improved error reporting. +# (This only works if the *-dkms package is not yet installed.) +touch /etc/dkms/no-autoinstall for pkg in $(awk '/^Package:/ { print $2 }' debian/control | grep "\-dkms$"); do # package might be arch: restriction or udeb etc. @@ -94,3 +115,5 @@ for pkg in $(awk '/^Package:/ { print $2 }' debian/control | grep "\-dkms$"); do fi run_pkg $pkg done + +exit $result -- 2.20.1