fixes to last commit
[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 err-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
38 pre="${0##*/}:"
39 m() { printf "$pre %s\n" "$*"; "$@"; }
40 e() { printf "$pre %s\n" "$*"; }
41 err() { echo "$pre ERROR: $*" >&2; }
42 mexit() { echo "$pre exiting with status $1"; exit $1; }
43
44 ##### begin command line parsing ########
45
46 force=false
47 mp_args="-m /o,/q,/a"
48 temp=$(getopt -l force,help owh "$@") || usage 1
49 eval set -- "$temp"
50 while true; do
51 case $1 in
52 --force) force=true ;;
53 -o) mp_args="-m /o"; shift ;;
54 -h|--help) usage ;;
55 --) shift; break ;;
56 *) echo "$0: Internal error! unexpected args: $*" ; mexit 1 ;;
57 esac
58 done
59
60
61 (( $# == 2 )) || usage 1
62
63 if [[ ! $HOSTNAME ]]; then
64 err '$HOSTNAME is unset'
65 mexit 1
66 fi
67
68 case $1 in
69 push)
70 old_host=$HOSTNAME
71 old_hostname=$HOSTNAME
72 new_host=$2
73 bbk_args="-t $new_host"
74 new_shell="ssh $new_host"
75 new_hostname=$($new_shell hostname)
76 ;;
77 pull)
78 old_host=$2
79 new_host=$HOSTNAME
80 new_hostname=$HOSTNAME
81 bbk_args="-s $old_host"
82 old_shell="ssh $old_host"
83 # tests ssh connection
84 old_hostname=$($old_shell hostname)
85 ;;
86 *)
87 err invalid first argument
88 mexit 1
89 ;;
90 esac
91
92 source /a/bin/bash_unpublished/source-state
93
94 if [[ $old_hostname != "$MAIL_HOST" ]] && ! $force; then
95 err "\$old_hostname($old_hostname) != \$MAIL_HOST($MAIL_HOST). Rerun with --force if you really want this."
96 mexit 1
97 fi
98
99 if [[ ! $new_host || ! $old_host ]]; then
100 echo "$0: bad args. see script"
101 mexit 1
102 fi
103
104
105 ########### end initial processing, begin actually modifying things ##########
106
107 if $new_shell systemctl is-active btrbk.timer; then
108 m $new_shell sudo systemctl stop btrbk.timer
109 restore_new_btrbk=true
110 fi
111 if $old_shell systemctl is-active btrbk.timer; then
112 m $old_shell sudo systemctl stop btrbk.timer
113 restore_old_btrbk=true
114 fi
115
116 btrbk_test="systemctl is-active btrbk.service"
117 active=true
118 while $active; do
119 active=false
120 for shell in "$new_shell" "$old_shell"; do
121 e $shell $btrbk_test
122 status=$($shell $btrbk_test) ||:
123 case $status in
124 inactive|failed) : ;;
125 *)
126 # This covers conditions like "activating", which still return 3 from
127 # systemctl is-active.
128 active=true
129 e "btrbk active on shell:$shell, status:$status, sleeping 8 seconds"
130 sleep 8
131 break
132 ;;
133 esac
134 done
135 done
136
137 # ensure these are unused before doing anything
138
139 e "umounting /m and /o via $new_shell"
140 $new_shell bash -xs <<'EOF'
141 set -eE
142 if mountpoint -q /m; then sudo umount /m; fi
143 if mountpoint -q /o; then sudo umount /o; fi
144 EOF
145
146 # previously, I was checking to see if the new mail host
147 # is on my home network, then changing my home dns
148 # to resolve on the local network, so that I didnt
149 # have to send traffic out to the internet or rely
150 # on that. However, that breaks for a laptop that roams.
151 # So, we could have a cronjob that updates that dns,
152 # however, another solution is to just use ipv6,
153 # and I prefer that.
154 #
155 # TODO: enable ipv6 for email. exim config setting disables it.
156 # need to add vpn support. need to add firewall / routing.
157 # I think exim will try ipv6 first, so no need to disable
158 # ipv6 i think.
159
160
161 e Running initial btrbk
162 if ! m btrbk-run -v $bbk_args $mp_args; then
163 ret=$?
164 err "failed initial btrbk"
165 mexit $ret
166 fi
167
168 m $old_shell /a/exe/primary-setup $new_hostname
169
170 e Running main btrbk
171 m btrbk-run -v $bbk_args -m /o || ret=$?
172 if (( ret )); then
173 bang="$(printf "$(tput setaf 5)█$(tput sgr0)%.0s" 1 2 3 4 5 6 7)"
174 e $bang failed btrbk of /o. restoring old host as primary
175 m $old_shell /a/exe/primary-setup localhost
176 mexit $ret
177 fi
178
179 m $new_shell /a/exe/primary-setup localhost
180
181 mexit 0