static usb ethnet addresses
[automated-distro-installer] / fai / config / files / root / fai-check / VOL_BOOKWORM_BOOTSTRAP
1 #!/bin/bash
2
3 set -eE -o pipefail
4 trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR
5
6 #set -x
7
8 usage() {
9 cat <<EOF
10 Usage: ${0##*/} [OPTION] [HOST]
11 If grub var set, act like pxe rom and pxe-kexec to faiserver
12
13 -f|--force do kexec if we can reach faiserver
14 -h|--help Print help and exit.
15
16 Note: Uses GNU getopt options parsing style
17 EOF
18 exit $1
19 }
20
21
22
23 # Keep it short so we don't delay too much wnen we don't have networking.
24 # In practice, on my home network, on an x200, it took 15 seconds, so
25 # give it an extra 10 seconds, which seems fairly short as I write this.
26 NETWORK_TIMOUT_SECS=25
27 did_fai_check=false
28
29 m() { printf "%s\n" "$*"; "$@"; }
30
31 try-kexec() {
32 deadline=$(( `date +%s` + NETWORK_TIMOUT_SECS ))
33 while ! timeout -s 9 3 nc -zu $faiserver 69; do
34 if (( `date +%s` > deadline )); then
35 echo "fai-check: hit $NETWORK_TIMOUT_SECS s tftp server timeout"
36 return 0
37 fi
38 sleep 1
39 done
40 m pxe-kexec -n --ignore-whitelist -l fai-generated $faiserver ||:
41 }
42
43 force=false
44 case $1 in
45 -h|--help)
46 usage
47 ;;
48 -f|--force)
49 force=true
50 shift
51 ;;
52 esac
53
54 faiserver=${1:-faiserver.b8.nz}
55
56
57 if $force; then
58 try-kexec
59 exit
60 fi
61
62 # on one machine, I could do this:
63 # dmidecode -t system | grep -F "Version: ThinkPad X200"
64 # however, on another, the version field just says invalid data.
65 # todo: figure out some better way to check if we are on
66 # an x200.
67
68 if ! dmidecode | grep -i thinkpad &>/dev/null; then
69 echo "not x200, exiting"
70 exit 0
71 fi
72
73 first=true
74 for dev in $(btrfs fi show / | sed -rn 's#^\s*devid\s.*\s([^0-9 ]+)\S+$#\1#p' \
75 |sort); do
76 echo dev=$dev
77 found=false
78 # Decide which is my grub_ext partition. see partition.DEFAULT file
79 # for details. currently it is 4
80 for (( i=4; i<=7; i++ )); do
81 if [[ $(blockdev --getsize64 ${dev}$i) == 8388608 ]]; then
82 grub_extn=${dev}$i
83 found=true
84 echo grub_extn=$grub_extn
85 break
86 fi
87 done
88 if ! $found; then
89 echo "$0: error: failed to find grub_ext partition."
90 exit 1
91 fi
92 m mount $grub_extn /mnt
93 if $first; then
94 if [[ -e /mnt/grubenv ]]; then
95 m grub-editenv /mnt/grubenv list
96 source <(grub-editenv /mnt/grubenv list)
97 fi
98 first=false
99 # we could just as well check if last_boot != /debianbullseye_bootstrap
100 # the intent with this one is just a little clearer.
101 if [[ $did_fai_check == true ]]; then
102 m grub-editenv /mnt/grubenv set did_fai_check=os_true
103 # our service does not wait for network-online.target,
104 # because it will wait for too long when we don't have a network
105 # connection. So, we wait for 10 seconds.
106 # ref: https://www.freedesktop.org/wiki/Software/systemd/NetworkTarget/
107 try-kexec ||:
108 fi
109 else
110 # we make sure there is only 1 grubenv,
111 # so grub can just find the first one, in whatever order
112 # if looks at them, which may not be the same as us.
113 # If the disk dies, we just lose the default boot option,
114 # we will have to do manual steps to replace it anyways.
115 m rm -f /mnt/gruvenv
116 fi
117 m umount /mnt
118 done
119
120 # the check for last_boot is not needed afaik, just sanity check.
121 case $did_fai_check in
122 true|os_true)
123 if [[ $last_boot != /debian*_bootstrap ]]; then
124 # no need to reboot if we actually want to boot into this os.
125 echo "last_boot=$last_boot not debian*_bootstrap, rebooting"
126 reboot
127 fi
128 esac