Compare commits

..

No commits in common. "rawhide" and "f38" have entirely different histories.

15 changed files with 598 additions and 1024 deletions

View file

@ -41,13 +41,19 @@ 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=$?
# needs to run in background as rpmdb might be locked otherwise
if [ -e /bin/systemctl ] ; then
# Exit early if system-update.target is active - rhbz#1518401
/bin/systemctl is-active system-update.target &>/dev/null
RET=$?
[[ $RET == 0 ]] && exit 0
[ $RET == 0 ] && exit 0
/bin/systemctl restart "akmods@${KERNEL_VERSION}.service" --no-block >/dev/null 2>&1
/bin/systemctl restart akmods@${KERNEL_VERSION}.service --no-block >/dev/null 2>&1
else
nohup /usr/sbin/akmods --from-kernel-posttrans --kernels ${KERNEL_VERSION} > /dev/null 2>&1 &
fi
exit 0
;;
remove)
# Nothing to do

View file

@ -46,6 +46,6 @@ below.
You can confirm the enrollment of the new keypair once the system
rebooted with:
`mokutil --list-enrolled
`mokutil --list-enrolled | grep Issuer`
or with:
`mokutil --test-key /etc/pki/akmods/certs/public_key.der`

237
akmods
View file

@ -1,4 +1,4 @@
#!/usr/bin/bash -
#!/bin/bash -
########################################################################
#
# akmods - Rebuilds and install akmod RPMs
@ -37,7 +37,7 @@
# global vars
myprog="akmods"
myver="0.6.2"
myver="0.5.7"
kmodlogfile=
continue_line=""
tmpdir=
@ -47,39 +47,6 @@ verboselevel=2
# 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
@ -91,7 +58,7 @@ akmods_echo()
shift
# output to console
if (( verboselevel >= this_verbose )) ; then
if (( ${verboselevel} >= ${this_verbose} )) ; then
if [[ "${1}" == "--success" ]] ; then
echo_success
continue_line=""
@ -110,7 +77,7 @@ akmods_echo()
elif [[ "${1}" == "-n" ]] ; then
continue_line="true"
fi
echo "$@" >&"${this_fd}"
echo "$@" >&${this_fd}
fi
# no need to print the status flags in the logs
@ -124,11 +91,11 @@ akmods_echo()
fi
# global logfile
echo "$(date +%Y/%m/%d\ %H:%M:%S) akmods: $*" >> "/var/log/akmods/akmods.log"
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}"
echo "$(date +%Y/%m/%d\ %H:%M:%S) akmods: $@" >> "${kmodlogfile}"
fi
}
@ -140,7 +107,7 @@ finally()
# remove lockfile
rm -f /var/cache/akmods/.lockfile
exit "${1:-128}"
exit ${1:-128}
}
# Make sure finally() is run regardless of reason for exiting.
@ -148,7 +115,7 @@ trap "finally" ABRT HUP INT QUIT
create_tmpdir()
{
if ! tmpdir="$(mktemp -d -p /tmp "${myprog}.XXXXXXXX")/" ; then
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
@ -169,13 +136,11 @@ remove_tmpdir()
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
for one_file in $(ls /var/cache/akmods/*/* 2>/dev/null | \
grep -v "$(ls -I "*rescue*" /boot/vmlinuz-* | \
sed 's%.*vmlinuz-%%g')") ; do
if $(grep -qE ".*\.rpm$" <<< "${one_file}") ; then
if ! $(rpm -q "$(basename ${one_file%.rpm})" >/dev/null) ; then
rm -f "${one_file}"
fi
else
@ -196,6 +161,16 @@ init ()
UMASK=022
umask ${UMASK}
# fall back to current kernel if user didn't provide one
if [[ ! -n "${kernels}" ]] ; then
kernels="$(uname -r)"
fi
# ensure to build for grub default kernel
default_kernel=$(grubby --default-kernel | sed -e 's/^.*vmlinuz-//')
if ! $(echo "${kernels}" | grep -q "${default_kernel}") ; then
kernels="${kernels} ${default_kernel}"
fi
# 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
@ -248,7 +223,7 @@ init ()
# tools needed
for tool in akmodsbuild chown flock sed rpmdev-vercmp ; do
if ! command -v "${tool}" &> /dev/null ; then
if ! which "${tool}" &> /dev/null ; then
echo -n "${tool} not found" >&2
echo_failure ; echo ; exit 1
fi
@ -259,64 +234,6 @@ init ()
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}
@ -362,9 +279,8 @@ buildinstall_kmod()
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
akmods_echo 1 4 "Building RPM using the command '$(which akmodsbuild) --kernels ${this_kernelver} ${this_kmodsrpm}'"
/sbin/runuser -s /bin/bash -c "$(which 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
@ -373,14 +289,10 @@ buildinstall_kmod()
fi
# result
if (( returncode != 0 )) ; then
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=""
@ -389,18 +301,13 @@ buildinstall_kmod()
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
dnf -y install --disablerepo='*' $(find "${tmpdir}results" -type f -name '*.rpm' | grep -v debuginfo) >> "${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
yum -y install --disablerepo='*' $(find "${tmpdir}results" -type f -name '*.rpm' | grep -v debuginfo) >> "${kmodlogfile}" 2>&1
fi
local returncode=$?
@ -408,14 +315,10 @@ buildinstall_kmod()
cp "${tmpdir}results/"* "/var/cache/akmods/${this_kmodname}/"
# everything fine?
if (( returncode != 0 )) ; then
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"
@ -430,8 +333,6 @@ buildinstall_kmod()
kmodlogfile=""
remove_tmpdir
akmods_echo_plymouth 0 ""
return 0
}
@ -439,14 +340,7 @@ 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)"
local 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
@ -454,22 +348,13 @@ check_kmod_up2date()
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)"
if [ -n "${kmodpackage_file}" ] && [ -h "${kmodpackage_file}" ] && $(echo "${kmodpackage_file}" | grep -q "weak-updates") ; then
local 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)"
local 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
@ -477,10 +362,8 @@ check_kmod_up2date()
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')
local kmodver=$(rpm -q --qf '%{EPOCH}:%{VERSION}-%{RELEASE}\n' "${kmodpackage}" | sed 's|(none)|0|; s!\.\(fc\|el\|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\|el\|lvn\)[0-9]*!!g')
rpmdev-vercmp "${kmodver}" "${akmodver}" &>/dev/null
local retvalue=$?
@ -507,8 +390,7 @@ check_kmods()
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}")"
local this_kmodname="$(basename ${akmods_kmodfile%%-kmod.latest})"
# actually check this akmod?
if [[ -n "${akmods}" ]] ; then
@ -521,7 +403,7 @@ check_kmods()
fi
# go
if ! check_kmod_up2date "${this_kernelver}" "${this_kmodname}" ; then
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
@ -539,15 +421,14 @@ check_kmods()
fi
fi
local this_kmodverrel
this_kmodverrel="$(rpm -qp --qf '%{VERSION}-%{RELEASE}' "${akmods_kmodfile}" | sed 's!\.\(fc\|el\|lvn\)[0-9]*!!g' )"
local 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}"
buildinstall_kmod ${this_kernelver} ${this_kmodname} ${akmods_kmodfile} ${this_kmodverrel}
local returncode=$?
if [[ "$returncode" == "0" ]] ; then
akmods_echo 1 2 --success
@ -574,7 +455,7 @@ check_kmods()
# 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
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
@ -590,7 +471,6 @@ myprog_help ()
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>"
}
@ -603,13 +483,19 @@ while [ "${1}" ] ; do
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
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}"
echo "Are the development files for kernel ${1} or the appropriate kernel-devel package installed?"
exit 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"
exit 1
fi
# overwrites the default:
if [[ ! -n "${kernels}" ]] ; then
kernels="${1}"
@ -645,25 +531,18 @@ while [ "${1}" ] ; do
# 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++ ))
let verboselevel++
shift
;;
--quiet)
(( verboselevel-- ))
let verboselevel--
shift
;;
--help)
@ -682,18 +561,12 @@ while [ "${1}" ] ; do
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}"
check_kmods ${kernel}
done
# finished :)

View file

@ -1,588 +1,151 @@
#!/bin/bash
# NAME: 'kmodgenca'
# PURPOSE: Helper script to create CA/key pair to sign modules.
#
# kmodgenca - Helper script to create CA/Keypair 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.
# 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 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
# 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="kmodgenca"
MYVER="0.5.7"
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 ""
myprog_help ()
{
echo "Build CA/Keypair to sign modules"
echo $'\n'"Usage: ${MYPROG} [OPTIONS]"
echo $'\n'"Options:"
echo " -a, --auto -- generate default values for cacert.config file without prompt"
echo " -f, --force -- build CA/Keypair even if there is already ones"
echo " -h, --help -- print usage"
echo " -V, --version -- show version"
}
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
# Parse command line options.
#
while [ "${1}" ] ; do
case "${1}" in
-a|--auto)
AUTOMATIC_BUILD=1
shift
;;
-f|--force)
FORCE_BUILD=1
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
;;
esac
done
# Exit early if cert and private key already exist and if FORCE_BUILD
# is not equal to 1.
#
if $(readlink -e /etc/pki/akmods/certs/public_key.der &>/dev/null) && \
$(readlink -e /etc/pki/akmods/private/private_key.priv &>/dev/null) && \
[ ${FORCE_BUILD} -eq 0 ] ; then
exit 0
fi
CACERT_CONFIG="/etc/pki/akmods/cacert.config"
KEYNAME="$(hostname)"-"$(od -vAn -N4 -tu4 < /dev/urandom | awk '{print $1}')"
# Create cacert.config file with local values if AUTOMATIC_BUILD is set
# or ask for values manually.
#
echo "Update cacert.config..."
if [ ${AUTOMATIC_BUILD} -eq 1 ] ; then
# Set OpenSSL fields values, comment default values and min/max ones.
sed -e "s#\(0.organizationName *= \).*#\1$(hostname)#" \
-e "s#\(organizationalUnitName *= \).*#\1$(hostname)#" \
-e "s#\(emailAddress *= \).*#\1akmods@$(hostname)#" \
-e "s#\(localityName *= \).*#\1None#" \
-e "s#\(stateOrProvinceName *= \).*#\1None#" \
-e "s#\(countryName *= \).*#\1$(locale country_ab2)#" \
-e "s#\(commonName *= \).*#\1$(hostname)"-"$(od -vAn -N4 -tu4 < /dev/urandom | awk '{print $1}')#" \
-e "s/^[^#]*_default *= /#&/" \
-e "s/^[^#]*_min/#&/" \
-e "s/^[^#]*_max/#&/" ${CACERT_CONFIG}.in > ${CACERT_CONFIG}
AUTOMATIC_BUILD_OPTION=" -batch"
else
# Activate prompt directive.
sed -e "s#\(prompt *= \).*#\1yes#" ${CACERT_CONFIG}.in > ${CACERT_CONFIG}
fi
KEY_SUFF="$(date "+%F_%T_%N")"
# If cert and private key files names already exists, do not overwrite
# them but save them.
#
if [[ -e /etc/pki/akmods/certs/${KEYNAME}.der ]] ; then
# If the cert has already been loaded in MOK, add "already_enrolled"
# to the suffix of the backup file.
# `mokutil --help` fails if EFI variables are not supported on the
# system. It is therefore impossible to test the presence of the key
# in MOK, and then do not add special suffix to the backup file.
#
if $(which mokutil &> /dev/null) && $(mokutil --help &> /dev/null) && $(mokutil --test-key /etc/pki/akmods/certs/${KEYNAME}.der &> /dev/null) ; then
KEY_SUFF="${KEY_SUFF}_already_enrolled"
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
mv /etc/pki/akmods/certs/${KEYNAME}.der /etc/pki/akmods/certs/${KEYNAME}.der.${KEY_SUFF}.bak
if [[ -e /etc/pki/akmods/private/${KEYNAME}.priv ]] ; then
mv /etc/pki/akmods/private/${KEYNAME}.priv /etc/pki/akmods/private/${KEYNAME}.priv.${KEY_SUFF}.bak
fi
fi
echo "Generate new keypair..."
sg akmods -c "
umask 037
openssl req -x509 -new -nodes -utf8 -sha256 -days 3650${AUTOMATIC_BUILD_OPTION} \
-config ${CACERT_CONFIG} -outform DER \
-out /etc/pki/akmods/certs/${KEYNAME}.der \
-keyout /etc/pki/akmods/private/${KEYNAME}.priv
"
# Ensure that akmods group can read keys.
#
chmod g+r /etc/pki/akmods/certs/${KEYNAME}.*
chmod g+r /etc/pki/akmods/private/${KEYNAME}.*
# Sanitize permissions.
#
if [[ -x /usr/sbin/restorecon ]] ; then
/usr/sbin/restorecon /etc/pki/akmods/certs/${KEYNAME}.der
/usr/sbin/restorecon /etc/pki/akmods/private/${KEYNAME}.priv
fi
# Update symlink to use new keypair.
#
ln -nsf /etc/pki/akmods/certs/${KEYNAME}.der /etc/pki/akmods/certs/public_key.der
ln -nsf /etc/pki/akmods/private/${KEYNAME}.priv /etc/pki/akmods/private/private_key.priv
# 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

@ -43,7 +43,7 @@ finally()
# remove tmpfiles
remove_tmpdir
exit "${1:-128}"
exit ${1:-128}
}
# Make sure finally() is run regardless of reason for exiting.
@ -51,7 +51,7 @@ trap "finally" ABRT HUP INT QUIT
create_tmpdir()
{
if ! tmpdir="$(mktemp -d -p /tmp "${myprog}.XXXXXXXX")/" ; then
if ! tmpdir="$(mktemp -d -p /tmp ${myprog}.XXXXXXXX)/" ; then
echo "ERROR: failed to create tmpdir." >&2
finally 1
fi
@ -79,24 +79,24 @@ 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
akmodsbuild --quiet --kernels ${kernel} --outputdir ${tmpdir}results --logfile "${tmpdir}/akmodsbuild.log" "${srpm}" 2>&1
returncode=$?
if (( returncode != 0 )); then
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
rpm2cpio $f | cpio --quiet -D / -id
returncode=$?
if (( returncode != 0 )); then
if (( ! ${returncode} == 0 )); then
echo "Extracting $f failed:" 2>&1
finally 1
fi
done
for kernel in ${kernels} ; do
depmod -v "${kernel}" 2>&1
depmod -v ${kernel} 2>&1
done
finally 0

View file

@ -23,9 +23,9 @@
# 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 ..."
echo "Building modules for all installed kernels."
for kernel in /usr/src/kernels/* ; do
kernel=$(basename $kernel)
/usr/sbin/akmods --kernels $kernel
done
sleep 6
/usr/sbin/akmods

View file

@ -7,7 +7,7 @@ Conflicts=shutdown.target
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/true
ExecStop=-/usr/sbin/akmods
ExecStop=-/usr/sbin/akmods-shutdown
TimeoutStopSec=5min
[Install]

View file

@ -1,9 +1,9 @@
[BUGS]
https://bugz.fedoraproject.org/akmods
https://bugzilla.rpmfusion.org/buglist.cgi?product=Fedora&component=akmods&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED
[REPORTING BUGS]
Submit a bug against the akmods component at:
.br
https://bugzilla.redhat.com/enter_bug.cgi?product=Fedora
https://bugzilla.rpmfusion.org/enter_bug.cgi?product=Fedora
[AUTHOR]
Thorsten Leemhuis <fedora [AT] leemhuis [DOT] info>
[MAINTAINER]

View file

@ -1,7 +1,7 @@
[Unit]
Description=Builds and install new kmods from akmod packages
ConditionPathExists=!/run/ostree-booted
Before=display-manager.service
Before=@SERVICE@
After=akmods-keygen.target
Wants=akmods-keygen.target

View file

@ -1,6 +1,6 @@
Name: akmods
Version: 0.6.2
Release: %autorelease
Version: 0.5.7
Release: 10%{?dist}
Summary: Automatic kmods build and install tool
License: MIT
@ -11,7 +11,8 @@ Source0: 95-akmods.preset
Source1: akmods
Source2: akmodsbuild
Source3: akmods.h2m
Source6: akmods.service
Source5: akmodsposttrans
Source6: akmods.service.in
Source7: akmods-shutdown
Source8: akmods-shutdown.service
Source9: README
@ -26,16 +27,15 @@ 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
%if 0%{?rhel} == 6
Requires: %{_bindir}/nohup
%endif
Requires: %{_bindir}/flock
Requires: %{_bindir}/time
@ -48,27 +48,49 @@ 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
Requires: gzip make sed tar unzip util-linux which rpm-build
# On EL, kABI list was renamed
%if 0%{?rhel}
Requires: (kernel-abi-stablelists if kernel-core)
%if 0%{?rhel} >= 8
Requires: (kernel-abi-stablelists or kernel-abi-whitelists)
%else
Requires: kernel-abi-whitelists
%endif
%endif
%if 0%{?fedora} || 0%{?rhel} > 7
# 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
%if 0%{?fedora} >= 36 || 0%{?rhel} >= 9
Requires: (kernel-debug-devel-matched if kernel-debug-core)
Requires: (kernel-devel-matched if kernel-core)
%ifarch %{arm}
Requires: (kernel-lpae-devel-matched if kernel-lpae-core)
%endif
%else
Suggests: (kernel-debug-devel if kernel-debug-core)
Suggests: (kernel-devel if kernel-core)
Suggests: (kernel-debug-devel if kernel-debug)
Suggests: (kernel-devel if kernel)
%ifarch %{arm}
Suggests: (kernel-lpae-devel if kernel-lpae)
%endif
%endif
%ifarch %{ix86}
Suggests: (kernel-PAE-devel if kernel-PAE)
Suggests: (kernel-PAEdebug-devel if kernel-PAEdebug)
# Theses are from planetccrma-core or rhel-7-server-rt-rpms
Suggests: (kernel-rtPAE-devel if kernel-rtPAE)
%endif
Suggests: (kernel-rt-devel if kernel-rt)
%else
# There is no much variant there, so using a sane default
Requires: kernel-devel
%endif
# we create a special user that used by akmods to build kmod packages
Requires(pre): shadow-utils
# systemd unit requirements.
BuildRequires: systemd
@ -78,11 +100,6 @@ 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
@ -114,6 +131,7 @@ mkdir -p %{buildroot}%{_usrsrc}/%{name} \
install -pm 0755 %{SOURCE1} %{buildroot}%{_sbindir}/
install -pm 0755 %{SOURCE2} %{buildroot}%{_sbindir}/
install -pm 0755 %{SOURCE12} %{buildroot}%{_sbindir}/
install -pm 0755 %{SOURCE5} %{buildroot}%{_sysconfdir}/kernel/postinst.d/
install -pm 0644 %{SOURCE14} %{buildroot}%{_sysconfdir}/logrotate.d/%{name}
install -pm 0640 %{SOURCE16} %{buildroot}%{_sysconfdir}/pki/%{name}/
install -pm 0755 %{SOURCE17} %{buildroot}%{_sbindir}/kmodgenca
@ -125,9 +143,9 @@ install -pm 0755 %{SOURCE13} %{buildroot}%{_prefix}/lib/kernel/install.d/
mkdir -p \
%{buildroot}%{_unitdir} \
%{buildroot}%{_presetdir}
sed "s|@SERVICE@|display-manager.service|" %{SOURCE6} >\
%{buildroot}%{_unitdir}/akmods.service
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}/
@ -143,11 +161,13 @@ 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}
# 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
%systemd_post akmods.service
@ -176,6 +196,7 @@ install -m0644 -D %{SOURCE21} %{buildroot}%{_sysusersdir}/akmods.conf
%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}
%{_sysconfdir}/kernel/postinst.d/akmodsposttrans
%{_unitdir}/akmods.service
%{_unitdir}/akmods@.service
%{_sbindir}/akmods-shutdown
@ -195,8 +216,213 @@ install -m0644 -D %{SOURCE21} %{buildroot}%{_sysusersdir}/akmods.conf
%dir %attr(-,akmods,akmods) %{_localstatedir}/cache/akmods
%dir %attr(0775,root,akmods) %{_localstatedir}/log/%{name}
%{_mandir}/man1/*
%{_sysusersdir}/akmods.conf
%changelog
%autochangelog
* Wed Jan 18 2023 Fedora Release Engineering <releng@fedoraproject.org> - 0.5.7-10
- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild
* Wed Jul 20 2022 Fedora Release Engineering <releng@fedoraproject.org> - 0.5.7-9
- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild
* Wed May 04 2022 Nicolas Chauvet <kwizart@gmail.com> - 0.5.7-8
- Fix logrotate permission access to /var/log/akmods directory - rhbz#2078490
- Rename logrotate config file
* Wed Mar 09 2022 Timothée Ravier <tim@siosm.fr> - 0.5.7-7
- Use 'Require' instead of 'Suggest' for kernel*-devel packages.
* Thu Jan 27 2022 Nicolas Viéville <nicolas.vieville@uphf.fr> - 0.5.7-6
- Adapt usage of lockfile to systemd-tmpfiles
- Re-locate akmods logs in /var/log
* Wed Jan 26 2022 Timothée Ravier <tim@siosm.fr> - 0.5.7-5
- Use kernel*-core variants in conditional Suggests
* Wed Jan 19 2022 Fedora Release Engineering <releng@fedoraproject.org> - 0.5.7-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild
* Mon Dec 20 2021 Nicolas Chauvet <kwizart@gmail.com> - 0.5.7-3
- Drop perl-interpeter
- Drop akmodsinit
- Only use preset on rhel
- kernel-devel-matched support
see also https://src.fedoraproject.org/rpms/akmods/pull-request/7
* Fri Dec 10 2021 Nicolas Chauvet <kwizart@gmail.com> - 0.5.7-2
- Bump kmodtool requirement
- Rename kABI list
- Drop EL6 support
- Switch to distro agnostic deps
* Fri Oct 22 2021 Nicolas Viéville <nicolas.vieville@uphf.fr> - 0.5.7-1
- Add local akmods CA signing keys and support tools to sign modules for
Secure boot thanks to Stanislas Leduc <stanislas.leduc@balinor.net>
- Add akmods-keygen service to generate MOK key pair on first run
* Fri Oct 22 2021 Nicolas Viéville <nicolas.vieville@uphf.fr> - 0.5.6-29
- Remove trailing spaces and clean-up
- Use %%{name} when possible
- Convert if statement from "[!] $variable" to "[!] -n $variable"
- Fix kernel list build when parsing command line options
- Ensure to build for grub default kernel
- Improve detection of already installed (weak-)modules in akmods (RHEL)
- akmods uses logrotate and clean-up /var/cache/akmods sub-directories of
old logs and rpm files from no more installed kmod packages
(rhbz #1542658).
* Wed Jul 21 2021 Fedora Release Engineering <releng@fedoraproject.org> - 0.5.6-28
- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild
* Mon Jan 25 2021 Fedora Release Engineering <releng@fedoraproject.org> - 0.5.6-27
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
* Mon Jul 27 2020 Fedora Release Engineering <releng@fedoraproject.org> - 0.5.6-26
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
* Tue Jan 28 2020 Fedora Release Engineering <releng@fedoraproject.org> - 0.5.6-25
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
* Wed Nov 20 2019 Nicolas Viéville <nicolas.vieville@uphf.fr> - 0.5.6-24
- Check kernel presence differently for systemd-boot machines - rhbz#1769144
* Wed Oct 16 2019 Leigh Scott <leigh123linux@googlemail.com> - 0.5.6-23
- Add requires kernel-abi-whitelists for RHEL
* Wed Jul 24 2019 Fedora Release Engineering <releng@fedoraproject.org> - 0.5.6-22
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
* Mon May 20 2019 Nicolas Chauvet <kwizart@gmail.com> - 0.5.6-21
- Add check for rhel8
* Wed May 15 2019 Nicolas Viéville <nicolas.vieville@uphf.fr> - 0.5.6-20
- Fix akmodsposttrans after kernel update/install on Fedora >= 28 and
RHEL >= 7 - rhbz#1709055
* Thu Feb 28 2019 Alexander Larsson <alexl@redhat.com> - 0.5.6-19
- Support ostree/silverblue builds - rhbz#1667014
* Thu Feb 28 2019 Hans de Goede <hdegoede@redhat.com>
- Do not fail when the old initscripts pkg is not installed - rhbz#1680121
* Thu Jan 31 2019 Fedora Release Engineering <releng@fedoraproject.org> - 0.5.6-18
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
* Mon Nov 05 2018 Nicolas Chauvet <kwizart@gmail.com> - 0.5.6-17
- Don't enforce target arch - rhbz#1644430
- Rework log file path
- Avoid using /usr/lib/modules for el6 compat
* Thu Jul 12 2018 Fedora Release Engineering <releng@fedoraproject.org> - 0.5.6-16
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
* Mon Mar 26 2018 Nicolas Chauvet <kwizart@gmail.com> - 0.5.6-15
- Add inihibitor for akmods@.service
- Use restart on akmodsposttrans
* Mon Mar 26 2018 Nicolas Chauvet <kwizart@gmail.com> - 0.5.6-14
- Switch to always retry by default
- Drop akmods preset by f28
- Don't enable service on ah
- Test a rw directory
* Wed Feb 07 2018 Fedora Release Engineering <releng@fedoraproject.org> - 0.5.6-13
- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
* Wed Dec 13 2017 Nicolas Chauvet <kwizart@gmail.com> - 0.5.6-12
- Update kernel posttrans method - rhbz#1518401
* Thu Aug 03 2017 Nicolas Chauvet <kwizart@gmail.com> - 0.5.6-11
- Rework kernel-devel requires on el
* Thu Aug 03 2017 Nicolas Chauvet <kwizart@gmail.com> - 0.5.6-10
- Enable suggests on fedora
- Add back el6 support in spec
- Add Requires elfutils-libelf-devel
* Wed Jul 26 2017 Fedora Release Engineering <releng@fedoraproject.org> - 0.5.6-9
- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild
* Thu Jul 13 2017 Petr Pisar <ppisar@redhat.com> - 0.5.6-8
- perl dependency renamed to perl-interpreter
<https://fedoraproject.org/wiki/Changes/perl_Package_to_Install_Core_Modules>
* Thu May 4 2017 Hans de Goede <hdegoede@redhat.com> - 0.5.6-7
- "udevadm trigger" may have bad side-effects (rhbz#454407) instead
look for modalias files under /sys/devices and call modprobe directly
- Fix exit status when no akmod packages are installed, so that systemd
does not consider the akmods.service as having failed to start
* Wed May 3 2017 Hans de Goede <hdegoede@redhat.com> - 0.5.6-6
- Run "udevadm trigger" and "systemctl restart systemd-modules-load.service"
when new kmod packages have been build and installed so that the new
modules may be used immediately without requiring a reboot
* Mon Mar 6 2017 Hans de Goede <hdegoede@redhat.com> - 0.5.6-5
- Add LICENSE file (rhbz#1422918)
* Fri Feb 24 2017 Hans de Goede <hdegoede@redhat.com> - 0.5.6-4
- Replace %%{_prefix}/lib/systemd/system-preset with %%{_presetdir}
* Thu Feb 16 2017 Hans de Goede <hdegoede@redhat.com> - 0.5.6-3
- Submit to Fedora for package review
* Mon Nov 28 2016 Nicolas Chauvet <kwizart@gmail.com> - 0.5.6-2
- Use Suggests kernel-devel weak-dependency - see rfbz#3386
* Fri Oct 14 2016 Richard Shaw <hobbes1069@gmail.com> - 0.5.6-1
- Disable shutdown systemd service file by default.
- Remove modprobe line from main service file.
* Wed Aug 17 2016 Sérgio Basto <sergio@serjux.com> - 0.5.4-3
- New release
* Sun Jan 03 2016 Nicolas Chauvet <kwizart@gmail.com> - 0.5.4-2
- Revert conflicts kernel-debug-devel
* Thu Jul 23 2015 Richard Shaw <hobbes1069@gmail.com> - 0.5.4-1
- Do not mark a build as failed when only installing the RPM fails.
- Run akmods-shutdown script instead of akmods on shutdown.
- Add systemd preset file to enable services by default.
* Wed Jul 15 2015 Richard Shaw <hobbes1069@gmail.com> - 0.5.3-2
- Add package conflicts to stop pulling in kernel-debug-devel, fixes BZ#3386.
- Add description for the formatting of the <kernel> parameter, BZ#3580.
- Update static man pages and clean them up.
- Fixed another instance of TMPDIR causing issues.
- Added detection of dnf vs yum to akmods, fixed BZ#3481.
* Wed Apr 1 2015 Richard Shaw <hobbes1069@gmail.com> - 0.5.2-1
- Fix temporary directory creation when TMPDIR environment variable is set,
fixes BZ#2596.
- Update systemd scripts to use macros.
- Fix akmods run on shutdown systemd unit file, fixes BZ#3503.
* Sun Nov 16 2014 Nicolas Chauvet <kwizart@gmail.com> - 0.5.1-4
- Fix akmods on armhfp - rfbz#3117
- Use yum instead of rpm to install packages - rfbz#3350
Switch to a better date format
* Fri Jan 11 2013 Richard Shaw <hobbes1069@gmail.com> - 0.5.1-3
- Really fix akmods.service.in.
* Fri Jun 01 2012 Richard Shaw <hobbes1069@gmail.com> - 0.5.1-2
- Add service file to run again on shutdown.
- Add conditional for Fedora 18 to specify correct systemd graphical service.
* Thu Apr 12 2012 Nicolas Chauvet <kwizart@gmail.com> - 0.4.0-4
- Rebuilt
* Tue Mar 20 2012 Richard Shaw <hobbes1069@gmail.com> - 0.4.0-3
- Add additional error output if the needed kernel development files are not
installed. (Fixes #561)
* Mon Mar 05 2012 Richard Shaw <hobbes1069@gmail.com> - 0.4.0-2
- Remove remaining references to previous Fedora releases
- Remove legacy SysV init script from CVS.
- Added man page for akmods and cleaned up man page for akmodsbuild.
* Tue Feb 07 2012 Nicolas Chauvet <kwizart@gmail.com> - 0.4.0-1
- Update for UsrMove support
- Remove unused references to older fedora
- Change Requires from kernel-devel to kernel-devel-uname-r

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

@ -23,10 +23,14 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
myprog="akmodsbuild"
myver="0.6.2"
myver="0.5.6"
# defaults that might get overwritten by user:
kernels="$(uname -r)"
target="$(uname -m)"
if [[ "${target}" == "armv7l" ]] ; then
target="armv7hl"
fi
numberofjobs=$(grep -c processor /proc/cpuinfo 2> /dev/null)
verboselevel=2
outputdir="${PWD}"
@ -60,7 +64,7 @@ init ()
# SRPMS available?
for srpm in ${srpms}; do
if [[ ! -r "${srpm}" ]] ; then
if [[ ! -r ${srpm} ]] ; then
echo "ERROR: Can't find SRPM ${srpm}"
exit 1
fi
@ -77,28 +81,19 @@ init ()
# make sure this is a number
if ! (( numberofjobs > 0 )) ; then
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
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
# buildtreee
mkdir "${tmpdir}"/{BUILD,SOURCES,SPECS,SRPMS,RPMS,RPMS/"${target}"}
# logfile
@ -106,7 +101,7 @@ init ()
logfile="${tmpdir}/logfile"
fi
if { [[ -e "${logfile}" ]] && [[ ! -w "${logfile}" ]] ; } || ! touch "${logfile}" ; then
if ( [[ -e "${logfile}" ]] && [[ ! -w "${logfile}" ]] ) || ! touch "${logfile}" ; then
echo "ERROR: Could not write logfile."
finally
exit 1
@ -148,12 +143,12 @@ akmods_echo()
fi
# output to console
if (( verboselevel >= this_verbose )) ; then
echo "$@" >&"${this_fd}"
if (( ${verboselevel} >= ${this_verbose} )) ; then
echo "$@" >&${this_fd}
fi
# global logfile
if [[ ! -n "${notlogfile}" ]] ; then
if [[ ! -n ${notlogfile} ]] ; then
echo "$@" >> "${logfile}"
fi
}
@ -164,8 +159,8 @@ 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 (( ${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
@ -177,8 +172,8 @@ watch_rpmbuild()
# last linefeed is done by the caller
fi
done
elif (( verboselevel > 2 )) ; then
tail --pid "${1}" -n +1 -s 0.1 -f "${2}"
elif (( ${verboselevel} > 2 )) ; then
tail --pid ${1} -n +1 -s 0.1 -f ${2}
fi
}
@ -199,32 +194,31 @@ process_srpm()
--define "_rpmdir ${tmpdir}/RPMS" \
--define "_smp_mflags -j${numberofjobs}" \
--define "kernels ${kernels}" \
--target "${target}" \
--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 &
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")
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
if (( ${verboselevel} >= 2 )) ; then
sleep 0.5
kill "${watch_jobid}" &> /dev/null
kill ${watch_jobid} &> /dev/null
unset watch_jobid
fi
# did rpmbuild succeed?
if (( rpmbuild_returncode != 0 )) ; then
if (( ${rpmbuild_returncode} != 0 )) ; then
# linefeed:
akmods_echo 1 2 ""
@ -232,16 +226,15 @@ process_srpm()
akmods_echo 2 2 --not-logfile "--- "
tail -n 35 "${tmpdir}/.joblog" >&2
akmods_echo 2 2 --not-logfile "---"
return "${rpmbuild_returncode}"
return ${rpmbuild_returncode}
fi
# finish status for watch_rpmbuild
if (( verboselevel >= 2 )) ; then
akmods_echo 1 2 -n "Successful; "
if (( ${verboselevel} >= 2 )) ; then
akmods_echo 1 2 -n "Successfull; "
fi
local rpms_built
rpms_built="$(cd "${tmpdir}"/RPMS/"${target}" || exit ; echo *)"
local rpms_built="$(cd "${tmpdir}"/RPMS/"${target}" ; echo *)"
if ! mv "${tmpdir}/RPMS/${target}/"* "${outputdir}" ; then
# linefeed:
@ -251,11 +244,11 @@ process_srpm()
return 128
fi
if (( verboselevel == 1 )) ; then
if (( ${verboselevel} == 1 )) ; then
for rpm in ${rpms_built}; do
echo "${outputdir%%/}/${rpm}"
done
elif (( verboselevel >= 2 )) ; then
elif (( ${verboselevel} >= 2 )) ; then
akmods_echo 1 2 "Saved ${rpms_built} in ${outputdir%%/}/"
fi
@ -318,11 +311,11 @@ while [ "${1}" ] ; do
shift
;;
-v|--verbose)
(( verboselevel++ ))
let verboselevel++
shift
;;
-q|--quiet)
(( verboselevel-- ))
let verboselevel--
shift
;;
-h|--help)
@ -350,12 +343,12 @@ init
# go
for srpm in ${srpms}; do
process_srpm "${srpm}"
process_srpm ${srpm}
returncode=$?
if (( returncode != 0 )) ; then
if (( ${returncode} != 0 )) ; then
finally
exit "${returncode}"
exit ${returncode}
fi
done

47
akmodsinit Normal file
View file

@ -0,0 +1,47 @@
#!/bin/bash -
#
# akmodinit Builds and install new kmods from akmod packages
#
# Author: Thorsten Leemhuis <fedora@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 2
;;
esac

47
akmodsposttrans Executable file
View file

@ -0,0 +1,47 @@
#!/bin/bash -
#
# akmodposttrans - Calls akmods for newly installed kernels
#
# Copyright (c) 2009 Thorsten Leemhuis <fedora@leemhuis.info>
# Copyright (c) 2017 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.
#
# 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
# needs to run in background as rpmdb might be locked otherwise
if [ -e /bin/systemctl ] ; then
# Exit early if system-update.target is active - rhbz#1518401
/bin/systemctl is-active system-update.target &>/dev/null
RET=$?
[ $RET == 0 ] && exit 0
/bin/systemctl restart akmods@${1}.service --no-block >/dev/null 2>&1
else
nohup /usr/sbin/akmods --from-kernel-posttrans --kernels ${1} > /dev/null 2>&1 &
fi
exit 0

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