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