various fixes
[distro-setup] / switch-mail-host
1 #!/bin/bash
2 set -x
3 set -eE -o pipefail
4 trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR
5
6 usage() {
7 cat <<EOF
8 Usage: ${0##*/} OLD_HOST NEW_HOST
9
10 Adjust home network dns so NEW_HOST resolves locally if it is on the
11 local network. Turn off mail receiving on OLD_HOST, run btrbk to move
12 mail to NEW_HOST, turn on mail receiving on NEW_HOST.
13
14
15 -h|--help Print help and exit.
16
17 Note: Uses GNU getopt options parsing style
18 EOF
19 exit $1
20 }
21
22 ##### begin command line parsing ########
23
24 if (( $# != 2 )) || [[ $1 == -* || $2 == -* ]]; then
25 usage 1
26 fi
27
28 old_host=$1
29 new_host=$2
30
31 if [[ $old_host != $MAIL_HOST ]]; then
32 read -p "warning: \$old_host != \$MAIL_HOST: $old_host != $MAIL_HOST, proceed? y/N "
33 if [[ $REPLY != [yY] ]]; then
34 exit 1
35 fi
36 fi
37
38 if [[ $new_host == "$HOSTNAME" ]]; then
39 localhost_new=true
40 ssh_prefix=ssh
41 else
42 localhost_new=false
43 ssh_prefix=
44 fi
45 if [[ ! $new_host || ! $old_host ]]; then
46 echo "$0: bad args. see script"
47 exit 1
48 fi
49
50 at_home=false
51 if timeout -s 9 10 ssh root@wrt.lan :; then
52 at_home=true
53 fi
54
55 source /a/bin/bash_unpublished/source-semi-priv
56 #### begin convert private hostnames to public hostnames ####
57 if ! $at_home; then
58 for var in old_host new_host; do
59 case ${!var} in
60 treetowl)
61 eval $var=$HOME_DOMAIN
62 ;;
63 esac
64 done
65 fi
66 #### end convert private hostnames to public hostnames ####
67
68
69 # because our port forward is not robust enough, we can't use proxy command,
70 # todo: just open an ssh port to the world on wrt
71 if ! $at_home; then
72 ssh_cmd="ssh $HOME_DOMAIN ssh wrt"
73 else
74 ssh_cmd="ssh wrt"
75 fi
76 # if new_host is not on home network, make mail.iankelling.org not resolve
77 # on the home network.
78 if [[ $new_host == $HOSTNAME ]] && ! $at_home; then
79 echo | $ssh_cmd cedit mail_host /etc/hosts
80 else
81 $ssh_cmd bash -s <<EOFOUTER
82 cedit mail_host /etc/hosts <<'EOF' || /etc/init.d/dnsmasq restart
83 \$(grep "\b$new_host\b" /etc/hosts | awk '{print $1}') mail.iankelling.org
84 EOF
85 EOFOUTER
86 fi
87
88 mail-setup() {
89 shell="$1"
90 $shell sed -ri "s/MAIL_HOST=.*/MAIL_HOST=$new_host/" /a/bin/bash_unpublished/source-semi-priv
91 $shell /a/bin/distro-setup/mail-setup exim4
92 }
93
94 mail-setup "ssh $old_host"
95
96 sudo dd of=/etc/btrbk.conf <<'EOF'
97 ssh_identity /root/.ssh/id_rsa
98 # Just a guess that local7 is a good facility to pick.
99 # It's a bit odd that the transaction log has to be logged to
100 # a file or syslog, while other output is sent to std out.
101 # The man does not mention a way for them to be together, but
102 # I dunno if setting a log level like warn might also output
103 # transaction info.
104 transaction_syslog local7
105
106 # so we only run one at a time
107 lockfile /var/lock/btrbk.lock
108
109 # default format of short does not accomidate hourly preservation setting
110 timestamp_format long-iso
111
112 # only make a snapshot if things have changed
113 snapshot_create onchange
114 # I could make this different from target_preserve,
115 # if one disk had less space.
116 # for now, keeping them equal.
117 snapshot_preserve 36h 14d 8w 24m
118 snapshot_preserve_min 4h
119 snapshot_dir btrbk
120
121 # so, total backups = ~89
122 target_preserve 36h 14d 8w 24m
123 target_preserve_min 4h
124
125 # if something fails and it's not obvious, try doing
126 # btrbk -l debug -v dryrun
127
128
129 EOF
130
131
132 if $localhost_new; then
133 btrbk_src=ssh://$old_host/mnt/root
134 btrbk_dst=/mnt/root/btrbk
135 else
136 btrbk_src=/mnt/root
137 btrbk_dst=ssh://$old_host/mnt/root/btrbk
138 fi
139
140 sudo tee -a /etc/btrbk.conf <<EOF
141 volume $btrbk_src
142 subvolume o
143 target send-receive $btrbk_dst
144 EOF
145
146
147 sudo btrbk --progress run
148 $ssh_prefix $new_host mount-latest-subvol
149
150 mail-setup