Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,28 @@ dh-python

Then use these commands to build the package:
```
git clone https://github.com/pop-os/kernelstub
git clone https://github.com/isantop/kernelstub
cd kernelstub
dpkg-buildpackage -b -us -uc
sudo dpkg -i ../kernelstub*.deb
```
For installation on non-debian systems, or if you prefer to use Python

For installation on RPM-based systems (Fedora, RHEL, etc.), the Python packaging
can automatically build an RPM package for use on your system:
```
git clone https://github.com/isantop/kernelstub
cd kernelstub
python3 setup.py bdist_rpm
```
After this, you can install the resulting RPM package directly:
```
sudo rpm -i dist/kernelstub-*.rpm
```

For installation on other systems, or if you prefer to use Python
packaging, use:
```
git clone https://github.com/pop-os/kernelstub
git clone https://github.com/isantop/kernelstub
cd kernelstub
sudo python3 setup.py install --record=installed_files.txt
```
Expand Down
24 changes: 21 additions & 3 deletions data/initramfs/zz-kernelstub
Original file line number Diff line number Diff line change
@@ -1,8 +1,26 @@
#!/bin/bash

KERNEL="/boot/vmlinuz-$1"
INITRD="$2"
# Grab OS information to figure out how to operate
source /etc/os-release

# If ID_LIKE is empty, use ID instead. Base Distros don't always use ID_LIKE
if [[ "$ID_LIKE" == "" ]]; then
ID_LIKE="$ID"
fi

# Determine how to handle kernel paths:
if [[ "$ID_LIKE" == *"fedora"* ]]; then
echo "Operating in Fedora-mode (initramfs, /boot)"
INITRD="/boot/initramfs-$1.img"
KERNEL="$2"
elif [[ "$ID_LIKE" == *"debian"* ]]; then
echo "Operating in Debian-mode (initrd.img, /symlinks)"
INITRD="/initrd.img"
KERNEL="/vmlinuz"
fi

kernelstub \
--verbose \
--preserve-live-mode
--preserve-live-mode \
--kernel-path $KERNEL \
--initrd-path $INITRD
24 changes: 21 additions & 3 deletions data/kernel/zz-kernelstub
Original file line number Diff line number Diff line change
@@ -1,8 +1,26 @@
#!/bin/bash

INITRD="/boot/initrd.img-$1"
KERNEL="$2"
# Grab OS information to figure out how to operate
source /etc/os-release

# If ID_LIKE is empty, use ID instead. Base Distros don't always use ID_LIKE
if [[ "$ID_LIKE" == "" ]]; then
ID_LIKE="$ID"
fi

# Determine how to handle kernel paths:
if [[ "$ID_LIKE" == *"fedora"* ]]; then
echo "Operating in Fedora-mode (initramfs, /boot)"
INITRD="/boot/initramfs-$1.img"
KERNEL="$2"
elif [[ "$ID_LIKE" == *"debian"* ]]; then
echo "Operating in Debian-mode (initrd.img, /symlinks)"
INITRD="/initrd.img"
KERNEL="/vmlinuz"
fi

kernelstub \
--verbose \
--preserve-live-mode
--preserve-live-mode \
--kernel-path $KERNEL \
--initrd-path $INITRD
6 changes: 6 additions & 0 deletions debian/changelog
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
kernelstub (4.0.1) bionic; urgency=medium

* Add support for Fedora-like kernel setups

-- Ian Santopietro <isantop@gmail.com> Wed, 09 Aug 2023 17:18:19 -0600

kernelstub (3.1.4) bionic; urgency=medium

* Do live mode check immediately after parsing config
Expand Down
38 changes: 36 additions & 2 deletions kernelstub/kernel_option.py
Original file line number Diff line number Diff line change
@@ -1,48 +1,80 @@
#!/usr/bin/python3

from debian.changelog import Version
import logging

log = logging.getLogger('kernelstub.kernel_option')

try:
from debian.changelog import Version
def vCompare(version1:str, version2:str):
if Version(version1) > Version(version2):
return True
return False

