Skip to content

Instantly share code, notes, and snippets.

@conqp
Created November 19, 2021 12:55
Show Gist options
  • Save conqp/92d422b026ffc3d06714345374c0f5ff to your computer and use it in GitHub Desktop.
Save conqp/92d422b026ffc3d06714345374c0f5ff to your computer and use it in GitHub Desktop.
Check whether your running kernel is equal to the installed kernel.
#! /usr/bin/env python3
"""Check whether the running kernel equals the installed kernel package."""
from argparse import ArgumentParser, Namespace
from logging import INFO, WARNING, basicConfig, getLogger
from subprocess import check_output
from sys import exit # pylint: disable=W0622
from typing import NamedTuple, Optional
__all__ = ['Kernel', 'get_running_kernel', 'get_installed_kernel', 'main']
LOGGER = getLogger('kdiff')
class Kernel(NamedTuple):
"""Representation of kernel flavor and version."""
major: int
minor: int
micro: int
revision: str
patch: Optional[str] = None
flavor: Optional[str] = None
class Suffix(NamedTuple):
"""Representation of kernel version suffixes."""
revision: str
patch: Optional[str] = None
flavor: Optional[str] = None
def get_suffix(suffix: list[str]) -> Suffix:
"""Returns revision, patch and flavor."""
try:
patch, revision, flavor = suffix
except ValueError:
revision, flavor = suffix
patch = None
if revision.startswith('arch'):
revision, patch, flavor = flavor, revision, None
return Suffix(revision, patch, flavor)
def get_running_kernel() -> Kernel:
"""Returns the running kernel."""
text = check_output(['/usr/bin/uname', '-r'], text=True)
version, *suffix = text.strip().split('-')
return Kernel(*map(int, version.split('.')), *get_suffix(suffix))
def get_installed_kernel(flavor: Optional[str] = None) -> Kernel:
"""Returns the installed kernel."""
pkg = 'linux' if flavor is None else f'linux-{flavor}'
text = check_output(['/usr/bin/pacman', '-Q', pkg], text=True)
_, version = text.strip().split()
version, revision = version.split('-')
major, minor, micro, *patch = version.split('.')
patch = '.'.join(patch) or None
return Kernel(int(major), int(minor), int(micro), revision, patch, flavor)
def get_args(*, description: str = __doc__) -> Namespace:
"""Parses the command line arguments."""
parser = ArgumentParser(description=description)
parser.add_argument('-v', '--verbose', action='store_true',
help='enable verbose output')
return parser.parse_args()
def main() -> int:
"""Returns 0 if running and installed kernel equal else 1."""
args = get_args()
basicConfig(level=INFO if args.verbose else WARNING)
running_kernel = get_running_kernel()
LOGGER.info('Running kernel: %s', running_kernel)
installed_kernel = get_installed_kernel(running_kernel.flavor)
LOGGER.info('Installed kernel: %s', installed_kernel)
return int(running_kernel != installed_kernel)
if __name__ == '__main__':
exit(main())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment