Ability to parse recommended kernel versions from the command line

With the retirement of the linux-latest metapackage, it has become somewhat tricky to know exactly which kernel version ought to be installed when running Manjaro strictly in a headless manner. Let’s assume that I am using a headless Manjaro system and that I would like to remain on the latest officially Recommended kernel version. How do I find out what that is?

Turns out this is not so simple to do even manually. The only way I found, short of reviewing the source code of the Manjaro Settings Manager (more on that later), was to install Manjaro inside a VM, run the Manjaro Settings Manager, and view the recommended (or LTS, or whatever) tags there. It only takes a few minutes nowadays on a decently-capable system to do this, but it’s an understatement to say that this is a very roundabout way of doing things.

The source code does tell us what we need. Here is an excerpt from https://gitlab.manjaro.org/applications/manjaro-settings-manager/-/blob/master/src/libmsm/KernelModel.cpp:

QStringList
KernelModel::getLtsKernels() const
{
    return QStringList() << "linux310" << "linux312" << "linux314" << "linux316" << "linux318" << "linux41" << "linux44" << "linux49" << "linux414" << "linux414-rt" << "linux419" << "linux419-rt" << "linux54" << "linux510";
}

QStringList
KernelModel::getRecommendedKernels() const
{
    return QStringList() << "linux414" << "linux419" << "linux54" << "linux510";
}

Just a couple of hard-coded constants on line 300-something, surrounded by logic. Nothing to see here.

When someone requested that the mhwd-kernel tool display the Manjaro kernel tags in another post (https://forum.manjaro.org/t/mhwd-kernel-display-tags-attributes-lts-recommended-when-listing/65500), the less-than-helpful response was:

The idea is good, but unfortunately it cannot be implemented. The reason for this is that mhwd-linux queries the existing or installed kernels via pacman and this information is not stored there.

True enough, as far as that is concerned: the information is stored inside the compiled manjaro-settings-manager binary (shudder). There has to be a better way.

The simplest and canonical way to share static data between programs in Linux is to use the filesystem. In this case, manjaro-settings-manager could write out the kernel version tags to /usr/share/manjaro-settings-manager/kernel_versions or some such. Or the /etc tree could be used, though by convention /usr strongly implies that the data is read-only, while /etc makes no such representations.

If it is desirable to continue setting the tags via hard-coded constants in C++ code (shudder), this can continue. The only change would be that manjaro-settings-manager would also expose those settings to the filesystem. This would become an interface for any other program (mhwd-kernel or anything else) to access the information.

If the devs want to keep the definitions solely within C++ code for some reason, then perhaps they can be moved to some kind of configuration object that could be exported as a shared library. This seems clunky but would be doable.

I understand that Manjaro primarily targets less-experienced folks and graphical systems, but that doesn’t mean more experienced users and headless systems can’t also be supported. Especially in a case like this where the existing mechanism needs a bit of work anyways (maybe it’s a subjective thing, but I really don’t like that these tags are set way down in the middle of business code).

[Edited to include both LTS and Recommended tags and to specify that I’m after the most recent Recommended version]

3 Likes

so now you have all

curl -s "https://gitlab.manjaro.org/applications/manjaro-settings-manager/-/raw/master/src/libmsm/KernelModel.cpp" | awk 'BEGIN {x=1}; /<< "linux.*/ { if (x==1) {printf "last lts:"} else {printf "recommand:"};gsub(/"|;/,"",$NF);print "\t"$NF;x=0}'

:clown_face:


And we can create a hook:

/etc/pacman.d/hooks/kernels.hook

#/etc/pacman.d/hooks/kernels.hook
[Trigger]
Operation = Install
Operation = Upgrade
Type = Path
Target = boot/linux*.kver

[Action]
Description = last kernels manjaro
When = PostTransaction
Depends = mhwd
Exec = /etc/pacman.d/scripts/kernels.sh

/etc/pacman.d/scripts/kernels.sh

#!/usr/bin/bash

declare -a lts=($(curl -s "https://gitlab.manjaro.org/applications/manjaro-settings-manager/-/raw/master/src/libmsm/KernelModel.cpp" | awk '/<< "linux.*/ { gsub(/"|;/,"",$NF);print $NF}'))
echo -e "Last LTS:\t\t${lts[0]}"
[[ "${lts[0]}" != "${lts[1]}" ]] && echo -e "Recommanded LTS:\t${lts[1]}"

#echo -n "kernels installed: "
declare -a installeds=($(mhwd-kernel -li | awk '/* / {print $2}'))
#echo "${installeds[*]}"

echo -n "Last LTS is installed ? "
printf "%s\n" "${installeds[@]}" | grep ^${lts[0]}$ -c >/dev/null && echo "OK"
if [[ "${lts[0]}" != "${lts[1]}" ]]; then
    echo -n "Last recommanded kernel is installed ?"
    printf "%s\n" "${installeds[@]}" | grep ^${lts[1]}$ -c >/dev/null && echo "OK"
fi

# and test if we have a too old kernel
declare -a caninstalleds=($(mhwd-kernel -l | awk '/* / {print $2}'))
for k in "${installeds[@]}"; do
    if [[ $(printf "%s\n" "${caninstalleds[@]}"|grep ^$k$ -c) < 1 ]]; then
        echo "Error: kernel $k not exists in manjaro repo"
        exit 5
    fi
done
exit 0
2 Likes

Yes, obviously the source code can be parsed. But the getLtsKernels() and getRecommendedKernels() methods are private, which means they aren’t stable and indeed can completely change tonight without breaking any promises.

It’s already super wonky to be hard-coding these things like this. But knowingly relying on that unstable and poorly thought-out implementation? Nuts. Does no one else see this?

I applaud the effort, it is far better than the previous answer of “can’t be done.”

But is there no desire to fix the conceptually broken underlying code? All I am asking is that, when this is being done, it be done in a way that will let the information be accessed in a more stable and reliable way than parsing C++ source code.

Like the old adage says, first make it easy to implement the change you want (this step may be hard). Then make the easy change.

Sharing information about kernel version tags should be trivially easy and reliable if the underlying implementation is sane. The fact that it isn’t is a good sign that the implementation isn’t sane.

From a System administration angle, it became easier: you stay on the LTS kernel until Linus announces a new LTS kernel which happens only every couple of years…

:innocent:

We won’t change anything in this codebase, I promise you :joy:
MSM is quite old and needs to be replaced. As @Fabby said I have an idea and the new tool will be landed in (maybe not so?) near future.

3 Likes

@rallyemax
:point_up_2:

Now is your chance to become a real FLOSS developer and add that to your CV…

Just DM our Lord Termor and volunteer!

:bowing_man:

2 Likes