Skip to content

Commit

Permalink
Add scripts for kernel updates
Browse files Browse the repository at this point in the history
- Makefile: include specific target update-sources
- Refactor get-fedora-latest-config

(cherry picked from commit 8a001e9)
  • Loading branch information
fepitre committed Mar 7, 2020
1 parent 43854b5 commit 56dbda2
Show file tree
Hide file tree
Showing 4 changed files with 221 additions and 25 deletions.
8 changes: 6 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ endif

get-sources: $(SRC_FILE) $(SIGN_FILE) $(WG_SRC_FILE) $(WG_SIG_FILE)

verrel:
@echo $(NAME)-$(VERSION)-$(RELEASE)

$(SRC_FILE):
@wget -q -N $(URL)

Expand Down Expand Up @@ -90,8 +93,9 @@ ifneq ($(WG_SRC_FILE), None)
-rm $(WG_SRC_FILE) $(WG_SIG_FILE)
endif

verrel:
@echo $(NAME)-$(VERSION)-$(RELEASE)
.PHONY: update-sources
update-sources:
@$(WORKDIR)/update-sources $(BRANCH)

help:
@echo "Usage: make <target>"
Expand Down
99 changes: 76 additions & 23 deletions get-fedora-latest-config
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,6 @@ if [ "${VERBOSE:-0}" -ge 2 ] || [ "${DEBUG:-0}" -eq 1 ]; then
set -x
fi

localdir="$(dirname "$(readlink -f "$0")")"
releasever="$1"
# Set to 1 to include rc srpm
rc="$2"

kernelver="$(cat "$localdir/version")"
kernelsrc="linux-$kernelver"

exit_clean() {
local exit_code=$?
rm -rf "$tmpdir"
Expand All @@ -25,26 +17,86 @@ errecho() {
>&2 echo "$@"
}

# example of releasever: '29' or 'rawhide'
if [ "x$releasever" != "x" ]; then
if [[ ! "$releasever" =~ ^[1-9][0-9]$ ]] && [ "$releasever" != "rawhide" ]; then
errecho "Invalid release format"
exit 1
fi
elif [ "x$releasever" == "x" ]; then
listver="$(curl -s -L https://dl.fedoraproject.org/pub/fedora/linux/releases 2> /dev/null)"
releasever="$(echo "$listver" | sed -e 's/<[^>]*>//g' | awk '{print $1}' | grep -o "[1-9][0-9]" | tail -1)"
if ! [[ "$releasever" =~ ^[1-9][0-9]$ ]]; then
errecho "An error occurred while trying to determine latest Fedora version"
exit 1
usage() {
errecho "Usage: $0 [OPTIONS]... []
This script is used for fetching latest Fedora kernel config for the current
kernel version used by Qubes.
Options:
--releasever <Fedora RELEASEVER> Fedora release version to use. Default is latest.
--include-testing Include testing updates repository
--include-rc Include release candidate kernels
Remark:
Ensure to have downloaded kernel sources in local directory (make get-sources).
"
exit 1
}

get_releasever() {
releasever="$1"
# example of releasever: '29' or 'rawhide'
if [ "x$releasever" != "x" ]; then
if [[ ! "$releasever" =~ ^[1-9][0-9]$ ]] && [ "$releasever" != "rawhide" ]; then
errecho "Invalid release format"
exit 1
fi
elif [ "x$releasever" == "x" ]; then
listver="$(curl -s -L https://dl.fedoraproject.org/pub/fedora/linux/releases 2> /dev/null)"
releasever="$(echo "$listver" | sed -e 's/<[^>]*>//g' | awk '{print $1}' | grep -o "[1-9][0-9]" | tail -1)"
if ! [[ "$releasever" =~ ^[1-9][0-9]$ ]]; then
errecho "An error occurred while trying to determine latest Fedora version"
exit 1
fi
fi
echo "$releasever"
}

localdir="$(dirname "$(readlink -f "$0")")"
kernelver="$(cat "$localdir/version")"
kernelsrc="linux-$kernelver"

if ! OPTS=$(getopt -o hv:t:r: --long help,releasever:,include-testing,include-rc -n "$0" -- "$@"); then
errecho "An error occurred while parsing options."
exit 1
fi

eval set -- "$OPTS"

while [[ $# -gt 0 ]]; do
case "$1" in
-a | --releasever ) releasever="$2"; shift ;;
-m | --include-testing ) ktesting="1"; shift ;;
-i | --include-rc ) krc="1"; shift ;;
-h | --help) usage ;;
esac
shift
done

