Merge pull request #23881 from keszybz/kernel-install-strikes-yet-again

kernel-install: fix invocation as installkernel, add tests, tweak documentation
This commit is contained in:
Yu Watanabe 2022-07-13 02:44:50 +02:00 committed by GitHub
commit 0925c79c9e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 288 additions and 113 deletions

View file

@ -144,6 +144,7 @@
<refsect1> <refsect1>
<title>The <varname>$BOOT</varname> partition</title> <title>The <varname>$BOOT</varname> partition</title>
<para>The partition where the kernels and <ulink url="https://systemd.io/BOOT_LOADER_SPECIFICATION">Boot <para>The partition where the kernels and <ulink url="https://systemd.io/BOOT_LOADER_SPECIFICATION">Boot
Loader Specification</ulink> snippets are located is called <varname>$BOOT</varname>. Loader Specification</ulink> snippets are located is called <varname>$BOOT</varname>.
<command>kernel-install</command> determines the location of this partition by checking <command>kernel-install</command> determines the location of this partition by checking
@ -173,77 +174,101 @@
<refsect1> <refsect1>
<title>Environment variables</title> <title>Environment variables</title>
<para>If <option>--verbose</option> is used, <varname>$KERNEL_INSTALL_VERBOSE=1</varname> will be set for <refsect2>
the plugins. They may output additional logs in this case.</para> <title>Environment variables exported for plugins</title>
<para>If <varname>$MACHINE_ID</varname> is set and not empty when <command>kernel-install</command> is <para>If <option>--verbose</option> is used, <varname>$KERNEL_INSTALL_VERBOSE=1</varname> will be
invoked, it will be used as <replaceable>MACHINE-ID</replaceable>, overriding any automatic detection exported for plugins. They may output additional logs in this case.</para>
attempts. The value must be a valid machine ID (32 hexadecimal characters).</para>
<para><varname>$KERNEL_INSTALL_MACHINE_ID</varname> is set for the plugins to the desired <para><varname>$KERNEL_INSTALL_MACHINE_ID</varname> is set for the plugins to the desired machine-id to
<replaceable>MACHINE-ID</replaceable> to use. It's always a 128bit ID, and typically the ID from use. It's always a 128-bit ID. Normally it's read from <filename>/etc/machine-id</filename>, but it can
<filename>/etc/machine-id</filename> or the one passed in via <varname>$MACHINE_ID</varname>. (If no also be overriden via <varname>$MACHINE_ID</varname> (see below). If not specified via these methods a
machine ID was specified via these methods it might be generated randomly by fallback value will generated by <command>kernel-install</command>, and used only for a single
<command>kernel-install</command>, in which case it only applies to this invocation.)</para> invocation.</para>
<para><varname>$KERNEL_INSTALL_ENTRY_TOKEN</varname> is set for the plugins to the desired entry "token" <para><varname>$KERNEL_INSTALL_ENTRY_TOKEN</varname> is set for the plugins to the desired entry
to use. It's an identifier that shall be used to identify the local installation, and is often the "token" to use. It's an identifier that shall be used to identify the local installation, and is often
machine ID, i.e. same as <varname>$KERNEL_INSTALL_MACHINE_ID</varname>, but might also be a different the machine ID, i.e. same as <varname>$KERNEL_INSTALL_MACHINE_ID</varname>, but might also be a
type of identifier, for example a fixed string or the <varname>ID=</varname>, different type of identifier, for example a fixed string or the <varname>ID=</varname>,
<varname>IMAGE_ID=</varname> values from <filename>/etc/os-release</filename>. The string passed here <varname>IMAGE_ID=</varname> values from <filename>/etc/os-release</filename>. The string passed here
will be used to name Boot Loader Specification entries, or the directories the kernel image and initial will be used to name Boot Loader Specification entries, or the directories the kernel image and initial
RAM disk images are placed into. Note that while oftentimes RAM disk images are placed into.</para>
<varname>$KERNEL_INSTALL_ENTRY_TOKEN</varname> and <varname>$KERNEL_INSTALL_MACHINE_ID</varname> are set
to the same value, the latter is guaranteed to be a valid 32 character ID in lowercase hexadecimals while
the former can be any short string. The entry token to use is read from
<filename>/etc/kernel/entry-token</filename>, if it exists. Otherwise a few possible candidates below the
<varname>$BOOT</varname> are searched for Boot Loader Specification Type 1 entry directories, and if
found the entry token is derived from that. If that is not successful the machine ID is used as
fallback.</para>
<para><varname>$KERNEL_INSTALL_BOOT_ROOT</varname> is set for the plugins to the absolute path of the <para>Note that while <varname>$KERNEL_INSTALL_ENTRY_TOKEN</varname> and
root directory (mount point, usually) of the hierarchy where boot loader entries, kernel images, and <varname>$KERNEL_INSTALL_MACHINE_ID</varname> are often set to the same value, the latter is guaranteed
associated resources should be placed. This usually is the path where the XBOOTLDR partition or the ESP to be a valid 32 character ID in lowercase hexadecimals while the former can be any short string. The
(EFI System Partition) are mounted, and also conceptually referred to as <varname>$BOOT</varname>. Can be entry token to use is read from <filename>/etc/kernel/entry-token</filename>, if it exists. Otherwise a
overridden by setting <varname>$BOOT_ROOT</varname>.</para> few possible candidates below <varname>$BOOT</varname> are checked for Boot Loader Specification Type 1
entry directories, and if found the entry token is derived from that. If that is not successful,
<varname>$KERNEL_INSTALL_MACHINE_ID</varname> is used as fallback.</para>
<para><varname>$KERNEL_INSTALL_LAYOUT=bls|other|...</varname> is set for the plugins to specify the <para><varname>$KERNEL_INSTALL_BOOT_ROOT</varname> is set for the plugins to the absolute path of the
installation layout. Defaults to <option>bls</option> if root directory (mount point, usually) of the hierarchy where boot loader entries, kernel images, and
<filename>$BOOT/<replaceable>ENTRY-TOKEN</replaceable></filename> exists, or <option>other</option> associated resources should be placed. This usually is the path where the XBOOTLDR partition or the ESP
otherwise. Additional layout names may be defined by convention. If a plugin uses a special layout, it's (EFI System Partition) are mounted, and also conceptually referred to as <varname>$BOOT</varname>. Can
encouraged to declare its own layout name and configure <varname>layout=</varname> in be overridden by setting <varname>$BOOT_ROOT</varname> (see below).</para>
<filename>install.conf</filename> upon initial installation. The following values are currently
understood:</para>
<variablelist> <para><varname>$KERNEL_INSTALL_LAYOUT=bls|other|...</varname> is set for the plugins to specify the
<varlistentry> installation layout. Defaults to <option>bls</option> if
<term>bls</term> <filename>$BOOT/<replaceable>ENTRY-TOKEN</replaceable></filename> exists, or <option>other</option>
<listitem> otherwise. Additional layout names may be defined by convention. If a plugin uses a special layout,
<para>Standard <ulink url="https://systemd.io/BOOT_LOADER_SPECIFICATION">Boot Loader it's encouraged to declare its own layout name and configure <varname>layout=</varname> in
Specification</ulink> Type #1 layout, compatible with <filename>install.conf</filename> upon initial installation. The following values are currently
<citerefentry><refentrytitle>systemd-boot</refentrytitle><manvolnum>7</manvolnum></citerefentry>: understood:</para>
entries in
<filename>$BOOT/loader/entries/<replaceable>ENTRY-TOKEN</replaceable>-<replaceable>KERNEL-VERSION</replaceable>[+<replaceable>TRIES</replaceable>].conf</filename>,
kernel and initrds under
<filename>$BOOT/<replaceable>ENTRY-TOKEN</replaceable>/<replaceable>KERNEL-VERSION</replaceable>/</filename></para>
<para>Implemented by <filename>90-loaderentry.install</filename>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>other</term>
<listitem>
<para>Some other layout not understood natively by <command>kernel-install</command>.</para>
</listitem>
</varlistentry>
</variablelist>
<para><varname>$KERNEL_INSTALL_INITRD_GENERATOR</varname> is set for plugins to select the initrd <variablelist>
generator. This may be configured as <varname>initrd_generator=</varname> in <varlistentry>
<filename>install.conf</filename>. See below.</para> <term>bls</term>
<listitem>
<para>Standard <ulink url="https://systemd.io/BOOT_LOADER_SPECIFICATION">Boot Loader
Specification</ulink> Type #1 layout, compatible with
<citerefentry><refentrytitle>systemd-boot</refentrytitle><manvolnum>7</manvolnum></citerefentry>:
entries in
<filename>$BOOT/loader/entries/<replaceable>ENTRY-TOKEN</replaceable>-<replaceable>KERNEL-VERSION</replaceable>[+<replaceable>TRIES</replaceable>].conf</filename>,
kernel and initrds under
<filename>$BOOT/<replaceable>ENTRY-TOKEN</replaceable>/<replaceable>KERNEL-VERSION</replaceable>/</filename></para>
<para>Implemented by <filename>90-loaderentry.install</filename>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>other</term>
<listitem>
<para>Some other layout not understood natively by <command>kernel-install</command>.</para>
</listitem>
</varlistentry>
</variablelist>
<para><varname>$KERNEL_INSTALL_STAGING_AREA</varname> is set for plugins to a path to a directory. <para><varname>$KERNEL_INSTALL_INITRD_GENERATOR</varname> is set for plugins to select the initrd
Plugins may drop files in that directory, and they will be installed as part of the loader entry, based generator. This may be configured as <varname>initrd_generator=</varname> in
on the file name and extension.</para> <filename>install.conf</filename>, see below.</para>
<para><varname>$KERNEL_INSTALL_STAGING_AREA</varname> is set for plugins to a path to a directory.
Plugins may drop files in that directory, and they will be installed as part of the loader entry, based
on the file name and extension.</para>
</refsect2>
<refsect2>
<title>Environment variables understood by <command>kernel-install</command></title>
<para><varname>$KERNEL_INSTALL_CONF_ROOT</varname> can be set to override the location of the
configuration files read by <command>kernel-install</command>. When set,
<filename>install.conf</filename>, <filename>entry-token</filename>, and other files will be
read from this directory.</para>
<para><varname>$KERNEL_INSTALL_PLUGINS</varname> can be set to override the list of plugins executed by
<command>kernel-install</command>. The argument is a whitespace-separated list of paths.
<literal>KERNEL_INSTALL_PLUGINS=:</literal> may be used to prevent any plugins from running.
</para>
<para><varname>$MACHINE_ID</varname> can be set for <command>kernel-install</command> to override
<varname>$KERNEL_INSTALL_MACHINE_ID</varname>, the machine ID.</para>
<para><varname>$BOOT_ROOT</varname> can be set for <command>kernel-install</command> to override
<varname>$KERNEL_INSTALL_BOOT_ROOT</varname>, the installation location for boot entries.</para>
<para>The last two variables may also be set in <filename>install.conf</filename>. Variables set in the
environment take precedence over the values specified in the config file.</para>
</refsect2>
</refsect1> </refsect1>
<refsect1> <refsect1>
@ -271,9 +296,10 @@
</term> </term>
<listitem> <listitem>
<para>Read by <filename>90-loaderentry.install</filename>. The content of the file <para>Read by <filename>90-loaderentry.install</filename>. The content of the file
<filename>/etc/kernel/cmdline</filename> specifies the kernel command line to use. If that file does not <filename>/etc/kernel/cmdline</filename> specifies the kernel command line to use. If that file
exist, <filename>/usr/lib/kernel/cmdline</filename> is used. If that also does not exist, does not exist, <filename>/usr/lib/kernel/cmdline</filename> is used. If that also does not
<filename>/proc/cmdline</filename> is used.</para> exist, <filename>/proc/cmdline</filename> is used. <varname>$KERNEL_INSTALL_CONF_ROOT</varname>
may be used to override the path.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
@ -286,7 +312,8 @@
<filename>$BOOT/loader/entries/<replaceable>MACHINE-ID</replaceable>-<replaceable>KERNEL-VERSION</replaceable>+<replaceable>TRIES</replaceable>.conf</filename>. This <filename>$BOOT/loader/entries/<replaceable>MACHINE-ID</replaceable>-<replaceable>KERNEL-VERSION</replaceable>+<replaceable>TRIES</replaceable>.conf</filename>. This
is useful for boot loaders such as is useful for boot loaders such as
<citerefentry><refentrytitle>systemd-boot</refentrytitle><manvolnum>7</manvolnum></citerefentry> which <citerefentry><refentrytitle>systemd-boot</refentrytitle><manvolnum>7</manvolnum></citerefentry> which
implement boot attempt counting with a counter embedded in the entry file name.</para> implement boot attempt counting with a counter embedded in the entry file name.
<varname>$KERNEL_INSTALL_CONF_ROOT</varname> may be used to override the path.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
@ -295,8 +322,9 @@
</term> </term>
<listitem> <listitem>
<para>If this file exists it is read and used as "entry token" for this system, i.e. is used for <para>If this file exists it is read and used as "entry token" for this system, i.e. is used for
naming Boot Loader Specification entries, see naming Boot Loader Specification entries, see <varname>$KERNEL_INSTALL_ENTRY_TOKEN</varname>
<varname>$KERNEL_INSTALL_ENTRY_TOKEN</varname> above for details.</para> above for details. <varname>$KERNEL_INSTALL_CONF_ROOT</varname> may be used to override the
path.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
@ -327,8 +355,19 @@
<listitem> <listitem>
<para>Configuration options for <command>kernel-install</command>, as a series of <para>Configuration options for <command>kernel-install</command>, as a series of
<varname>KEY=</varname><replaceable>VALUE</replaceable> assignments, compatible with shell <varname>KEY=</varname><replaceable>VALUE</replaceable> assignments, compatible with shell
syntax. This currently supports two keys: <varname>layout=</varname> and syntax, following the same rules as described in
<varname>initrd_generator=</varname>, for details see the Environment variables section above.</para> <citerefentry><refentrytitle>os-release</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
<filename>/etc/kernel/install.conf</filename> will be read if present, and
<filename>/usr/lib/kernel/install.conf</filename> otherwise. This file is optional.
<varname>$KERNEL_INSTALL_CONF_ROOT</varname> may be used to override the path.
</para>
<para>Currently, the following keys are supported:
<varname>MACHINE_ID=</varname>,
<varname>BOOT_ROOT=</varname>,
<varname>layout=</varname>,
<varname>initrd_generator=</varname>.
See the Environment variables section above for details.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
</variablelist> </variablelist>

