[Pkg-dkms-maint] RFS: dkms

Debian DKMS Maintainers pkg-dkms-maint at lists.alioth.debian.org
Wed Dec 24 11:00:11 UTC 2008


This is what our sponsor found out wrong about DKMS.

We should fix everything :)

Inizio messsaggio inviato:

Data: Tue, 23 Dec 2008 23:20:53 +0000
Da: Ben Hutchings <ben at decadent.org.uk>
A: David Paleino <d.paleino at gmail.com>
Oggetto: Re: RFS: dkms


Here's the overdue review of the dkms script itself.  I'll quote and
comment on the key functions for Debian integration:

> function remake_initrd()
> {
>     # $1 = kernel version
>     # $2 = arch
> 
>     local exitval="0"
>     local mkinitrd='mkinitrd'
> 
>     # Support initramfs distributions (Ubuntu).
>     if [ -x "/usr/sbin/mkinitramfs" ]; then
>         mkinitrd='mkinitramfs'
>     fi

Under Debian, this should read /etc/kernel-img.conf and search through
the list assigned to ramdisk, or "mkinitrd mkinitrd.yaird mkinitramfs"
by default.

>     $mkinitrd --version >/dev/null 2>&1
>     if [ "$?" -eq 0 ]; then
>       	echo $""
> 	initrd_dir="/boot"
> 	[ "$2" == "ia64" ] && [ -d "/boot/efi/efi/redhat" ] &&
> initrd_dir="/boot/efi/efi/redhat" echo $"Saving old initrd as
> $initrd_dir/initrd-$1_old.img" cp -f "$initrd_dir/initrd-$1.img"
> "$initrd_dir/initrd-$1_old.img" echo $"Making new initrd as
> $initrd_dir/initrd-$1.img" echo $"(If next boot fails, revert to the _old
> initrd image)" invoke_command "$mkinitrd -f $initrd_dir/initrd-$1.img $1"
> "$mkinitrd" background exitval="$?"
>     elif [ -e /etc/SuSE-release ] || [ -d /etc/SuSEconfig ]; then
> 	echo $""
> 	initrd_dir="/boot"
> 	echo $"Saving old initrd as $initrd_dir/initrd-$1_old"
> 	cp -f "$initrd_dir/initrd-$1" "$initrd_dir/initrd-$1_old"
> 	echo $"Making new initrd as $initrd_dir/initrd-$1"
> 	echo $"(If next boot fails, revert to the _old initrd image)"
> 	invoke_command "$mkinitrd -k vmlinuz-$1 -i initrd-$1" "$mkinitrd"
> background exitval="$?"
>     elif [ -e /etc/debian_version ]; then
>       	echo $""
> 	initrd_dir="/boot"
> 	echo $"Saving old initrd as $initrd_dir/initrd.img_old-$1"
> 	cp -f "$initrd_dir/initrd.img-$1" "$initrd_dir/initrd.img_old-$1"
> 	echo $"Making new initrd as $initrd_dir/initrd.img-$1"
> 	echo $"(If next boot fails, revert to the _old initrd image)"
> 	invoke_command "$mkinitrd -o $initrd_dir/initrd.img-$1 $1"
> "$mkinitrd" background exitval="$?"
>     else
> 	echo $""
> 	echo $"Calling $mkinitrd (bad exit status 9 may occur)"
> 	invoke_command "$mkinitrd" "$mkinitrd" background
> 	exitval="$?"
>     fi
> 
>     # Rerun lilo if necessary
>     if ! [ -e /boot/grub/grub.conf ] && [ -e /etc/lilo.conf ] && !
> [ -e /boot/grub/menu.lst ]; then invoke_command "/sbin/lilo" "Updating lilo"
>     fi

Just because there's a GRUB configuration present doesn't mean LILO
isn't installed.  This should check /etc/kernel-img.conf to find out
what to do.

>     return $exitval
> }
> 
> function distro_version()
> {
> # What distribution are we running?
>     local WHATPROVIDES_REDHAT_RELEASE
>     local WHATPROVIDES_SLES_RELEASE
>     local WHATPROVIDES_SUSE_RELEASE
>     local REDHAT_RELEASE
>     local CENTOS_RELEASE
>     local FEDORA_RELEASE
>     local LSB_RELEASE
>     local VER
>     local dist=unknown
> 
>     if which rpm > /dev/null 2>&1 ; then
> 	WHATPROVIDES_REDHAT_RELEASE=$(rpm -q --whatprovides redhat-release)
> 	if [ $? -eq 0 ]; then
> 	    if $(echo "${WHATPROVIDES_REDHAT_RELEASE}" | grep redhat-release
> > /dev/null 2>&1) ; then REDHAT_RELEASE=1
> 	    elif (echo "${WHATPROVIDES_REDHAT_RELEASE}" | grep centos-release
> > /dev/null 2>&1) ; then CENTOS_RELEASE=1
> 	    elif $(echo "${WHATPROVIDES_REDHAT_RELEASE}" | grep
> fedora-release > /dev/null 2>&1) ; then FEDORA_RELEASE=1
> 	    fi
> 	fi
> 
> 	WHATPROVIDES_SLES_RELEASE=$(rpm -q --whatprovides sles-release)
> 	if [ $? -eq 0 ]; then
> 	    SLES_RELEASE=1
> 	fi
> 
> 	WHATPROVIDES_SUSE_RELEASE=$(rpm -q --whatprovides suse-release)
> 	if [ $? -eq 0 ]; then
> 	    SUSE_RELEASE=1
> 	fi
>     fi
>     if [ -r /etc/lsb-release ]; then
> 	. /etc/lsb-release
> 	LSB_RELEASE=1
>     fi

This is wrong; /etc/lsb-release should only be interpreted by
lsb_release and may not be present (it isn't in Debian).  dkms should
run lsb_release -i -r to find the distributor name and release.

>     if [ -n "${FEDORA_RELEASE}" ]; then
> 	VER=$(rpm -q --qf "%{version}\n" ${WHATPROVIDES_REDHAT_RELEASE})
> 	dist=fc${VER}
>     elif [ -n "${REDHAT_RELEASE}" ]; then
> 	VER=$(rpm -q --qf "%{version}\n" ${WHATPROVIDES_REDHAT_RELEASE})
>         # format is 3AS, 4AS, 5Desktop...
> 	VER=$(echo "${VER}" | sed -e 's/^\([[:digit:]]*\).*/\1/g')
> 	dist=el${VER}
>     elif [ -n "${CENTOS_RELEASE}" ]; then
> 	VER=$(rpm -q --qf "%{version}\n" ${WHATPROVIDES_REDHAT_RELEASE})
>         # format is 3, 4, ...
> 	dist=el${VER}
>     elif [ -n "${SLES_RELEASE}" ]; then
> 	VER=$(rpm -q --qf "%{version}\n" ${WHATPROVIDES_SLES_RELEASE})
> 	dist=sles${VER}
>     elif [ -n "${SUSE_RELEASE}" ]; then
> 	VER=$(rpm -q --qf "%{version}\n" ${WHATPROVIDES_SUSE_RELEASE})
> 	dist=suse${VER}
>     elif [ -n "${LSB_RELEASE}" ]; then
> 	if [ -n "${DISTRIB_ID}" -a -n "${DISTRIB_RELEASE}" ]; then
> 	    dist="${DISTRIB_ID}${DISTRIB_RELEASE}"
> 	fi
>     fi
> 
>     echo "$dist"
> }
> 
> function override_dest_module_location()
> {
>     local orig_location="$1"
>     [ -n "${addon_modules_dir}" ] && echo "/${addon_modules_dir}" && return
> 
>     case "$running_distribution" in
> 	fc[12345]) ;;
>         el[1234]) ;;
> 	sles[123456789]) ;;
> 	suse[123456789]) ;;
> 	suse10\.[01]) ;;
> 	fc*) echo "/extra" && return ;;
> 	el*) echo "/extra" && return ;;
> 	sles*) echo "/updates" && return ;;
> 	suse*) echo "/updates" && return ;;
> 	Ubuntu*) echo "/updates/dkms" && return ;;