if [ ! -e "$localdir/$kernelsrc.tar.xz" ]; then
errecho "Cannot find $kernelsrc.tar.xz in local directory."
exit 1
fi

releasever=$(get_releasever "$releasever")

# get the latest kernel rpm
latestver=$(dnf -q repoquery kernel-core --disablerepo=* --enablerepo=fedora --enablerepo=updates --releasever="$releasever")
if [ "$rc" != "1" ]; then
repo_opts="--disablerepo=* --enablerepo=fedora --enablerepo=updates --releasever=$releasever"

# include testing
if [ "$ktesting" == "1" ]; then
repo_opts="$repo_opts --enablerepo=updates-testing"
fi

# shellcheck disable=SC2086
latestver=$(dnf -q repoquery kernel-core $repo_opts)

# include rc
if [ "$krc" != "1" ]; then
latestver=$(echo "$latestver" | grep -v "rc[0-9]*")
fi

latestver=$(echo "$latestver" | sort -V | tail -1 | cut -d ':' -f2)
latestrpm="kernel-core-$latestver.rpm"

Expand All @@ -58,7 +110,8 @@ if [ "x$latestrpm" != "x" ] && [ "x$releasever" != "x" ]; then
trap 'exit_clean' 0 1 2 3 6 15
tmpdir="$(mktemp -d -p "$localdir")"
# download latest kernel rpm
dnf -q download kernel-core --disablerepo=* --enablerepo=fedora --enablerepo=updates --releasever="$releasever"
# shellcheck disable=SC2086
dnf -q download kernel-core $repo_opts
mv "$latestrpm" "$tmpdir/$latestrpm.untrusted"

# check signature
Expand Down
73 changes: 73 additions & 0 deletions kernel-updater.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#!/usr/bin/python3

import sys
import argparse
import requests
import json

from packaging import version
from packaging.version import parse as parse_version


class KernelUpdaterClient:
def __init__(self, version, branch):
self.version = version
self.branch = branch

def get_version_qubes(self):
return self.version

def get_version_upstream(self):
url_releases = 'https://www.kernel.org/releases.json'
r = requests.get(url_releases)
latest_upstream = None
if 200 <= r.status_code < 300:
content = json.loads(r.content.decode('utf-8'))
releases = [rel['version'] for rel in content['releases'] if
rel['moniker'] in ('stable', 'longterm')]

releases.sort(key=parse_version, reverse=True)

if 'stable-' in self.branch:
branch_version = self.branch.split('-')[1]
releases = [rel for rel in releases if
rel.startswith(branch_version)]

latest_upstream = releases[0]
else:
print('An error occurred while downloading "%s"' % url_releases)

return latest_upstream

def is_update_needed(self):
version_qubes = self.get_version_qubes()
version_upstream = self.get_version_upstream()
if version_qubes and version_upstream and (version.parse(version_qubes) < version.parse(version_upstream)):
return version_upstream

def parse_args(argv):
parser = argparse.ArgumentParser()

parser.add_argument('--check-update', required=False, action='store_true')
parser.add_argument('--version', required=True)
parser.add_argument('--branch', required=True)

args = parser.parse_args(argv[1:])

return args


def main(argv):
args = parse_args(argv)
client = KernelUpdaterClient(version=args.version, branch=args.branch)

if args.check_update:
is_update_needed = client.is_update_needed()
if is_update_needed is not None:
print(is_update_needed)

return 0


if __name__ == '__main__':
sys.exit(main(sys.argv))
66 changes: 66 additions & 0 deletions update-sources
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#!/bin/bash
# vim: set ts=4 sw=4 sts=4 et :

