#!/bin/bash set -e usage () { >&2 echo 'makekernel version #VERSION#' >&2 echo 'usage:' >&2 echo ' makekernel [ -a | --allowDownload ] [ -c $version | --compileVersion=$version ] [ -f | --force ] [ -n | --noAction ]:' >&2 echo ' download and compile kernel' >&2 echo ' -a | --allowDownload:' >&2 echo ' allow to download complete source instead of patch if necessary' >&2 echo ' -c | --compileVersion $version:' >&2 echo ' download and compile version $version instead of most current stable' >&2 echo ' -f | --force:' >&2 echo ' build kernel even if it appears to be up to date' >&2 echo ' -n | --noAction:' >&2 echo ' do not do anything, just print what would be done' >&2 echo ' makekernel ( -s | --showVersion ):' >&2 echo ' show version of most current stable kernel' exit 1 } dlExVer () { if ${noAction} then echo "download and verify '$1.xz'" return 0 fi wget -nd "${proxyPrefix}$1.xz" || wget -nd "$1.xz" wget -nd "${proxyPrefix}$1.sign" || wget -nd "$1.sign" xz -d "$2.xz" if ! gpg --verify $2{.sign,} then >&2 echo 'ERROR: Wrong signature! Closing.' exit 1 fi rm "$2.sign" } export MAKEFLAGS="-j$(nproc)" . #ETCDIR#/makekernel.conf if [ "$(whoami)" == "root" ] then >&2 echo 'ERROR: Do not call as root! Closing.' exit 1 fi eval set -- "$( getopt -o ac:fns \ --long allowDownload \ --long compileVersion: \ --long force \ --long noAction \ --long showVersion \ -n "$(basename "$0")" \ -- "$@" || echo usage )" allowDownload=false forceBuild=false forceVersion=false showVersion=false noAction=false hasGit="[ -d "${kernelDir}/.git" ]" while true do case "$1" in -a|--allowDownload) ${allowDownload} && usage ${showVersion} && usage ${hasGit} && usage allowDownload=true ;; -c|--compileVersion) ${forceVersion} && usage ${showVersion} && usage curVer="$2" forceVersion=true shift ;; -f|--force) ${showVersion} && usage forceBuild=true shift ;; -n|--noAction) ${showVersion} && usage noAction=true ;; -s|--showVersion) ${allowDownload} && usage ${forceBuild} && usage ${forceVersion} && usage ${showVersion} && usage ${noAction} && usage showVersion=true ;; --) shift break ;; *) >&2 echo "ERROR: Option \"$1\" unknown in the end! Closing." usage esac shift done [ $# -ne 0 ] && usage if ${showVersion} then if ${hasGit} then git -C "${kernelDir}" fetch --all --tags &> /dev/null || true git -C "${kernelDir}" tag --list | \ grep '^v[0-9.]\+$' | \ sed 's|^v||' | \ sort -V | \ tail -n1 else mainVersion="$( curl 'https://cdn.kernel.org/pub/linux/kernel/' 2> /dev/null | \ tr '>/' '\n' | \ grep '^v.*$' | \ sort -V | \ tail -n1 )" curl "https://cdn.kernel.org/pub/linux/kernel/${mainVersion}/" 2> /dev/null | \ tr '<>' '\n\n' | \ grep '^linux-.*\.tar\.xz$' | \ sed 's/^linux-\(.*\)\.tar\.xz$/\1/' | \ sort -V | \ tail -n1 fi exit 0 fi if ! stty &> /dev/null then >&2 echo 'ERROR: Must be called from a terminal! Closing.' >&2 echo 'Did you forget "-t" for ssh?' exit 1 fi [ -z "${curVer}" ] && curVer="$("$0" -s)" if ! ${forceBuild} \ && [ -f '/boot/vmlinuz-'"${curVer}" ]; then >&2 echo 'kernel is up to date.' exit fi mainVer="$( echo "${curVer}" | \ sed 's|^\([0-9]\+\.[0-9]\+\)\(\..*\)\?$|\1|' )" if [ "${curVer}" == "${mainVer}" ] then minPreVer='#invalid#' mainPreVer="${curVer%.*}.$[${curVer##*.}-1]" else minPreVer="${mainVer}.$[${curVer##*.}-1]" mainPreVer='#invalid#' fi # possible updates with patches from old sources are: # - "recompile" old source # - "minor" incremental (e.g. 4.7.2 -> 4.7.3) # - make a "stablePatch" (e.g. 4.7 -> 4.7.3) # - "major" incremental (e.g. 4.6 -> 4.7) # alternative (if allowed): # - download complete source if ${hasGit} then updateType='git' patchSrc='' dlSrch='' elif [ -d "${kernelDir}/linux-${curVer}" ] then updateType='recompile' patchSrc='' dlSrc='' elif [ -d "${kernelDir}/linux-${minPreVer}" ] then updateType='minor' srcDir="linux-${minPreVer}" patch="patch-${minPreVer}-${curVer##*.}" patchSrc="https://cdn.kernel.org/pub/linux/kernel/v${curVer%%.*}.x/incr/${patch}" dlSrc='' elif [ -d "${kernelDir}/linux-${mainVer}" ] then updateType='stablePatch' srcDir="linux-${mainVer}" patch="patch-${curVer}" patchSrc="https://cdn.kernel.org/pub/linux/kernel/v${curVer%%.*}.x/${patch}" dlSrc='' elif [ -d "${kernelDir}/linux-${mainPreVer}" ] then updateType='major' srcDir="linux-${mainPreVer}" patch="patch-${curVer}" patchSrc="https://cdn.kernel.org/pub/linux/kernel/v${curVer%%.*}.x/${patch}" dlSrc='' elif ${allowDownload} then updateType='download' patchSrc='' dlSrc="https://cdn.kernel.org/pub/linux/kernel/v${curVer%%.*}.x/linux-${curVer}.tar" else >&2 echo 'No patch method available and download of complete source not allowed! Closing.' usage fi cd "${kernelDir}" echo "update type: ${updateType}" if ${hasGit} then if ${noAction} then echo "verify and checkout git tag 'v${curVer}'" else git verify-tag "v${curVer}" git checkout "v${curVer}" fi elif [ -n "${patchSrc}" ] then dlExVer "${patchSrc}" "${patch}" if ${noAction} then echo "copy '${srcDir}' to 'linux-${curVer}' and patch via '${patch}'" else cp -r "${srcDir}" "linux-${curVer}" cd "linux-${curVer}" patch -p1 -i "../${patch}" rm "../${patch}" fi elif [ -n "${dlSrc}" ] then dlExVer "${dlSrc}" "linux-${curVer}.tar" if ! ${noAction} then tar -xf "linux-${curVer}.tar" rm "linux-${curVer}.tar" fi fi if ${noAction} then echo "copy config (can't say, from where, right now)" else if ${hasGit} then cd "${kernelDir}" else cd "${kernelDir}/linux-${curVer}" fi [ ! -r .config ] && zcat /proc/config.gz > .config fi if ${noAction} then ${hasGit} || echo "make clean" echo "make oldconfing" echo "make" echo "possibly: make modules_install" echo echo "as root:" echo " before_install_hook &&" echo ' install -m644 --owner=root "${kernelImg}" "/boot/vmlinuz-'"${curVer}"'" &&' echo " grub-mkconfig -o /boot/grub/grub.cfg &&" echo " after_install_hook" else ${hasGit} || make clean make oldconfig make grep -q '^# CONFIG_MODULES is not set$' .config || make modules_install if ${hasGit} then kernelImg="$(find ${kernelDir}/arch/ -type f -iname '*image')" else kernelImg="$(find ${kernelDir}/linux-${curVer}/arch/ -type f -iname '*image')" fi if [ $(echo "${kernelImg}" | wc -l) -ne 1 ] then >&2 echo 'ERROR: Did not find exactly one compiled kernel image:' >&2 echo "${kernelImg}" >&2 echo 'Closing.' exit 1 fi echo 'becoming root ...' err=1 while [ ${err} -eq 1 ] do su -c ' \ . #ETCDIR#/makekernel.conf && \ before_install_hook && \ install -m644 --owner=root "'"${kernelImg}"'" "/boot/vmlinuz-'"${curVer}"'" && \ grub-mkconfig -o /boot/grub/grub.cfg && \ after_install_hook || \ exit 2 \ ' && err=0 || err=$? done fi echo 'Success.'