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