set -e
set -o pipefail

[ "$DEBUG" = "1" ] && set -x

distance_version() {
read -ra VER1 <<<"$(echo "$1" | tr '.' ' ')"
read -ra VER2 <<<"$(echo "$2" | tr '.' ' ')"

[[ ${VER1[0]} -eq ${VER2[0]} ]] && [[ $((VER1[1] - VER2[1])) -le 1 ]] && [[ $((VER1[1] - VER2[1])) -ge 0 ]]
}

LOCALDIR="$(readlink -f "$(dirname "$0")")"
BUILDERDIR="$LOCALDIR/../../"
VERSION="$(cat version)"
BRANCH="$1"

if [ -z "$BRANCH" ]; then
# Check if qubes-builder Makefile is here
# else rely on current checkout branch
if [ -e "$BUILDERDIR/Makefile" ]; then
BRANCH="$(make -C ../../ -s get-var GET_VAR=BRANCH_linux_kernel 2>/dev/null)"
else
BRANCH="$(git rev-parse --abbrev-ref HEAD)"
fi
fi

# Filter allowed branches
if [[ ! "$BRANCH" =~ ^stable-[0-9]+\.[0-9]+$ ]] && [ "$BRANCH" != "master" ]; then
echo "Cannot determine kernel branch to use."
exit 1
fi

LATEST_KERNEL_VERSION="$(python3 "$LOCALDIR/kernel-updater.py" --check-update --version "$VERSION" --branch "$BRANCH")"

if [ "x$LATEST_KERNEL_VERSION" == "x" ]; then
echo "Current kernel version in branch ${BRANCH} is up to date"
exit 0
fi

# Download latest kernel
echo "$LATEST_KERNEL_VERSION" > version
make get-sources

FC_LATEST="$(curl -s -L https://dl.fedoraproject.org/pub/fedora/linux/releases | sed -e 's/<[^>]*>//g' | awk '{print $1}' | grep -o "[1-9][0-9]" | tail -1)"
STABLE_KERNEL="$(dnf -q repoquery kernel --disablerepo=* --enablerepo=fedora --enablerepo=updates --releasever="$FC_LATEST" | sort -V | tail -1 | cut -d ':' -f2 | cut -d '-' -f1)"
if [ "$BRANCH" == "master" ]; then
TESTING_KERNEL="$(dnf -q repoquery kernel --disablerepo=* --enablerepo=fedora --enablerepo=updates --enablerepo=updates-testing --releasever="$FC_LATEST" | sort -V | tail -1 | cut -d ':' -f2 | cut -d '-' -f1)"
RAWHIDE_KERNEL="$(dnf -q repoquery kernel --disablerepo=* --enablerepo=fedora --enablerepo=updates --releasever=rawhide | grep -v "rc[0-9]*" | sort -V | tail -1 | cut -d ':' -f2 | cut -d '-' -f1 || true)"
fi

if distance_version "$STABLE_KERNEL" "$LATEST_KERNEL_VERSION"; then
"$LOCALDIR/get-fedora-latest-config" --releasever "$FC_LATEST"
mv config-base-"$STABLE_KERNEL" config-base
elif [ "$BRANCH" == "master" ] && { distance_version "$TESTING_KERNEL" "$LATEST_KERNEL_VERSION"; }; then
"$LOCALDIR/get-fedora-latest-config" --releasever "$FC_LATEST" --include-testing
mv config-base-"$STABLE_KERNEL" config-base
elif [ "$BRANCH" == "master" ] && { distance_version "$RAWHIDE_KERNEL" "$LATEST_KERNEL_VERSION"; }; then
"$LOCALDIR/get-fedora-latest-config" --releasever rawhide
mv config-base-"$RAWHIDE_KERNEL" config-base
else
echo "Cannot determine latest config for kernel ${LATEST_KERNEL_VERSION}. Use the current existing config..."
fi

0 comments on commit 56dbda2

Please sign in to comment.