rpms/akmods/devel akmods, NONE, 1.1 akmods.spec, NONE, 1.1 akmodsbuild, NONE, 1.1 akmodsbuild.1, NONE, 1.1 akmodsinit, NONE, 1.1 akmodsposttrans, NONE, 1.1

Thorsten Leemhuis thl at rpmfusion.org
Thu Oct 2 19:28:11 CEST 2008


Author: thl

Update of /cvs/free/rpms/akmods/devel
In directory se02.es.rpmfusion.net:/tmp/cvs-serv18556

Added Files:
	akmods akmods.spec akmodsbuild akmodsbuild.1 akmodsinit 
	akmodsposttrans 
Log Message:
inital import to rpmfusion


--- NEW FILE akmods ---
#!/bin/bash -
############################################################################
#
# akmods - Rebuilds and install akmod RPMs
# Copyright (c) 2007, 2008 Thorsten Leemhuis <fedora at leemhuis.info>
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
############################################################################
#
# ToDo:
# - use yum on install required kernel-devel pacakges?
# - subprocess on dameon stop?
# - better way to detect if a earlier build failed or succeed
# - manpage
# - make use of the new posttrans hook in kenrel package?
# - locking?
# - special kernel "all" (all that are installed with a matching -devel package; could be called from posttrans in akmods packages)

# global vars
myprog="akmods"
myver="0.3.3"
kmodlogfile=
continue_line=""
tmpdir=
kernels=
verboselevel=2

akmods_echo()
{
	# where to output
	local this_fd=${1}
	shift

	# verboselevel
	local this_verbose=${1}
	shift

	# output to console
	if [[ ! ${daemon} ]] && (( ${verboselevel} >= ${this_verbose} )) ; then
		if [[ "${1}" == "--success" ]] ; then
			echo_success
			continue_line=""
			echo
			return 0	
		elif [[ "${1}" == "--failure" ]]; then
			echo_failure
			echo
			continue_line=""
			return 0
		elif [[ "${1}" == "--warning" ]]; then
			echo_warning
			echo
			continue_line=""
			return 0
		elif [[ "${1}" == "-n" ]]; then
			continue_line="true"
		fi
		echo "$@" >&${this_fd}
	fi

	# no need to print the status flags in the logs
	if [[ "${1}" == "--success" ]] || [[ "${1}" == "--failure" ]] || [[ "${1}" == "--warning" ]]; then
		return 0
	fi

	# no need to continues in the log
	if [[ "${1}" == "-n" ]]; then
		shift
	fi

	# global logfile
	echo "$(date +%d\ %b\ %H:%M:%S) akmods: $@" >> "/var/cache/akmods/akmods.log"

	# the kmods logfile as well, if we work on a kmod
	if [[ "${kmodlogfile}" ]]; then
		echo "$(date +%d\ %b\ %H:%M:%S) akmods: $@" >> "${kmodlogfile}"
	fi
}

finally()
{
	# remove tmpfiles
	remove_tmpdir

	# remove pidfile
	[[ "${daemon}" ]] && rm -f /var/run/${myprog}.pid

	exit 128
}
trap "finally" ABRT EXIT HUP INT QUIT

create_tmpdir()
{
	if ! tmpdir="$(mktemp -d -t ${myprog}.XXXXXXXX)/" ; then 
		akmods_echo 2 1  "ERROR: failed to create tmpdir."
		akmods_echo 2 1 --failure; return 1
	fi
	if ! mkdir "${tmpdir}"results ; then
		akmods_echo 2 1  "ERROR: failed to create result tmpdir."
		akmods_echo 2 1 --failure; return 1
	fi
}

