1#! @bash@/bin/sh -e
2
3shopt -s nullglob
4
5export PATH=/empty
6for i in @path@; do PATH=$PATH:$i/bin; done
7
8default=$1
9if test -z "$1"; then
10 echo "Syntax: generations-dir-builder.sh <DEFAULT-CONFIG>"
11 exit 1
12fi
13
14echo "updating the boot generations directory..."
15
16mkdir -p /boot
17
18rm -Rf /boot/system* || true
19
20target=/boot/grub/menu.lst
21tmp=$target.tmp
22
23# Convert a path to a file in the Nix store such as
24# /nix/store/<hash>-<name>/file to <hash>-<name>-<file>.
25cleanName() {
26 local path="$1"
27 echo "$path" | sed 's|^/nix/store/||' | sed 's|/|-|g'
28}
29
30# Copy a file from the Nix store to /boot/kernels.
31declare -A filesCopied
32
33copyToKernelsDir() {
34 local src="$1"
35 local dst="/boot/kernels/$(cleanName $src)"
36 # Don't copy the file if $dst already exists. This means that we
37 # have to create $dst atomically to prevent partially copied
38 # kernels or initrd if this script is ever interrupted.
39 if ! test -e $dst; then
40 local dstTmp=$dst.tmp.$$
41 cp $src $dstTmp
42 mv $dstTmp $dst
43 fi
44 filesCopied[$dst]=1
45 result=$dst
46}
47
48
49# Copy its kernel and initrd to /boot/kernels.
50addEntry() {
51 local path="$1"
52 local generation="$2"
53 local outdir=/boot/system-$generation
54
55 if ! test -e $path/kernel -a -e $path/initrd; then
56 return
57 fi
58
59 local kernel=$(readlink -f $path/kernel)
60 local initrd=$(readlink -f $path/initrd)
61
62 if test -n "@copyKernels@"; then
63 copyToKernelsDir $kernel; kernel=$result
64 copyToKernelsDir $initrd; initrd=$result
65 fi
66
67 mkdir -p $outdir
68 ln -sf $(readlink -f $path) $outdir/system
69 ln -sf $(readlink -f $path/init) $outdir/init
70 ln -sf $initrd $outdir/initrd
71 ln -sf $kernel $outdir/kernel
72
73 if test $(readlink -f "$path") = "$default"; then
74 cp "$kernel" /boot/nixos-kernel
75 cp "$initrd" /boot/nixos-initrd
76 cp "$(readlink -f "$path/init")" /boot/nixos-init
77
78 mkdir -p /boot/default
79 # ln -sfT: overrides target even if it exists.
80 ln -sfT $(readlink -f $path) /boot/default/system
81 ln -sfT $(readlink -f $path/init) /boot/default/init
82 ln -sfT $initrd /boot/default/initrd
83 ln -sfT $kernel /boot/default/kernel
84 fi
85}
86
87if test -n "@copyKernels@"; then
88 mkdir -p /boot/kernels
89fi
90
91# Add all generations of the system profile to the menu, in reverse
92# (most recent to least recent) order.
93for generation in $(
94 (cd /nix/var/nix/profiles && ls -d system-*-link) \
95 | sed 's/system-\([0-9]\+\)-link/\1/' \
96 | sort -n -r); do
97 link=/nix/var/nix/profiles/system-$generation-link
98 addEntry $link $generation
99done
100
101# Remove obsolete files from /boot/kernels.
102for fn in /boot/kernels/*; do
103 if ! test "${filesCopied[$fn]}" = 1; then
104 rm -vf -- "$fn"
105 fi
106done