Compare commits

..

1 commit

Author SHA1 Message Date
Troy Dawson
f45cf75600 epel8-playground decommissioned : https://pagure.io/epel/issue/136 2022-01-31 08:58:14 -08:00
26 changed files with 1 additions and 2437 deletions

0
.gitignore vendored
View file

View file

@ -1,8 +0,0 @@
# Also see:
# https://fedoraproject.org/wiki/Starting_services_by_default
# Installing presets is not the preferred solution but until another one
# presents itself:
# https://bugzilla.rpmfusion.org/show_bug.cgi?id=3713
enable akmods.service
#enable akmods-shutdown.service

View file

@ -1,59 +0,0 @@
#!/bin/bash -
#
# 95-akmodposttrans.install - Calls akmods for newly installed kernels
#
# Copyright (c) 2019 Nicolas Viéville <nicolas.vieville@uphf.fr>
#
# 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.
#
COMMAND="$1"
KERNEL_VERSION="$2"
BOOT_DIR_ABS="$3"
KERNEL_IMAGE="$4"
# just check in case a user calls this directly
if [[ ! -w /var ]] ; then
echo "Needs to run as root to be able to install rpms." >&2
exit 4
fi
if [[ ! -n "${KERNEL_VERSION}" ]] ; then
exit 1
fi
case "${COMMAND}" in
add)
# Exit early if system-update.target is active - rhbz#1518401
/usr/bin/systemctl -q is-active system-update-pre.target system-update.target
RET=$?
[[ $RET == 0 ]] && exit 0
/bin/systemctl restart "akmods@${KERNEL_VERSION}.service" --no-block >/dev/null 2>&1
;;
remove)
# Nothing to do
;;
*)
;;
esac
exit 0

18
LICENSE
View file

@ -1,18 +0,0 @@
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.

12
README
View file

@ -1,12 +0,0 @@
Akmods startup script will rebuild akmod packages during system
boot, while its background daemon will build them for kernels right
after they were installed.
The akmods systemd service provides both, and is enabled by default.
The akmods-shutdown service is disabled by default but can, in some
circumstances, provide an additional chance to build and install a kernel
module. Users who would prefer longer shutdowns over delayed startups
may wish to consider enabling it with the following command:
sudo systemctl enable --now akmods-shutdown.service

View file

