at 17.09-beta 4.2 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>]" >&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:" 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 \?) usage ;; 33 esac 34done 35 36[ "$timeout" = "" -o "$default" = "" ] && usage 37 38mkdir -p $target/nixos 39mkdir -p $target/extlinux 40 41# Convert a path to a file in the Nix store such as 42# /nix/store/<hash>-<name>/file to <hash>-<name>-<file>. 43cleanName() { 44 local path="$1" 45 echo "$path" | sed 's|^/nix/store/||' | sed 's|/|-|g' 46} 47 48# Copy a file from the Nix store to $target/nixos. 49declare -A filesCopied 50 51copyToKernelsDir() { 52 local src=$(readlink -f "$1") 53 local dst="$target/nixos/$(cleanName $src)" 54 # Don't copy the file if $dst already exists. This means that we 55 # have to create $dst atomically to prevent partially copied 56 # kernels or initrd if this script is ever interrupted. 57 if ! test -e $dst; then 58 local dstTmp=$dst.tmp.$$ 59 cp -r $src $dstTmp 60 mv $dstTmp $dst 61 fi 62 filesCopied[$dst]=1 63 result=$dst 64} 65 66# Copy its kernel, initrd and dtbs to $target/nixos, and echo out an 67# extlinux menu entry 68addEntry() { 69 local path=$(readlink -f "$1") 70 local tag="$2" # Generation number or 'default' 71 72 if ! test -e $path/kernel -a -e $path/initrd; then 73 return 74 fi 75 76 copyToKernelsDir "$path/kernel"; kernel=$result 77 copyToKernelsDir "$path/initrd"; initrd=$result 78 # XXX UGLY: maybe the system config should have a top-level "dtbs" entry? 79 dtbDir=$(readlink -m "$path/kernel/../dtbs") 80 if [ -d "$dtbDir" ]; then 81 copyToKernelsDir "$dtbDir"; dtbs=$result 82 fi 83 84 timestampEpoch=$(stat -L -c '%Z' $path) 85 86 timestamp=$(date "+%Y-%m-%d %H:%M" -d @$timestampEpoch) 87 nixosLabel="$(cat $path/nixos-version)" 88 extraParams="$(cat $path/kernel-params)" 89 90 echo 91 echo "LABEL nixos-$tag" 92 if [ "$tag" = "default" ]; then 93 echo " MENU LABEL NixOS - Default" 94 else 95 echo " MENU LABEL NixOS - Configuration $tag ($timestamp - $nixosLabel)" 96 fi 97 echo " LINUX ../nixos/$(basename $kernel)" 98 echo " INITRD ../nixos/$(basename $initrd)" 99 if [ -d "$dtbDir" ]; then 100 echo " FDTDIR ../nixos/$(basename $dtbs)" 101 fi 102 echo " APPEND systemConfig=$path init=$path/init $extraParams" 103} 104 105tmpFile="$target/extlinux/extlinux.conf.tmp.$$" 106 107cat > $tmpFile <<EOF 108# Generated file, all changes will be lost on nixos-rebuild! 109 110# Change this to e.g. nixos-42 to temporarily boot to an older configuration. 111DEFAULT nixos-default 112 113MENU TITLE ------------------------------------------------------------ 114TIMEOUT $timeout 115EOF 116 117addEntry $default default >> $tmpFile 118 119if [ "$numGenerations" -gt 0 ]; then 120 # Add up to $numGenerations generations of the system profile to the menu, 121 # in reverse (most recent to least recent) order. 122 for generation in $( 123 (cd /nix/var/nix/profiles && ls -d system-*-link) \ 124 | sed 's/system-\([0-9]\+\)-link/\1/' \ 125 | sort -n -r \ 126 | head -n $numGenerations); do 127 link=/nix/var/nix/profiles/system-$generation-link 128 addEntry $link $generation 129 done >> $tmpFile 130fi 131 132mv -f $tmpFile $target/extlinux/extlinux.conf 133 134# Remove obsolete files from $target/nixos. 135for fn in $target/nixos/*; do 136 if ! test "${filesCopied[$fn]}" = 1; then 137 echo "Removing no longer needed boot file: $fn" 138 chmod +w -- "$fn" 139 rm -rf -- "$fn" 140 fi 141done