except ImportError:
from rpm import labelCompare
def vCompare(version1:str, version2:str):
if labelCompare(version1, version2) == 1:
return True
return False
import os
import os.path

def options(path):
items={}
for name in os.listdir(path):
log.debug('Checking item %s', name)
key = None
if name.startswith("vmlinuz-"):
log.debug('Item %s is kernel-image', name)
key = "kernel"
elif name.startswith("initrd.img-"):
log.debug('Item %s is debian-style initrd', name)
key = "initrd"
elif name.startswith("initramfs"):
log.debug('Item %s is fedora-style initrd', name)
key = "initrd"

if key is None:
continue

parts = name.split("-", 1)
version = parts[1]
if version.endswith('.img'):
version = version[:-4]
log.debug('Item version is %s', version)

if not version in items:
log.debug('Adding item %s to list', name)
items[version] = {}

items[version][key] = os.path.join(path, name)

log.debug('Found items: %s', items)
return items

def get_newest_option(opts):
log.debug('Getting latest boot item version')
latest_version = None
latest_option = None

for version, option in opts.items():
log.debug('Checking option %s', option)
# If option is not complete, skip
if 'kernel' not in option or 'initrd' not in option:
log.debug('%s does not contain all items, skipping...', version)
continue

# If this option is newer, store this option and continue
if latest_version is None or Version(version) > Version(latest_version):
if latest_version is None or vCompare (version, latest_version):
log.debug('%s is the latest version', version)
latest_version = version
latest_option = option

return latest_option, latest_version

def latest_option(path):
log.debug('Checking for boot items in %s', path)
opts = options(path)
latest_option, latest_version = get_newest_option(opts)

Expand All @@ -52,6 +84,8 @@ def latest_option(path):
if len(opts) > 0:
previous_option, latest_version = get_newest_option(opts)

log.debug('Latest option: %s', latest_option)
log.debug('Previous option: %s', previous_option)
return latest_option, previous_option

if __name__ == "__main__":
Expand Down
28 changes: 27 additions & 1 deletion kernelstub/opsys.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,13 @@
terms.
"""

import platform
import logging, platform

class OS():

name_pretty = "Linux"
name = "Linux"
like = ["Linux"]
version = "1.0"
cmdline = ['quiet', 'splash']
kernel_name = 'vmlinuz'
Expand All @@ -39,12 +40,16 @@ class OS():
initrd_path = '/initrd.img'
old_kernel_path = '/vmlinuz.old'
old_initrd_path = '/initrd.img.old'
os_mode = 'debian'

def __init__(self):
self.log = logging.getLogger('kernelstub.Opsys')
self.name_pretty = self.get_os_name()
self.name = self.clean_names(self.name_pretty)
self.like = self.get_os_like()
self.version = self.get_os_version()
self.cmdline = self.get_os_cmdline()
self.set_os_mode()

def clean_names(self, name):
# This is a list of characters we can't/don't want to have in technical
Expand Down Expand Up @@ -116,6 +121,21 @@ def get_os_version(self):
if item.startswith('VERSION_ID='):
version = item.split('=')[1]
return self.strip_quotes(version[:-1])

def get_os_like(self):
os_release = self.get_os_release()
for item in os_release:
if item.startswith('ID_LIKE='):
like = item.split('=')[1]
like = self.strip_quotes(like)
return like.split()

# Fallback on ID= if we aren't on a derivative
for item in os_release:
if item.startswith('ID='):
like = item.split('=')[1]
like = self.strip_quotes(like)
return like.split()

def strip_quotes(self, value):
new_value = value
Expand All @@ -124,6 +144,12 @@ def strip_quotes(self, value):
if value.endswith('"'):
new_value = new_value[:-1]
return new_value

def set_os_mode(self):
if 'debian' in self.like:
self.os_mode = 'debian'
elif 'fedora' in self.like:
self.os_mode = 'fedora'

def get_os_release(self):
try:
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def run(self):
run_pyflakes3()

setup(name='kernelstub',
version='3.1.4',
version='4.0.1',
description='Automatic kernel efistub manager for UEFI',
url='https://launchpad.net/kernelstub',
author='Ian Santopietro',
Expand Down