View file

@ -3752,7 +3752,7 @@ executable(
install : true, install : true,
install_dir : rootlibexecdir) install_dir : rootlibexecdir)
public_programs += custom_target( exe = custom_target(
'kernel-install', 'kernel-install',
input : kernel_install_in, input : kernel_install_in,
output : 'kernel-install', output : 'kernel-install',
@ -3760,6 +3760,13 @@ public_programs += custom_target(
install : want_kernel_install, install : want_kernel_install,
install_mode : 'rwxr-xr-x', install_mode : 'rwxr-xr-x',
install_dir : bindir) install_dir : bindir)
public_programs += exe
if want_tests != 'false'
test('test-kernel-install',
test_kernel_install_sh,
args : [exe.full_path(), loaderentry_install])
endif
############################################################ ############################################################

7
src/kernel-install/50-depmod.install Normal file → Executable file
View file

@ -18,8 +18,10 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with systemd; If not, see <https://www.gnu.org/licenses/>. # along with systemd; If not, see <https://www.gnu.org/licenses/>.
COMMAND="$1" set -e
KERNEL_VERSION="$2"
COMMAND="${1:?}"
KERNEL_VERSION="${2:?}"
case "$COMMAND" in case "$COMMAND" in
add) add)
@ -44,4 +46,5 @@ case "$COMMAND" in
;; ;;
*) *)
exit 0 exit 0
;;
esac esac

