#! @bash@/bin/sh -e shopt -s nullglob export PATH=/empty for i in @path@; do PATH=$PATH:$i/bin; done usage() { echo "usage: $0 -t -c [-d ] [-g ]" >&2 exit 1 } timeout= # Timeout in centiseconds default= # Default configuration target=/boot # Target directory numGenerations=0 # Number of other generations to include in the menu while getopts "t:c:d:g:" opt; do case "$opt" in t) # U-Boot interprets '0' as infinite and negative as instant boot if [ "$OPTARG" -lt 0 ]; then timeout=0 elif [ "$OPTARG" = 0 ]; then timeout=-10 else timeout=$((OPTARG * 10)) fi ;; c) default="$OPTARG" ;; d) target="$OPTARG" ;; g) numGenerations="$OPTARG" ;; \?) usage ;; esac done [ "$timeout" = "" -o "$default" = "" ] && usage mkdir -p $target/nixos mkdir -p $target/extlinux # Convert a path to a file in the Nix store such as # /nix/store/-/file to --. cleanName() { local path="$1" echo "$path" | sed 's|^/nix/store/||' | sed 's|/|-|g' } # Copy a file from the Nix store to $target/nixos. declare -A filesCopied copyToKernelsDir() { local src=$(readlink -f "$1") local dst="$target/nixos/$(cleanName $src)" # 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 -r $src $dstTmp mv $dstTmp $dst fi filesCopied[$dst]=1 result=$dst } # Copy its kernel, initrd and dtbs to $target/nixos, and echo out an # extlinux menu entry addEntry() { local path=$(readlink -f "$1") local tag="$2" # Generation number or 'default' if ! test -e $path/kernel -a -e $path/initrd; then return fi copyToKernelsDir "$path/kernel"; kernel=$result copyToKernelsDir "$path/initrd"; initrd=$result # XXX UGLY: maybe the system config should have a top-level "dtbs" entry? dtbDir=$(readlink -m "$path/kernel/../dtbs") if [ -d "$dtbDir" ]; then copyToKernelsDir "$dtbDir"; dtbs=$result fi timestampEpoch=$(stat -L -c '%Z' $path) timestamp=$(date "+%Y-%m-%d %H:%M" -d @$timestampEpoch) nixosLabel="$(cat $path/nixos-version)" extraParams="$(cat $path/kernel-params)" echo echo "LABEL nixos-$tag" if [ "$tag" = "default" ]; then echo " MENU LABEL NixOS - Default" else echo " MENU LABEL NixOS - Configuration $tag ($timestamp - $nixosLabel)" fi echo " LINUX ../nixos/$(basename $kernel)" echo " INITRD ../nixos/$(basename $initrd)" if [ -d "$dtbDir" ]; then echo " FDTDIR ../nixos/$(basename $dtbs)" fi echo " APPEND systemConfig=$path init=$path/init $extraParams" } tmpFile="$target/extlinux/extlinux.conf.tmp.$$" cat > $tmpFile <> $tmpFile if [ "$numGenerations" -gt 0 ]; then # Add up to $numGenerations generations of the system profile to the menu, # in reverse (most recent to least recent) order. for generation in $( (cd /nix/var/nix/profiles && ls -d system-*-link) \ | sed 's/system-\([0-9]\+\)-link/\1/' \ | sort -n -r \ | head -n $numGenerations); do link=/nix/var/nix/profiles/system-$generation-link addEntry $link $generation done >> $tmpFile fi mv -f $tmpFile $target/extlinux/extlinux.conf # Remove obsolete files from $target/nixos. for fn in $target/nixos/*; do if ! test "${filesCopied[$fn]}" = 1; then echo "Removing no longer needed boot file: $fn" chmod +w -- "$fn" rm -rf -- "$fn" fi done