changes for buster linode
[automated-distro-installer] / fai-redep
1 #!/bin/bash
2 # Copyright (C) 2019 Ian Kelling
3 # SPDX-License-Identifier: AGPL-3.0-or-later
4 set -eE -o pipefail
5 trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR
6
7 readonly this_file="$(readlink -f -- "${BASH_SOURCE[0]}")"; cd "${this_file%/*}"
8
9 usage() {
10 cat <<EOF
11 usage: ${0##*/} [OPTIONS] [HOST]
12 Deploy fai config (the one in nfs) to HOST or default faiserver
13
14
15 -d DISTRO DISTRO for setting up fai class DESKTOP packages, for preinstalling stuff.
16 -t TARGET_HOST Copy only secrets for TARGET_HOST into the config space. Useful for virtual server
17 on hardware we don't control.
18 -h|--help Print help and exit
19
20 Note: uses paths specific to authors machine.
21 EOF
22 exit $1
23 }
24
25 ##### begin command line parsing ########
26
27 # ensure we can handle args with spaces or empty.
28 ret=0; getopt -T || ret=$?
29 [[ $ret == 4 ]] || { echo "Install util-linux for enhanced getopt" >&2; exit 1; }
30
31 temp=$(getopt -l help hd:t: "$@") || usage 1
32 eval set -- "$temp"
33 while true; do
34 case $1 in
35 -d) distro=$2; shift ;;
36 -t) target=$2; shift ;;
37 -h|--help) usage ;;
38 --) shift; break ;;
39 *) echo "$0: unexpected args: $*" >&2 ; usage 1 ;;
40 esac
41 shift
42 done
43 host=${1:-faiserver}
44
45 readonly host distro target
46
47 ##### end command line parsing ########
48
49 # i use faiserver as a dns alias, but ssh key is associated with
50 # a canonical hostname and we will have ssh warning spam unless we
51 # use it, so look it up just to avoid the warning spam.
52 faiserver_host=$(chost $host) || faiserver_host=$host
53
54 rsync -rlpt --delete --relative --exclude /fai/config/basefiles/ fai/config root@$faiserver_host:/srv
55
56 sudo rsync -a /root/.ssh/home.pub \
57 root@$faiserver_host:/srv/fai/config/files/root/.ssh/authorized_keys/STANDARD
58 # todo: automatically disable faiserver after a period so
59 # these files are not available.
60
61 if [[ $target ]]; then
62 sudo rsync -lpt --files-from=- /q/root root@$faiserver_host:/srv/fai/config/distro-install-common <<EOF
63 luks/$target
64 luks/host-$target
65 shadow/$target
66 EOF
67 else
68 sudo rsync -rlpt /q/root/shadow /q/root/luks root@$faiserver_host:/srv/fai/config/distro-install-common
69 fi
70
71 dirs=(/p/c/machine_specific/${target:-*}/filesystem/etc/ssh)
72 if [[ -e ${dirs[0]} ]]; then
73 rsync -rlpt --delete --relative ${dirs[@]} root@$faiserver_host:/srv/fai/config/distro-install-common
74 fi
75
76 . /a/bin/distro-setup/pkgs
77 pall+=($(/a/bin/buildscripts/emacs -p; /a/bin/distro-setup/distro-pkgs $distro))
78
79 printf "%s\n%s\n" "PACKAGES install" ${pall[*]} | \
80 ssh root@$faiserver_host dd of=/srv/fai/config/package_config/DESKTOP 2>/dev/null ||: # broken pipe
81
82
83 rsync -rplt --delete $BASEFILE_DIR/*.gz root@$faiserver_host:/srv/fai/config/basefiles/
84 ssh root@$faiserver_host bash <<'EOF'
85 set -eE -o pipefail
86 # make it the root because pxe-kexec only looks there.
87 # It wouldn't be too hard to change if we needed.
88 # We could also just dump things in /srv/tftp, but fai
89 # has some defaults, which I don't even use, which expect
90 # the other directory, so it's kind of a tossup, whatever.
91 sed -ri 's,^ *(TFTP_DIRECTORY=).*,\1"/srv/tftp/fai",' /etc/default/tftpd-hpa
92 systemctl restart tftpd-hpa
93
94 changed=false
95 f=/srv/fai/nfsroot/root/.ssh/known_hosts
96 install -d -m 700 /srv/fai/nfsroot/root/.ssh
97 # the known hosts entries that fai already sets up are like
98 # IP,HOSTNAME key_info...
99 # we are skipping the ip, because it doesn't block ssh
100 # with a prompt as long as you have the user supplied hostname,
101 # and i don't want to deal with getting it, it's not adding
102 # any important security in this case.
103 if ! grep -xFq "$line" $f &>/dev/null; then
104 changed=true
105 printf "%s\n" "$line" >>$f
106 fi
107
108 if ! modprobe nfsd &>/dev/null; then
109 # no apt-cache on maru debian, because we are low on space already
110 sed -i '/^ *APTPROXY=/d' /srv/fai/config/class/DEBIAN.var
111 # maru debian doesn't have loopback devs created
112 if ! losetup -f; then
113 shopt -s nullglob
114 x=(/dev/loop*)
115 minor=0
116 if (( ${#x[@]} )); then
117 minor=$(( ${x[-1]#/dev/loop} + 1 ))
118 fi
119 mknod -m660 /dev/loop$minor b 7 $minor
120 losetup -f
121 fi
122 # -B boo only iso, no nfsroot, no paritial miorr, no config space.
123 # -f = force, for overwriting
124 # -S = make squash image for http booting
125 # -d config space url, instead of putting it in the squash.img,
126 # this just makes it so that we don't have to regenerate the img
127 # when the config changes.
128 cd /srv/fai/config
129 tar czf /var/www/faiserver/html/config.tar.gz .
130 if $changed || [[ ! -e /var/www/faiserver/html/squash.img ]]; then
131 # note, on maru, selinux needs to be disabled in android before
132 # this will work.
133 mount
134 export debug=true
135 fai-cd -d http://faiserver:8080/config.tar.gz -f -M -S /var/www/faiserver/html/squash.img
136 mount
137 fi
138 fi
139 EOF