Mainly add external monitoring of mail server
[distro-setup] / switch-mail-host
1 #!/bin/bash
2
3 source /usr/local/lib/err
4
5 usage() {
6 cat <<EOF
7 Usage: ${0##*/} push|pull HOST
8
9 Turn off mail receiving on OLD_HOST, run btrbk to move mail to NEW_HOST,
10 turn on mail receiving on NEW_HOST. Assumes we want to move all
11 filesystems unless passing -o.
12
13 -o Only btrbk /o, instead of all filesystems.
14 -h|--help Print help and exit.
15
16 I used to adjust home network dns so NEW_HOST resolves locally if it is
17 on the local network, but its simpler just not to and just rely
18 on the internet. Email can wait.
19
20 Note: Uses GNU getopt options parsing style
21 EOF
22 exit $1
23 }
24
25 restore_new_btrbk=false
26 restore_old_btrbk=false
27 cleanup() {
28 if $restore_new_btrbk; then
29 e WARNING: due to failure, btrbk.timer may need manual restoration:
30 e $new_shell sudo systemctl start btrbk.timer
31 fi
32 if $restore_old_btrbk; then
33 e WARNING: due to failure, btrbk.timer may need manual restoration:
34 e $old_shell sudo systemctl start btrbk.timer
35 fi
36 }
37 b
38 pre="${0##*/}:"
39 m() { printf "$pre %s\n" "$*"; "$@"; }
40 e() { printf "$pre %s\n" "$*"; }
41 err() { echo "[$(date +'%Y-%m-%d %H:%M:%S%z')]: $pre: $*" >&2; }
42
43 ##### begin command line parsing ########
44
45 temp=$(getopt -l help owh "$@") || usage 1
46 mp_args="-m /o,/q,/a"
47 eval set -- "$temp"
48 while true; do
49 case $1 in
50 -o) mp_args="-m /o"; shift ;;
51 -h|--help) usage ;;
52 --) shift; break ;;
53 *) echo "$0: Internal error! unexpected args: $*" ; exit 1 ;;
54 esac
55 done
56
57
58 (( $# == 2 )) || usage 1
59
60
61 case $1 in
62 push)
63 new_host=$2
64 bbk_args="-s $old_host"
65 new_shell="ssh $new_host"
66 old_host=$HOSTNAME
67 ;;
68 pull)
69 old_host=$2
70 bbk_args="-t $new_host"
71 bbk_args="-s $old_host"
72 new_host=$HOSTNAME
73 old_shell="ssh $old_host"
74 ;;
75 *)
76 err invalid first argument
77 exit 1
78 ;;
79 esac
80
81
82 source /a/bin/bash_unpublished/source-state
83
84 if [[ $old_host != "$MAIL_HOST" ]]; then
85 read -r -p "warning: \$old_host != \$MAIL_HOST: $old_host != $MAIL_HOST, proceed? y/N "
86 if [[ $REPLY != [yY] ]]; then
87 exit 1
88 fi
89 fi
90
91 if [[ ! $new_host || ! $old_host ]]; then
92 echo "$0: bad args. see script"
93 exit 1
94 fi
95
96 e $new_shell hostname
97 new_hostname=$($new_shell hostname)
98
99 ########### end initial processing, begin actually modifying things ##########
100
101 if $new_shell systemctl is-active btrbk.timer; then
102 m $new_shell sudo systemctl stop btrbk.timer
103 _errcatch_cleanup=cleanup
104 restore_new_btrbk=true
105 fi
106 if $old_shell systemctl is-active btrbk.timer; then
107 m $old_shell sudo systemctl stop btrbk.timer
108 _errcatch_cleanup=cleanup
109 restore_old_btrbk=true
110 fi
111
112 btrbk_test="systemctl is-active btrbk.service"
113 while true; do
114 for shell in "$new_shell" "$old_shell"; do
115 e $shell $btrbk_test
116 status=$($shell $btrbk_test) ||:
117 case $status in
118 inactive|failed) : ;;
119 *)
120 e "btrbk active on shell:$shell, status:$status, sleeping 8 seconds"
121 sleep 8
122 continue
123 ;;
124 esac
125 done
126 break
127 done
128
129 # ensure these are unused before doing anything
130
131 e "umounting /m and /o via $new_shell"
132 $new_shell bash -xs <<'EOF'
133 set -eE
134 if mountpoint -q /m; then sudo umount /m; fi
135 if mountpoint -q /o; then sudo umount /o; fi
136 EOF
137
138 # previously, I was checking to see if the new mail host
139 # is on my home network, then changing my home dns
140 # to resolve on the local network, so that I didnt
141 # have to send traffic out to the internet or rely
142 # on that. However, that breaks for a laptop that roams.
143 # So, we could have a cronjob that updates that dns,
144 # however, another solution is to just use ipv6,
145 # and I prefer that.
146 #
147 # TODO: enable ipv6 for email. exim config setting disables it.
148 # need to add vpn support. need to add firewall / routing.
149 # I think exim will try ipv6 first, so no need to disable
150 # ipv6 i think.
151
152
153
154 m $old_shell /a/exe/primary-setup $new_hostname
155
156 if ! m btrbk-run -v $bbk_args $mp_args; then
157 ret=$?
158 bang="$(printf "$(tput setaf 5)█$(tput sgr0)%.0s" 1 2 3 4 5 6 7)"
159 e $bang failed btrbk. restoring old host as primary
160 m $old_shell /a/exe/primary-setup localhost
161 exit $ret
162 fi
163
164 m $new_shell /a/exe/primary-setup localhost