better checking for uninstalled changes in btrfs send related scripts
[distro-setup] / switch-mail-host
index 4e8dfdece189e4080966d72e18ed5e025bc93c18..d0117af58203015ec87fe91594b9df7756621c84 100644 (file)
@@ -10,6 +10,10 @@ Turn off mail receiving on OLD_HOST, run btrbk to move mail to NEW_HOST,
 turn on mail receiving on NEW_HOST.  Assumes we want to move all
 filesystems unless passing -o.
 
+-a         Avoid snapshot /a, /q, and similar. If we haven't
+           made any changes in the last hour, there is no
+           need to snapshot anything but /o, and we will
+           just do that once.
 -i         Disallow incremental backup.
 -o         Only btrbk /o, instead of all filesystems.
 --force    Run even though our local state does not say that MAIL_HOST is
@@ -57,13 +61,18 @@ fi
 mail_only=false
 host2_only=false
 force=false
-mp_args="-m /o,/q,/a"
-temp=$(getopt -l force,help ioh "$@") || usage 1
+pull_reexec=false
+mp_args="-m /o,/a,/ar,/q,/qd,/qr"
+orig_args=("$@")
+temp=$(getopt -l force,pull-reexec,help aioh "$@") || usage 1
 eval set -- "$temp"
 while true; do
   case $1 in
+    -a) snapshot_arg=resume ;;
     --force) force=true ;;
     -i) incremental_arg="-i" ;;
+    # internal option for rerunning under newer old_host when doing pull
+    --pull-reexec) pull_reexec=true;;
     -o)
       mail_only=true ;;
     -h|--help) usage ;;
@@ -81,6 +90,28 @@ if [[ ! $HOSTNAME ]]; then
   exit 1
 fi
 
+uninstalled-file-die() {
+  err "uninstalled file $1. run install-my-scripts or rerun with -f"
+  exit 1
+}
+
+if ! $force; then
+  install_bin_files=(
+    mount-latest-subvol
+    check-subvol-stale
+    btrbk-run
+    switch-mail-host
+  )
+  for f in ${install_bin_files[@]}; do
+    if ! diff -q /a/bin/ds/$f /usr/local/bin/$f; then
+      uninstalled-file-die $f
+    fi
+  done
+  if ! diff -q /a/bin/errhandle/err /usr/local/lib/err; then
+    uninstalled-file-die err
+  fi
+fi
+
 source /a/bin/bash_unpublished/source-state
 
 direction=$1
@@ -103,7 +134,6 @@ case $direction in
     new_hostname=$HOSTNAME
     bbk_args="-s $old_host"
     old_shell="ssh -F $HOME/.ssh/confighome root@$old_host"
-    old_shelliank="ssh -F $HOME/.ssh/confighome iank@$old_host"
     # tests ssh connection. crafted this to not need to do escape chars
     f=/a/bin/bash_unpublished/source-state
     if ! old_info=($($old_shell "hostname; sed -n s,.*MAIL_HOST=,,p $f; sed -n s,.*HOST2=,,p $f")); then
@@ -114,6 +144,18 @@ case $direction in
     old_hostname=${old_info[0]}
     MAIL_HOST=${old_info[1]}
     HOST2=${old_info[2]}
+
+    if ! $mail_only && ! $pull_reexec ; then
+      tmpf=$(mktemp)
+      m scp -F $HOME/.ssh/confighome root@$old_host:/usr/local/bin/switch-mail-host $tmpf
+      if ! diff -q $tmpf ${BASH_SOURCE[0]}; then
+        e "found different version on old_host=$old_hostname, reexecing"
+        install -T $tmpf /usr/local/bin/switch-mail-host
+        m /usr/local/bin/switch-mail-host --pull-reexec "${orig_args[@]}"
+        mexit 0
+      fi
+    fi
+
     ;;
   *)
     err invalid first argument
@@ -138,18 +180,19 @@ esac
 if $mail_only; then
   mp_args="-m /o"
 elif $host2_only; then
-  mp_args="-m /a,/ar,/q,/qr"
+  mp_args="-m /a,/ar,/q,/qd,/qr"
 fi
 
-
-if $host2_only; then
-  if [[ $old_hostname != "$HOST2" ]]; then
-    err "\$old_hostname($old_hostname) != \$HOST2($HOST2). Rerun with --force if you really want this."
+if ! $force; then
+  if $host2_only; then
+    if [[ $old_hostname != "$HOST2" ]]; then
+      err "\$old_hostname($old_hostname) != \$HOST2($HOST2). Rerun with --force if you really want this."
+      exit 1
+    fi
+  elif [[ $old_hostname != "$MAIL_HOST" ]]; then
+    err "\$old_hostname($old_hostname) != \$MAIL_HOST($MAIL_HOST). Rerun with --force if you really want this."
     exit 1
   fi
-elif [[ $old_hostname != "$MAIL_HOST" ]] && ! $force; then
-  err "\$old_hostname($old_hostname) != \$MAIL_HOST($MAIL_HOST). Rerun with --force if you really want this."
-  exit 1
 fi
 
 if [[ ! $new_host || ! $old_host ]]; then
@@ -204,11 +247,11 @@ if pgrep -G iank -u iank -f 'emacs --daemon' &>/dev/null; then
 fi
 EOF
   if ! $host2_only; then
-    cat <<'EOF'
+    cat <<EOF
 for dir in m o; do
-  if mountpoint -q /$dir; then
-    echo On $new_host: umount /$dir
-    umount /$dir
+  if mountpoint -q /\$dir; then
+    echo On $new_host: umount /\$dir
+    umount /\$dir
   fi
 done
 EOF
@@ -241,8 +284,8 @@ EOF
 
 
 e Running initial btrbk
-if ! m btrbk-run -v $bbk_args $incremental_arg $mp_args; then
-  ret=$?
+m btrbk-run -v $bbk_args $incremental_arg $mp_args $snapshot_arg || ret=$?
+if (( ret )); then
   err "failed initial btrbk"
   exit $ret
 fi
@@ -260,8 +303,8 @@ if $host2_only; then
   exit 0
 fi
 
-if ! m $old_shell /a/exe/primary-setup $new_hostname; then
-  ret=$?
+m $old_shell /a/exe/primary-setup $new_hostname || ret=$?
+if (( ret )); then
   err "failed \$old_shell primary-setup \$new_hostname. fix and rerun $script_name"
   exit $ret
 fi
@@ -291,8 +334,8 @@ echo
 #
 # shopt -s nullglob; find . -type f -mtime -2 | while read -r f; do a=( /m/4e/Sent/cur/${f%,*}* ); if (( ${#a[@]} )); then e exists $a; else m cp -a $f /m/4e/Sent/cur; fi; done
 
-if ! m $new_shell /a/exe/primary-setup localhost; then
-  ret=$?
+m $new_shell /a/exe/primary-setup localhost || ret=$?
+if (( ret )); then
   err "failed final primary-setup, just fix and rerun: $new_shell /a/exe/primary-setup localhost"
   exit $ret
 fi