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

Reply via email to