36
src/kernel-install/90-loaderentry.install Normal file → Executable file
View file

@ -18,9 +18,11 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with systemd; If not, see <https://www.gnu.org/licenses/>. # along with systemd; If not, see <https://www.gnu.org/licenses/>.
COMMAND="$1" set -e
KERNEL_VERSION="$2"
ENTRY_DIR_ABS="$3" COMMAND="${1:?}"
KERNEL_VERSION="${2:?}"
ENTRY_DIR_ABS="${3:?}"
KERNEL_IMAGE="$4" KERNEL_IMAGE="$4"
INITRD_OPTIONS_SHIFT=4 INITRD_OPTIONS_SHIFT=4
@ -48,14 +50,14 @@ case "$COMMAND" in
add) add)
;; ;;
*) *)
exit 1 exit 0
;; ;;
esac esac
if [ -r /etc/os-release ]; then if [ -f /etc/os-release ]; then
# shellcheck source=/dev/null # shellcheck source=/dev/null
. /etc/os-release . /etc/os-release
elif [ -r /usr/lib/os-release ]; then elif [ -f /usr/lib/os-release ]; then
# shellcheck source=/dev/null # shellcheck source=/dev/null
. /usr/lib/os-release . /usr/lib/os-release
fi fi
@ -65,9 +67,13 @@ fi
SORT_KEY="$IMAGE_ID" SORT_KEY="$IMAGE_ID"
[ -z "$SORT_KEY" ] && SORT_KEY="$ID" [ -z "$SORT_KEY" ] && SORT_KEY="$ID"
if [ -r /etc/kernel/cmdline ]; then if [ -n "$KERNEL_INSTALL_CONF_ROOT" ]; then
if [ -f "$KERNEL_INSTALL_CONF_ROOT/cmdline" ]; then
BOOT_OPTIONS="$(tr -s "$IFS" ' ' <"$KERNEL_INSTALL_CONF_ROOT/cmdline")"
fi
elif [ -f /etc/kernel/cmdline ]; then
BOOT_OPTIONS="$(tr -s "$IFS" ' ' </etc/kernel/cmdline)" BOOT_OPTIONS="$(tr -s "$IFS" ' ' </etc/kernel/cmdline)"
elif [ -r /usr/lib/kernel/cmdline ]; then elif [ -f /usr/lib/kernel/cmdline ]; then
BOOT_OPTIONS="$(tr -s "$IFS" ' ' </usr/lib/kernel/cmdline)" BOOT_OPTIONS="$(tr -s "$IFS" ' ' </usr/lib/kernel/cmdline)"
else else
BOOT_OPTIONS="$(tr -s "$IFS" '\n' </proc/cmdline | grep -ve '^BOOT_IMAGE=' -e '^initrd=' | tr '\n' ' ')" BOOT_OPTIONS="$(tr -s "$IFS" '\n' </proc/cmdline | grep -ve '^BOOT_IMAGE=' -e '^initrd=' | tr '\n' ' ')"
@ -83,10 +89,12 @@ if [ "$ENTRY_TOKEN" = "$MACHINE_ID" ]; then
BOOT_OPTIONS="$BOOT_OPTIONS systemd.machine_id=$MACHINE_ID" BOOT_OPTIONS="$BOOT_OPTIONS systemd.machine_id=$MACHINE_ID"
fi fi
if [ -r /etc/kernel/tries ]; then TRIES_FILE="${KERNEL_INSTALL_CONF_ROOT:-/etc/kernel}/tries"
read -r TRIES </etc/kernel/tries
if [ -f "$TRIES_FILE" ]; then
read -r TRIES <"$TRIES_FILE"
if ! echo "$TRIES" | grep -q '^[0-9][0-9]*$'; then if ! echo "$TRIES" | grep -q '^[0-9][0-9]*$'; then
echo "/etc/kernel/tries does not contain an integer." >&2 echo "$TRIES_FILE does not contain an integer." >&2
exit 1 exit 1
fi fi
LOADER_ENTRY="$BOOT_ROOT/loader/entries/$ENTRY_TOKEN-$KERNEL_VERSION+$TRIES.conf" LOADER_ENTRY="$BOOT_ROOT/loader/entries/$ENTRY_TOKEN-$KERNEL_VERSION+$TRIES.conf"
@ -99,10 +107,11 @@ if ! [ -d "$ENTRY_DIR_ABS" ]; then
exit 1 exit 1
fi fi
install -g root -o root -m 0644 "$KERNEL_IMAGE" "$ENTRY_DIR_ABS/linux" || { install -m 0644 "$KERNEL_IMAGE" "$ENTRY_DIR_ABS/linux" || {
echo "Error: could not copy '$KERNEL_IMAGE' to '$ENTRY_DIR_ABS/linux'." >&2 echo "Error: could not copy '$KERNEL_IMAGE' to '$ENTRY_DIR_ABS/linux'." >&2
exit 1 exit 1
} }
chown root.root "$ENTRY_DIR_ABS/linux" || :
shift "$INITRD_OPTIONS_SHIFT" shift "$INITRD_OPTIONS_SHIFT"
# All files listed as arguments, and staged files starting with "initrd" are installed as initrds. # All files listed as arguments, and staged files starting with "initrd" are installed as initrds.
@ -115,10 +124,11 @@ for initrd in "$@" "${KERNEL_INSTALL_STAGING_AREA}"/initrd*; do
initrd_basename="${initrd##*/}" initrd_basename="${initrd##*/}"
[ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && echo "Installing $ENTRY_DIR_ABS/$initrd_basename" [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && echo "Installing $ENTRY_DIR_ABS/$initrd_basename"
install -g root -o root -m 0644 "$initrd" "$ENTRY_DIR_ABS/$initrd_basename" || { install -m 0644 "$initrd" "$ENTRY_DIR_ABS/$initrd_basename" || {
echo "Error: could not copy '$initrd' to '$ENTRY_DIR_ABS/$initrd_basename'." >&2 echo "Error: could not copy '$initrd' to '$ENTRY_DIR_ABS/$initrd_basename'." >&2
exit 1 exit 1
} }
chown root.root "$ENTRY_DIR_ABS/$initrd_basename" || :
done done
mkdir -p "${LOADER_ENTRY%/*}" || { mkdir -p "${LOADER_ENTRY%/*}" || {

View file

@ -20,6 +20,8 @@
skip_remaining=77 skip_remaining=77
set -e
usage() usage()
{ {
echo "Usage:" echo "Usage:"
@ -83,7 +85,7 @@ if [ "${0##*/}" = "installkernel" ]; then
# kernel's install.sh invokes us as # kernel's install.sh invokes us as
# /sbin/installkernel <version> <vmlinuz> <map> <installation-dir> # /sbin/installkernel <version> <vmlinuz> <map> <installation-dir>
# We ignore the last two arguments. # We ignore the last two arguments.
set -- "$1" set -- "${1:?}" "${2:?}"
else else
COMMAND="$1" COMMAND="$1"
[ $# -ge 1 ] && shift [ $# -ge 1 ] && shift
@ -101,23 +103,27 @@ else
shift shift
fi fi
# These two settings are settable in install.conf # These two settings are only settable via install.conf
layout= layout=
initrd_generator= initrd_generator=
# These two settings can be inherited from the environment
_MACHINE_ID_SAVED="$MACHINE_ID"
_BOOT_ROOT_SAVED="$BOOT_ROOT"
if [ -r "/etc/kernel/install.conf" ]; then if [ -n "$KERNEL_INSTALL_CONF_ROOT" ]; then
install_conf="$KERNEL_INSTALL_CONF_ROOT/install.conf"
elif [ -f "/etc/kernel/install.conf" ]; then
install_conf="/etc/kernel/install.conf" install_conf="/etc/kernel/install.conf"
elif [ -r "/usr/lib/kernel/install.conf" ]; then elif [ -f "/usr/lib/kernel/install.conf" ]; then
install_conf="/usr/lib/kernel/install.conf" install_conf="/usr/lib/kernel/install.conf"
else else
install_conf= install_conf=
fi fi
if [ -n "$install_conf" ]; then if [ -f "$install_conf" ]; then
[ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && echo "Reading $install_conf…" [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && echo "Reading $install_conf…"
# shellcheck source=/dev/null # shellcheck source=/dev/null
. "$install_conf" . "$install_conf"
# FIXME: This may override configuration in environment variables, e.g. $BOOT_ROOT.
fi fi
[ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && [ -n "$layout" ] && \ [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && [ -n "$layout" ] && \
@ -125,21 +131,37 @@ fi
[ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && [ -n "$initrd_generator" ] && \ [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && [ -n "$initrd_generator" ] && \
echo "$install_conf configures initrd_generator=$initrd_generator" echo "$install_conf configures initrd_generator=$initrd_generator"
[ -n "$MACHINE_ID" ] && [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && \ if [ -n "$_MACHINE_ID_SAVED" ]; then
echo "machine-id $MACHINE_ID set via environment or install.conf" MACHINE_ID="$_MACHINE_ID_SAVED"
[ -n "$BOOT_ROOT" ] && [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && \ [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && \
echo "BOOT_ROOT=$BOOT_ROOT set via environment or install.conf" echo "MACHINE_ID=$MACHINE_ID set via environment"
else
[ -n "$MACHINE_ID" ] && [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && \
echo "MACHINE_ID=$MACHINE_ID set via install.conf"
fi
if [ -n "$_BOOT_ROOT_SAVED" ]; then
BOOT_ROOT="$_BOOT_ROOT_SAVED"
[ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && \
echo "BOOT_ROOT=$BOOT_ROOT set via environment"
else
[ -n "$BOOT_ROOT" ] && [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && \
echo "BOOT_ROOT=$BOOT_ROOT set via install.conf"
fi
# If /etc/machine-id is initialized we'll use it, otherwise we'll use a freshly # If /etc/machine-id is initialized we'll use it, otherwise we'll use a freshly
# generated one. If the user configured an explicit machine ID to use in # generated one. If the user configured an explicit machine ID to use in
# /etc/machine-info to use for our purpose, we'll use that instead (for # /etc/machine-info to use for our purpose, we'll use that instead (for
# compatibility). # compatibility).
# shellcheck source=/dev/null # shellcheck source=/dev/null
if [ -z "$MACHINE_ID" ] && [ -r /etc/machine-info ] && . /etc/machine-info && MACHINE_ID="$KERNEL_INSTALL_MACHINE_ID"; then if [ -z "$MACHINE_ID" ] && [ -f /etc/machine-info ]; then
. /etc/machine-info
MACHINE_ID="$KERNEL_INSTALL_MACHINE_ID"
[ -n "$MACHINE_ID" ] && [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && \ [ -n "$MACHINE_ID" ] && [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && \
echo "machine-id $MACHINE_ID acquired from /etc/machine-info" echo "machine-id $MACHINE_ID acquired from /etc/machine-info"
fi fi
if [ -z "$MACHINE_ID" ] && [ -r /etc/machine-id ] && read -r MACHINE_ID </etc/machine-id; then if [ -z "$MACHINE_ID" ] && [ -f /etc/machine-id ]; then
read -r MACHINE_ID </etc/machine-id
[ -n "$MACHINE_ID" ] && [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && \ [ -n "$MACHINE_ID" ] && [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && \
echo "machine-id $MACHINE_ID acquired from /etc/machine-id" echo "machine-id $MACHINE_ID acquired from /etc/machine-id"
fi fi
@ -153,9 +175,12 @@ fi
# $BOOT where we want to place the kernel/initrd and related resources, as well # $BOOT where we want to place the kernel/initrd and related resources, as well
# for naming the .conf boot loader spec entry. Typically this is just the # for naming the .conf boot loader spec entry. Typically this is just the
# machine ID, but it can be anything else, too, if we are told so. # machine ID, but it can be anything else, too, if we are told so.
if [ -z "$ENTRY_TOKEN" ] && [ -r /etc/kernel/entry-token ] && read -r ENTRY_TOKEN </etc/kernel/entry-token; then ENTRY_TOKEN_FILE="${KERNEL_INSTALL_CONF_ROOT:-/etc/kernel}/entry-token"
if [ -z "$ENTRY_TOKEN" ] && [ -f "$ENTRY_TOKEN_FILE" ]; then
read -r ENTRY_TOKEN <"$ENTRY_TOKEN_FILE"
[ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && \ [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && \
echo "entry-token \"$ENTRY_TOKEN\" acquired from /etc/kernel/entry-token" echo "entry-token \"$ENTRY_TOKEN\" acquired from $ENTRY_TOKEN_FILE"
fi fi
if [ -z "$ENTRY_TOKEN" ]; then if [ -z "$ENTRY_TOKEN" ]; then
# If not configured explicitly, then use a few candidates: the machine ID, # If not configured explicitly, then use a few candidates: the machine ID,
@ -163,7 +188,7 @@ if [ -z "$ENTRY_TOKEN" ]; then
# string "Default" # string "Default"
ENTRY_TOKEN_SEARCH="$MACHINE_ID" ENTRY_TOKEN_SEARCH="$MACHINE_ID"
# shellcheck source=/dev/null # shellcheck source=/dev/null
[ -r /etc/os-release ] && . /etc/os-release [ -f /etc/os-release ] && . /etc/os-release
[ -n "$IMAGE_ID" ] && ENTRY_TOKEN_SEARCH="$ENTRY_TOKEN_SEARCH $IMAGE_ID" [ -n "$IMAGE_ID" ] && ENTRY_TOKEN_SEARCH="$ENTRY_TOKEN_SEARCH $IMAGE_ID"
[ -n "$ID" ] && ENTRY_TOKEN_SEARCH="$ENTRY_TOKEN_SEARCH $ID" [ -n "$ID" ] && ENTRY_TOKEN_SEARCH="$ENTRY_TOKEN_SEARCH $ID"
ENTRY_TOKEN_SEARCH="$ENTRY_TOKEN_SEARCH Default" ENTRY_TOKEN_SEARCH="$ENTRY_TOKEN_SEARCH Default"
@ -289,15 +314,20 @@ MAKE_ENTRY_DIR_ABS=$?
ret=0 ret=0
PLUGINS="$( if [ -z "$KERNEL_INSTALL_PLUGINS" ]; then
dropindirs_sort ".install" \ KERNEL_INSTALL_PLUGINS="$(
"/etc/kernel/install.d" \ dropindirs_sort ".install" \
"/usr/lib/kernel/install.d" "/etc/kernel/install.d" \
)" "/usr/lib/kernel/install.d"
IFS=" )"
" fi
[ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && printf '%s\n' "Plugin files:" "$PLUGINS" if [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ]; then
printf '%s\n' "Plugin files:"
for f in $KERNEL_INSTALL_PLUGINS; do
printf '%s\n' "$f"
done
fi
case "$COMMAND" in case "$COMMAND" in
add) add)
@ -323,7 +353,7 @@ case "$COMMAND" in
fi fi
fi fi
for f in $PLUGINS; do for f in $KERNEL_INSTALL_PLUGINS; do
[ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && echo "+$f add $KERNEL_VERSION $ENTRY_DIR_ABS" "$@" [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && echo "+$f add $KERNEL_VERSION $ENTRY_DIR_ABS" "$@"
"$f" add "$KERNEL_VERSION" "$ENTRY_DIR_ABS" "$@" "$f" add "$KERNEL_VERSION" "$ENTRY_DIR_ABS" "$@"
@ -334,7 +364,7 @@ case "$COMMAND" in
;; ;;
remove) remove)
for f in $PLUGINS; do for f in $KERNEL_INSTALL_PLUGINS; do
[ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && echo "+$f remove $KERNEL_VERSION $ENTRY_DIR_ABS" [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && echo "+$f remove $KERNEL_VERSION $ENTRY_DIR_ABS"
"$f" remove "$KERNEL_VERSION" "$ENTRY_DIR_ABS" "$f" remove "$KERNEL_VERSION" "$ENTRY_DIR_ABS"
err=$? err=$?

View file

@ -1,10 +1,11 @@
# SPDX-License-Identifier: LGPL-2.1-or-later # SPDX-License-Identifier: LGPL-2.1-or-later
kernel_install_in = files('kernel-install.in') kernel_install_in = files('kernel-install.in')
loaderentry_install = files('90-loaderentry.install')
if want_kernel_install if want_kernel_install
install_data('50-depmod.install', install_data('50-depmod.install',
'90-loaderentry.install', loaderentry_install,
install_mode : 'rwxr-xr-x', install_mode : 'rwxr-xr-x',
install_dir : kernelinstalldir) install_dir : kernelinstalldir)
@ -16,4 +17,5 @@ if want_kernel_install
mkdir_p.format(sysconfdir / 'kernel/install.d')) mkdir_p.format(sysconfdir / 'kernel/install.d'))
endif endif
test_kernel_install_sh = find_program('test-kernel-install.sh')
endif endif

View file

@ -0,0 +1,84 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: LGPL-2.1-or-later
# shellcheck disable=SC2235
set -eu
set -o pipefail
kernel_install="${1:?}"
plugin="${2:?}"
D="$(mktemp --tmpdir --directory "test-kernel-install.XXXXXXXXXX")"
# shellcheck disable=SC2064
trap "rm -rf '$D'" EXIT INT QUIT PIPE
mkdir -p "$D/boot"
mkdir -p "$D/efi"
mkdir -p "$D/sources"
echo 'buzy image' >"$D/sources/linux"
echo 'the initrd' >"$D/sources/initrd"
echo 'the-token' >"$D/sources/entry-token"
echo 'opt1 opt2' >"$D/sources/cmdline"
cat >"$D/sources/install.conf" <<EOF
layout=bls
initrd_generator=none
# those are overriden by envvars
BOOT_ROOT="$D/badboot"
MACHINE_ID=badbadbadbadbadbad6abadbadbadbad
EOF
export KERNEL_INSTALL_CONF_ROOT="$D/sources"
export KERNEL_INSTALL_PLUGINS="$plugin"
export BOOT_ROOT="$D/boot"
export MACHINE_ID='3e0484f3634a418b8e6a39e8828b03e3'
"$kernel_install" -v add 1.1.1 "$D/sources/linux" "$D/sources/initrd"
entry="$BOOT_ROOT/loader/entries/the-token-1.1.1.conf"
test -f "$entry"
grep -qE '^title ' "$entry"
grep -qE '^version +1.1.1' "$entry"
grep -qE '^options +opt1 opt2' "$entry"
grep -qE '^linux .*/the-token/1.1.1/linux' "$entry"
grep -qE '^initrd .*/the-token/1.1.1/initrd' "$entry"
grep -qE 'image' "$BOOT_ROOT/the-token/1.1.1/linux"
grep -qE 'initrd' "$BOOT_ROOT/the-token/1.1.1/initrd"
"$kernel_install" inspect
"$kernel_install" -v remove 1.1.1
test ! -f "$entry"
test ! -f "$BOOT_ROOT/the-token/1.1.1/linux"
test ! -f "$BOOT_ROOT/the-token/1.1.1/initrd"
# Invoke kernel-install as installkernel
ln -s --relative -v "$kernel_install" "$D/sources/installkernel"
"$D/sources/installkernel" -v 1.1.2 "$D/sources/linux" System.map /somedirignored
entry="$BOOT_ROOT/loader/entries/the-token-1.1.2.conf"
test -f "$entry"
grep -qE '^title ' "$entry"
grep -qE '^version +1.1.2' "$entry"
grep -qE '^options +opt1 opt2' "$entry"
grep -qE '^linux .*/the-token/1.1.2/linux' "$entry"
( ! grep -qE '^initrd' "$entry" )
grep -qE 'image' "$BOOT_ROOT/the-token/1.1.2/linux"
test ! -e "$BOOT_ROOT/the-token/1.1.2/initrd"
# Check installation with boot counting
echo '56' >"$D/sources/tries"
"$kernel_install" -v add 1.1.1 "$D/sources/linux" "$D/sources/initrd"
entry="$BOOT_ROOT/loader/entries/the-token-1.1.1+56.conf"
test -f "$entry"
grep -qE '^title ' "$entry"
grep -qE '^version +1.1.1' "$entry"
grep -qE '^options +opt1 opt2' "$entry"
grep -qE '^linux .*/the-token/1.1.1/linux' "$entry"
grep -qE '^initrd .*/the-token/1.1.1/initrd' "$entry"
grep -qE 'image' "$BOOT_ROOT/the-token/1.1.1/linux"
grep -qE 'initrd' "$BOOT_ROOT/the-token/1.1.1/initrd"