add file for bootstrap distro
[automated-distro-installer] / fai / config / scripts / IANK / 11-iank
1 #!/bin/bash -x
2
3 set -eE -o pipefail
4 trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR
5
6 if [[ $EUID != 0 ]]; then
7 echo "$0: error: expected to be root."
8 exit 1
9 fi
10
11 if ! type -t fcopy &>/dev/null; then
12 sudo apt-get -y install fai-client
13 fi
14
15 if [[ -e /a/bin/fai/fai-wrapper ]]; then
16 chroot() {
17 shift
18 "$@"
19 }
20 fi
21
22
23
24 # -r = recursive
25 # -i = ignore non-matching class warnings, always exit 0
26 # -B = no backup files
27 fcopy -riBM /boot
28 # this is also done by FAIBASE/10-misc by default (without B)
29 fcopy -riBM /root
30 fcopy -riBM /usr/local/bin
31
32 # this gets done by fai, but just happens too often that
33 # I add sources due to new distros, whatever.
34 fcopy -riBM /etc/apt/preferences.d
35 fcopy -riBM /etc/apt/sources.list.d
36
37
38 src=$FAI/distro-install-common/shadow
39 dst=/q/root/shadow
40 if [[ ! -e $dst && -e $src ]]; then
41 # outside of fai context, we skip this
42 mkdir -p $dst
43 mount -o bind $src $dst
44 fi
45
46 $FAI/distro-install-common/end
47
48
49
50 ### begin sources install + updates
51 # these get copied in an earlier stage by fai, but leaving it here since
52 # I run this as a single post-fai script to update things that have changed.
53 tmpfile1=$(mktemp)
54 # this can fail if we need an apt update
55 chroot $FAI_ROOT /usr/bin/apt-cache policy >$tmpfile1 ||:
56 fcopy -riBM /etc/apt
57
58 # get ubuntu key, for running from fai wrapper.
59 apt-key add $FAI/package_config/UBUNTU.asc
60
61 tmpfile2=$(mktemp)
62 chroot $FAI_ROOT /usr/bin/apt-cache policy >$tmpfile2
63 if ! diff -q $tmpfile1 $tmpfile2; then
64 chroot $FAI_ROOT /usr/bin/apt update
65 fi
66 # outside of fai, this seems to regularly lead to
67 # E: Could not get lock /var/lib/apt/lists/lock - open (11: Resource temporarily unavailable)
68 # so add a sleep. 1 sec is probably way more than needed.
69 sleep 1
70 f=$FAI_ROOT/var/cache/apt/pkgcache.bin
71 if [[ ! -r $f ]] || (( $(( $(date +%s) - $(stat -c %Y $f ) )) > 60*60*2 )); then
72 i=0
73 while fuser $FAI_ROOT/var/lib/dpkg/lock &>/dev/null; do
74 sleep 1
75 i=$(( i+1 ))
76 if (( i > 300 )); then
77 echo "error: timed out waiting for /var/lib/dpkg/lock" >&2
78 exit 1
79 fi
80 $ROOTCMD apt-get update
81 done
82 fi
83 ### end sources install + updates
84
85
86 #### misc configurations
87 chroot $FAI_ROOT bash <<'EOFOUTER'
88 if getent group systemd-journal >/dev/null; then
89 # makes the journal be saved to disk.
90 mkdir -p /var/log/journal
91 chmod 755 /var/log/journal
92 fi
93 debconf-set-selections <<EOF
94 kexec-tools kexec-tools/load_kexec boolean false
95 EOF
96 apt-get install -y pxe-kexec
97
98 # this is usefull. Only thing reason I see this being disabled by default is
99 # that a normal user can disrupt the system, eg cause a reboot.
100 sed -i '$a kernel.sysrq=1
101 /^kernel.sysrq=/d' /etc/sysctl.conf
102
103 EOFOUTER
104
105
106 if [[ $FAI_ACTION != dirinstall ]] && ! ifclass NOCRYPT; then
107 # luks options, see man systemd-cryptsetup-generator
108 # all i know is that with luks.crypttab=no, swap still timed out on boot.
109 # and with rd.luks.crypttab=no, it works.
110 if ifclass LINODE; then
111 speed=19200
112 cmdline="rd.luks.crypttab=no net.ifnames=0 console=ttyS0,${speed}n8"
113 else
114 speed=115200
115 cmdline="rd.luks.crypttab=no net.ifnames=0 console=ttyS0,${speed}n8 console=tty0"
116 case $HOSTNAME in
117 kd)
118 fcopy -v /usr/bin/myncq
119
120 cat >$target/etc/systemd/system/myncq.service <<'EOF'
121 [Unit]
122 Description=fix ncq errors
123
124 [Service]
125 Type=oneshot
126 ExecStart=/usr/bin/myncq
127 TimeoutStartSec=20
128
129 [Install]
130 # https://www.enricozini.org/blog/2017/debian/systemd-07-devices/
131 WantedBy=dev-disk-by\x2did-ata\x2dSamsung_SSD_870_QVO_8TB_S5VUNG0N900656V.device
132 EOF
133
134 chroot $FAI_ROOT bash <<'EOFOUTER'
135 systemctl enable myncq.service
136 /usr/bin/myncq no-upgrub
137 EOFOUTER
138
139 ;;
140 # per rubens suggestion to make a d16 more stable
141 kd|kw) cmdline+=" pci=realloc=off" ;;
142 esac
143 fi
144
145 cat >$FAI_ROOT/etc/grub.d/40_custom <<EOF
146 #!/bin/sh
147 exec tail -n +3 \$0
148 # This file provides an easy way to add custom menu entries. Simply type the
149 # menu entries you want to add after this comment. Be careful not to change
150 # the 'exec tail' line above.
151
152 # https://www.coreboot.org/Serial_console # tty
153 # but removed unneeded stuff
154
155 serial --speed=$speed
156 terminal_input --append serial
157 terminal_output --append serial
158 EOF
159
160
161 chroot $FAI_ROOT bash <<EOF
162 set -eE -o pipefail
163 # https://askubuntu.com/questions/33416/how-do-i-disable-the-boot-splash-screen-and-only-show-kernel-and-boot-text-inst
164
165 sed -ri 's/(^GRUB_CMDLINE_LINUX_DEFAULT=")quiet/\1/;s/^(GRUB_CMDLINE_LINUX_DEFAULT=".*) quiet([ "])/\1\2/' /etc/default/grub
166 sed -ri 's/(^GRUB_CMDLINE_LINUX_DEFAULT=")splash/\1/;s/^(GRUB_CMDLINE_LINUX_DEFAULT=".*) splash([ "])/\1\2/' /etc/default/grub
167
168 for arg in $cmdline; do
169 if ! grep "^GRUB_CMDLINE_LINUX_DEFAULT=.*[\" ]${arg//./\\.}[\" ]" /etc/default/grub; then
170 sed -ri "s/^GRUB_CMDLINE_LINUX_DEFAULT=\"(.*)/GRUB_CMDLINE_LINUX_DEFAULT=\"$arg \1/" /etc/default/grub
171 fi
172 done
173
174 if grep -qF "$cmdline" /etc/default/grub; then
175 # already set things, exit
176 exit 0
177 fi
178 sed -ri 's/^ *GRUB_CMDLINE_LINUX_DEFAULT=.*/GRUB_CMDLINE_LINUX_DEFAULT="$cmdline"/' /etc/default/grub
179 # on xenial, no grub is displayed at all. fix that.
180 # found just by noticing this in the config file, and a
181 # warning about it in error.log
182 sed -i '/^ *GRUB_HIDDEN_TIMEOUT/d' /etc/default/grub
183
184 if type -P update-grub2 &>/dev/null; then
185 update-grub2
186 else
187 update-grub
188 fi
189
190 EOF
191 fi ##### end != dirinstall && != NOCRYPT
192
193
194 ###### begin network setup ####
195
196 # use old names. the idea of them changing between boots has never
197 # happened to me and I usually only have 1 wired or other type.
198 # If I ever do need to care about it, I will.
199 # Strangely this didn't work on kw, so I added kernel cmdline parameter.
200 # https://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames/
201 ln -sf /dev/null $target/etc/systemd/network/99-default.link
202
203
204 # bitfolk installer handles the rest
205 case $HOSTNAME in
206 bk|je) exit 0 ;;
207 esac
208
209
210 # bug fix, somewhere between t9's xorg 1.19.6
211 # and 1.20.1-3ubuntu2
212 # xserver-xorg-video-nouveau 1:1.0.15-3
213 # xorg stopped load nouveau
214 # https://www.linuxquestions.org/questions/slackware-14/kernel-modules-conflicting-with-nouveau-driver-4175623867/
215 # https://nouveau.freedesktop.org/InstallNouveau.html
216 if lspci|grep -q 'GeForce GTX 6[0-9][0-9]\]'; then
217 mkdir -p $target/etc/X11/xorg.conf.d/
218 cat >$target/etc/X11/xorg.conf.d/10-nouveau.conf <<'EOF'
219 Section "Device"
220 Identifier "Device0"
221 Driver "nouveau"
222 EndSection
223 EOF
224 fi
225
226 # use networkmanager if this host has wireless.
227 if [[ $HOSTNAME == bo ]] || type -p iw &>/dev/null && [[ $(iw dev) ]]; then
228 chroot $FAI_ROOT bash <<EOF
229 apt-get -y install network-manager
230 EOF
231
232 # allow networkmanager to manage interfaces
233 #https://bugs.launchpad.net/ubuntu/+source/network-manager/+bug/1638842
234 touch $target/etc/NetworkManager/conf.d/10-globally-managed-devices.conf
235 # in a default desktop install, it looks like netplan creates this file under
236 # run/NetworkManager/conf.d in early boot.
237
238 # By default, dns=default is set in etiona, and dns is just broken.
239 # Maybe with resolvconf it would work, but theres no need for that.
240 # https://wiki.gnome.org/Projects/NetworkManager/DNS
241 cat >$target/etc/NetworkManager/conf.d/99-iank.conf <<'EOF'
242 [main]
243 dns=systemd-resolved
244 EOF
245 if [[ $HOSTNAME == frodo ]]; then
246 cat > $target/etc/network/interfaces <<-EOF
247 # generated by FAI
248 auto lo eth0
249 iface lo inet loopback
250 iface eth0 inet static
251 address 10.3.0.2/16
252
253 source-directory /etc/network/interfaces.d
254 EOF
255 fi
256
257 else
258 cat > $target/etc/network/interfaces <<-EOF
259 # generated by FAI
260 auto lo eth0
261 iface lo inet loopback
262 iface eth0 inet dhcp
263 iface eth0 inet6 auto
264
265 source-directory /etc/network/interfaces.d
266 EOF
267
268 # previously had an else condition after
269 #elif ifclass VM || ifclass LINODE; then
270 # iface $NIC1 inet manual
271 # iface br0 inet dhcp
272 # bridge_ports $NIC1
273 # bridge_stp off
274 # bridge_maxwait 0
275 # however, on t9, on startup, br0, became
276 # rename1 and didn't come up. i dunno why,
277 # but the bridge is for vms that I rarely use,
278 # so not bothering to figure it out.
279
280
281 fi
282
283 if ifclass LINODE; then
284 mkdir -p $target/etc/initramfs-tools/conf.d
285 cat >$target/etc/initramfs-tools/conf.d/mine <<EOF
286 # dhcp in initramfs doesn't work on linode. i dunno why, whatever.
287 # man 5 initramfs.conf
288 # /usr/share/doc/klibc-utils/README.ipconfig.gz
289 # /usr/share/initramfs-tools/scripts/functions
290 IP=$linode_ip::$linode_gw:255.255.255.0::eth0:off
291 EOF
292
293
294 if [[ $HOSTNAME == li ]]; then
295
296 cat > $target/etc/network/interfaces <<-EOF
297 # generated by FAI
298 auto lo eth0
299 iface lo inet loopback
300 iface eth0 inet dhcp
301 # for the standard network config, uncomment this and comment the lines after it.
302 #iface eth0 inet6 auto
303
304 iface eth0 inet6 static
305 # this is really a /128. it seems like we need to assign it for ipv6 to work.
306 address 2600:3c00::f03c:91ff:fe6d:baf8/64
307 gateway fe80::1
308
309 iface eth0 inet6 static
310 # from a requested /64 pool
311 address 2600:3c00:e000:280::2/64
312
313 source-directory /etc/network/interfaces.d
314 EOF
315 fi
316 fi
317
318 # I prefer to stick with ifup/down for now. a. networkd is not in its
319 # own package, so cant use in other init systems. b. it works fine.
320 chroot $FAI_ROOT bash <<EOF
321 systemctl disable systemd-networkd.socket systemd-networkd networkd-dispatcher systemd-networkd-wait-online
322 systemctl mask systemd-networkd.socket systemd-networkd networkd-dispatcher systemd-networkd-wait-online
323 EOF
324
325 ##### end network setup #####
326
327
328 if ifclass VOL_BULLSEYE_BOOTSTRAP; then
329 fcopy /etc/systemd/system/faicheck.service
330 chroot $FAI_ROOT bash <<'EOFOUTER'
331 systemctl enable faicheck.service
332 EOFOUTER
333 exit 0 # avoid unnecessary stuff in bootstrap vol
334 fi
335
336
337 ## misc settings
338 chroot $FAI_ROOT bash <<'EOFOUTER'
339 #### begin .ssh setup ###
340 set -x
341 set -eE -o pipefail
342 if ! [[ -s /home/iank/.ssh/authorized_keys ]]; then
343 mkdir -p /home/iank/.ssh
344 f=/root/.ssh/authorized_keys
345 if [[ -e $f ]]; then
346 cp $f /home/iank/.ssh
347 fi
348 chown -R 1000:1000 /home/iank/.ssh
349 chmod -R u=Xrw,og= /home/iank/.ssh
350 rm -rf /root/.ssh
351 # remove broken symlinks or the following cp will fail
352 find /home/iank/.ssh -xtype l -exec rm '{}' \;
353 cp -rL /home/iank/.ssh /root
354 chown -R root:root /root/.ssh
355 chmod 700 /root/.ssh
356 fi
357
358 # old link from
359 # # https://ticktockhouse.svbtle.com/my-obligatory-ubuntu-ssh-agent-post
360 # but that made a service that started too soon and didn't pick up our
361 # x env vars. instead, copy from the root ssh-agent just the
362 # appropriate things into a new service.
363 rm -f /home/iank/.config/systemd/user/default.target.wants/ssh-agent.service
364
365 rm -f /home/iank/.local/share/systemd/user/sshaiank.service \
366 /home/iank/.config/systemd/user/default.target.wants/sshaiank.service
367
368 #### end .ssh setup ###
369
370 ## duplicated in ssh-emacs-setup
371 # done here so its setup earlier for convenience
372 line='AcceptEnv INSIDE_EMACS BRC COLUMNS'
373 f=/etc/ssh/sshd_config
374 grep -xFq "$line" $f || tee -a $f <<<"$line"
375
376
377 # default debian groups (jessie through buster) + adm, root, admin
378 for g in cdrom floppy audio dip video plugdev netdev adm sudo admin; do
379 if getent group $g >/dev/null; then
380 usermod -aG $g iank
381 fi
382 done
383
384 if getent group systemd-journal >/dev/null; then
385 usermod -aG systemd-journal iank
386 fi
387 EOFOUTER
388
389 rm -f $target/etc/resolv.conf
390 ln -s ../run/systemd/resolve/stub-resolv.conf $target/etc/resolv.conf
391 # needed for bitfolk image
392 if [[ -e /a/bin/fai/fai-wrapper ]]; then
393 systemctl enable systemd-resolved
394 systemctl start systemd-resolved
395 fi
396
397
398
399 # reading through the groups that iank is in but user2 isn't,
400 for g in plugdev audio video cdrom; do
401 $ROOTCMD usermod -a -G $g user2
402 done