How to build kernel packages which requires user's ZERO manual intervention when they are installed, removed or God forbids! even upgraded
by LuckyCyborg from LinuxQuestions.org on (#6PPSS)
There are already several years since I repeat like a broken gramophone that it's dead simple to build kernel package for Slackware, which needs ZERO intervention from the user part when they are installed. Or removed, or even upgraded.
Read: the user should do NOTHING more when install or removes a kernel package.
How the honorable Slackers managed to exasperate me with their obsession for symlinks, even after our BDFL claimed that he adopted the versioned naming for the kernels and initrds, I have decided to show practically, instead of repeating thousand time again how to do these kernel packages which needs NO user manual intervention after their installation.
For the sake of speeding up your experience with this new kind of kernel packages, I have decided to show you a variant of repackaging the official kernel packages. But of course, nothing stops you to adopt this design on building for real your kernel packages.
So, what you will get? Well, the packages kernel-generic and kernel-modules will be merged in a single package named kernel-generic and the kernel-huge will be repackaged too to get the appropriate scripting. And you will have NO symlinks at all on your /boot directory. Nothing, nada. Yet, everything will work. ;)
But from beginning I strive you to note that I do not believe on Automagic, then on making your computer to think instead of you. Instead, I for one I believe on Automatic, then to make your computer to execute certain mundane tasks on a precise order and timing. I do this observation because I have noticed that many Slackers understand by Automatic that their computer will think for them. This is NOT true. The computers does NOT think. Yet.
So, we will start with instructing the system to make initrds with a minimum of ulterior information, then we will setup a proper /etc/mkinitrd.conf config file.
Believe it or not, this config file is not my invention, but a very part of Slackware, but seems like that the people are so busy on talking about kernel symlinks that I am the single one talking about this /etc/mkinitrd.conf.
For configuring it, you should start by executing this command:
Code:/usr/share/mkinitrd/mkinitrd_command_generator.sh -c > /etc/mkinitrd.confYou will get something like bellow on your new config file:
Code:SOURCE_TREE="/boot/initrd-tree"
CLEAR_TREE="1"
OUTPUT_IMAGE="/boot/initrd.gz"
KERNEL_VERSION="6.10.2"
KEYMAP="us"
MODULE_LIST="usb-storage:uas:xhci-hcd:xhci-pci:ohci-pci:ehci-pci:uhci-hcd:ehci-hcd:hid:usbhid:i2c-hid:hid_generic:hid-asus:hid-cherry:hid-logitech:hid-logitech-dj:hid-logitech-hidpp:hid-lenovo:hid-microsoft:hid_multitouch:ext4"
LUKSDEV=""
ROOTDEV="/dev/sdc3"
ROOTFS="ext4"
RESUMEDEV=""
RAID=""
LVM=""
UDEV="1"
WAIT="1"There the $SOURCE_TREE, $OUTPUT_IMAGE and $KERNEL_VERSION does not matter much because these options will be latter overridden by the command line when the mkinitrd is called. BUT, you should may or may not adapt the other options after your taste and needs.
Once done this, you should create an executable script named /boot/setup-kernel, with the following content:
Code:#!/bin/sh
# Copyright 2024 LuckyCyborg, Terra, Solar System.
# All rights reserved.
#
# Redistribution and use of this script, with or without modification, is
# permitted provided that the following conditions are met:
#
# 1. Redistributions of this script must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
############################################################################
# THE SETUP LOGIC. PLEASE DO NOT MODIFY THE PART BELLOW!
############################################################################
# The version of kernel which we will setup:
KVERSION=""
# The flavor of kernel which we will setup:
KFLAVOR=""
# Disable the initrd generation?
NOINITRD=0
# Cleanup the initrd files and directories?
CLEANUP=0
# So that we know what to expect...
umask 022
usage() {
cat << EOF
Usage: setup-kernel [options]
Setup-kernel is used to update the GRUB2 configuration and to generate an
initrd for a given kernel version and flavor, with a command like this:
/boot/setup-kernel --version 6.10.2 --flavor generic [--no-initrd]
options: --version kernel_version (the version of the kernel to setup)
--flavor kernel_flavor (the flavor of the kernel to setup)
--no-initrd (do not create an initrd)
EOF
}
# Parse options:
while [ ! -z "$1" ]; do
if [ "$1" == "-version" -o "$1" == "--version" ]; then
if [ "$2" == "" ]; then
usage
exit
fi
KVERSION="$2"
shift 2
elif [ "$1" == "-flavor" -o "$1" == "--flavor" ]; then
if [ "$2" == "" ]; then
usage
exit
fi
KFLAVOR="$2"
shift 2
elif [ "$1" == "-no-initrd" -o "$1" == "--no-initrd" ]; then
NOINITRD=1
shift
elif [ "$1" == "-cleanup" -o "$1" == "--cleanup" ]; then
CLEANUP=1
shift
else
break
fi
done
# usage(), exit if called without a kernel version as arguments:
if [[ -z "${KVERSION}" ]]; then
usage;
exit
fi
# Ensure that the kernel flavor starts with the "-" char when not empty:
if [[ ! -z "${KFLAVOR}" ]]; then
[[ "${KFLAVOR}" =~ ^-.* ]] || KFLAVOR="-${KFLAVOR}"
fi
# Calculate the initrd version:
INITRD_VERSION="${KVERSION}${KFLAVOR}"
# We will create an initrd only when the file /etc/mkinitrd.conf exists:
[ -r /etc/mkinitrd.conf ] || NOINITRD=1
############################################################################
# YOU CAN CUSTOMIZE AS YOU LIKE ANYTHING BELLOW
############################################################################
#
# CLEANUP OR GENERATE AN INITRD FOR THE SPECIFIED KERNEL VERSION:
if [ ${CLEANUP} == 1 ]; then
/bin/rm -f "/boot/initrd-${INITRD_VERSION}.img"
elif [ ${NOINITRD} == 0 ]; then
/sbin/mkinitrd -F -k "${KVERSION}" \
-s "/boot/initrd-${INITRD_VERSION}" \
-o "/boot/initrd-${INITRD_VERSION}.img"
# Cleanup the initrd tree after creating it:
/bin/rm -rf "/boot/initrd-${INITRD_VERSION}"
fi
############################################################################
# UPDATE THE GRUB2 CONFIGURATION:
#
# We will update the GRUB2 configuration ONLY when that file already exists.
if [ -r /boot/grub/grub.cfg ]; then
/usr/sbin/update-grub
fiAS you can see, this script receives a series of parameters and essentially handles the creation and removal of a given initrd, and also always calls the update-grub . With the condition that you already have the file /boot/grub/grub.cfg.
Because this particular script is called by the install/doinst.sh and install/dounist.sh from the (repackaged) kernel packages, this little trick permits to install these packages from an installer, without calling yet the update-grub. Yep, it works. I have tested this practically.
You may ask WHY I thought to put this script on /boot directory, instead of /sbin or whatever. Well, I think that it can get a .new treatment with permissions preservation, and you as user can modify it as you want. For example, modifying it, you can handle the Limine configuration instead of the GRUB2 one. Believe it or not, I have did this too. ;)
Finally, with this done, it's time to prepare the tree for repackage the kernels. For this, you will need an empty directory, which contains only an folder named "incoming" which contains the stock kernel packages which you will download manually from your favorite mirror. I for one, I have used for tests these packages from /testing
Code:root@darkstar:~/works/kernels/incoming# ls -1
kernel-generic-6.10.2-x86_64-1.txz
kernel-huge-6.10.2-x86_64-1.txz
kernel-modules-6.10.2-x86_64-1.txz
root@darkstar:~/works/kernels/incoming#And, of course a script for repackaging the kernels, with the content bellow:
Code:#!/bin/sh
# Copyright 2024 LuckyCyborg, Terra, Solar System.
# All rights reserved.
#
# Redistribution and use of this script, with or without modification, is
# permitted provided that the following conditions are met:
#
# 1. Redistributions of this script must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
CWD=$(pwd)
INCOMING=$CWD/incoming
OUTPUT=$CWD/output
WORKPATH=$CWD/build
# The version of the kernel packages which we will repack:
KVERSION=""
# So that we know what to expect...
umask 022
usage() {
cat << EOF
Usage: repack-kernels.sh [options]
repack-kernels is used to repack the kernel packages, with a command like this:
./repack-kernels.sh --version 6.10.2
options: --version kernel_version (the version of the kernel packages)
EOF
}
# Parse options:
while [ ! -z "$1" ]; do
if [ "$1" == "-version" -o "$1" == "--version" ]; then
if [ "$2" == "" ]; then
usage
exit
fi
KVERSION="$2"
shift 2
else
break
fi
done
# usage(), exit if called without a kernel version as arguments:
if [[ -z "${KVERSION}" ]]; then
usage;
exit
fi
# Create the work directories:
mkdir -p $OUTPUT $WORKPATH
############################################################################
# BUILD LOGIC
############################################################################
if [ ! -r $INCOMING/kernel-generic-$KVERSION-*.t?z -o ! -r $INCOMING/kernel-huge-$KVERSION-*.t?z -o ! -r $INCOMING/kernel-modules-$KVERSION-*.t?z ]; then
echo "Cannot find the stock kernel packages"
exit
fi
############################################################################
#
# Repack the kernel-generic package including the modules:
rm -rf $WORKPATH/*
( cd $WORKPATH
explodepkg $INCOMING/kernel-modules-$KVERSION-*.t?z $INCOMING/kernel-generic-$KVERSION-*.t?z
)
cat << EOF > $WORKPATH/install/doinst.sh
#!/bin/sh
if [ -x boot/setup-kernel ] ; then
/bin/chroot . /bin/sh -c "/boot/setup-kernel --version ${KVERSION} --flavor generic"
fi
EOF
cat << EOF > $WORKPATH/install/douninst.sh
#!/bin/sh
if [ -x boot/setup-kernel ] ; then
/bin/chroot . /bin/sh -c "/boot/setup-kernel --version ${KVERSION} --flavor generic --cleanup"
fi
EOF
# Add the build symlink on the modules directory:
( cd $WORKPATH/lib/modules/$KVERSION
ln -sf /usr/src/linux-$KVERSION build
)
# Create the new package:
( cd $WORKPATH
/sbin/makepkg -l y -c n $OUTPUT/kernel-generic-$KVERSION-x86_64-1_local.txz
)
############################################################################
#
# Repack the kernel-huge package:
rm -rf $WORKPATH/*
( cd $WORKPATH
explodepkg $INCOMING/kernel-huge-$KVERSION-*.t?z
)
cat << EOF > $WORKPATH/install/doinst.sh
#!/bin/sh
if [ -x boot/setup-kernel ] ; then
/bin/chroot . /bin/sh -c "/boot/setup-kernel --version ${KVERSION} --flavor huge --no-initrd"
fi
EOF
cat << EOF > $WORKPATH/install/douninst.sh
#!/bin/sh
if [ -x boot/setup-kernel ] ; then
/bin/chroot . /bin/sh -c "/boot/setup-kernel --version ${KVERSION} --flavor huge --no-initrd"
fi
EOF
# Create the new package:
( cd $WORKPATH
/sbin/makepkg -l y -c n $OUTPUT/kernel-huge-$KVERSION-x86_64-1_local.txz
)
# Final cleanup of the workpath:
rm -rf $WORKPATH/*This script (named by me repack-kernels.sh) should stay on the parent folder of that "incoming" directory where you have put the stock packages.
Then, all you need is to execute this script as root, with a command like:
Code:./repack-kernels.sh --version 6.10.2After the script finishes the repacking and adjusts the install/ scripts, you will get on a folder named "output" the following packages:
Code:root@darkstar:~/works/kernels/output# ls -1
kernel-generic-6.10.2-x86_64-1_local.txz
kernel-huge-6.10.2-x86_64-1_local.txz
root@darkstar:~/works/kernels/output#The first package contains both the generic kernel and the associated modules, the second one obviously contains the huge kernel.
Arrived at this point, you may ask: in the end, what's the point?
Well, the point is that these new packages you can just install (or remove them) like any package and reboot the system. You can just do this:
Code:installpkg kernel-generic-6.10.2-x86_64-1_local.txzYou will see the associated initrd generated on-fly, you will see the GRUB2 configuration updated on-fly, and all you need to do is to reboot the system and to enjoy this new kernel.
Yep, there is ZERO manual intervention needed for installing them from your part. No need to remember to generate initrds, no need to remember to update the GRUB2 configuration, you do not need to do nothing. Like I have said many times already, I do not think something could be simpler than doing nothing. And as you see practically, it's really dead simple to implement it.
That being said, have your fun with this shameless stolen Ubuntu technology. Or it was stolen from openSUSE? Honestly, I do not remember anymore. :hattip:
PS. Maybe next time I will tell you how to make kernel packages which ALWAYS will be installed along with the previous kernels, no matter matter if you use the upgradepkg or not. Because upgrading kernels is an atrocity, you know... ;)
Read: the user should do NOTHING more when install or removes a kernel package.
How the honorable Slackers managed to exasperate me with their obsession for symlinks, even after our BDFL claimed that he adopted the versioned naming for the kernels and initrds, I have decided to show practically, instead of repeating thousand time again how to do these kernel packages which needs NO user manual intervention after their installation.
For the sake of speeding up your experience with this new kind of kernel packages, I have decided to show you a variant of repackaging the official kernel packages. But of course, nothing stops you to adopt this design on building for real your kernel packages.
So, what you will get? Well, the packages kernel-generic and kernel-modules will be merged in a single package named kernel-generic and the kernel-huge will be repackaged too to get the appropriate scripting. And you will have NO symlinks at all on your /boot directory. Nothing, nada. Yet, everything will work. ;)
But from beginning I strive you to note that I do not believe on Automagic, then on making your computer to think instead of you. Instead, I for one I believe on Automatic, then to make your computer to execute certain mundane tasks on a precise order and timing. I do this observation because I have noticed that many Slackers understand by Automatic that their computer will think for them. This is NOT true. The computers does NOT think. Yet.
So, we will start with instructing the system to make initrds with a minimum of ulterior information, then we will setup a proper /etc/mkinitrd.conf config file.
Believe it or not, this config file is not my invention, but a very part of Slackware, but seems like that the people are so busy on talking about kernel symlinks that I am the single one talking about this /etc/mkinitrd.conf.
For configuring it, you should start by executing this command:
Code:/usr/share/mkinitrd/mkinitrd_command_generator.sh -c > /etc/mkinitrd.confYou will get something like bellow on your new config file:
Code:SOURCE_TREE="/boot/initrd-tree"
CLEAR_TREE="1"
OUTPUT_IMAGE="/boot/initrd.gz"
KERNEL_VERSION="6.10.2"
KEYMAP="us"
MODULE_LIST="usb-storage:uas:xhci-hcd:xhci-pci:ohci-pci:ehci-pci:uhci-hcd:ehci-hcd:hid:usbhid:i2c-hid:hid_generic:hid-asus:hid-cherry:hid-logitech:hid-logitech-dj:hid-logitech-hidpp:hid-lenovo:hid-microsoft:hid_multitouch:ext4"
LUKSDEV=""
ROOTDEV="/dev/sdc3"
ROOTFS="ext4"
RESUMEDEV=""
RAID=""
LVM=""
UDEV="1"
WAIT="1"There the $SOURCE_TREE, $OUTPUT_IMAGE and $KERNEL_VERSION does not matter much because these options will be latter overridden by the command line when the mkinitrd is called. BUT, you should may or may not adapt the other options after your taste and needs.
Once done this, you should create an executable script named /boot/setup-kernel, with the following content:
Code:#!/bin/sh
# Copyright 2024 LuckyCyborg, Terra, Solar System.
# All rights reserved.
#
# Redistribution and use of this script, with or without modification, is
# permitted provided that the following conditions are met:
#
# 1. Redistributions of this script must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
############################################################################
# THE SETUP LOGIC. PLEASE DO NOT MODIFY THE PART BELLOW!
############################################################################
# The version of kernel which we will setup:
KVERSION=""
# The flavor of kernel which we will setup:
KFLAVOR=""
# Disable the initrd generation?
NOINITRD=0
# Cleanup the initrd files and directories?
CLEANUP=0
# So that we know what to expect...
umask 022
usage() {
cat << EOF
Usage: setup-kernel [options]
Setup-kernel is used to update the GRUB2 configuration and to generate an
initrd for a given kernel version and flavor, with a command like this:
/boot/setup-kernel --version 6.10.2 --flavor generic [--no-initrd]
options: --version kernel_version (the version of the kernel to setup)
--flavor kernel_flavor (the flavor of the kernel to setup)
--no-initrd (do not create an initrd)
EOF
}
# Parse options:
while [ ! -z "$1" ]; do
if [ "$1" == "-version" -o "$1" == "--version" ]; then
if [ "$2" == "" ]; then
usage
exit
fi
KVERSION="$2"
shift 2
elif [ "$1" == "-flavor" -o "$1" == "--flavor" ]; then
if [ "$2" == "" ]; then
usage
exit
fi
KFLAVOR="$2"
shift 2
elif [ "$1" == "-no-initrd" -o "$1" == "--no-initrd" ]; then
NOINITRD=1
shift
elif [ "$1" == "-cleanup" -o "$1" == "--cleanup" ]; then
CLEANUP=1
shift
else
break
fi
done
# usage(), exit if called without a kernel version as arguments:
if [[ -z "${KVERSION}" ]]; then
usage;
exit
fi
# Ensure that the kernel flavor starts with the "-" char when not empty:
if [[ ! -z "${KFLAVOR}" ]]; then
[[ "${KFLAVOR}" =~ ^-.* ]] || KFLAVOR="-${KFLAVOR}"
fi
# Calculate the initrd version:
INITRD_VERSION="${KVERSION}${KFLAVOR}"
# We will create an initrd only when the file /etc/mkinitrd.conf exists:
[ -r /etc/mkinitrd.conf ] || NOINITRD=1
############################################################################
# YOU CAN CUSTOMIZE AS YOU LIKE ANYTHING BELLOW
############################################################################
#
# CLEANUP OR GENERATE AN INITRD FOR THE SPECIFIED KERNEL VERSION:
if [ ${CLEANUP} == 1 ]; then
/bin/rm -f "/boot/initrd-${INITRD_VERSION}.img"
elif [ ${NOINITRD} == 0 ]; then
/sbin/mkinitrd -F -k "${KVERSION}" \
-s "/boot/initrd-${INITRD_VERSION}" \
-o "/boot/initrd-${INITRD_VERSION}.img"
# Cleanup the initrd tree after creating it:
/bin/rm -rf "/boot/initrd-${INITRD_VERSION}"
fi
############################################################################
# UPDATE THE GRUB2 CONFIGURATION:
#
# We will update the GRUB2 configuration ONLY when that file already exists.
if [ -r /boot/grub/grub.cfg ]; then
/usr/sbin/update-grub
fiAS you can see, this script receives a series of parameters and essentially handles the creation and removal of a given initrd, and also always calls the update-grub . With the condition that you already have the file /boot/grub/grub.cfg.
Because this particular script is called by the install/doinst.sh and install/dounist.sh from the (repackaged) kernel packages, this little trick permits to install these packages from an installer, without calling yet the update-grub. Yep, it works. I have tested this practically.
You may ask WHY I thought to put this script on /boot directory, instead of /sbin or whatever. Well, I think that it can get a .new treatment with permissions preservation, and you as user can modify it as you want. For example, modifying it, you can handle the Limine configuration instead of the GRUB2 one. Believe it or not, I have did this too. ;)
Finally, with this done, it's time to prepare the tree for repackage the kernels. For this, you will need an empty directory, which contains only an folder named "incoming" which contains the stock kernel packages which you will download manually from your favorite mirror. I for one, I have used for tests these packages from /testing
Code:root@darkstar:~/works/kernels/incoming# ls -1
kernel-generic-6.10.2-x86_64-1.txz
kernel-huge-6.10.2-x86_64-1.txz
kernel-modules-6.10.2-x86_64-1.txz
root@darkstar:~/works/kernels/incoming#And, of course a script for repackaging the kernels, with the content bellow:
Code:#!/bin/sh
# Copyright 2024 LuckyCyborg, Terra, Solar System.
# All rights reserved.
#
# Redistribution and use of this script, with or without modification, is
# permitted provided that the following conditions are met:
#
# 1. Redistributions of this script must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
CWD=$(pwd)
INCOMING=$CWD/incoming
OUTPUT=$CWD/output
WORKPATH=$CWD/build
# The version of the kernel packages which we will repack:
KVERSION=""
# So that we know what to expect...
umask 022
usage() {
cat << EOF
Usage: repack-kernels.sh [options]
repack-kernels is used to repack the kernel packages, with a command like this:
./repack-kernels.sh --version 6.10.2
options: --version kernel_version (the version of the kernel packages)
EOF
}
# Parse options:
while [ ! -z "$1" ]; do
if [ "$1" == "-version" -o "$1" == "--version" ]; then
if [ "$2" == "" ]; then
usage
exit
fi
KVERSION="$2"
shift 2
else
break
fi
done
# usage(), exit if called without a kernel version as arguments:
if [[ -z "${KVERSION}" ]]; then
usage;
exit
fi
# Create the work directories:
mkdir -p $OUTPUT $WORKPATH
############################################################################
# BUILD LOGIC
############################################################################
if [ ! -r $INCOMING/kernel-generic-$KVERSION-*.t?z -o ! -r $INCOMING/kernel-huge-$KVERSION-*.t?z -o ! -r $INCOMING/kernel-modules-$KVERSION-*.t?z ]; then
echo "Cannot find the stock kernel packages"
exit
fi
############################################################################
#
# Repack the kernel-generic package including the modules:
rm -rf $WORKPATH/*
( cd $WORKPATH
explodepkg $INCOMING/kernel-modules-$KVERSION-*.t?z $INCOMING/kernel-generic-$KVERSION-*.t?z
)
cat << EOF > $WORKPATH/install/doinst.sh
#!/bin/sh
if [ -x boot/setup-kernel ] ; then
/bin/chroot . /bin/sh -c "/boot/setup-kernel --version ${KVERSION} --flavor generic"
fi
EOF
cat << EOF > $WORKPATH/install/douninst.sh
#!/bin/sh
if [ -x boot/setup-kernel ] ; then
/bin/chroot . /bin/sh -c "/boot/setup-kernel --version ${KVERSION} --flavor generic --cleanup"
fi
EOF
# Add the build symlink on the modules directory:
( cd $WORKPATH/lib/modules/$KVERSION
ln -sf /usr/src/linux-$KVERSION build
)
# Create the new package:
( cd $WORKPATH
/sbin/makepkg -l y -c n $OUTPUT/kernel-generic-$KVERSION-x86_64-1_local.txz
)
############################################################################
#
# Repack the kernel-huge package:
rm -rf $WORKPATH/*
( cd $WORKPATH
explodepkg $INCOMING/kernel-huge-$KVERSION-*.t?z
)
cat << EOF > $WORKPATH/install/doinst.sh
#!/bin/sh
if [ -x boot/setup-kernel ] ; then
/bin/chroot . /bin/sh -c "/boot/setup-kernel --version ${KVERSION} --flavor huge --no-initrd"
fi
EOF
cat << EOF > $WORKPATH/install/douninst.sh
#!/bin/sh
if [ -x boot/setup-kernel ] ; then
/bin/chroot . /bin/sh -c "/boot/setup-kernel --version ${KVERSION} --flavor huge --no-initrd"
fi
EOF
# Create the new package:
( cd $WORKPATH
/sbin/makepkg -l y -c n $OUTPUT/kernel-huge-$KVERSION-x86_64-1_local.txz
)
# Final cleanup of the workpath:
rm -rf $WORKPATH/*This script (named by me repack-kernels.sh) should stay on the parent folder of that "incoming" directory where you have put the stock packages.
Then, all you need is to execute this script as root, with a command like:
Code:./repack-kernels.sh --version 6.10.2After the script finishes the repacking and adjusts the install/ scripts, you will get on a folder named "output" the following packages:
Code:root@darkstar:~/works/kernels/output# ls -1
kernel-generic-6.10.2-x86_64-1_local.txz
kernel-huge-6.10.2-x86_64-1_local.txz
root@darkstar:~/works/kernels/output#The first package contains both the generic kernel and the associated modules, the second one obviously contains the huge kernel.
Arrived at this point, you may ask: in the end, what's the point?
Well, the point is that these new packages you can just install (or remove them) like any package and reboot the system. You can just do this:
Code:installpkg kernel-generic-6.10.2-x86_64-1_local.txzYou will see the associated initrd generated on-fly, you will see the GRUB2 configuration updated on-fly, and all you need to do is to reboot the system and to enjoy this new kernel.
Yep, there is ZERO manual intervention needed for installing them from your part. No need to remember to generate initrds, no need to remember to update the GRUB2 configuration, you do not need to do nothing. Like I have said many times already, I do not think something could be simpler than doing nothing. And as you see practically, it's really dead simple to implement it.
That being said, have your fun with this shameless stolen Ubuntu technology. Or it was stolen from openSUSE? Honestly, I do not remember anymore. :hattip:
PS. Maybe next time I will tell you how to make kernel packages which ALWAYS will be installed along with the previous kernels, no matter matter if you use the upgradepkg or not. Because upgrading kernels is an atrocity, you know... ;)