conflink detect systemd changes, better btrbk for roaming laptops
[distro-setup] / conflink
1 #!/bin/bash
2
3 source /a/bin/errhandle/err
4 _errcatch_cleanup() {
5 echo 1 >~/.local/conflink
6 }
7
8
9 usage() {
10 cat <<EOF
11 Usage: ${0##*/} [OPTIONS]
12 Link or otherwise install configuration files.
13
14 -f For fast. Dont use lnf, use ln -sf. Good for updating existing files.
15 EOF
16 exit $1
17 }
18
19
20 m() {
21 echo "$*"
22 "$@"
23 }
24 s() { sudo "$@"; }
25
26 lnf() { /a/exe/lnf "$@"; }
27 if [[ $1 == -f ]]; then # f for fast
28 lnf() { ln -sf "$@"; }
29 elif
30 [[ $1 ]]; then
31 echo "error: unrecognized arguments" >&2
32 exit 0
33 fi
34
35 shopt -s nullglob
36 shopt -s extglob
37 shopt -s dotglob
38
39 # If we make a link back to the root, we stop going deeper into subdir_files.
40 # This makes it so we can do subdir directories.
41 #
42 # Also note, under filesystem/, symlinks are expanded.
43
44 subdir-link-r() {
45 local root="$1"
46 local targets=()
47 if [[ $2 ]]; then
48 targets=( "$2"/!(.git|..|.) )
49 else
50 for f in "$1"/!(.git|..|.); do
51 if [[ -d $f ]]; then targets+=("$f"); fi
52 done
53 fi
54 local below
55 below="$( readlink -f "$root/..")"
56 for path in "${targets[@]}"; do
57 local fullpath
58 fullpath="$(readlink -f "$path")"
59 #e $fullpath $below # debug
60 if [[ -f $path || $(dirname $(readlink -f "$fullpath")) == "$below" ]]; then
61 m lnf -T "$path" "$HOME/${path#$root/}"
62 elif [[ -d "$path" ]]; then
63 subdir-link-r "$root" "$path"
64 fi
65 done
66 }
67
68
69 common-file-setup() {
70 local dir fs x f systemd_reload
71 systemd_reload=false
72 for dir in "$@"; do
73 fs=$dir/filesystem
74 if [[ -e $fs && $user =~ ^iank?$ ]]; then
75 # this could be done with rsync, something like this,
76 # but I haven't looked at the symlinks.
77 # s rsync -n -ahviSAXPH --specials --devices --chown=root:root --chmod=g-s $fs /
78 # note, symlinks get resolved, not copied.
79 if s tar --mode=g-s --owner=0 --group=0 -cz -C $fs . | s tar -dz -C / | grep /etc/systemd &>/dev/null; then
80 systemd_reload=true
81 fi
82 s tar --mode=g-s --owner=0 --group=0 -cz -C $fs . | s tar -xz -C /
83 fi
84
85 if [[ -e $dir/subdir_files ]]; then
86 m subdir-link-r $dir/subdir_files
87 fi
88 local x=( $dir/!(binds|subdir_files|filesystem|machine_specific|..|.) )
89 (( ${#x[@]} >= 1 )) || continue
90 m lnf ${x[@]} ~
91 done
92 if $systemd_reload; then
93 m s systemctl daemon-reload
94 fi
95 }
96
97 user=$(id -un)
98 all_dirs=({/a/bin/ds,/p/c}{,/machine_specific/$HOSTNAME})
99 # note, we assume a group of hosts does not have the
100 # same name as a single host, which is no problem on our scale.
101 for x in /p/c/machine_specific/*.hosts /a/bin/ds/machine_specific/*.hosts; do
102 if grep -qxF $HOSTNAME $x; then all_dirs+=( ${x%.hosts} ); fi
103 done
104
105 c_dirs=(/a/c{,/machine_specific/$HOSTNAME})
106 case $user in
107 iank)
108 files=(/p/c/machine_specific/*/filesystem/etc/ssh/*_key
109 /p/c/filesystem/etc/openvpn/client/*.key
110 /p/c/filesystem/etc/openvpn/easy-rsa/keys/*.key
111 /p/c/machine_specific/kw/filesystem/etc/openvpn/client/*.key
112 )
113 if [[ -e ${files[0]} ]]; then
114 chmod 600 ${files[@]}
115 fi
116 # p needs to go first so .ssh link is created, then config link inside it
117 m common-file-setup ${all_dirs[@]}
118
119 #### begin special extra stuff ####
120 install -d -m700 ~/gpg-agent-socket
121
122 f=/var/lib/bind
123 if [[ -e $f ]]; then
124 # reset to the original permissions.
125 m s chgrp -R bind $f
126 m s chmod g+w $f
127 fi
128 sudo bash -c 'shopt -s nullglob; for f in /etc/bind/*.key /etc/bind/*.private /etc/bind/key.*; do chgrp bind $f; done'
129 if [[ -e /etc/davpass ]] && getent group www-data &>/dev/null; then
130 s chgrp www-data /etc/davpass
131 fi
132 if [[ -e /var/lib/znc ]] && getent group znc; then
133 s chown -R znc:znc /var/lib/znc
134 fi
135 /a/exe/lnf -T /p/arbtt-capture.log ~/.arbtt/capture.log
136 f=/etc/prometheus-htpasswd
137 if [[ -e $f ]]; then
138 s chmod 640 $f /etc/prometheus-pass
139 s chown root:www-data $f
140 if getent passwd prometheus; then
141 s chown root:prometheus /etc/prometheus-pass
142 fi
143 fi
144
145 ##### end special extra stuff #####
146
147 if [[ -e /etc/openvpn ]]; then
148 sudo bash -c 'shopt -s nullglob && cd /etc/openvpn && for f in client/* server/*; do ln -sf $f .; done'
149 fi
150
151 m sudo -H -u user2 "${BASH_SOURCE[0]}"
152
153 f=/a/bin/distro-setup/system-status
154 if [[ -x $f ]]; then
155 $f _
156 fi
157 echo 0 >~/.local/conflink
158
159 ;;
160 user2)
161 m common-file-setup ${c_dirs[@]}
162 ;;
163 *)
164 echo "$0: error: unexpected user"; exit 1
165 ;;
166 esac
167