#! @bash@/bin/sh -e shopt -s nullglob export PATH=/empty for i in @path@; do PATH=$PATH:$i/bin; done if test $# -ne 1; then echo "Usage: grub-menu-builder.sh DEFAULT-CONFIG" exit 1 fi grubVersion="@version@" defaultConfig="$1" case "$grubVersion" in 1|2) echo "updating GRUB $grubVersion menu..." ;; *) echo "Unsupported GRUB version \`$grubVersion'" >&2 echo "Supported versions are \`1' (GRUB Legacy) and \`2' (GRUB 1.9x)." >&2 exit 1 ;; esac # Discover whether /boot is on the same filesystem as / and # /nix/store. If not, then all kernels and initrds must be copied to # /boot, and all paths in the GRUB config file must be relative to the # root of the /boot filesystem. `$bootRoot' is the path to be # prepended to paths under /boot. if [ "$(stat -c '%D' /.)" != "$(stat -c '%D' /boot/.)" ]; then bootRoot= copyKernels=1 elif [ "$(stat -c '%D' /boot/.)" != "$(stat -c '%D' /nix/store/.)" ]; then bootRoot=/boot copyKernels=1 else bootRoot=/boot copyKernels="@copyKernels@" # user can override in the NixOS config fi prologue() { case "$grubVersion" in 1) cp -f "@splashImage@" /boot/background.xpm.gz cat > "$1" << GRUBEND # Automatically generated. DO NOT EDIT THIS FILE! default @default@ timeout @timeout@ GRUBEND if test -n "@splashImage@"; then echo "splashimage $bootRoot/background.xpm.gz" >> "$1" fi ;; 2) cp -f @grub@/share/grub/unicode.pf2 /boot/grub/unicode.pf2 cat > "$1" <> "$1" <-/file to --. cleanName() { local path="$1" echo "$path" | sed 's|^/nix/store/||' | sed 's|/|-|g' } # Copy a file from the Nix store to /boot/kernels. declare -A filesCopied copyToKernelsDir() { local src="$1" local p="kernels/$(cleanName $src)" local dst="/boot/$p" # Don't copy the file if $dst already exists. This means that we # have to create $dst atomically to prevent partially copied # kernels or initrd if this script is ever interrupted. if ! test -e $dst; then local dstTmp=$dst.tmp.$$ cp $src $dstTmp mv $dstTmp $dst fi filesCopied[$dst]=1 result="$bootRoot/$p" } # Add an entry for a configuration to the Grub menu, and if # appropriate, copy its kernel and initrd to /boot/kernels. addEntry() { local name="$1" local path="$2" local shortSuffix="$3" configurationCounter=$((configurationCounter + 1)) if test $configurationCounter -gt @configurationLimit@; then return fi if ! test -e $path/kernel -a -e $path/initrd; then return fi local kernel=$(readlink -f $path/kernel) local initrd=$(readlink -f $path/initrd) if test "$path" = "$defaultConfig"; then cp "$kernel" /boot/nixos-kernel cp "$initrd" /boot/nixos-initrd cp "$(readlink -f "$path/init")" /boot/nixos-init case "$grubVersion" in 1) cat > /boot/nixos-grub-config < /boot/nixos-grub-config </dev/null || true) if test -n "$confName"; then name="$confName $3" fi case "$grubVersion" in 1) cat >> "$tmp" << GRUBEND title $name @extraPerEntryConfig@ kernel $kernel systemConfig=$(readlink -f $path) init=$(readlink -f $path/init) $(cat $path/kernel-params) initrd $initrd GRUBEND ;; 2) cat >> "$tmp" << GRUBEND menuentry "$name" { @extraPerEntryConfig@ linux $kernel systemConfig=$(readlink -f $path) init=$(readlink -f $path/init) $(cat $path/kernel-params) initrd $initrd } GRUBEND ;; esac } if test -n "$copyKernels"; then mkdir -p /boot/kernels fi # Additional entries specified verbatim by the configuration. extraEntries=`cat <> $tmp <> $tmp fi addEntry "NixOS - Default" $defaultConfig "" if test -z "@extraEntriesBeforeNixOS@"; then echo "$extraEntries" >> $tmp fi # Add all generations of the system profile to the menu, in reverse # (most recent to least recent) order. for link in $((ls -d $defaultConfig/fine-tune/* ) | sort -n); do date=$(stat --printf="%y\n" $link | sed 's/\..*//') addEntry "NixOS - variation" $link "" done for generation in $( (cd /nix/var/nix/profiles && ls -d system-*-link) \ | sed 's/system-\([0-9]\+\)-link/\1/' \ | sort -n -r); do link=/nix/var/nix/profiles/system-$generation-link date=$(stat --printf="%y\n" $link | sed 's/\..*//') kernelVersion=$(cd $(dirname $(readlink -f $link/kernel))/lib/modules && echo *) addEntry "NixOS - Configuration $generation ($date - $kernelVersion)" $link "$generation ($date)" done # Atomically update the GRUB configuration file. mv $tmp $target # Remove obsolete files from /boot/kernels. for fn in /boot/kernels/*; do if ! test "${filesCopied[$fn]}" = 1; then rm -vf -- "$fn" fi done