This should handle Debian* like Ubuntu*.  That depends on fixing
distro_version() first.

> 	*) ;;
>     esac
>     echo "$orig_location"
> }


> function make_debian()
> {
>     create_type="$1"
> 
>     make_common_test "mk${create_type}"
> 
>     debian_package=$(echo $module | sed s/_/-/)

The s/// needs a g modifier to replace all underscores.

>     SYNAPTIC=""
>     #Synaptic availablity
>     if [ -x /usr/sbin/synaptic ]; then
>         SYNAPTIC="TRUE"
>     fi
> 
>     #test who we are
>     ROOT=""
>     ADMINABLE=""
>     if [ "$USER" != "root" ]; then
>         if [ -x /usr/bin/gksudo ] && [ ! -z "$DISPLAY" ]; then
>             ROOT="/usr/bin/gksudo --description 'DKMS Debian package builder'
> " elif [ -x /usr/bin/kdesu ] && [ ! -z "$DISPLAY" ]; then
>             ROOT="/usr/bin/kdesu"
>         elif [ -x /usr/bin/sudo ]; then
>             ROOT="/usr/bin/sudo"
>         fi

This should look for su-to-root (from the menu package) first.

>         if groups | sed 's/lpadmin//' | grep admin 2>&1 1>/dev/null; then
>             ADMINABLE="TRUE"
>         fi

This is absolutely not a correct way to grep for exactly the word
"admin" (what do they think the -w option is for?!), but in any case
this is not a standard group in Debian and has no special status in
being able to run e.g. sudo.  The test should be only that $ROOT is
non-null. 

>     else
>         ADMINABLE="TRUE"
>     fi
> 
>     # Read the conf file
>     read_conf "${kernelver_array[0]}" "${arch_array[0]}"
>     if [ "$?" -ne 0 ]; then
>         echo $"" >&2
>         echo $"Error! Bad conf file." >&2
>         echo $"Your dkms.conf is not valid." >&2
>         exit 4
>     fi
> 
>     #test if we are missing dependencies that are needed during package build
>     INSTALL_PACKAGES="`make_debian_test_depends`"
>     if [ ! -z "$INSTALL_PACKAGES" ]; then
>         if [ -z "ADMINABLE" ]; then

This is testing the string ADMINABLE, not the variable value
$ADMINABLE. 

>             echo $"" >&2
>             echo $"Error! Missing $INSTALL_PACKAGES" >&2
>             echo $"and unable to install.  Please ask an admin to install for
> you." >&2 exit 4
>         fi
>         if [ ! -z "$SYNAPTIC" ] && [ ! -z "$DISPLAY" ]; then
>             local TEMPFILE=`/bin/tempfile`
>             echo $INSTALL_PACKAGES | sed 's/|/\ install\
> /g' > $TEMPFILE
>             $ROOT "sh -c '/usr/sbin/synaptic --set-selections
> --non-interactive --hide-main-window < $TEMPFILE'" trap 'rm -f $TEMPFILE'
> EXIT HUP TERM else
>             $ROOT apt-get -y install $INSTALL_PACKAGES
>         fi
> 
>         INSTALL_PACKAGES="`make_debian_test_depends`"
>         #Retest packages
>         if [ ! -z "$INSTALL_PACKAGES" ]; then
>             echo $"" >&2
>             echo $"Error! Missing $INSTALL_PACKAGES" >&2
>             echo $"and unable to install.  Please ask an admin to install for
> you." >&2 exit 4
>         fi
>     fi

All of the above installation crap should be dead code in the package,
anyway.  But you do need to add dpkg-dev to the package dependencies. 

>     #skeleton to load templates from
>     local
> system_mk="$dkms_tree/$module/$module_version/source/$module-dkms-mk${create_type}"
> local local_mk="/etc/dkms/template-dkms-mk${create_type}" if [ -e
> "${system_mk}" ]; then echo $"Using ${system_mk}"
>         DEBDIR=${system_mk}
>     elif [ -e "${local_mk}" ]; then
>         echo $"Using ${local_mk}"
>         DEBDIR=${local_mk}
>     else
>         echo $"" >&2
>         echo $"Cannot find ${local_mk} which is needed by" >&2
>         echo $"DKMS in order to use mk${create_type}." >&2
>         exit 5
>     fi
> 
>     #test for binary or source modules
>     local mktarball_line
>     if [ -n "$source_only" ]; then
>         mktarball_line="--source-only"
>     else
>         local i=0
>         echo $""
>         while [ $i -lt ${#kernelver_array[@]} ]; do
>             if ! [ -d
> "$dkms_tree/$module/$module_version/${kernelver_array[$i]}/${arch_array[$i]}" ];
> then echo $"" >&2 echo $"You do not seem to have $module $module_version
> built for" >&2 echo $"${kernelver_array[$i]} (${arch_array[$i]}).  All
> modules must be in" >&2 echo $"the built state before you can use mkdeb." >&2
>                 exit 5
>             fi
>             echo $"Marking ${kernelver_array[$i]} (${arch_array[$i]}) for
> deb..." mktarball_line="-k ${kernelver_array[$i]} -a ${arch_array[$i]}
> $mktarball_line" i=$(($i + 1))
>         done
>     fi
> 
>     #prepare build directory and copy template
>     local temp_dir=`mktemp -d $tmp_location/dkms.XXXXXX`
>     trap 'rm -rf $temp_dir' EXIT HUP TERM
>     local temp_dir_debian="$temp_dir/$debian_package-dkms-$module_version"
>     invoke_command "cp -ar '$DEBDIR/' '$temp_dir_debian'" "copying template"
>     pushd "$temp_dir_debian" > /dev/null 2>&1
>     for file in debian/*; do
>         preproc_file "$file"
>         chmod 755 "$file"
>     done
>     popd > /dev/null 2>&1
> 
>     #create tar.gz that lives in DKMS deb
>     archive_location="$module-$module_version.dkms.tar.gz"
>     invoke_command "make_tarball -m $module -v $version $mktarball_line"
> "gathering sources" if [ -f
> $dkms_tree/$module/$module_version/tarball/$archive_location ]; then
> invoke_command "cp
> '$dkms_tree/$module/$module_version/tarball/$archive_location'
> '$temp_dir_debian'" "Copying DKMS tarball into DKMS tree" else echo $"" >&2
> echo $"Error! Unable to find created tarball." >&2 exit 12
>     fi
> 
>     #calculate destination directory
>     deb_basedir=$dkms_tree/$module/$module_version/${create_type}
>     mkdir -p ${deb_basedir} >/dev/null 2>&1
> 
>     #create deb
>     pushd "$temp_dir_debian" > /dev/null 2>&1
>     case "$create_type" in
>         dsc)
>             invoke_command "fakeroot dpkg-buildpackage -S -us -uc
> 1>/dev/null" "Building source package"

Drop the fakeroot; it's not needed.

>             invoke_command "mv
> '$temp_dir/${debian_package}-dkms_${module_version}.dsc'
> '$temp_dir/${debian_package}-dkms_${module_version}.tar.gz' '$deb_basedir'"
> "Moving built files to $deb_basedir" ;; deb) invoke_command "fakeroot
> dpkg-buildpackage -b -us -uc 1>/dev/null" "Building binary package"

Replace the fakeroot with the -rfakeroot option and dpkg-buildpackage
will use it only as necessary.  (Current dpkg-buildpackage doesn't even
need the option but upstream will presumably want to maintain
backward-compatibility.) 

>             invoke_command "mv
> '$temp_dir/${debian_package}-dkms_${module_version}_all.deb' '$deb_basedir'"
> "Moving built files to $deb_basedir" ;; esac
> 
>     #cleanup
>     invoke_command "rm $temp_dir -fr" "Cleaning up temporary files"
> 
>     #done
>     if [ "$?" -eq 0 ]; then
>         echo $""
>         echo $"DKMS: mk${create_type} Completed."

Unfortunately this just tests that the rm -rf was successful.  The
preceding build steps appear to be unchecked. 

>     else
>         echo $"" >&2
>         echo $"Error! There was a problem creating your ${create_type}." >&2
>         exit 7
>     fi
> }

Ben.

-- 
Ben Hutchings
Unix is many things to many people,
but it's never been everything to anybody.




More information about the Pkg-dkms-maint mailing list