at 24.11-pre 4.9 kB view raw
1#! @bash@/bin/sh -e 2 3shopt -s nullglob 4 5export PATH=/empty 6for i in @path@; do PATH=$PATH:$i/bin; done 7 8usage() { 9 echo "usage: $0 -t <timeout> -c <path-to-default-configuration> [-d <boot-dir>] [-g <num-generations>] [-n <dtbName>] [-r]" >&2 10 exit 1 11} 12 13timeout= # Timeout in centiseconds 14default= # Default configuration 15target=/boot # Target directory 16numGenerations=0 # Number of other generations to include in the menu 17 18while getopts "t:c:d:g:n:r" opt; do 19 case "$opt" in 20 t) # U-Boot interprets '0' as infinite and negative as instant boot 21 if [ "$OPTARG" -lt 0 ]; then 22 timeout=0 23 elif [ "$OPTARG" = 0 ]; then 24 timeout=-10 25 else 26 timeout=$((OPTARG * 10)) 27 fi 28 ;; 29 c) default="$OPTARG" ;; 30 d) target="$OPTARG" ;; 31 g) numGenerations="$OPTARG" ;; 32 n) dtbName="$OPTARG" ;; 33 r) noDeviceTree=1 ;; 34 \?) usage ;; 35 esac 36done 37 38[ "$timeout" = "" -o "$default" = "" ] && usage 39 40mkdir -p $target/nixos 41mkdir -p $target/extlinux 42 43# Convert a path to a file in the Nix store such as 44# /nix/store/<hash>-<name>/file to <hash>-<name>-<file>. 45cleanName() { 46 local path="$1" 47 echo "$path" | sed 's|^/nix/store/||' | sed 's|/|-|g' 48} 49 50# Copy a file from the Nix store to $target/nixos. 51declare -A filesCopied 52 53copyToKernelsDir() { 54 local src=$(readlink -f "$1") 55 local dst="$target/nixos/$(cleanName $src)" 56 # Don't copy the file if $dst already exists. This means that we 57 # have to create $dst atomically to prevent partially copied 58 # kernels or initrd if this script is ever interrupted. 59 if ! test -e $dst; then 60 local dstTmp=$dst.tmp.$$ 61 cp -r $src $dstTmp 62 mv $dstTmp $dst 63 fi 64 filesCopied[$dst]=1 65 result=$dst 66} 67 68# Copy its kernel, initrd and dtbs to $target/nixos, and echo out an 69# extlinux menu entry 70addEntry() { 71 local path=$(readlink -f "$1") 72 local tag="$2" # Generation number or 'default' 73 74 if ! test -e $path/kernel -a -e $path/initrd; then 75 return 76 fi 77 78 copyToKernelsDir "$path/kernel"; kernel=$result 79 copyToKernelsDir "$path/initrd"; initrd=$result 80 dtbDir=$(readlink -m "$path/dtbs") 81 if [ -e "$dtbDir" ]; then 82 copyToKernelsDir "$dtbDir"; dtbs=$result 83 fi 84 85 timestampEpoch=$(stat -L -c '%Z' $path) 86 87 timestamp=$(date "+%Y-%m-%d %H:%M" -d @$timestampEpoch) 88 nixosLabel="$(cat $path/nixos-version)" 89 extraParams="$(cat $path/kernel-params)" 90 91 echo 92 echo "LABEL nixos-$tag" 93 if [ "$tag" = "default" ]; then 94 echo " MENU LABEL NixOS - Default" 95 else 96 echo " MENU LABEL NixOS - Configuration $tag ($timestamp - $nixosLabel)" 97 fi 98 echo " LINUX ../nixos/$(basename $kernel)" 99 echo " INITRD ../nixos/$(basename $initrd)" 100 echo " APPEND init=$path/init $extraParams" 101 102 if [ -n "$noDeviceTree" ]; then 103 return 104 fi 105 106 if [ -d "$dtbDir" ]; then 107 # if a dtbName was specified explicitly, use that, else use FDTDIR 108 if [ -n "$dtbName" ]; then 109 echo " FDT ../nixos/$(basename $dtbs)/${dtbName}" 110 else 111 echo " FDTDIR ../nixos/$(basename $dtbs)" 112 fi 113 else 114 if [ -n "$dtbName" ]; then 115 echo "Explicitly requested dtbName $dtbName, but there's no FDTDIR - bailing out." >&2 116 exit 1 117 fi 118 fi 119} 120 121tmpFile="$target/extlinux/extlinux.conf.tmp.$$" 122 123cat > $tmpFile <<EOF 124# Generated file, all changes will be lost on nixos-rebuild! 125 126# Change this to e.g. nixos-42 to temporarily boot to an older configuration. 127DEFAULT nixos-default 128 129MENU TITLE ------------------------------------------------------------ 130TIMEOUT $timeout 131EOF 132 133addEntry $default default >> $tmpFile 134 135if [ "$numGenerations" -gt 0 ]; then 136 # Add up to $numGenerations generations of the system profile to the menu, 137 # in reverse (most recent to least recent) order. 138 for generation in $( 139 (cd /nix/var/nix/profiles && ls -d system-*-link) \ 140 | sed 's/system-\([0-9]\+\)-link/\1/' \ 141 | sort -n -r \ 142 | head -n $numGenerations); do 143 link=/nix/var/nix/profiles/system-$generation-link 144 addEntry $link "${generation}-default" 145 for specialisation in $( 146 ls /nix/var/nix/profiles/system-$generation-link/specialisation \ 147 | sort -n -r); do 148 link=/nix/var/nix/profiles/system-$generation-link/specialisation/$specialisation 149 addEntry $link "${generation}-${specialisation}" 150 done 151 done >> $tmpFile 152fi 153 154mv -f $tmpFile $target/extlinux/extlinux.conf 155 156# Remove obsolete files from $target/nixos. 157for fn in $target/nixos/*; do 158 if ! test "${filesCopied[$fn]}" = 1; then 159 echo "Removing no longer needed boot file: $fn" 160 chmod +w -- "$fn" 161 rm -rf -- "$fn" 162 fi 163done