remove_tmpdir()
{
	# remove tmpfiles
	if [[ "${tmpdir}" ]] && [[ -d "${tmpdir}" ]]; then
		rm -f "${tmpdir}"results/* "${tmpdir}"*.log
		rmdir "${tmpdir}"results/ "${tmpdir}"
	fi
}

cleanup_cachedir ()
{
	create_tmpdir
	find /boot/ -maxdepth 1 -name 'vmlinuz*' | sed 's|/boot/vmlinuz-||' > "${tmpdir}"results/kernels
	find "/var/cache/akmods/" -maxdepth 2 -mtime +14 -type f \( -name '*.rpm' -or -name '*.log' \) | grep -v --file "${tmpdir}"results/kernels | xargs --no-run-if-empty rm
	remove_tmpdir
}

init ()
{
	# some security provisions 
	\export PATH='/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin'
	\unalias -a
	hash -r
	ulimit -H -c 0 --
	IFS=$' \t\n'
	UMASK=022
	umask ${UMASK}

	# fall back to current kernel if user didn't provide one
	if [[ ! "${kernels}" ]]; then
		kernels="$(uname -r)"
	fi

	# we get the echo_{success,failure} stuff and the daemon method from there
	if [[ -r /etc/rc.d/init.d/functions ]]; then
		source /etc/rc.d/init.d/functions
	else
		echo "/etc/rc.d/init.d/functions not found" >&2
		exit 1
	fi

	# needs root permissions
	if [[ ! -w / ]]; then
		echo -n "Needs to run as root to be able to install rpms." >&2
		echo_failure; echo; exit 1
	fi

	# no akmods
	if [[ ! -d "/usr/src/akmods/" ]] ; then
		echo -n "/usr/src/akmods/ not found." >&2
		echo_failure; echo; exit 1
	fi

	# if there are no akmod packages installed there is nothing to do for us
	if ! ls /usr/src/akmods/*-kmod.latest &> /dev/null ; then
		echo -n "No akmod packages found." >&2
		echo_failure; echo; exit 1
	fi


	# now that we know that we're root make sure our dir for logging and results is avilable
	if [[ ! -d "/var/cache/akmods/" ]] ; then
		if ! mkdir -p "/var/cache/akmods/" ; then
			echo -n "/var/cache/akmods/ not found and could not be created" >&2
			echo_failure; echo; exit 1
		fi
	fi
	if [[ ! -w "/var/cache/akmods/" ]] ; then
		echo -n "${directory} not writable" >&2
		echo_failure; echo; exit 1
	fi

	# tools needed
	for tool in akmodsbuild chown sed rpmdev-vercmp; do
		if ! which "${tool}" &> /dev/null ; then
			echo -n "${tool} not found" >&2
			echo_failure; echo; exit 1
		fi
	done
}

buildinstall_kmod()
{
	local this_kernelver=${1}
	local this_kmodname=${2}
	local this_kmodsrpm=${3}
	local this_kmodverrel=${4}

	if [[ ! -r "${this_kmodsrpm}" ]]; then
		akmods_echo 2 1 "ERROR: ${this_kmodsrpm} not found."
		akmods_echo 2 1 --failure; return 1
	fi


	# result and logdir
	if [[ ! -d "/var/cache/akmods/${this_kmodname}" ]]; then
		if ! mkdir "/var/cache/akmods/${this_kmodname}" ; then
			akmods_echo 2 1  "ERROR: could not create /var/cache/akmods/${this_kmodname}."
			akmods_echo 2 1 --failure; return 1
		fi
	fi

	## preparations
	# tmpdir
	create_tmpdir

	# akmods needs to write there (and nobody else, but mktemp takes care fo that!)
	chown akmods "${tmpdir}" "${tmpdir}"results

	# remove old logfiles if they exist
	rm -f "/var/cache/akmods/${this_kmodname}/${this_kmodverrel}-for-${this_kernelver}.log" "/var/cache/akmods/${this_kmodname}/.last.log"

	# create a per kmod logfile
	if ! touch "/var/cache/akmods/${this_kmodname}/.last.log" ; then
		akmods_echo 2 1  "ERROR: failed to create kmod specific logfile."
		return 1
	fi

	# akmods_echo will log to this file from now on as well
	kmodlogfile="/var/cache/akmods/${this_kmodname}/.last.log"

	# build module using akmod
	akmods_echo 1 4 "Building RPM using the command '$(which akmodsbuild) --target $(uname -m) --kernels ${this_kernelver} ${this_kmodsrpm}'"
	/sbin/runuser -s /bin/bash -c "$(which akmodsbuild) --quiet --quiet --target $(uname -m) --kernels ${this_kernelver} --outputdir ${tmpdir}results --logfile ${tmpdir}/akmodsbuild.log ${this_kmodsrpm}" akmods >> "${kmodlogfile}" 2>&1
	local returncode=$?

	# copy rpmbuild log to kmod specific logfile
	if [[ -s "${tmpdir}"/akmodsbuild.log ]]; then
		while read line ; do
			echo "$(date +%d\ %b\ %H:%M:%S) akmodsbuild: ${line}" >> "${kmodlogfile}"
		done < "${tmpdir}"/akmodsbuild.log
	fi

	# result
	if (( ! ${returncode} == 0 )); then
		if [[ "${continue_line}" ]]; then
			akmods_echo 1 2 --failure
		fi
		akmods_echo 2 1  "Building rpms failed; see /var/cache/akmods/${this_kmodname}/${this_kmodverrel}-for-${this_kernelver}.failed.log for details"
		cp -l "${kmodlogfile}" "/var/cache/akmods/${this_kmodname}/${this_kmodverrel}-for-${this_kernelver}.failed.log"
		kmodlogfile=""
		remove_tmpdir
		return 4
	fi

	# install
	akmods_echo 1 4 "Installing newly built rpms"
	rpm -U $(find "${tmpdir}results" -type f -name '*.rpm' | grep -v debuginfo) >> "${kmodlogfile}" 2>&1 
	local returncode=$?

	# place the newly built rpms where user expects them
	cp "${tmpdir}results/"* "/var/cache/akmods/${this_kmodname}/"

	# everything fine?
	if (( ${returncode} != 0 )); then
			if [[ "${continue_line}" ]]; then
				akmods_echo 1 2 --failure
			fi
			akmods_echo 2 1 "Could not install newly built RPMs. You can find them and the logfile"
			akmods_echo 2 1 "${this_kmodverrel}-for-${this_kernelver}.failed.log in /var/cache/akmods/${this_kmodname}/"
			cp -l "${kmodlogfile}" "/var/cache/akmods/${this_kmodname}/${this_kmodverrel}-for-${this_kernelver}.failed.log"
			kmodlogfile=""
			remove_tmpdir
			return 8
	fi

	# finish
	akmods_echo 1 4 "Successful."
	cp -l "${kmodlogfile}" "/var/cache/akmods/${this_kmodname}/${this_kmodverrel}-for-${this_kernelver}.log"
	kmodlogfile=""
	remove_tmpdir

	return 0
}

check_kmod_up2date()
{
	local this_kernelver=${1}
	local this_kmodname=${2}

	# kmod present?
	if [[ ! -d /lib/modules/${this_kernelver}/extra/${this_kmodname}/ ]] ; then
		# build it
		return 1
	fi

	# kmod up2date? 
	local kmodpackage="$(rpm -qf /lib/modules/${this_kernelver}/extra/${this_kmodname}/ 2> /dev/null)"
	if [[ ! "${kmodpackage}" ]]; then
		# seems we didn't get what we wanted
		# well, better to do nothing in this case
		akmods_echo 1 2 -n "Warning: Could not determine what package owns /lib/modules/${this_kernelver}/extra/${this_kmodname}/"
		return 0
	fi
	local kmodver=$(rpm -q --qf '%{EPOCH}:%{VERSION}-%{RELEASE}\n' "${kmodpackage}" | sed 's|(none)|0|; s!\.\(fc\|lvn\)[0-9]*!!g')
	local akmodver=$(rpm -qp --qf '%{EPOCH}:%{VERSION}-%{RELEASE}\n' /usr/src/akmods/"${this_kmodname}"-kmod.latest | sed 's|(none)|0|; s!\.\(fc\|lvn\)[0-9]*!!g')

	# are they equal?
	if [[ "${kmodver}" == "${akmodver}" ]]; then
		return 0
	fi
	
	local newestpkgver=$(rpmdev-vercmp "${kmodver}" "${akmodver}" 2>/dev/null | awk '{print $1}')
	if [[ ! "${kmodver}" ]] || [[ ! "${akmodver}" ]] || [[ ! "${newestpkgver}" ]] ; then
		# seems we didn't get what we wanted
		# well, better to do nothing in this case
		akmods_echo 1 2 -n "Warning: Could not determine if akmod is newer then the installed kmod"
		return 0
	elif [[ "${akmodver}" == "${newestpkgver}" ]] ; then
		# build it
		return 1
	else
		return 0
	fi
}

check_kmods()
{
	local this_kernelver="${1}"

	akmods_echo 1 2 -n "Checking kmods exist for ${this_kernelver}"
	for akmods_kmodfile in /usr/src/akmods/*-kmod.latest ; do
		local this_kmodname="$(basename ${akmods_kmodfile%%-kmod.latest})"
		
		# actually check this akmod?
		if [[ "${akmods}" ]]; then
			for akmod in ${akmods} ; do
				if [[ "${this_kmodname}" != "${akmod}" ]] ; then
					# ignore this one
					continue 2
				fi
			done
		fi

		# go
		if ! check_kmod_up2date ${this_kernelver} ${this_kmodname} ; then
			# okay, kmod wasn't found or is not up2date
			if [[ "${continue_line}" ]]; then
				akmods_echo 1 2 --warning
				# if the files for building modules are not avilable don't even try to build modules
				if [[ ! -r /usr/src/kernels/"${this_kernelver}"/Makefile ]] || [[ ! -r  /lib/modules/${this_kernelver}/build/Makefile ]]; then
					akmods_echo 1 2 "Files needed for building modules against kernel"
					akmods_echo 1 2 "${this_kernelver} could not be found as the following" 
					akmods_echo 1 2 "directories are missing:" 
					akmods_echo 1 2 "/usr/src/kernels/${this_kernelver}/" 
					akmods_echo 1 2 -n "/lib/modules/${this_kernelver}/build/" 
					akmods_echo 1 2 --failure
					return 1
				fi
			fi

			local this_kmodverrel="$(rpm -qp --qf '%{VERSION}-%{RELEASE}' "${akmods_kmodfile}" | sed 's!\.\(fc\|lvn\)[0-9]*!!g' )"
			if [[ ! "${alwaystry}" ]] && [[ -e "/var/cache/akmods/${this_kmodname}/${this_kmodverrel}-for-${this_kernelver}".failed.log ]]; then
				akmods_echo 1 2 -n "Ignoring ${this_kmodname}-kmod as it failed earlier" 
				akmods_echo 1 2 --warning
				local someignored="true"
			else
				akmods_echo 1 2 -n "Building and installing ${this_kmodname}-kmod"
			 	if buildinstall_kmod ${this_kernelver} ${this_kmodname} ${akmods_kmodfile} ${this_kmodverrel} ; then
					akmods_echo 1 2 --success
				else
					local somefailed="true"
				fi
			fi
		fi
	done

	if [[ "${continue_line}" ]]; then
		akmods_echo 1 2 --success
	elif [[ "${someignored}" ]] || [[ "${somefailed}" ]] ; then
		echo
		akmods_echo 1 2 "Hint: Some kmods were ignored or failed to build or install." 
		akmods_echo 1 2 "You can try to rebuild and install them by by calling" 
		akmods_echo 1 2 "'/usr/sbin/akmods --force' as root."
		echo
		sleep 2
	fi

}

myprog_help ()
{
	echo "Usage: ${myprog} [OPTIONS]"
	echo $'\n'"Checks the akmod packages and rebuilds them if needed"
	echo $'\n'"Available options:"
	echo " --force             -- try all, even if they failed earlier"
	echo " --kernels <kernel>  -- build and install only for kernel <kernel>"
	echo " --akmod <akmod>     -- build and install only akmod <akmod>"
}


# first parse command line options
while [ "${1}" ] ; do
	case "${1}" in
		--kernel|--kernels)
			shift
			if [[ ! "${1}" ]] ; then
				echo "ERROR: Please provide the kernel-version to build for together with --kernel" >&2
				exit 1
			elif [[ ! -r /usr/src/kernels/"${1}"/Makefile ]] || [[ ! -r  /lib/modules/${1}/build/Makefile ]]; then
				echo "Could not find files needed to compile modules for ${1}"
				exit 1
			elif [[ -r /usr/src/kernels/"${1}"/Makefile ]] && [[ ! -r  /boot/vmlinuz-"${1}" ]]; then
				# this is a red hat / fedora kernel-devel package, but the kernel for it is not installed
				# kmodtool would adds a dep on that kernel when building; thus when we'd try to install the 
				# rpms we'd run into a missing-dep problem. Thus we prevent that case
				echo "Kernel ${1} not installed"
				exit 1
			fi
			# overwrites the default:
			kernels="${kernels}${1}"
			# an try to build, even if we tried already
			alwaystry=true
			shift
			;;
		--akmod|--kmod)
			shift
			if [[ ! "${1}" ]] ; then
				echo "ERROR: Please provide a name of a akmod package together with --akmods" >&2
				exit 1
			elif [[ -r /usr/src/akmods/"${1}"-kmod.latest ]] ; then 
				akmods="${akmods}${1} "
			elif [[ -r /usr/src/akmods/"${1}".latest ]] ; then 
				akmods="${akmods}${1%%-kmod} "
			else
				echo "Could not find akmod ${1}"
				exit 1
			fi
			shift
			;;
		--force)
			alwaystry=true
			shift
			;;
		--from-posttrans|--from-init|--from-akmod)
			# does nothing (yet!)
			shift
			;;
		--verbose)
			let verboselevel++
			shift
			;;
		--quiet)
			let verboselevel--
			shift
			;;
		--help)
			myprog_help
			exit 0
			;;
		--version)
			echo "${myprog} ${myver}"
			exit 0
			;;
		*)
			echo "Error: Unknown option '${1}'." >&2
			myprog_help >&2
			exit 2
			;;
	esac
done

# sanity checks
init

# go
for kernel in ${kernels} ; do
		check_kmods ${kernel}
done

# finished :)
finally


--- NEW FILE akmods.spec ---
Name:           akmods
Version:        0.3.3
Release:        2%{?dist}
Summary:        Automatic kmods build and install tool 

Group:          System Environment/Kernel
License:        MIT
URL:            http://rpmfusion.org/Packaging/KernelModules/Akmods
Source0:        akmods
#to be written: Source1:        akmods.1
Source2:        akmodsbuild
Source3:        akmodsbuild.1
Source4:        akmodsinit
Source6:        akmodsposttrans
BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)

BuildArch:      noarch

# needed for actually building kmods:
#Requires:       %{_bindir}/inotifywait
Requires:       %{_bindir}/rpmdev-vercmp
Requires:       kmodtool >= 1-9

# this should track in all stuff that is normally needed to compile modules:
Requires:       bzip2 coreutils diffutils file findutils gawk gcc grep
Requires:       gzip perl make sed tar unzip util-linux which rpm-build

# do we need akmods-{xen,PAE,foo,bar} packages that depend on the proper
# kernel-devel package? Well, maybe later; for now we just go with the 
# easy variant; note that the requires is weak in any case, as a older
# kernel-devel package can provice it as well :-/ 
Requires:       kernel-devel

# we create a special user that used by akmods to build kmod packages
Requires(pre):  shadow-utils

# for the akmods init script:
Requires(post):  /sbin/chkconfig
Requires(preun): /sbin/chkconfig
Requires(preun): /sbin/service


%description
Akmods startup script will rebuild akmod packages during system 
boot while its background daemon will build them for kernels right
after they were installed.

%prep
echo nothing to prep


%build
echo nothing to build


%install
rm -rf $RPM_BUILD_ROOT
mkdir -p \
   $RPM_BUILD_ROOT/%{_usrsrc}/akmods/ \
   $RPM_BUILD_ROOT/%{_localstatedir}/cache/akmods/
install -D -p -m 0755 %{SOURCE0} $RPM_BUILD_ROOT/%{_sbindir}/akmods
install -D -p -m 0755 %{SOURCE2} $RPM_BUILD_ROOT/%{_bindir}/akmodsbuild
install -D -p -m 0644 %{SOURCE3} ${RPM_BUILD_ROOT}%{_mandir}/man1/akmodsbuild.1
install -D -p -m 0755 %{SOURCE4} $RPM_BUILD_ROOT/%{_initrddir}/akmods
# %%{_sysconfdir}/kernel/posttrans.d/ should be owned my mkinitrd #441111
install -D -p -m 0755 %{SOURCE6} $RPM_BUILD_ROOT/%{_sysconfdir}/kernel/postinst.d/akmods

%clean
rm -rf $RPM_BUILD_ROOT

%pre
# create group and user
getent group akmods >/dev/null || groupadd -r akmods
getent passwd akmods >/dev/null || \
useradd -r -g akmods -d /var/cache/akmods/ -s /sbin/nologin \
    -c "User is used by akmods to build akmod packages" akmods

%post
# add init script
/sbin/chkconfig --add akmods
# enable init script; users that installed akmods directly or indirectly
# want it to work
if [ $1 = 1 ]; then
   /sbin/chkconfig akmods on
fi

%preun
if [ $1 = 0 ]; then
   /sbin/chkconfig --del akmods
fi


%files 
%defattr(-,root,root,-)
%{_usrsrc}/akmods
%{_localstatedir}/cache/akmods/
%{_bindir}/akmodsbuild
%{_sbindir}/akmods
%{_initrddir}/akmods
%{_sysconfdir}/kernel/postinst.d/akmods
%{_mandir}/man1/*

%changelog
* Thu Oct 02 2008 Thorsten Leemhuis <fedora [AT] leemhuis [DOT] info - 0.3.3-2
- rebuild for rpm fusion

* Sun Sep 21 2008 Thorsten Leemhuis <fedora[AT]leemhuis[DOT]info> - 0.3.3-1
- proper check for kernel-devel files in akmods as well

* Tue Sep 02 2008 Thorsten Leemhuis <fedora[AT]leemhuis[DOT]info> - 0.3.2-1
- Start akmods way earlier (level 05) during boot (#1995)
- proper check for kernel-devel files (#1942)

* Tue Sep 02 2008 Thorsten Leemhuis <fedora[AT]leemhuis[DOT]info> - 0.3.1-2
- Remove check section

* Sun May 18 2008 Thorsten Leemhuis <fedora[AT]leemhuis[DOT]info> - 0.3.1-1
- Remove check for inotify

* Sat Apr 12 2008 Thorsten Leemhuis <fedora[AT]leemhuis[DOT]info> - 0.3.0-1
- Fix thinko in akmodsposttrans

* Sat Apr 12 2008 Thorsten Leemhuis <fedora[AT]leemhuis[DOT]info> - 0.3.0-0.4
- split init script and poststrans stuff from akmodsds
- rename akmodsd to akmods
- rename akmodbuild to akmodsbuild
- remove the inotifywatch stuff

* Sun Mar 30 2008 Thorsten Leemhuis <fedora[AT]leemhuis[DOT]info> - 0.2.3-1
- update akmodbuid manpage

* Sat Mar 29 2008 Thorsten Leemhuis <fedora[AT]leemhuis[DOT]info> - 0.2.2-1
- adjust to recent "arch and flavor in uname" changes from j-rod
- add man page for akmodbuild
- cleanups to akmodbuild

* Thu Jan 31 2008 Thorsten Leemhuis <fedora[AT]leemhuis[DOT]info> - 0.2.1-2
- add a hard dep on kmodtool which is needed during akmod building

* Sat Jan 26 2008 Thorsten Leemhuis <fedora[AT]leemhuis[DOT]info> - 0.2.1-1
- rename akmods to akmodbuild

* Sun Jan 20 2008 Thorsten Leemhuis <fedora[AT]leemhuis[DOT]info> - 0.2.0-1
- require kernel-devel
- use rpmdev-vercmp to compare f a akmods is newer then the installed kmod
- build and install akmods on install

* Wed Jan 09 2007 Thorsten Leemhuis <fedora[AT]leemhuis[DOT]info> - 0.1.1-3
- remove akmodstool and integrate it into kmodtool

* Wed Jan 09 2007 Thorsten Leemhuis <fedora[AT]leemhuis[DOT]info> - 0.1.1-2
- own /usr/src/akmods

* Sun Jan 06 2007 Thorsten Leemhuis <fedora[AT]leemhuis[DOT]info> - 0.1.1-1
- add rpm-build as Require
- add a status function to akmodsd

* Sun Jan 06 2007 Thorsten Leemhuis <fedora[AT]leemhuis[DOT]info> - 0.1.0-1
- Initial RPM release.


--- NEW FILE akmodsbuild ---
#!/bin/bash
#
# akmodbuild - Helper script for building kernel module SRPMs
# Copyright (c) 2007 Thorsten Leemhuis <fedora at leemhuis.info>
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
myprog="akmodsbuild"
myver="0.3.2"

# defaults that might get overwritten by user:
kernels="$(uname -r)"
target="$(uname -m)"
numberofjobs=$(grep -c processor /proc/cpuinfo 2> /dev/null)
verboselevel=2
outputdir="${PWD}"
srpms=

init ()
{
	## startup checks
	# prevent root-usage
	if [[ -w / ]]; then
		echo "ERROR: Not to be used as root; start as user or '${myprog}' instead." >&2
		exit 1 
	fi

	# do we have everything we need to build for the kernels in question?
	for kernel in ${kernels}; do
		if [[ ! -e /usr/src/kernels/${kernel}/Makefile ]] && [[ ! -e /lib/modules/${kernel}/build/Makefile ]]; then
			echo "ERROR: Files needed for building modules against kernel" >&2
			echo " ${kernel} could not be found as the following" >&2
			echo " directories are missing:"
			echo " /usr/src/kernels/${kernel}/" >&2
			echo " /lib/modules/${kernel}/build/" >&2
			exit 2
		fi
	done

	if [[ ! "${srpms}" ]]; then
			echo "ERROR: Please provide a list of SRPM-files to build."
			exit 2
	fi

	# SRPMS available?
	for srpm in ${srpms}; do
		if [[ ! -r ${srpm} ]]; then
			echo "ERROR: Can't find SRPM ${srpm}"
			exit 1
		fi
	done

	# room to save things
	if [[ ! -d "${outputdir}" ]]; then
		echo "ERROR: ${outputdir} is not a directory" >&2
		exit 1
	elif [[ ! -w "${outputdir}" ]]; then
		echo "ERROR: ${outputdir} is not a writable" >&2
		exit 1
	fi


	# make sure this is a number
	if ! (( ${numberofjobs} > 0 )); then
		echo "Warning: using hardcoded defaut value for number of jobs"
		numberofjobs=2
	fi

	## preparations
	# tmpdir
	if ! tmpdir="$(mktemp -d -t ${myprog}.XXXXXXXX)" ; then 
			echo "ERROR: Could create tempdir."
			exit 1
	fi

	# buildtreee
	mkdir "${tmpdir}"/{BUILD,SOURCES,SPECS,SRPMS,RPMS,RPMS/"${target}"}

	# logfile
	if [[ ! "${logfile}" ]] ; then
		logfile="${tmpdir}/logfile"
	fi

	if ( [[ -e "${logfile}" ]] && [[ ! -w "${logfile}" ]] ) || ! touch "${logfile}" ; then
			echo "ERROR: Could not write logfile."
			finally
			exit 1
	fi
}


finally()
{
	# kill background jobs if needed
	if [[ "${watch_jobid}" ]]; then
		kill "${watch_jobid}"
	fi
	if [[ "${rpmbuild_jobid}" ]]; then
		kill "${rpmbuild_jobid}"
	fi

	# remove tmpfiles
	if [[ -d "${tmpdir}" ]]; then
		rm -rf "${tmpdir}"
	fi
}
trap "finally" 2


akmods_echo()
{
	# where to output
	local this_fd=${1}
	shift

	# verboselevel
	local this_verbose=${1}
	shift

	if [[ "${1}" == "--not-logfile" ]]; then
		local notlogfile=true
		shift
	fi

	# output to console
	if (( ${verboselevel} >= ${this_verbose} )) ; then
		echo "$@" >&${this_fd}
	fi

	# global logfile
	if [[ ! ${notlogfile} ]]; then
		echo "$@" >> "${logfile}"
	fi
}


watch_rpmbuild()
{
	# background function to show rpmbuild progress
	# does't use akmods_echo here; this stage handles the output on its own
	# (seperate process and there is no need to log this)
	if (( ${verboselevel} == 2 )); then
		tail --pid ${1} -n +1 -s 0.1 -f ${2} 2>/dev/null | grep --line-buffered -e '%prep' -e '%build' -e '%install' -e '%clean' |  while read line; do 
			if [[ "${line}" != "${line##*prep}" ]]; then
				echo -n "prep "
			elif [[ "${line}" != "${line##*build}" ]]; then
				echo -n "build "
			elif [[ "${line}" != "${line##*install}" ]]; then
				echo -n "install "
			elif [[ "${line}" != "${line##*clean}" ]]; then
				echo -n "clean; "
				# last linefeed is done by the caller
			fi
		done
	elif (( ${verboselevel} > 2 )); then
		tail --pid ${1} -n +1 -s 0.1 -f ${2}
	fi
}

process_srpm()
{
	local source_rpm="${1}"

	# status info
	akmods_echo 1 2 -n "* Rebuilding ${source_rpm} for kernel(s) ${kernels}: "

	# kick off rebuild into background
	/usr/bin/time --format='%x' --output="${tmpdir}/.jobexit" rpmbuild \
		--define "_topdir     ${tmpdir}/" \
		--define "_buildtree  ${tmpdir}/BUILD" \
		--define "_specdir    ${tmpdir}/SPECS" \
		--define "_sourcedir  ${tmpdir}/SOURCES" \
		--define "_srcrpmdir  ${tmpdir}/SRPMS" \
		--define "_rpmdir     ${tmpdir}/RPMS" \
		--define "_smp_mflags -j${numberofjobs}" \
		--define "kernels     ${kernels}" \
		--target ${target} \
		--rebuild "${source_rpm}" 2>&1 | tee -a "${logfile}" > "${tmpdir}/.joblog"  &

	local rpmbuild_jobid=$!

	# show progress
	if (( ${verboselevel} >= 2 )); then
		watch_rpmbuild ${rpmbuild_jobid} "${tmpdir}/.joblog" 2> /dev/null &
		local watch_jobid=$!
	fi

	# wait for rpmbuild
	wait ${rpmbuild_jobid}
	local rpmbuild_returncode=$(tail -n 1 "${tmpdir}/.jobexit")
	unset rpmbuild_jobid

	# give watch_rpmbuild a moment to catch up; kill it if it does not
	if (( ${verboselevel} >= 2 )); then
		sleep 0.5
		kill ${watch_jobid} &> /dev/null
		unset watch_jobid
	fi

	# did rpmbuild succeed?
	if (( ${rpmbuild_returncode} != 0 )); then
		# linefeed:
		akmods_echo 1 2 ""

		akmods_echo 2 2 --not-logfile "rpmbuild failed with errorcode ${rpmbuild_returncode}; last 35 Lines of log:"
		akmods_echo 2 2 --not-logfile "--- "
		tail -n 35 "${tmpdir}/.joblog" >&2
		akmods_echo 2 2  --not-logfile "---"
		return ${rpmbuild_returncode}
	fi

	# finish status for watch_rpmbuild
	if (( ${verboselevel} >= 2 )); then 
		akmods_echo 1 2 -n "Successfull; "
	fi

	local rpms_built="$(cd "${tmpdir}"/RPMS/"${target}" ; echo *)"

	if ! mv "${tmpdir}/RPMS/${target}/"* "${outputdir}" ; then
		# linefeed:
		akmods_echo 1 2 "" 

		akmods_echo 2 2 "Failed to move ${tmpdir}/RPMS/${target}/"* "to ${outputdir}"
		return 128
	fi

	if (( ${verboselevel} == 1 )); then 
		for rpm in ${rpms_built}; do
			echo "${outputdir%%/}/${rpm}"
		done
	elif (( ${verboselevel} >= 2 )); then 
		akmods_echo 1 2  "Saved ${rpms_built} in ${outputdir%%/}/"
	fi


	# finished
	return 0
}

myprog_help ()
{
	echo "Usage: ${myprog} [OPTIONS] <SRPMS>"
	echo $'\n'"Rebuilds kmod SRPM(s)"
	echo $'\n'"Available options (and their defaults): "
	echo " -k, --kernels         -- build for kernel-versions (output from 'uname -r')"
	echo " -l, --logfile <file>  -- save rpmduild output to <file>"
	echo " -o, --outputdir <dir> -- save rpms and logs here (current directory)"
	echo " -t, --target          -- target-arch (output from 'uname -m')"
	echo " -v, --verbose         -- increase verboseness"
	echo " -q, --quiet           -- be more quiet"
	echo
	echo " -h, --help            -- show usage"
	echo " -V, --version           -- show version"
}

while [ "${1}" ] ; do
	case "${1}" in
		-k|--kernels)
			shift
			if [[ ! "${1}" ]] ; then
				echo "ERROR: Please provide kernel-version(s) to build for together with --kernel" >&2
				exit 1
			fi
			kernels="${1}"
			shift
			;;
		-l|--logfile)
			shift
			if [[ ! "${1}" ]]; then
				echo "ERROR: Please provide a filename together with --logfile" >&2
				exit 1
			fi
			logfile="${1}"
			shift
			;;
		-o|--outputdir)
			shift
			if [[ ! "${1}" ]]; then
				echo "ERROR: Please provide the output directory together with --outputdir" >&2
				exit 1
			fi
			outputdir="${1}"
			shift
			;;
		-t|--target)
			shift
			if [[ ! "${1}" ]] ; then
				echo "ERROR: Please provide the target-arch together with --target" >&2
				exit 1
			fi
			target="${1}"
			shift
			;;
		-v|--verbose)
			let verboselevel++
			shift
			;;
		-q|--quiet)
			let verboselevel--
			shift
			;;
		-h|--help)
			myprog_help
			exit 0
			;;
		-V|--version)
			echo "${myprog} ${myver}"
			exit 0
			;;
		--*)
			echo "Error: Unknown option '${1}'." >&2
			myprog_help >&2
			exit 2
			;;
		*)
			srpms="${srpms} ${1}"
			shift
			;;
	esac
done

# sanity checks
init

# go
for srpm in ${srpms}; do
	process_srpm ${srpm}
	returncode=$?

	if (( ${returncode} != 0 )); then
		finally
		exit ${returncode}
	fi
done

# finished
finally

exit 0


--- NEW FILE akmodsbuild.1 ---
." Text automatically generated by txt2man
.TH akmodsbuild  "1" "" ""
.SH NAME
\fBakmodsbuild \fP- Rebuilds kmod SRPM(s)
.SH SYNOPSIS
.nf
.fam C
\fBakmodsbuild\fP [\fIoptions\fP] <\fISRPM(s)\fP>
.fam T
.fi
.SH DESCRIPTION
Rebuilds kmod-SRPMs for kernels 
.SH OPTIONS
.TP
.B
\fB-k\fP, \fB--kernels\fP <list>
.PP
.nf
.fam C
   Build the kmod for kernels in list; try to build for the current kernel
   (e.g. output from 'uname -r') if option is not used.

.fam T
.fi
\fB-l\fP, \fB--logfile\fP <file>
.PP
.nf
.fam C
   Write output from rpmbuild to <file>

.fam T
.fi
\fB-o\fP, \fB--outputdir\fP <directory>
.PP
.nf
.fam C
   Save resulting RPMS in <direcotry>. Use current working directory if 
   directory is not specified.
    
.fam T
.fi
\fB-t\fP, \fB--target\fP 
.PP
.nf
.fam C
   Target architecture. Default: output from 'uname -m'.

.fam T
.fi
\fB-v\fP, \fB--verbose\fP
.PP
.nf
.fam C
   Increase verboselevel; option can be given multiple times

.fam T
.fi
\fB-q\fP, \fB--quiet\fP
.PP
.nf
.fam C
   Decrease verboselevel; option can be given multiple times

.fam T
.fi
\fB-h\fP, \fB--help\fP
.PP
.nf
.fam C
   Show usage

.fam T
.fi
\fB-V\fP, \fB--version\fP
.PP
.nf
.fam C
   Output program version

.SH EXAMPLE
To compile the kmod SRPMs ndiswrapper-kmod-1.52-1.lvn9.1.src.rpm and madwifi-kmod-0.9.4-2.lvn9.src.rpm found in /usr/src/akmods/ use:
.PP
.nf
.fam C
      $ akmodsbuild /usr/src/akmods/ndiswrapper-kmod-1.52-1.lvn9.1.src.rpm /usr/src/akmods/madwifi-kmod-0.9.4-2.lvn9.src.rpm

.SH BUGS
None know, but there are likely some
.SH AUTHOR
Thorsten Leemhuis <fedora [AT] leemhuis [DOT] info>


--- NEW FILE akmodsinit ---
#!/bin/bash -
#
# akmodinit     Builds and install new kmods from akmod packages
#
# Author:       Thorsten Leemhuis <fedora at leemhuis.info>
#
# chkconfig:    2345 5 95
#
# description:  akmodsinit calls akmod during system boot to build and install
#               kmods for the currently running kernel if neccessary.
#
# processname:  akmodsd
# pidfile:      /var/run/akmodsd.pid
#

### BEGIN INIT INFO
# Provides: akmodsd
# Required-Start: $local_fs
# Required-Stop: $local_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Builds and install new kmods from akmod packages
# Description: akmodsinit calls akmod during system boot to build and install
#              kmods for the currently running kernel if neccessary.
### END INIT INFO

start_akmods ()
{
	# build and install all kmods if neccessary
	# for the currently running kernel (default in akmods)
	/usr/sbin/akmods --from-init
}


# See how we were called.
case "$1" in
	start|restart|reload|condrestart)
		start_akmods
		;;
	stop|status)
		exit 0
		;;
	*)
		echo $"Usage: $0 start"
		exit 1
		;;
esac


--- NEW FILE akmodsposttrans ---
#!/bin/bash -
#
# akmodposttras - Calls akmods for newly installed kernels
#
# Copyright (c) 2009 Thorsten Leemhuis <fedora at leemhuis.info>
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# todo-list:
# - scary idea: install kernel-devel packages on demand?
# - redirect output to a seperate logfile?

# just check in case a user calls this directly
if [[ ! -w / ]]; then
	echo "Needs to run as root to be able to install rpms." >&2
	exit 1
fi

# needs to run in background as rpmdb might be locked otherwise
nohup /usr/sbin/akmods --from-posttrans --kernels ${1} &> /dev/null &



More information about the rpmfusion-commits mailing list