aboutsummaryrefslogtreecommitdiff
path: root/nixpkgs/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.sh
diff options
context:
space:
mode:
Diffstat (limited to 'nixpkgs/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.sh')
-rw-r--r--nixpkgs/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.sh140
1 files changed, 140 insertions, 0 deletions
diff --git a/nixpkgs/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.sh b/nixpkgs/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.sh
new file mode 100644
index 00000000000..0092ee92b62
--- /dev/null
+++ b/nixpkgs/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.sh
@@ -0,0 +1,140 @@
+#! @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 <timeout> -c <path-to-default-configuration> [-d <boot-dir>] [-g <num-generations>]" >&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/<hash>-<name>/file to <hash>-<name>-<file>.
+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
+ dtbDir=$(readlink -m "$path/dtbs")
+ if [ -e "$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 <<EOF
+# Generated file, all changes will be lost on nixos-rebuild!
+
+# Change this to e.g. nixos-42 to temporarily boot to an older configuration.
+DEFAULT nixos-default
+
+MENU TITLE ------------------------------------------------------------
+TIMEOUT $timeout
+EOF
+
+addEntry $default default >> $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