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