@ -1,51 +0,0 @@
Secure boot is a setup using UEFI firmware to check cryptographic
signatures on the bootloader and associated OS kernel to ensure they
have not been tampered with or bypassed in the boot process.
This verification can be extended to Kernel and its modules.
It's default case in Fedora with UEFI and Secure boot enabled.
Fedora Project have signed kernels and also main modules with Fedora
Key, but 3rd party modules as NVidia, VirtualBox, etc. need to be signed
to load.
Akmods provides an enroll process to sign third party modules with your
own keypair.
At the first run of the akmods.service, certificate and keypair will be
created with default value using the '/usr/sbin/kmodgenca' script.
You may also wish to manually create your own certificate and keypair
with `/usr/sbin/kmodgenca` command.
If '/usr/sbin/kmodgenca' is launched with the '-a' parameter, it will
use default values to complete the cacert.config file, and to generate
automatically the cert and the private key.
If '/usr/sbin/kmodgenca' is launched without parameters, user will be
prompted to complete manually the cacert.config file, then the cert and
the private key will be automatically generated.
If the cert and the private key files already exist,
'/usr/sbin/kmodgenca' will exit unless the '-f' parameter is used.
The cert and the private key are stored respectively in
/etc/pki/akmods/certs and /etc/pki/akmods/private/ directories.
Now you need to enroll the public key in MOK, this process is described
below.
- Ask MOK to enroll new keypair with certificate with the command
`mokutil --import /etc/pki/akmods/certs/public_key.der`.
- mokutil asks to generate a password to enroll the public key.
- Rebooting the system is needed for MOK to enroll the new public key.
- On next boot MOK Management is launched and you have to choose
"Enroll MOK".
- Choose "Continue" to enroll the key or "View key 0" to show the keys
already enrolled.
- Confirm enrollment by selecting "Yes".
- You will be invited to enter the password generated above.
WARNING: keyboard is mapped to QWERTY!
- The new key is enrolled, and system ask you to reboot.
You can confirm the enrollment of the new keypair once the system
rebooted with:
`mokutil --list-enrolled
or with:
`mokutil --test-key /etc/pki/akmods/certs/public_key.der`

700
akmods
View file

@ -1,700 +0,0 @@
#!/usr/bin/bash -
########################################################################
#
# akmods - Rebuilds and install akmod RPMs
# Copyright (c) 2007, 2008 Thorsten Leemhuis <fedora@leemhuis.info>
# Copyright (c) 2018 Nicolas Chauvet <kwizart@gmail.com>
#
# 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/dnf to install required kernel-devel packages?
# - better way to detect if a earlier build failed or succeeded
# - special kernel "all" (all that are installed with a matching -devel package; could be called from posttrans in akmods packages)
# - manpage
# - make it configurable if kmod building is done with nohup
# - check on shutdown if akmods is still running and let it finish before continuing
# - make it configurable if kmods from the repo replace local ones
# global vars
myprog="akmods"
myver="0.6.2"
kmodlogfile=
continue_line=""
tmpdir=
kernels=
verboselevel=2
# We cannot differenciate from a code failure to shutdown kill9 oom etc
# So we always retry anyway
alwaystry=1
# Check Running plymouth
no_plymouth=1
last_message=""
function check_plymouth() {
which plymouth > /dev/null 2> /dev/null
if [[ "$?" -eq 1 ]]
then
no_plymouth=1
return 0
fi
plymouth --ping
no_plymouth=$?
}
# new or del, msg
akmods_echo_plymouth(){
if [[ "$no_plymouth" -eq 0 ]]
then
if [[ "$1" -eq 1 ]]
then
plymouth display-message --text="$2"
last_message=$2
else
if [ -z "${last_message}" ]; then
plymouth hide-message --text="$last_message" &
last_message=""
fi
fi
fi
}
akmods_echo()
{
# where to output
local this_fd=${1}
shift
# verboselevel
local this_verbose=${1}
shift
# output to console
if (( 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 +%Y/%m/%d\ %H:%M:%S) akmods: $*" >> "/var/log/akmods/akmods.log"
# the kmods logfile as well, if we work on a kmod
if [[ -n "${kmodlogfile}" ]] ; then
echo "$(date +%Y/%m/%d\ %H:%M:%S) akmods: $*" >> "${kmodlogfile}"
fi
}
finally()
{
# remove tmpfiles
remove_tmpdir
# remove lockfile
rm -f /var/cache/akmods/.lockfile
exit "${1:-128}"
}
# Make sure finally() is run regardless of reason for exiting.
trap "finally" ABRT HUP INT QUIT
create_tmpdir()
{
if ! tmpdir="$(mktemp -d -p /tmp "${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 [[ -n "${tmpdir}" ]] && [[ -d "${tmpdir}" ]] ; then
rm -f "${tmpdir}"results/* "${tmpdir}"*.log
rmdir "${tmpdir}"results/ "${tmpdir}"
fi
}
cleanup_cachedir ()
{
local excluded
excluded=$(find /boot -name 'vmlinuz-*' '!' -name '*rescue*' 2>/dev/null | sed 's/.*vmlinuz-//')
local -a file_list
mapfile -t file_list < <(find /var/cache/akmods -mindepth 2 -type f -not -name .last.log 2>/dev/null | grep -Fv -f <(echo "${excluded}"))
for one_file in "${file_list[@]}"; do
if grep -q ".*\.rpm$" <<< "${one_file}" ; then
if ! rpm -q "$(basename "${one_file%.rpm}")" >/dev/null ; then
rm -f "${one_file}"
fi
else
rm -f "${one_file}"
fi
done
}
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
# https://bugzilla.rpmfusion.org/show_bug.cgi?id=4023
#ulimit -H -c 0 --
IFS=$' \t\n'
UMASK=022
umask ${UMASK}
# we get the echo_{success,failure} stuff from there
if [[ -r /etc/rc.d/init.d/functions ]] ; then
source /etc/rc.d/init.d/functions
else
# Use our own simple replacements
echo_success() {
echo -ne " [ OK ]\r"
return 0
}
echo_failure() {
echo -ne " [FAILED]\r"
return 1
}
echo_warning() {
echo -ne " [WARNING]\r"
return 1
}
fi
# needs root permissions
if [[ ! -w /var ]] ; 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, nothing to do." >&2
echo_success ; echo ; exit 0
fi
# now that we know that we're root make sure our dir for logging and results is available
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 "/var/cache/akmods/ not writable" >&2
echo_failure ; echo ; exit 1
fi
# tools needed
for tool in akmodsbuild chown flock sed rpmdev-vercmp ; do
if ! command -v "${tool}" &> /dev/null ; then
echo -n "${tool} not found" >&2
echo_failure ; echo ; exit 1
fi
done
# create lockfile and wait till we get it
exec 99>/run/akmods/akmods.lock
flock -w 900 99
}
check_kernel_devel()
{
if [[ ! -r /usr/src/kernels/"${1}"/Makefile ]] && \
[[ ! -r /lib/modules/"${1}"/build/Makefile ]] ; then
echo "Could not find files needed to compile modules for ${1}"
echo "Are the development files for kernel ${1} or the appropriate kernel-devel package installed?"
return 1
elif [[ -r /usr/src/kernels/"${1}"/Makefile ]] && \
[[ ! -d /lib/modules/"${1}" ]] ; then
# this is a red hat / fedora kernel-devel package, but the kernel for it is not installed
# kmodtool would add 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"
return 1
fi
return 0
}
check_default_kernel()
{
# Ensure to build for grub or systemd-boot default kernel
#
# IMPORTANT: "bootctl is-installed" check that systemd-boot is installed only.
# It doesn't check if systemd-boot is the default loader.
# So we assume grubby results if available
if command -v grubby >/dev/null 2>&1 ; then
default_kernel=$(grubby --default-kernel | sed -e 's/^.*vmlinuz-//')
elif bootctl is-installed >/dev/null 2>&1 ; then
# Leave jq as optional - isDefault requires systemd 253
if command -v jq >/dev/null ; then
default_kernel="$(bootctl list --json=short | jq -r '.[] | select(.isDefault).version')"
# Validate the result or discard - rhbz#2270414
if [[ ! -f /boot/vmlinuz-"${default_kernel}" ]] ; then
default_kernel=""
fi
fi
else # They use neither systemd-boot nor grub2
echo -n "Unable to figure out the default kernel" >&2
echo_warning ; echo
default_kernel=""
fi
local _kernels
if [[ "${default_kernel}" == "$(uname -r)" ]] ; then
_kernels="${default_kernel}"
else
_kernels="${default_kernel} $(uname -r)"
fi
for _kernel in ${_kernels} ; do
if check_kernel_devel "${_kernel}" ; then
kernels="${kernels} ${_kernel}"
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 of 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"
# Unset TMPDIR since it is misused by "runuser"
# https://bugzilla.rpmfusion.org/show_bug.cgi?id=2596
unset TMPDIR
# build module using akmod
akmods_echo_plymouth 1 "akmod: Building ${this_kmodsrpm}..."
akmods_echo 1 4 "Building RPM using the command '/usr/sbin/akmodsbuild --kernels ${this_kernelver} ${this_kmodsrpm}'"
/sbin/runuser -s /bin/bash -c "/usr/sbin/akmodsbuild --quiet --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
sed -e "s|^|$(date +%Y/%m/%d\ %H:%M:%S) akmodsbuild: |" "${tmpdir}"/akmodsbuild.log >> "${kmodlogfile}"
fi
# result
if (( returncode != 0 )) ; then
if [[ -n "${continue_line}" ]] ; then
akmods_echo 1 2 --failure
fi
akmods_echo_plymouth 0 ""
akmods_echo_plymouth 1 "akmod: Building ${this_kmodsrpm} failed!"
sleep 5
akmods_echo 2 1 "Building rpms failed; see /var/cache/akmods/${this_kmodname}/${this_kmodverrel}-for-${this_kernelver}.failed.log for details"
cp -fl "${kmodlogfile}" "/var/cache/akmods/${this_kmodname}/${this_kmodverrel}-for-${this_kernelver}.failed.log"
kmodlogfile=""
remove_tmpdir
return 4
fi
# dnf/yum install - repository disabled on purpose see rfbz#3350
akmods_echo_plymouth 0 ""
akmods_echo_plymouth 1 "akmod: Installing ${this_kmodsrpm}..."
akmods_echo 1 4 "Installing newly built rpms"
local -a rpm_paths
mapfile -t rpm_paths < <(find "${tmpdir}results" -type f -name '*.rpm' | grep -v debuginfo)
if [[ -f /usr/bin/dnf ]] ; then
akmods_echo 1 4 "DNF detected"
dnf -y "${pkg_install:-install}" --nogpgcheck --disablerepo='*' "${rpm_paths[@]}" >> "${kmodlogfile}" 2>&1
else
akmods_echo 1 4 "DNF not found, using YUM instead."
yum -y "${pkg_install:-install}" --nogpgcheck --disablerepo='*' "${rpm_paths[@]}" >> "${kmodlogfile}" 2>&1
fi
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 [[ -n "${continue_line}" ]] ; then
akmods_echo 1 2 --failure
fi
akmods_echo_plymouth 0 ""
akmods_echo_plymouth 1 "akmod: Installing ${this_kmodsrpm} failed!"
sleep 5
akmods_echo 2 1 "Could not install newly built RPMs. You can find them and the logfile in:"
akmods_echo 2 1 "/var/cache/akmods/${this_kmodname}/${this_kmodverrel}-for-${this_kernelver}.failed.log"
cp -fl "${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 -fl "${kmodlogfile}" "/var/cache/akmods/${this_kmodname}/${this_kmodverrel}-for-${this_kernelver}.log"
kmodlogfile=""
remove_tmpdir
akmods_echo_plymouth 0 ""
return 0
}
check_kmod_up2date()
{
local this_kernelver=${1}
local this_kmodname=${2}
# with --rebuild we should always build
if [[ -n "${rebuild}" ]]; then
return 1
fi
local kmodpackage_file
kmodpackage_file="$(modinfo "${this_kmodname}" -k "${this_kernelver}" -n 2>/dev/null)"
# kmod present, even with weak-modules?
if [[ ! -n "${kmodpackage_file}" ]] && [[ ! -d /lib/modules/${this_kernelver}/extra/${this_kmodname}/ ]] ; then
# build it
return 1
fi
# special case where part of the kmod is mainlined using $this_kmodname
# making $kmodpackage_file non zero when the kmod is not install yet
if [[ "${kmodpackage_file}" == "/lib/modules/${this_kernelver}/"* ]] && \
[[ ! -d /lib/modules/${this_kernelver}/extra/${this_kmodname}/ ]] ; then
# build it
return 1
fi
# kmod up2date?
local kmodpackage
# Weak module symlink case
if [ -n "${kmodpackage_file}" ] && [ -h "${kmodpackage_file}" ] && echo "${kmodpackage_file}" | grep -q "weak-updates" ; then
kmodpackage="$(rpm -qf "$(readlink -e "${kmodpackage_file}")" 2> /dev/null)"
# Regular module file case
else
kmodpackage="$(rpm -qf "/lib/modules/${this_kernelver}/extra/${this_kmodname}/" 2> /dev/null)"
fi
if [[ ! -n "${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
kmodver=$(rpm -q --qf '%{EPOCH}:%{VERSION}-%{RELEASE}\n' "${kmodpackage}" | sed 's|(none)|0|; s!\.\(fc\|el\|lvn\)[0-9]*!!g')
local akmodver
akmodver=$(rpm -qp --qf '%{EPOCH}:%{VERSION}-%{RELEASE}\n' /usr/src/akmods/"${this_kmodname}"-kmod.latest | sed 's|(none)|0|; s!\.\(fc\|el\|lvn\)[0-9]*!!g')
rpmdev-vercmp "${kmodver}" "${akmodver}" &>/dev/null
local retvalue=$?
if [[ "$retvalue" == 0 ]] ; then
# Versions are the same. Nothing to do.
return 0
elif [[ "$retvalue" == 11 ]] ; then
# kmod is newer, nothing to do.
return 0
elif [[ "$retvalue" == 12 ]] ; then
# akmod is newer, need to build kmod.
return 1
else
# Something went wrong
akmods_echo 1 2 -n "Error: Could not determine if akmod is newer than the installed kmod"
akmods_echo 1 2 --failure
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
this_kmodname="$(basename "${akmods_kmodfile%%-kmod.latest}")"
# actually check this akmod?
if [[ -n "${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 [[ -n "${continue_line}" ]] ; then
akmods_echo 1 2 --success
# if the files for building modules are not available 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 -n "Is the correct kernel-devel package installed?"
akmods_echo 1 2 --failure
return 1
fi
fi
local this_kmodverrel
this_kmodverrel="$(rpm -qp --qf '%{VERSION}-%{RELEASE}' "${akmods_kmodfile}" | sed 's!\.\(fc\|el\|lvn\)[0-9]*!!g' )"
if [[ ! -n "${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"
buildinstall_kmod "${this_kernelver}" "${this_kmodname}" "${akmods_kmodfile}" "${this_kmodverrel}"
local returncode=$?
if [[ "$returncode" == "0" ]] ; then
akmods_echo 1 2 --success
local somesucceeded="true"
elif [[ "$returncode" == "8" ]] ; then
akmods_echo 1 2 --failure "New kmod RPM was built but could not be installed."
else
local somefailed="true"
fi
fi
fi
done
if [[ -n "${continue_line}" ]] ; then
akmods_echo 1 2 --success
elif [[ -n "${someignored}" ]] || [[ -n "${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
# akmods for newly installed akmod rpms as wells as akmods.service run
# after udev and systemd-modules-load.service have tried to load modules
if [[ -n "${somesucceeded}" ]] && [[ "${this_kernelver}" == "$(uname -r)" ]] ; then
find /sys/devices -name modalias -print0 | xargs -0 cat | xargs modprobe -a -b -q
if [ -f /usr/bin/systemctl ] ; then
systemctl restart systemd-modules-load.service
fi
fi
}
myprog_help ()
{
echo "Checks the akmod packages and rebuilds them if needed"
echo $'\n'"Usage: ${myprog} [OPTIONS]"
echo $'\n'"Options:"
echo " --force -- try all, even if they failed earlier"
echo " --kernels <kernel> -- build and install only for kernel <kernel>"
echo " (formatted the same as 'uname -r' would produce)"
echo " --rebuild -- rebuild all, even if they are up to date"
echo " --akmod <akmod> -- build and install only akmod <akmod>"
}
# first parse command line options
while [ "${1}" ] ; do
case "${1}" in
--kernel|--kernels)
shift
if [[ ! -n "${1}" ]] ; then
echo "ERROR: Please provide the kernel-version to build for together with --kernel" >&2
exit 1
fi
if ! check_kernel_devel "${1}" ; then
echo "ERROR: kernel or kernel-devel required for ${1}" >&2
exit 1
fi
# overwrites the default:
if [[ ! -n "${kernels}" ]] ; then
kernels="${1}"
else
kernels="${kernels} ${1}"
fi
# an try to build, even if we tried already
alwaystry=true
shift
;;
--akmod|--kmod)
shift
if [[ ! -n "${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-init)
# just in case: remove stale lockfile if it exists:
rm -f /var/cache/akmods/.lockfile
# Clean old logs and rpm files from no more installed kmod
# packages.
cleanup_cachedir
# akmods --from-init only operates on current kernel
kernels="$(uname -r)"
shift
;;
--from-posttrans|--from-kernel-posttrans|--from-akmod-posttrans)
# ignored
shift
;;
--rebuild)
rebuild=true
pkg_install=reinstall
shift
;;
--verbose)
(( verboselevel++ ))
shift
;;
--quiet)
(( 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
check_plymouth
# sanity checks
init
# only check for default_kernel if no value have been parsed
if [ -z "${kernels}" ] ; then
check_default_kernel
fi
# go
for kernel in ${kernels} ; do
check_kmods "${kernel}"
done
# finished :)
finally 0

View file

@ -1,3 +0,0 @@
[Unit]
Wants=akmods-keygen@.service
PartOf=akmods.service

View file

@ -1,11 +0,0 @@
[Unit]
Description=Akmods Secure boot MOK Key Generation
ConditionFileNotEmpty=|!/etc/pki/akmods/certs/public_key.der
ConditionFileNotEmpty=|!/etc/pki/akmods/private/private_key.priv
[Service]
Type=oneshot
ExecStart=/usr/sbin/kmodgenca -a
[Install]
WantedBy=akmods-keygen.target

View file

@ -1,588 +0,0 @@
#!/bin/bash
# NAME: 'kmodgenca'
# PURPOSE: Helper script to create CA/key pair to sign modules.
# Copyright (c) 2017 Stanislas Leduc <stanislas.leduc@balinor.net>
# Copyright (c) 2018-2019 Nicolas Viéville <nicolas.vieville@uphf.fr>
# Copyright (c) 2024 Rohan Barar <rohan.barar@gmail.com>
################################################################################
# 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.
################################################################################
# EXIT STATUS CODES AND DESCRIPTIONS
# 0 - SUCCESS
# 1 - INSUFFICIENT PRIVILEGES
# 2 - INVALID COMMAND LINE ARGUMENT
# 3 - BROKEN SYMLINKS TO DEFAULT KEY PAIR
# 4 - MISSING CACERT CONFIGURATION TEMPLATE
# 5 - FAILED TO READ CA CERTIFICATE CONFIGURATION TEMPLATE
# 6 - FAILED TO WRITE CA CERTIFICATE CONFIGURATION FILE
# 7 - UNSUCCESSFUL OPENSSL KEY PAIR CREATION COMMAND
# 8 - FAILED TO CREATE KEY PAIR FILES
# ENFORCE STRICT ERROR HANDLING
# - Exit script on error.
# - Ensure pipelines fail on the first error.
set -eo pipefail
# DECLARE CONSTANTS
# Script Information
readonly SCRIPT_NAME="kmodgenca"
readonly SCRIPT_VERSION="0.6.0"
# Directories
readonly AKMODS_DIR="/etc/pki/akmods"
readonly PRIVATE_KEY_DIR="${AKMODS_DIR}/private"
readonly PUBLIC_KEY_DIR="${AKMODS_DIR}/certs"
# Paths
readonly PRIVATE_KEY_PATH="${PRIVATE_KEY_DIR}/private_key.priv"
readonly PUBLIC_KEY_PATH="${PUBLIC_KEY_DIR}/public_key.der"
readonly CACERT_CONFIG_PATH="${AKMODS_DIR}/cacert.config"
readonly RESTORECON_PATH="/usr/sbin/restorecon"
# ANSI
readonly BOLD_RED_TEXT="\e[1;31m"
readonly BOLD_YELLOW_TEXT="\e[1;33m"
readonly BOLD_GREEN_TEXT="\033[1;32m"
readonly BOLD_BLUE_TEXT="\e[1;34m"
readonly BOLD_GREY_TEXT="\e[1;37m"
readonly CLEAR_TEXT="\e[0m"
# DECLARE VARIABLES
# Command Line Argument Flags
FORCE_BUILD=0
AUTOMATIC_BUILD=0
SHOW_HELP=0
SHOW_VER=0
BAD_ARGS=0
# Unique New Key Pair Name (Hostname + UNIX/POSIX Timestamp + Dashless UUID)
cert_hostname="${HOSTNAME}"
KEYNAME="${cert_hostname:0:44}_$(date +%s)_$(uuidgen | awk -F '-' '{print $1}')"
# Other
AUTOMATIC_BUILD_OPTION=""
# FUNCTIONS
function help() {
echo -e "${BOLD_GREY_TEXT}KMODGENCA HELP${CLEAR_TEXT}"
echo "Creates a Certificate Authority (CA) and key pair for module signing."
echo "Private keys are created in: '${PRIVATE_KEY_DIR}'."
echo "Public keys (certificates) are created in: '${PUBLIC_KEY_DIR}'."
echo -e "\nUsage: ${SCRIPT_NAME} [OPTIONS]"
echo -e "\nOptions:"
echo " -a, --auto Utilise default values for 'cacert.config'."
echo " -f, --force Create CA/key pair even if one already exists."
echo " -h, --help Display this help message."
echo " -V, --version Display script version information."
echo ""
}
function check_root() {
# Notify user.
echo -e "${BOLD_BLUE_TEXT}INFO:${CLEAR_TEXT} CHECKING FOR ELEVATED PRIVILEGES..."
if [ "$EUID" -ne 0 ]; then
echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} INSUFFICIENT PRIVILEGES!" >&2
echo "Please run the command using 'sudo' or as root." >&2
echo "Quitting." >&2
exit 1
fi
}
function parse_arguments() {
if [ $# -gt 0 ]; then
while [ "$1" ] ; do
case "$1" in
-a|--auto)
AUTOMATIC_BUILD=1
shift
;;
-f|--force)
FORCE_BUILD=1
shift
;;
-h|--help)
SHOW_HELP=1
shift
;;
-V|--version)
SHOW_VER=1
shift
;;
-*)
# Handle combined single-letter options.
for (( i=1; i<${#1}; i++ )); do
case "${1:$i:1}" in
a)
AUTOMATIC_BUILD=1
;;
f)
FORCE_BUILD=1
;;
h)
SHOW_HELP=1
;;
V)
SHOW_VER=1
;;
*)
echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} INVALID OPTION '${1:$i:1}' in '${1}'." >&2
BAD_ARGS=1
;;
esac
done
shift
;;
*)
echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} INVALID OPTION '${1}'." >&2
BAD_ARGS=1
shift
;;
esac
done
fi
# Display help message and then exit in the event of invalid argument(s).
if [[ "$BAD_ARGS" -eq 1 ]]; then
echo "" >&2
help >&2
echo "Quitting." >&2
exit 2
fi
# Display script help information if requested.
if [[ "$SHOW_HELP" -eq 1 ]]; then
help
fi
# Display script version information if requested.
if [[ "$SHOW_VER" -eq 1 ]]; then
echo "${SCRIPT_NAME} v${SCRIPT_VERSION}"
fi
# Exit script if version and/or help information requested.
if [ "$SHOW_VER" -eq 1 ] || [ "$SHOW_HELP" -eq 1 ]; then
if [ "$AUTOMATIC_BUILD" -eq 1 ]; then
echo -e "${BOLD_YELLOW_TEXT}WARNING:${CLEAR_TEXT} IGNORING '-a' (--auto)." >&2
fi
if [ "$FORCE_BUILD" -eq 1 ]; then
echo -e "${BOLD_YELLOW_TEXT}WARNING:${CLEAR_TEXT} IGNORING '-f' (--force)." >&2
fi
exit 0
fi
# Warn user regarding forced builds.
if [[ "$FORCE_BUILD" -eq 1 ]]; then
echo -e "${BOLD_YELLOW_TEXT}WARNING:${CLEAR_TEXT} FORCED BUILD SELECTED. KEY PAIR OVERWRITE MAY OCCUR!" >&2
fi
# Warn user regarding automatic builds.
if [[ "$AUTOMATIC_BUILD" -eq 1 ]]; then
echo -e "${BOLD_YELLOW_TEXT}WARNING:${CLEAR_TEXT} AUTOMATIC BUILD SELECTED. USING DEFAULT VALUES FOR CA/KEY PAIR CREATION." >&2
fi
}
function check_broken_key_pair() {
# Check for broken non-selected key pairs.
local unmatched_public_key_paths=()
local unmatched_private_key_paths=()
# Store paths of public and private keys.
local public_key_paths=()
local private_key_paths=()
# Note: Requires superuser permissions (i.e., sudo).
mapfile -t public_key_paths < <(find "$PUBLIC_KEY_DIR" -maxdepth 1 -name "*.der")
mapfile -t private_key_paths < <(find "$PRIVATE_KEY_DIR" -maxdepth 1 -name "*.priv")
# Find public/private keys without corresponding private/public keys.
local key_file_path
for key_file_path in "${public_key_paths[@]}"; do
# Skip symlink.
if [[ "$key_file_path" == "$PUBLIC_KEY_PATH" ]]; then
continue
fi
# Remove file extension.
local public_key_name
public_key_name="$(basename "$key_file_path")"
public_key_name="${public_key_name%.*}"
# Check if the corresponding private key exists.
local found=0
for private_key_path in "${private_key_paths[@]}"; do
if [[ "$private_key_path" == "${PRIVATE_KEY_DIR}/${public_key_name}.priv" ]]; then
found=1
break
fi
done
# Store public key file name (with extension) if unpaired.
if [[ "$found" -eq 0 ]]; then
unmatched_public_key_paths+=("$key_file_path")
fi
done
for key_file_path in "${private_key_paths[@]}"; do
# Skip symlink.
if [[ "$key_file_path" == "$PRIVATE_KEY_PATH" ]]; then
continue
fi
# Remove file extension.
local private_key_name
private_key_name="$(basename "$key_file_path")"
private_key_name="${private_key_name%.*}"
# Check if the corresponding public key exists.
local found=0
for public_key_path in "${public_key_paths[@]}"; do
if [[ "$public_key_path" == "${PUBLIC_KEY_DIR}/${private_key_name}.der" ]]; then
found=1
break
fi
done
# Store private key file name (with extension) if unpaired.
if [[ "$found" -eq 0 ]]; then
unmatched_private_key_paths+=("$key_file_path")
fi
done
# Check if isolated keys were detected.
if [[ ${#unmatched_private_key_paths[@]} -gt 0 || ${#unmatched_public_key_paths[@]} -gt 0 ]]; then
echo -e "${BOLD_YELLOW_TEXT}WARNING:${CLEAR_TEXT} SOME KEY PAIRS ARE BROKEN!" >&2
# Notify user regarding isolated public keys.
if [[ ${#unmatched_public_key_paths[@]} -gt 0 ]]; then
echo "Isolated Public Keys:" >&2
local isolated_pub_key_path
for isolated_pub_key_path in "${unmatched_public_key_paths[@]}"; do
echo " ${isolated_pub_key_path}" >&2
done
echo "" >&2
fi
# Notify user regarding isolated private keys.
if [[ ${#unmatched_private_key_paths[@]} -gt 0 ]]; then
echo "Isolated Private Keys:" >&2
local isolated_pri_key_path
for isolated_pri_key_path in "${unmatched_private_key_paths[@]}"; do
echo " ${isolated_pri_key_path}" >&2
done
echo "" >&2
fi
fi
# Terminate the script when:
# 1. A certificate (public key) OR private key exists (but not both), AND
# 2. A forced rebuild was not requested (i.e., 'FORCE_BUILD' is NOT '1')
# Check for broken symlinks to the currently selected pair of keys.
# Note: Requires superuser permissions (i.e. sudo).
# shellcheck disable=SC2155
local pub_key_exists=$(readlink -e "$PUBLIC_KEY_PATH" &>/dev/null && echo 1 || echo 0)
# Note: Requires superuser permissions (i.e. sudo).
# shellcheck disable=SC2155
local pri_key_exists=$(readlink -e "$PRIVATE_KEY_PATH" &>/dev/null && echo 1 || echo 0)
if [[ "$pub_key_exists" -ne "$pri_key_exists" && "$FORCE_BUILD" -eq 0 ]]; then
# Notify user.
echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} BROKEN SYMLINK(S) TO THE DEFAULT KEY PAIR!" >&2
echo "Valid symlinks to a public and private key must exist." >&2
echo "" >&2
# Dynamic status output with colours.
echo -e "${PUBLIC_KEY_PATH}: $( [[ $pub_key_exists -eq 1 ]] && echo -e "${BOLD_GREEN_TEXT}WORKING${CLEAR_TEXT}" || echo -e "${BOLD_RED_TEXT}BROKEN${CLEAR_TEXT}" )" >&2
echo -e "${PRIVATE_KEY_PATH}: $( [[ $pri_key_exists -eq 1 ]] && echo -e "${BOLD_GREEN_TEXT}WORKING${CLEAR_TEXT}" || echo -e "${BOLD_RED_TEXT}BROKEN${CLEAR_TEXT}" )" >&2
echo "" >&2
echo "Quitting." >&2
# Exit script.
exit 3
fi
}
function check_existing_key_pair() {
# Notify user.
echo -e "${BOLD_BLUE_TEXT}INFO:${CLEAR_TEXT} CHECKING FOR AN EXISTING KEY PAIR..."
# Terminate the script when:
# 1. Both a certificate (public key) and private key already exist, AND
# 2. A forced rebuild was not requested (i.e., 'FORCE_BUILD' is NOT '1')
# Note: This approach will return '1' in the event of a broken symlink.
# Note: Requires superuser permissions (i.e. sudo).
if readlink -e "$PUBLIC_KEY_PATH" &>/dev/null && \
readlink -e "$PRIVATE_KEY_PATH" &>/dev/null && \
[ "$FORCE_BUILD" -eq 0 ]; then
# Notify user.
echo -e "${BOLD_YELLOW_TEXT}WARNING:${CLEAR_TEXT} EXISTING KEY PAIR." >&2
echo "Please specify argument '--force' to overwrite the existing key pair." >&2
echo "Quitting." >&2
# Exit script.
exit 0
fi
}
function set_key_pair_name() {
if [ "$AUTOMATIC_BUILD" -eq 0 ]; then
while true; do
local key_pair_file_name=""
local valid_name=1
# Request key pair name from user.
# shellcheck disable=SC2162
read -p "Key Pair Name: " key_pair_file_name
# Check for empty string.
if [[ -z $(echo "$key_pair_file_name" | xargs) ]]; then
valid_name=0
echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} NAME MUST NOT BE EMPTY.\n" >&2
fi
# Ensure name is not '.' or '..'.
if [[ $(echo "$key_pair_file_name" | xargs) == "." ]] || [[ $(echo "$key_pair_file_name" | xargs) == ".." ]]; then
valid_name=0
echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} NAME MUST NOT BE '.' OR '..'.\n" >&2
fi
# Ensure name is not longer than 255 characters.
if [ "$(echo "$key_pair_file_name" | xargs | awk '{print length}')" -gt 255 ]; then
valid_name=0
echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} NAME MUST NOT BE LONGER THAN 255 CHARACTERS.\n" >&2
fi
# Ensure name only contains valid characters.
# - Letters (A-Z) (a-z)
# - Numbers (0-9)
# - Special
# - Period ('.')
# - Underscore ('_')
# - Hyphen ('-')
if ! [[ $(echo "$key_pair_file_name" | xargs) =~ ^[0-9a-zA-Z._-]+$ ]]; then
# Avoid triggering on an empty string.
if [[ -n $(echo "$key_pair_file_name" | xargs) ]]; then
valid_name=0
# Inform user of illegal characters within provided name.
local illegal_chars
illegal_chars=$(echo "$key_pair_file_name" | awk -F '' '{for(i=1;i<=NF;i++) if ($i !~ /^[0-9a-zA-Z._-]$/) print $i}' | sort -u | tr -d '\n')
echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} NAME MUST NOT CONTAIN ILLEGAL CHARACTERS." >&2
echo -e "Illegal characters in provided name:" >&2
for (( i=0; i<${#illegal_chars}; i++ )); do
echo "- '${illegal_chars:i:1}'" >&2
done
echo -e "\nPlease ensure the name only contains letters, numbers, periods, underscores and hyphens.\n" >&2
fi
fi
# Ensure key pair with same name does not exist.
if [ -f "${PUBLIC_KEY_DIR}/${key_pair_file_name}.der" ] || [ -f "${PRIVATE_KEY_DIR}/${key_pair_file_name}.priv" ]; then
valid_name=0
echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} EXISTING KEY PAIR WITH SAME NAME.\n" >&2
fi
# Break the loop if a valid name was provided.
if [ "$valid_name" -eq 1 ]; then
break
fi
done
# Update global key pair name variable.
KEYNAME="$key_pair_file_name"
else
# Handle the extremely unlikely occurrence of a key pair name conflict with an existing key pair.
while [ -f "${PUBLIC_KEY_DIR}/${KEYNAME}.der" ]; do
KEYNAME="${cert_hostname:0:44}_$(date +%s)_$(uuidgen | awk -F '-' '{print $1}')"
done
fi
}
function create_cacert_config() {
# Notify user.
echo -e "${BOLD_BLUE_TEXT}INFO:${CLEAR_TEXT} UPDATING CACERT CONFIGURATION FILE AT '${CACERT_CONFIG_PATH}'..."
# Check if the cacert configuration template exists.
if [[ -f "${CACERT_CONFIG_PATH}.in" ]]; then
local sed_output=""
local sed_exit_status=0
if [ "$AUTOMATIC_BUILD" -eq 1 ]; then
# Set '-batch' argument.
AUTOMATIC_BUILD_OPTION="-batch"
local cert_country_code=$(locale country_ab2)
if [[ -z ${cert_country_code} ]]; then
echo -e "${BOLD_YELLOW_TEXT}WARNING:${CLEAR_TEXT} COULD NOT DETECT COUNTRY CODE FROM LOCALE; USING FALLBACK VALUE: US" >&2
cert_country_code=US
fi
# Utilise default values if 'AUTOMATIC_BUILD' is equal to '1'.
# - Set OpenSSL field values.
# - Comment default and min/max values.
sed_output=$(sed -e "s#\(0.organizationName *= \).*#\1${cert_hostname}#" \
-e "s#\(organizationalUnitName *= \).*#\1${cert_hostname}#" \
-e "s#\(emailAddress *= \).*#\1akmods@${cert_hostname}#" \
-e "s#\(localityName *= \).*#\1None#" \
-e "s#\(stateOrProvinceName *= \).*#\1None#" \
-e "s#\(countryName *= \).*#\1${cert_country_code}#" \
-e "s#\(commonName *= \).*#\1${KEYNAME}#" \
-e "s/^[^#]*_default *= /#&/" \
-e "s/^[^#]*_min/#&/" \
-e "s/^[^#]*_max/#&/" "${CACERT_CONFIG_PATH}.in")
sed_exit_status=$?
else
# Request user enter values manually if 'AUTOMATIC_BUILD' is equal to '0'.
# Request OpenSSL prompt user for values later.
sed_output=$(sed -e "s#\(prompt *= \).*#\1yes#" "${CACERT_CONFIG_PATH}.in")
sed_exit_status=$?
fi
# Check if 'sed' command failed.
if [ "$sed_exit_status" -ne 0 ]; then
echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} FAILED TO READ CACERT CONFIGURATION TEMPLATE at '${CACERT_CONFIG_PATH}.in'." >&2
echo "Quitting." >&2
exit 5
else
# Note: Requires superuser permissions (i.e. sudo).
if ! echo "$sed_output" > "$CACERT_CONFIG_PATH"; then
echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} FAILED TO WRITE CACERT CONFIGURATION FILE to '${CACERT_CONFIG_PATH}'." >&2
echo "Quitting." >&2
exit 6
fi
fi
else
echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} MISSING CACERT CONFIGURATION TEMPLATE!" >&2
echo "Failed to locate the CAcert configuration template at '${CACERT_CONFIG_PATH}.in'." >&2
echo "Quitting." >&2
exit 4
fi
}
function create_new_key_pair() {
# Notify user.
echo -e "${BOLD_BLUE_TEXT}INFO:${CLEAR_TEXT} CREATING NEW KEY PAIR..."
# Prepare an OpenSSL command to generate the key pair.
local key_pair_generation_command=(
"openssl req" # Request new certificate
"-x509" # X.509 certificate type
"-new" # New key pair
"-nodes" # No DES
"-utf8" # UTF-8 encoding
"-sha256" # SHA-256 hash algorithm
"-days" "3650" # 10 year cert validity
"${AUTOMATIC_BUILD_OPTION}" # Empty or "-batch"
"-config" "${CACERT_CONFIG_PATH}" # Configuration file path
"-outform" "DER" # DER output format
"-out" "${PUBLIC_KEY_DIR}/${KEYNAME}.der" # Public key output path
"-keyout" "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" # Private key output path
)
# Execute the key pair generation command within the 'akmods' group context.
# Ensure 'rw-rwx---' permissions.
# Note: Requires superuser permissions (i.e. sudo).
if sg akmods -c "umask 037 && ${key_pair_generation_command[*]}"; then
# Check if both a public and a private key file were created.
if [[ ! -f "${PUBLIC_KEY_DIR}/${KEYNAME}.der" || ! -f "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" ]]; then
echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} KEY PAIR CREATION FAILED!" >&2
echo "The OpenSSL key pair generation command ran, but key files were not created." >&2
echo "Quitting." >&2
exit 8
fi
else
echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} KEY PAIR CREATION FAILED!" >&2
echo "The OpenSSL key pair generation command did not complete successfully." >&2
echo "Quitting." >&2
exit 7
fi
}
function set_key_permissions() {
# Notify user.
echo -e "${BOLD_BLUE_TEXT}INFO:${CLEAR_TEXT} SETTING KEY PAIR PERMISSIONS..."
# Ensure that akmods group can read keys.
# Note: Requires superuser permissions (i.e. sudo).
chmod g+r "${PUBLIC_KEY_DIR}/${KEYNAME}.der"
chmod g+r "${PRIVATE_KEY_DIR}/${KEYNAME}.priv"
# Sanitise permissions.
# Note: Requires superuser permissions (i.e. sudo).
if [[ -x "$RESTORECON_PATH" ]] ; then
$RESTORECON_PATH "${PUBLIC_KEY_DIR}/${KEYNAME}.der"
$RESTORECON_PATH "${PRIVATE_KEY_DIR}/${KEYNAME}.priv"
fi
}
function update_key_symlinks() {
# Notify user.
echo -e "${BOLD_BLUE_TEXT}INFO:${CLEAR_TEXT} UPDATING KEY PAIR SYMLINKS..."
# Note: Requires superuser permissions (i.e. sudo).
ln -nsf "${PUBLIC_KEY_DIR}/${KEYNAME}.der" "$PUBLIC_KEY_PATH"
ln -nsf "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" "$PRIVATE_KEY_PATH"
chown -h root:akmods "$PUBLIC_KEY_PATH"
chown -h root:akmods "$PRIVATE_KEY_PATH"
}
# SCRIPT MAINLINE
# Parse any supplied arguments.
parse_arguments "$@"
# Check for elevated privileges.
check_root
# Check for broken key pairs.
check_broken_key_pair
# Check for existing key pair.
check_existing_key_pair
# Set key pair name.
set_key_pair_name
# Create 'cacert.config' using template file 'cacert.config.in'.
create_cacert_config
# Create new key pair.
create_new_key_pair
# Set permissions and sanitise keys.
set_key_permissions
# Update symlink to use new key pair.
update_key_symlinks
# Print completion messages.
echo -e "\n${BOLD_GREEN_TEXT}SUCCESS!${CLEAR_TEXT}"
echo "Public Key (Certificate) created at: ${PUBLIC_KEY_DIR}/${KEYNAME}.der"
echo "Private Key created at: ${PRIVATE_KEY_DIR}/${KEYNAME}.priv"
echo -e "\nSymlinks:"
echo "${KEYNAME}.der -> ${PUBLIC_KEY_PATH}"
echo "${KEYNAME}.priv -> ${PRIVATE_KEY_PATH}"
# Exit script.
exit 0

View file

@ -1,102 +0,0 @@
#!/bin/bash -
############################################################################
#
# akmods - Rebuilds and install akmod RPMs
# Copyright (c) 2007, 2008 Thorsten Leemhuis <fedora@leemhuis.info>
# Copyright (c) 2018 Nicolas Chauvet <kwizart@gmail.com>
#
# 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="akmods-post"
tmpdir=
# Only do %post builds in ostree
if ! grep -q OSTREE_VERSION= /etc/os-release && ! test -f /run/ostree-booted; then
exit 0
fi
kmodname=$1
srpm=$2
finally()
{
# remove tmpfiles
remove_tmpdir
exit "${1:-128}"
}
# Make sure finally() is run regardless of reason for exiting.
trap "finally" ABRT HUP INT QUIT
create_tmpdir()
{
if ! tmpdir="$(mktemp -d -p /tmp "${myprog}.XXXXXXXX")/" ; then
echo "ERROR: failed to create tmpdir." >&2
finally 1
fi
if ! mkdir "${tmpdir}"results ; then
echo "ERROR: failed to create result tmpdir." >&2
finally 1
fi
}
remove_tmpdir()
{
# remove tmpfiles
if [[ -n "${tmpdir}" ]] && [[ -d "${tmpdir}" ]]; then
rm -rf "${tmpdir}"
fi
}
# This is an ostree build, so do build for all
# deployed kernels in the %post
kernels="$(ls /lib/modules)"
create_tmpdir
for kernel in ${kernels} ; do
echo "Building ${srpm} for kernel ${kernel}"
# Note: This builds as root, but this is pretty safe because its happening in the ostree %post sandbox.
# In fact, given that /usr is a rofiles-fuse mount no other user can access /usr in this sandbox anyway.
akmodsbuild --quiet --kernels "${kernel}" --outputdir "${tmpdir}results" --logfile "${tmpdir}/akmodsbuild.log" "${srpm}" 2>&1
returncode=$?
if (( returncode != 0 )); then
finally 1
fi
done
for f in $(find "${tmpdir}results" -type f -name '*.rpm' | grep -v debuginfo) ; do
rpm2cpio "${f}" | cpio --quiet -D / -id
returncode=$?
if (( returncode != 0 )); then
echo "Extracting $f failed:" 2>&1
finally 1
fi
done
for kernel in ${kernels} ; do
depmod -v "${kernel}" 2>&1
done
finally 0

View file

@ -1,31 +0,0 @@
#!/bin/bash
#
# akmods-shutdown - Helper script to build kernel modules on shutdown
# Copyright (c) 2012 Richard shaw <hobbes1069@gmail.com>
#
# 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.
#
echo "This akmods-shutdown script is deprecated and will be removed in the future"
echo "Using akmods instead ..."
sleep 6
/usr/sbin/akmods

View file

@ -1,14 +0,0 @@
[Unit]
Description=Builds and install new kmods from akmod packages
Before=shutdown.service reboot.service halt.service
Conflicts=shutdown.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/true
ExecStop=-/usr/sbin/akmods
TimeoutStopSec=5min
[Install]
WantedBy=multi-user.target

View file

@ -1,2 +0,0 @@
# See tmpfiles.d(5) for details
d /run/akmods 0770 root akmods -

View file

@ -1,12 +0,0 @@
[BUGS]
https://bugz.fedoraproject.org/akmods
[REPORTING BUGS]
Submit a bug against the akmods component at:
.br
https://bugzilla.redhat.com/enter_bug.cgi?product=Fedora
[AUTHOR]
Thorsten Leemhuis <fedora [AT] leemhuis [DOT] info>
[MAINTAINER]
Richard Shaw <hobbes1069 [AT] gmail [DOT] com>
[SEE ALSO]
http://rpmfusion.org/Packaging/KernelModules/Akmods

View file

@ -1,8 +0,0 @@
/var/log/akmods/akmods.log {
monthly
rotate 12
missingok
notifempty
create 644 root root
su root akmods
}

View file

@ -1,3 +0,0 @@
addFilter("W: non-standard-.*")
addFilter("W: no-manual-page-for-binary .*")
addFilter("W: empty-%postun")

View file

@ -1,14 +0,0 @@
[Unit]
Description=Builds and install new kmods from akmod packages
ConditionPathExists=!/run/ostree-booted
Before=display-manager.service
After=akmods-keygen.target
Wants=akmods-keygen.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/sbin/akmods --from-init
[Install]
WantedBy=multi-user.target

View file

@ -1,202 +0,0 @@
Name: akmods
Version: 0.6.2
Release: %autorelease
Summary: Automatic kmods build and install tool
License: MIT
URL: http://rpmfusion.org/Packaging/KernelModules/Akmods
# We are upstream, these files are maintained directly in pkg-git
Source0: 95-akmods.preset
Source1: akmods
Source2: akmodsbuild
Source3: akmods.h2m
Source6: akmods.service
Source7: akmods-shutdown
Source8: akmods-shutdown.service
Source9: README
Source10: LICENSE
Source11: akmods@.service
Source12: akmods-ostree-post
Source13: 95-akmodsposttrans.install
Source14: akmods.log
Source15: README.secureboot
Source16: cacert.config.in
Source17: akmods-kmodgenca
Source18: akmods-keygen.target
Source19: akmods-keygen@.service
Source20: %{name}-tmpfiles.conf
Source21: akmods.sysusers.conf
BuildArch: noarch
BuildRequires: help2man
# Needed for older branches el8+, noop on f43+
%{?sysusers_requires_compat}
# not picked up automatically
Requires: %{_bindir}/flock
Requires: %{_bindir}/time
# needed for actually building kmods:
Requires: %{_bindir}/rpmdev-vercmp
Requires: kmodtool >= 1.1-1
# needed to create CA/Keypair to sign modules
Requires: openssl
# this should track in all stuff that is normally needed to compile modules:
Requires: bzip2 coreutils diffutils file findutils gawk gcc grep
Requires: gzip make sed tar unzip util-linux rpm-build
# On EL, kABI list was renamed
%if 0%{?rhel}
Requires: (kernel-abi-stablelists if kernel-core)
%endif
# We use a virtual provide that would match either
# kernel-devel or kernel-PAE-devel
Requires: kernel-devel-uname-r
# kernel-devel-matched enforces the same kernel version as the -devel
%if 0%{?fedora} || 0%{?rhel} >= 9
Requires: (kernel-debug-devel-matched if kernel-debug-core)
Requires: (kernel-devel-matched if kernel-core)
%else
Suggests: (kernel-debug-devel if kernel-debug-core)
Suggests: (kernel-devel if kernel-core)
%endif
Suggests: (kernel-rt-devel if kernel-rt)
# we create a special user that used by akmods to build kmod packages
# systemd unit requirements.
BuildRequires: systemd
Requires(post): systemd
Requires(preun): systemd
Requires(postun): systemd
# Optional but good to have on recent kernel
Requires: pkgconfig(libelf)
# We need grubby or systemd-boot to know the default kernel
# On EL7 assumes grubby is there by default - rhbz#2124086
%if 0%{?fedora} || 0%{?rhel} > 7
Requires: (grubby or sdubby)
%endif
%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
%setup -q -c -T
cp -p %{SOURCE9} %{SOURCE10} %{SOURCE15} .
%build
# Nothing to build
%install
mkdir -p %{buildroot}%{_usrsrc}/%{name} \
%{buildroot}%{_sbindir} \
%{buildroot}%{_sysconfdir}/rpm \
%{buildroot}%{_sysconfdir}/pki/%{name}/certs \
%{buildroot}%{_sysconfdir}/pki/%{name}/private \
%{buildroot}%{_sysconfdir}/kernel/postinst.d \
%{buildroot}%{_sysconfdir}/logrotate.d \
%{buildroot}%{_localstatedir}/cache/%{name} \
%{buildroot}%{_localstatedir}/log/%{name} \
%{buildroot}%{_tmpfilesdir}
install -pm 0755 %{SOURCE1} %{buildroot}%{_sbindir}/
install -pm 0755 %{SOURCE2} %{buildroot}%{_sbindir}/
install -pm 0755 %{SOURCE12} %{buildroot}%{_sbindir}/
install -pm 0644 %{SOURCE14} %{buildroot}%{_sysconfdir}/logrotate.d/%{name}
install -pm 0640 %{SOURCE16} %{buildroot}%{_sysconfdir}/pki/%{name}/
install -pm 0755 %{SOURCE17} %{buildroot}%{_sbindir}/kmodgenca
install -pm 0644 %{SOURCE20} %{buildroot}%{_tmpfilesdir}/%{name}.conf
install -dpm 0770 %{buildroot}%{_rundir}/%{name}/
mkdir -p %{buildroot}%{_prefix}/lib/kernel/install.d
install -pm 0755 %{SOURCE13} %{buildroot}%{_prefix}/lib/kernel/install.d/
mkdir -p \
%{buildroot}%{_unitdir} \
%{buildroot}%{_presetdir}
install -pm 0644 %{SOURCE0} %{buildroot}%{_presetdir}/
install -pm 0644 %{SOURCE6} %{buildroot}%{_unitdir}/
install -pm 0755 %{SOURCE7} %{buildroot}%{_sbindir}/
install -pm 0644 %{SOURCE8} %{buildroot}%{_unitdir}/
install -pm 0644 %{SOURCE11} %{buildroot}%{_unitdir}/
install -pm 0644 %{SOURCE18} %{buildroot}%{_unitdir}/
install -pm 0644 %{SOURCE19} %{buildroot}%{_unitdir}/
# Generate and install man pages.
mkdir -p %{buildroot}%{_mandir}/man1
help2man -N -i %{SOURCE3} -s 1 \
-o %{buildroot}%{_mandir}/man1/akmods.1 \
%{buildroot}%{_sbindir}/akmods
help2man -N -i %{SOURCE3} -s 1 \
-o %{buildroot}%{_mandir}/man1/akmodsbuild.1 \
%{buildroot}%{_sbindir}/akmodsbuild
install -m0644 -D %{SOURCE21} %{buildroot}%{_sysusersdir}/akmods.conf
%pre
%sysusers_create_compat %{SOURCE21}
%post
%systemd_post akmods.service
%systemd_post akmods@.service
%systemd_post akmods-shutdown.service
%preun
%systemd_preun akmods.service
%systemd_preun akmods@.service
%systemd_preun akmods-shutdown.service
%postun
%systemd_postun akmods.service
%systemd_postun akmods@.service
%systemd_postun akmods-shutdown.service
%files
%doc README README.secureboot
%license LICENSE
%{_sbindir}/akmodsbuild
%{_sbindir}/akmods
%{_sbindir}/akmods-ostree-post
%{_sbindir}/kmodgenca
%dir %attr(750,root,akmods) %{_sysconfdir}/pki/%{name}/certs
%dir %attr(750,root,akmods) %{_sysconfdir}/pki/%{name}/private
%config(noreplace) %attr(640,root,akmods) %{_sysconfdir}/pki/%{name}/cacert.config.in
%config(noreplace) %{_sysconfdir}/logrotate.d/%{name}
%{_unitdir}/akmods.service
%{_unitdir}/akmods@.service
%{_sbindir}/akmods-shutdown
%{_unitdir}/akmods-shutdown.service
%{_prefix}/lib/kernel/install.d/95-akmodsposttrans.install
%attr(0644,root,root) %{_unitdir}/akmods-keygen.target
%attr(0644,root,root) %{_unitdir}/akmods-keygen@.service
%dir %attr(0770,root,akmods) %{_rundir}/%{name}
%{_tmpfilesdir}/%{name}.conf
# akmods was enabled in the default preset by f28
%if 0%{?rhel}
%{_presetdir}/95-akmods.preset
%else
%exclude %{_presetdir}/95-akmods.preset
%endif
%{_usrsrc}/akmods
%dir %attr(-,akmods,akmods) %{_localstatedir}/cache/akmods
%dir %attr(0775,root,akmods) %{_localstatedir}/log/%{name}
%{_mandir}/man1/*
%{_sysusersdir}/akmods.conf
%changelog
%autochangelog

View file

@ -1,3 +0,0 @@
#Type Name ID GECOS Home directory Shell
g akmods - - - -
u akmods - 'User is used by akmods to build akmod packages' /var/cache/akmods/ -

View file

@ -1,12 +0,0 @@
[Unit]
Description=Builds and install new kmods from akmod for a given kernel
Wants=akmods-keygen.target
After=akmods-keygen.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/systemd-inhibit --mode=block --what=idle:sleep:shutdown --who="akmods" --why="Akmods Transaction running" /usr/sbin/akmods --from-kernel-posttrans --kernels %i
[Install]
WantedBy=multi-user.target

View file

@ -1,365 +0,0 @@
#!/bin/bash
#
# akmodbuild - Helper script for building kernel module SRPMs
# Copyright (c) 2007 Thorsten Leemhuis <fedora@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.6.2"
# defaults that might get overwritten by user:
kernels="$(uname -r)"
numberofjobs=$(grep -c processor /proc/cpuinfo 2> /dev/null)
verboselevel=2
outputdir="${PWD}"
srpms=
init ()
{
## startup checks
# prevent root-usage
if [[ -w /var ]] ; 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 /usr/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 " /usr/lib/modules/${kernel}/build/" >&2
exit 2
fi
done
if [[ ! -n "${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 -p /tmp "${myprog}.XXXXXXXX")" ; then
echo "ERROR: Could create tempdir."
exit 1
fi
if [ -z "${target}" ] ; then
case "${kernels}" in
*x86_64_v4) target=x86_64_v4;;
*x86_64_v3) target=x86_64_v3;;
*x86_64_v2) target=x86_64_v2;;
*armv7hl) target=armv7hl;;
*) target="$(uname -m)" ;;
esac
fi
# buildtree
mkdir "${tmpdir}"/{BUILD,SOURCES,SPECS,SRPMS,RPMS,RPMS/"${target}"}
# logfile
if [[ ! -n "${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 [[ -n "${watch_jobid}" ]] ; then
kill "${watch_jobid}"
fi
if [[ -n "${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 [[ ! -n "${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 -r 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
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 "Successful; "
fi
local rpms_built
rpms_built="$(cd "${tmpdir}"/RPMS/"${target}" || exit ; 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 "Rebuilds kmod SRPM(s)"
echo $'\n'"Usage: ${myprog} [OPTIONS] <SRPMS>"
echo $'\n'"Options:"
echo " -k, --kernels -- build for kernel-versions (output from 'uname -r')"
echo " -l, --logfile <file> -- save rpmbuild 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 " -h, --help -- show usage"
echo " -V, --version -- show version"
}
while [ "${1}" ] ; do
case "${1}" in
-k|--kernels)
shift
if [[ ! -n "${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 [[ ! -n "${1}" ]] ; then
echo "ERROR: Please provide a filename together with --logfile" >&2
exit 1
fi
logfile="${1}"
shift
;;
-o|--outputdir)
shift
if [[ ! -n "${1}" ]] ; then
echo "ERROR: Please provide the output directory together with --outputdir" >&2
exit 1
fi
outputdir="${1}"
shift
;;
-t|--target)
shift
if [[ ! -n "${1}" ]] ; then
echo "ERROR: Please provide the target-arch together with --target" >&2
exit 1
fi
target="${1}"
shift
;;
-v|--verbose)
(( verboselevel++ ))
shift
;;
-q|--quiet)
(( 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

View file

@ -1,41 +0,0 @@
# Default OpenSSL settings and configuration file for kmodgenca
# shell-script.
#
[ req ]
default_bits = 4096
distinguished_name = req_distinguished_name
prompt = no
utf8 = yes
string_mask = utf8only
x509_extensions = req_exts
[ req_distinguished_name ]
# Values settings
#
0.organizationName = Organization Name (eg, company)
organizationalUnitName = Organizational Unit Name (eg, section)
emailAddress = Email Address
emailAddress_max = 64
localityName = Locality Name (eg, city)
stateOrProvinceName = State or Province Name (full name)
countryName = Country Name (2 letter code)
countryName_min = 2
countryName_max = 2
commonName = Common Name (eg, your name or your server\'s hostname)
commonName_max = 64
# Default values
#
0.organizationName_default = akmods local
organizationalUnitName_default = akmods
emailAddress_default = akmods@localhost.localdomain
localityName_default = None
stateOrProvinceName_default = None
countryName_default = XX
commonName_default = akmods local signing CA
[ req_exts ]
basicConstraints = critical,CA:FALSE
keyUsage = digitalSignature
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid

178
changelog
View file

@ -1,178 +0,0 @@
* Fri May 02 2025 Marcel Hetzendorfer <mh7596@gmail.com> - 0.6.0-11
- Show building and installing on plymouth boot screen
* Tue Feb 11 2025 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 0.6.0-10
- Add sysusers.d config file to allow rpm to create users/groups
automatically
* Thu Jan 16 2025 Fedora Release Engineering <releng@fedoraproject.org> - 0.6.0-9
- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild
* Wed Dec 11 2024 Nicolas Chauvet <kwizart@gmail.com> - 0.6.0-8
- Update others hostname occurences
* Tue Dec 10 2024 Nicolas Chauvet <kwizart@gmail.com> - 0.6.0-7
- Drop hostname deps - rhbz#2330137
* Thu Nov 28 2024 Nicolas Chauvet <kwizart@gmail.com> - 0.6.0-6
- Validate or discard default_kernel - rhbz#2270414
* Fri Nov 08 2024 Nicolas Chauvet <kwizart@gmail.com> - 0.6.0-5
- Fix KEYNAME lengh - rhbz#2323702
* Wed Oct 02 2024 Rohan Barar <rohan.barar@gmail.com> - 0.6.0-4
- Add robust missing key pair logic
* Wed Oct 02 2024 Rohan Barar <rohan.barar@gmail.com> - 0.6.0-3
- Improved error handling + Bug fixes
* Tue Oct 01 2024 Rohan Barar <rohan.barar@gmail.com> - 0.6.0-2
- Add check for elevated privileges
* Tue Oct 01 2024 Nicolas Chauvet <kwizart@gmail.com> - 0.6.0-1
- Bump akmods version
* Tue Oct 01 2024 Nicolas Chauvet <kwizart@gmail.com> - 0.5.10-30
- Remove duplicate akmodsposttrans call - rhbz#2011120
* Thu Sep 26 2024 Rohan Barar <rohan.barar@gmail.com> - 0.5.10-29
- Avoid double error on empty user-provided key pair name.
* Thu Sep 26 2024 Rohan Barar <rohan.barar@gmail.com> - 0.5.10-28
- Corrected erroneous code introduced in previous commits.
* Thu Sep 26 2024 Rohan Barar <rohan.barar@gmail.com> - 0.5.10-27
- Fixed typo 'if' to 'fi'.
* Thu Sep 26 2024 Rohan Barar <rohan.barar@gmail.com> - 0.5.10-26
- Added check for existing key pair with same name as user-specified new
key pair name.
* Thu Sep 26 2024 Rohan Barar <rohan.barar@gmail.com> - 0.5.10-25
- Added ability for user to name key pair.
* Sun Sep 22 2024 Rohan Barar <rohan.barar@gmail.com> - 0.5.10-24
- Introduced loop to gracefully handle extremely rare key pair name
collision events.
* Sat Sep 21 2024 Rohan Barar <rohan.barar@gmail.com> - 0.5.10-23
- Refactor key pair naming scheme to enhance robustness + Removed collision
check and key pair backup function due to bug with ':' in file names
alongside superfluous nature of function given improved naming scheme.
* Sat Sep 21 2024 Rohan Barar <rohan.barar@gmail.com> - 0.5.10-22
- Removed 'sudo' prefixes as per request in PR #23.
* Sat Sep 21 2024 Rohan Barar <rohan.barar@gmail.com> - 0.5.10-21
- Further improvements to argument parsing logic.
* Fri Sep 20 2024 Rohan Barar <rohan.barar@gmail.com> - 0.5.10-20
- Improved clarity of exit status code comments.
* Fri Sep 20 2024 Rohan Barar <rohan.barar@gmail.com> - 0.5.10-19
- Revert "Utilise robust shebang." as per request on PR #23.
* Fri Sep 20 2024 Rohan Barar <rohan.barar@gmail.com> - 0.5.10-18
- Added support for combined single-letter arguments + Chowned symlinks.
* Fri Sep 20 2024 Rohan Barar <rohan.barar@gmail.com> - 0.5.10-17
- Improved mokutil error handling + Added sudo prefixes.
* Fri Sep 20 2024 Rohan Barar <rohan.barar@gmail.com> - 0.5.10-16
- Added error handling for failed cacert modification.
* Fri Sep 20 2024 Rohan Barar <rohan.barar@gmail.com> - 0.5.10-15
- Whitespace changes for consistency.
* Fri Sep 20 2024 Rohan Barar <rohan.barar@gmail.com> - 0.5.10-14
- Extract functions to enhance readability + Set 'commonName' to match
'KEYNAME'.
* Fri Sep 20 2024 Rohan Barar <rohan.barar@gmail.com> - 0.5.10-13
- Added logic to detect broken existing key pairs.
* Fri Sep 20 2024 Rohan Barar <rohan.barar@gmail.com> - 0.5.10-12
- Improved user feedback in event of existing key pair.
* Fri Sep 20 2024 Rohan Barar <rohan.barar@gmail.com> - 0.5.10-11
- Updated copyright information.
* Fri Sep 20 2024 Rohan Barar <rohan.barar@gmail.com> - 0.5.10-10
- Various changes to avoid ShellCheck warnings.
* Fri Sep 20 2024 Rohan Barar <rohan.barar@gmail.com> - 0.5.10-9
- Align license to 80 character width.
* Fri Sep 20 2024 Rohan Barar <rohan.barar@gmail.com> - 0.5.10-8
- Utilise robust shebang.
* Fri Sep 20 2024 Rohan Barar <rohan.barar@gmail.com> - 0.5.10-7
- Removed hard-coded paths.
* Fri Aug 23 2024 Nicolas Chauvet <kwizart@gmail.com> - 0.5.10-6
- Fix parsing multiple kernel
* Fri Aug 23 2024 Nicolas Chauvet <kwizart@gmail.com> - 0.5.10-5
- Use check_kernel_devel return code as appropriate
* Fri Aug 23 2024 Nicolas Chauvet <kwizart@gmail.com> - 0.5.10-4
- Change check_kernel_devel() to return instead of exit
* Fri Aug 23 2024 Nicolas Chauvet <kwizart@gmail.com> - 0.5.10-3
- akmods --from-init only operates on current kernel
* Fri Aug 23 2024 Nicolas Chauvet <kwizart@gmail.com> - 0.5.10-2
- Deprecate akmods-shutdown script
* Fri Aug 23 2024 Nicolas Chauvet <kwizart@gmail.com> - 0.5.10-1
- Bump to akmods 0.5.10
* Fri Aug 23 2024 Nicolas Chauvet <kwizart@gmail.com> - 0.5.9-8
- Only check for default_kernel is no value - rhbz#2293047
* Fri Aug 23 2024 Nicolas Chauvet <kwizart@gmail.com> - 0.5.9-7
- Revert "Call Init before the argument parser"
* Fri Aug 23 2024 Nicolas Chauvet <kwizart@gmail.com> - 0.5.9-6
- Switch to use sdubby alternatives to grubby
* Fri Aug 23 2024 Nicolas Chauvet <kwizart@gmail.com> - 0.5.9-5
- Drop older rhel and use -core
* Fri Aug 23 2024 Nicolas Chauvet <kwizart@gmail.com> - 0.5.9-4
- Drop older rhel cases
* Mon Aug 19 2024 Jonathan Wakely <jwakely@fedoraproject.org> - 0.5.9-3
- Fix bug URLs in man page
* Wed Jul 17 2024 Fedora Release Engineering <releng@fedoraproject.org> - 0.5.9-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild
* Thu Jul 04 2024 Nicolas Chauvet <kwizart@gmail.com> - 0.5.9-1
- akmods release 0.5.9
* Thu Jul 04 2024 Hans de Goede <hdegoede@redhat.com> - 0.5.8-10
- Fix intel-ipu6-kmod installation with kernel >= 6.10
* Thu Jul 04 2024 Marius Schwarz <fedoradev@cloud-foo.de> - 0.5.8-9
- Call Init before the argument parser
* Mon Jan 22 2024 Fedora Release Engineering <releng@fedoraproject.org> - 0.5.8-8
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
* Fri Jan 19 2024 Fedora Release Engineering <releng@fedoraproject.org> - 0.5.8-7
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
* Tue Dec 05 2023 Nicolas Chauvet <kwizart@gmail.com> - 0.5.8-6
- Workaround for rhbz#1889136 when localpkg_gpgcheck=True
* Wed Jul 19 2023 Fedora Release Engineering <releng@fedoraproject.org> - 0.5.8-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
* Fri May 05 2023 Nicolas Chauvet <kwizart@gmail.com> - 0.5.8-1
- Don't emit weak-deps from deprecated arches on all
- Allow akmods --rebuild to force rebuild+reinstall - rhbz#2140012
- ensure to build for grub or systemd-boot default kernel - rhbz#2124086
- Drop "which" as akmods dependency

1
dead.package Normal file
View file

@ -0,0 +1 @@
epel8-playground decommissioned : https://pagure.io/epel/issue/136

View file