Simple script and config (type-safe) for building custom Linux kernels for Firecracker MicroVMs

Refactor build script to improve kernel version validation and streamline repository cloning logic

+42 -12
+42 -12
build.sh
··· 1 1 #!/usr/bin/env bash 2 - 3 2 set -e 4 3 5 4 readonly MAGENTA="$(tput setaf 5 2>/dev/null || echo '')" ··· 8 7 readonly ORANGE="$(tput setaf 3 2>/dev/null || echo '')" 9 8 readonly NO_COLOR="$(tput sgr0 2>/dev/null || echo '')" 10 9 11 - if [[ ! "$1" =~ ^[0-9]+\.[0-9]+(\.[0-9]+|\.y)?$ ]]; then 12 - echo "${ORANGE}Error: Invalid kernel version format '${1}'. Expected format is X.Y or X.Y.Z (where Z can be 'y' or a number).${NO_COLOR}" 13 - echo "Example: ./build.sh 6.1 or ./build.sh 6.1.12 or ./build.sh 6.1.y" 10 + if [[ $# -lt 1 ]]; then 11 + echo "${ORANGE}Usage: $0 <kernel-version>{.y|.Z}${NO_COLOR}" 12 + echo "Example: ./build.sh 6.1 | 6.1.12 | 6.1.y | v6.1.12" 13 + exit 1 14 + fi 15 + 16 + INPUT="$1" 17 + NUM="${INPUT#v}" # normalize by stripping optional leading 'v' 18 + 19 + # Validate: X.Y, X.Y.Z, or X.Y.y 20 + if [[ ! "$NUM" =~ ^[0-9]+\.[0-9]+(\.(y|[0-9]+))?$ ]]; then 21 + echo "${ORANGE}Error: Invalid kernel version '${INPUT}'. Expected X.Y, X.Y.Z, or X.Y.y${NO_COLOR}" 22 + echo "Examples: 6.1 | 6.1.12 | 6.1.y | v6.1.12" 14 23 exit 1 15 24 fi 16 25 17 - echo "Building vmlinux for Linux kernel ${CYAN}${1}${NO_COLOR}" 26 + echo "Building vmlinux for Linux kernel ${CYAN}${NUM}${NO_COLOR}" 18 27 19 - type apt-get > /dev/null && sudo apt-get install -y git build-essential flex bison libncurses5-dev libssl-dev gcc bc libelf-dev pahole || true 28 + type apt-get >/dev/null 2>&1 && sudo apt-get install -y git build-essential flex bison libncurses5-dev libssl-dev gcc bc libelf-dev pahole || true 20 29 21 - [ -d linux-stable ] || git clone --depth=1 -b linux-${1} git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git 30 + REPO_URL="git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git" 31 + 32 + # Decide ref: maintenance branch vs tag 33 + if [[ "$NUM" == *".y" ]]; then 34 + REF="linux-${NUM}" # e.g. linux-6.16.y 35 + VERSION="${NUM%.y}" # e.g. 6.16 36 + else 37 + REF="v${NUM}" # e.g. v6.16.2 (ensure leading v) 38 + VERSION="${NUM}" # e.g. 6.16.2 (no leading v) 39 + fi 40 + 41 + if [[ ! -d linux-stable ]]; then 42 + # Clone directly at the desired ref (branch or tag) 43 + git clone --depth=1 --branch "$REF" "$REPO_URL" linux-stable 44 + else 45 + # Update existing checkout to the desired ref 46 + git -C linux-stable fetch --tags --force origin 47 + # Shallow-fetch the specific ref (works for both branches and tags) 48 + git -C linux-stable fetch --depth=1 origin "$REF":"$REF" || git -C linux-stable fetch origin "$REF":"$REF" 49 + git -C linux-stable checkout -f "$REF" 50 + fi 22 51 23 52 cp .config linux-stable/.config 24 53 25 54 cd linux-stable 26 55 27 - yes '' | make vmlinux -j$(nproc) < /dev/null 56 + # Build 57 + yes '' | make vmlinux -j"$(nproc)" < /dev/null 28 58 29 - VERSION=${1%.y} 30 - VMLINUX=$(echo vmlinux-${VERSION}) 31 - 32 - mv vmlinux ${VMLINUX}.$(uname -m) 59 + VMLINUX="vmlinux-${VERSION}" 60 + mv vmlinux "${VMLINUX}.$(uname -m)" 33 61 34 62 echo "${GREEN}vmlinux built successfully!${NO_COLOR}" 35 63 echo "You can find the vmlinux file in ${CYAN}$(pwd)/${VMLINUX}.$(uname -m)${NO_COLOR}" 64 + 65 + exit 0