amy backup restore, various improvements
authorIan Kelling <ian@iankelling.org>
Tue, 13 Jul 2021 04:11:48 +0000 (00:11 -0400)
committerIan Kelling <ian@iankelling.org>
Tue, 13 Jul 2021 04:11:48 +0000 (00:11 -0400)
20 files changed:
brc2
btrbk-run
btrbkr2 [new file with mode: 0755]
check-subvol-stale
distro-begin
distro-end
dynamic-ip-update
epanic-clean
filesystem/etc/cron.d/ian
filesystem/etc/systemd/system/btrfsmaint.service
filesystem/etc/systemd/system/btrfsmaintstop.service
filesystem/etc/systemd/system/dynamicipupdate.service
filesystem/etc/systemd/system/systemstatus.service [new file with mode: 0644]
filesystem/etc/systemd/system/systemstatus.timer [new file with mode: 0644]
gen-amy-fstab [new file with mode: 0755]
machine_specific/btrbk/filesystem/etc/systemd/system/btrbk.timer
machine_specific/kd/filesystem/etc/systemd/system/btrbkrust.service
mail-setup
mount-latest-subvol
system-status

diff --git a/brc2 b/brc2
index b57789fce80b4ae784a398c2e7bd54b83dfaa18e..ccc496812659d7bb9eb6ce09d5dad5127f0b2bfc 100644 (file)
--- a/brc2
+++ b/brc2
@@ -332,6 +332,10 @@ bbk() { # btrbk wrapper
   return $ret
 }
 
+faimon() {
+  fai-monitor | pee cat "fai-monitor-gui -"
+}
+
 bfg() { java -jar /a/opt/bfg-1.12.14.jar "$@"; }
 
 bigclock() {
@@ -945,15 +949,20 @@ o() {
 }
 ccomp xdg-open o
 
-jfilter() {
-  grep -Evi -e "^(\S+\s+){4}(sudo|sshd|cron)\[\S*:" \
-       -e "^(\S+\s+){4}systemd\[\S*: (starting|started) (btrfsmaintstop|dynamicipupdate|spamd dns bug fix cronjob|rss2email)\.*$"
-}
-jtail() {
-  journalctl -n 10000 -f "$@" | jfilter
-}
-jr() { journalctl "$@" | jfilter | less ; }
-jrf() { journalctl -n 200 -f "$@" | jfilter; }
+# jfilter() {
+#   grep -Evi -e "^(\S+\s+){4}(sudo|sshd|cron)\[\S*:" \
+  #        -e "^(\S+\s+){4}systemd\[\S*: (starting|started) (btrfsmaintstop|dynamicipupdate|spamd dns bug fix cronjob|rss2email)\.*$"
+# }
+# jtail() {
+#   journalctl -n 10000 -f "$@" | jfilter
+# }
+# jr() { journalctl "$@" | jfilter | less ; }
+# jrf() { journalctl -n 200 -f "$@" | jfilter; }
+
+jr() { journalctl "$@" ; }
+jrf() { journalctl -n 200 -f "$@" ; }
+
+
 ccomp journalctl jtail jr jrf
 
 kff() { # keyboardio firmware flash
index fd05c090a08e610c6a5665915a643f41efa060da..88676beb36318e83f8835a6d72ed48c6e1f118ad 100644 (file)
--- a/btrbk-run
+++ b/btrbk-run
@@ -143,11 +143,13 @@ fi
 ### end options parsing
 
 # note, this test succeeds if not installed
-if [[ /a/opt/btrbk/btrbk -nt /usr/btrbk ]]; then
+if [[ /a/opt/btrbk/btrbk -nt /usr/bin/btrbk ]]; then
   if [[ -e /b/distro-functions/src/package-manager-abstractions ]]; then
     . /b/distro-functions/src/package-manager-abstractions
     pi asciidoctor
   fi
+  # remove path from earlier version of btrbk
+  rm -f /usr/sbin/btrbk
   cd /a/opt/btrbk
   m make
   m sudo make install
@@ -191,15 +193,16 @@ if [[ ! -v targets && ! $source ]]; then
       targets+=($home x3)
       ;;
     x2|x3|sy)
-      targets+=($home kw.office.fsf.org)
-      ;;
-    kd)
-      targets+=(x2.b8.nz sy.b8.nz)
-      # might not be connected to the vpn
-      if timeout -s 9 6 ssh kw.office.fsf.org :; then
+      targets+=($home)
+      if $at_work; then
         targets+=(kw.office.fsf.org)
+      else
+        targets+=(kw.b8.nz)
       fi
       ;;
+    kd)
+      targets+=(x2.b8.nz sy.b8.nz kw.b8.nz)
+      ;;
     frodo)
       # no targets
       targets=()
@@ -388,9 +391,8 @@ ssh_identity /root/.ssh/home
 # transaction info.
 transaction_syslog local7
 
-# note, i had this because man said 20% speedup, but ran into
-# this issue, https://github.com/digint/btrbk/issues/275
-#stream_buffer 512m
+# trying this out
+stream_compress zstd
 
 # so we only run one at a time
 lockfile                   /var/lock/btrbk.lock
diff --git a/btrbkr2 b/btrbkr2
new file mode 100755 (executable)
index 0000000..321948c
--- /dev/null
+++ b/btrbkr2
@@ -0,0 +1,104 @@
+#!/bin/bash
+# Copyright (C) 2019 Ian Kelling
+# SPDX-License-Identifier: AGPL-3.0-or-later
+# SPDX-License-Identifier: GPL-3.0-or-later
+# SPDX-License-Identifier: Apache-2.0
+
+if ! test "$BASH_VERSION"; then echo "error: shell is not bash" >&2; exit 1; fi
+shopt -s inherit_errexit 2>/dev/null ||: # ignore fail in bash < 4.4
+set -eE -o pipefail
+trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" exit status: $?, PIPESTATUS: ${PIPESTATUS[*]}" >&2' ERR
+# alternatively, using https://iankelling.org/git/?p=errhandle;a=tree
+# source /path/errhandle/err
+# on my machine
+source /a/bin/errhandle/err
+
+[[ $EUID == 0 ]] || exec sudo -E "${BASH_SOURCE[0]}" "$@"
+
+usage() {
+  cat <<EOF
+Usage: ${0##*/} TARGET_HOST
+Send btrbk for root2
+
+
+-h|--help  Print help and exit.
+
+Note: Uses util-linux getopt option parsing: spaces between args and
+options, short options can be combined, options before args.
+EOF
+  exit $1
+}
+
+##### begin command line parsing ########
+
+# ensure we can handle args with spaces or empty.
+ret=0; getopt -T || ret=$?
+[[ $ret == 4 ]] || { echo "Install util-linux for enhanced getopt" >&2; exit 1; }
+
+temp=$(getopt -l help h "$@") || usage 1
+eval set -- "$temp"
+while true; do
+  case $1 in
+    -h|--help) usage ;;
+    --) shift; break ;;
+    *) echo "$0: unexpected args: $*" >&2 ; usage 1 ;;
+  esac
+  shift
+done
+
+read -r target <<<"$@"
+
+if [[ ! $target ]]; then
+  echo $0: error: specify target
+  exit 1
+fi
+
+cat >/etc/btrbk/root2.conf <<EOF
+
+ssh_identity /root/.ssh/home
+# Just a guess that local7 is a good facility to pick.
+# It's a bit odd that the transaction log has to be logged to
+# a file or syslog, while other output is sent to std out.
+# The man does not mention a way for them to be together, but
+# I dunno if setting a log level like warn might also output
+# transaction info.
+transaction_syslog local7
+
+# trying this out
+stream_compress zstd
+
+archive_preserve_min latest
+
+# so we only run one at a time
+lockfile   /var/lock/btrbkroot2.lock
+
+# default format of short does not accomidate hourly preservation setting
+timestamp_format long-iso
+
+# dont make new snapshot, we only receive new snapshots
+snapshot_create no
+
+# if something fails and it's not obvious, try doing
+# btrbk -l debug -v dryrun
+
+rate_limit no
+volume /mnt/r7/amy
+subvolume root_ubuntubionic
+target send-receive ssh://$target/mnt/root2/btrbk
+volume /mnt/r7/amy
+subvolume boot_ubuntubionic
+target send-receive ssh://$target/mnt/boot2/btrbk
+
+EOF
+
+tmpconf=$(mktemp -d)/b.conf
+
+timeout -s 9 6 ssh root@$target mkdir -p /mnt/{b,r}oot2/btrbk
+
+exclude=root
+for base in boot root; do
+  cat - /etc/btrbk/root2.conf >$tmpconf <<<"archive_exclude ${exclude}_ubuntubionic"
+  btrbk -c $tmpconf archive /mnt/r7/amy/btrbk ssh://$target/mnt/${base}2/btrbk
+  # swaps the vars
+  exclude=$base
+done
index 7758df7c2fc2eae2697b89eda1e7fa1241e62188..d20c1aaeb848cb85553a5ff82a72326d140ab54b 100644 (file)
@@ -23,7 +23,7 @@ shopt -s nullglob
 
 usage() {
   cat <<EOF
-usage: $0 SUBVOL_MOUNTPOINT...
+usage: $0 SUBVOL_MOUNTPOINT... | -p SUBVOL_PATH...
 
 In git this is not not executable because it's meant to be installed
 using ./install-my-scripts
@@ -35,7 +35,9 @@ Fresh is opposite of stale. To be fresh, either SUBVOL_MOUNTPOINT is a
 snapshot of the latest, or the latest snapshot is snapshot of
 SUBVOL_MOUNTPOINT.
 
--d         Enable debug output
+-p            Args are SUBVOL_PATH, not mountpoints from which we derive
+              that information.
+-v|--verbose  Be more verbose
 -h|--help  Print help and exit.
 
 Note: Uses GNU getopt options parsing style
@@ -45,16 +47,19 @@ EOF
 
 ##### begin command line parsing ########
 
-debug=false # default
-temp=$(getopt -l help,d hd "$@") || usage 1
+subvol_path=false
+verbose=false
+temp=$(getopt -l help,verbose hpv "$@") || usage 1
 eval set -- "$temp"
 while true; do
   case $1 in
-    -d) debug=true; shift ;;
+    -p) subvol_path=true ;;
+    -v|--verbose) verbose=true ;;
     -h|--help) usage ;;
     --) shift; break ;;
-    *) echo "$0: Internal error! unexpected args: $*" ; exit 1 ;;
+    *) echo "$0: unexpected args: $*" >&2 ; usage 1 ;;
   esac
+  shift
 done
 
 if [[ ! $1 ]]; then
@@ -73,38 +78,49 @@ stale-file() {
 
 }
 d() {
-  if $debug; then
+  if $verbose; then
     printf "%s\n" "$*"
   fi
 }
 
 for d; do
-  vol=${d##*/}
-  # second field, non-comment line == $d
-  dev=$(sed -rn "s,^\s*([^#]\S*)\s+$d\s.*,\1,p" /etc/fstab /etc/mtab|head -n1)
-
-  d dev=$dev
-  subvol_dir=$(sed -rn "s,^\s*[^#]\S*\s+$d\s.*\bsubvol=([a-zA-A/]+).*,\1,p" /etc/fstab /etc/mtab|head -n1)
-  if [[ ! $subvol_dir ]]; then
-    continue
-  fi
-  d subvol_dir=$subvol_dir
-  # note, we need $dev because $d might not be mounted, and we do this loop
-  # because the device in fstab for the rootfs can be different.
-  for devx in $(btrfs fil show $dev| sed -rn 's#.*path (/\S+)$#\1#p'); do
-    d devx=$devx
-    root_dir=$(sed -rn "s,^\s*$devx\s+(\S+).*\bsubvolid=[05]\b.*,\1,p" /etc/mtab /etc/fstab|head -n1)
-    if [[ $root_dir ]]; then
-      d root_dir=$root_dir
-      break
+  if $subvol_path; then
+    svp=$d
+    root_dir=${d%/*}
+    subvol_dir=${d##*/}
+    vol=$subvol_dir
+  else
+    vol=${d##*/}
+    # second field, non-comment line == $d
+    dev=$(sed -rn "s,^\s*([^#]\S*)\s+$d\s.*,\1,p" /etc/fstab /etc/mtab|head -n1)
+
+    d dev=$dev
+    subvol_dir=$(sed -rn "s,^\s*[^#]\S*\s+$d\s.*\bsubvol=([a-zA-A/]+).*,\1,p" /etc/fstab /etc/mtab|head -n1)
+    if [[ ! $subvol_dir ]]; then
+      continue
     fi
-  done
-  if [[ ! $root_dir ]]; then
-    echo "$0: error could not find root subvol mount for $dev" >&2
-    exit 1
+    d subvol_dir=$subvol_dir
+
+    ### begin getting root_dir
+    ### this is duplicated in mount-latest-subvol
+    # note, we need $dev because $d might not be mounted, and we do this loop
+    # because the device in fstab for the rootfs can be different.
+    for devx in $(btrfs fil show $dev| sed -rn 's#.*path (/\S+)$#\1#p'); do
+      d devx=$devx
+      root_dir=$(sed -rn "s,^\s*$devx\s+(\S+).*\bsubvolid=[05]\b.*,\1,p" /etc/mtab /etc/fstab|head -n1)
+      if [[ $root_dir ]]; then
+        d root_dir=$root_dir
+        break
+      fi
+    done
+    if [[ ! $root_dir ]]; then
+      echo "$0: error could not find root subvol mount for $dev" >&2
+      exit 1
+    fi
+    ### end getting root_dir
+    svp=$root_dir/$subvol_dir # subvolume path
+    d "svp=$svp # subvolume path"
   fi
-  svp=$root_dir/$subvol_dir # subvolume path
-  d "svp=$svp # subvolume path"
 
   snaps=($root_dir/btrbk/$subvol_dir.20*) # Assumes we are in the 21st century.
   if [[ ! ${snaps[*]} ]]; then
index b4fdfe6a0bbbe42ac81ad556ee0fb93d4a03e41a..4cd02df6b0ef08b675a57210a671c7f330fea7df 100755 (executable)
@@ -165,7 +165,7 @@ EOF
   sudo systemctl enable keyscriptoff.service
   sudo systemctl start keyscriptoff.service
 
-  pi rsync
+  pi rsync zstd
 
   ## /usr/share/doc/dropbear-initramfs/README.initramfs.gz
   ## claims we need to do this. but it works fine without it.
@@ -611,8 +611,6 @@ if isubuntu; then
   sudo dd of=/etc/default/apport <<<'enabled=0'
 fi
 
-
-
 ##### install laptop hardware packages
 if tp || x2 || x3; then
   case $distro in
index 2ca20056cb876012a45a5571eb6147af33ac25e9..b1de65474e898e85b69ae3c20cf30c2220e274a4 100755 (executable)
@@ -982,7 +982,7 @@ Type=oneshot
 # about 24 hours of failures
 # it copies over its files without respecting symlinks, so
 # we pass options to use different location.
-ExecStart=/a/bin/log-quiet/sysd-mail-once -288 rss2email r2e -d /p/c/rss2email.json -c /p/c/rss2email.cfg run
+ExecStart=/usr/local/bin/sysd-mail-once -288 rss2email r2e -d /p/c/rss2email.json -c /p/c/rss2email.cfg run
 EOF
   sd /etc/systemd/system/rss2email.timer <<'EOF'
 [Unit]
@@ -1011,7 +1011,7 @@ After=multi-user.target
 [Service]
 User=iank
 Type=oneshot
-ExecStart=/a/bin/log-quiet/sysd-mail-once irc-backup rsync -rlptDhSAX root@iankelling.org:/var/lib/znc/moddata/log/iank/freenode/ /k/irclogs
+ExecStart=/usr/local/bin/sysd-mail-once irc-backup rsync -rlptDhSAX root@iankelling.org:/var/lib/znc/moddata/log/iank/freenode/ /k/irclogs
 EOF
   sd /etc/systemd/system/ircbackup.timer <<'EOF'
 [Unit]
@@ -1250,7 +1250,7 @@ After=multi-user.target
 
 [Service]
 Type=oneshot
-ExecStart=/a/bin/log-quiet/sysd-mail-once schrootupdate /a/bin/distro-setup/schrootupdate
+ExecStart=/usr/local/bin/sysd-mail-once schrootupdate /a/bin/distro-setup/schrootupdate
 EOF
 sd /etc/systemd/system/schrootupdate.timer <<'EOF'
 [Unit]
@@ -1694,6 +1694,9 @@ EOF
 sgo btrfsmaint.timer
 sgo btrfsmaintstop.timer
 
+sgo systemstatus.timer
+
+
 # aren't autoupdating this, but I do check on it somewhat regularly.
 m cd /a/opt/btrbk
 sudo make install
index ccc7389bd1ddb0a51f0a7ef821ce9462a970aa6e..e10cdb7a4749f295ad1806c3a62b59ed9faf74de 100755 (executable)
@@ -11,7 +11,13 @@ main() {
 
   up4=false
 
-  read -r _ _  gateway _ < <(ip -4 route get 85.119.83.50)
+  if ! read -r _ _  gateway _ < <(ip -4 route get 85.119.83.50 2>/dev/null); then
+    # if our internet is down, just give up, no need to have an error
+    if [[ ! $INVOCATION_ID ]]; then
+      echo $0: failed to get route, giving up
+    fi
+    exit 0
+  fi
 
   case $gateway in
     10.2.0.1)
index d75574c8f46487b4e85c4c3480551fcb91476f6b..35b72583b12a2941218a6757352293ca9920643a 100755 (executable)
@@ -39,8 +39,13 @@ while read -r service regex; do
     jmin="$(date -d @$sec_min "+%F %H:%M:%S")"
     jmax="$(date -d @$sec_max "+%F %H:%M:%S")"
     description=$(systemctl cat $service | sed -rn 's/^ *Description=(.*)/\1/p')
+    regex="^Starting $description"
+    if [[ $service == spamassassin ]]; then
+      regex+="\|^spamd: restarting"
+    fi
+    # the sed clears out the initial time and process+pid
     if ! journalctl -u $service -S "$jmin" -U "$jmax" \
-        | grep "Starting $description" &>/dev/null; then
+        | sed -r 's/^([^ ]* ){6} //' | grep "$regex" &>/dev/null; then
       wipe=false
       break
     fi
index 7df6705008e9c50244ced96d8c31700b4db4dfd1..53dc8459b67c1fcaa8dd0251c97c85de0f021385 100644 (file)
@@ -2,8 +2,6 @@ SHELL=/bin/bash
 PATH=/usr/bin:/bin:/usr/local/bin:/a/exe
 MAILTO=root
 */10 * * * *   iank rootsshsync |& log-once -15 rootsshsync
-# this goes into bash prompt, does in cron for more efficient shell
-* * * * *   iank system-status |& log-once system-status
 # If theres any logged errors we didnt handle in 4 days, maybe we accidentally missed them,
 # so report if we did
 4 9  * * 5   root /a/bin/ds/check-stale-alerts
index 88705fee666e3813e803bd8b51f1c93098660ecc..3a899e233269718d47939a2a7a3a5a925a10bc03 100644 (file)
@@ -4,9 +4,6 @@ After=multi-user.target
 
 [Service]
 Type=oneshot
-# about 24 hours of failures
-# it copies over its files without respecting symlinks, so
-# we pass options to use different location.
-ExecStart=/a/bin/log-quiet/sysd-mail-once -1 btrfsmaint /a/bin/ds/btrfsmaint
+ExecStart=/usr/local/bin/sysd-mail-once -1 btrfsmaint /usr/local/bin/btrfsmaint
 IOSchedulingClass=idle
 CPUSchedulingPolicy=idle
index e564e1cf534276dea3ebfa9c15daf4c5b115af7b..31b4a652b3d6836a782a4e6a33d9af30b475a55e 100644 (file)
@@ -4,4 +4,4 @@ After=multi-user.target
 
 [Service]
 Type=oneshot
-ExecStart=/a/bin/log-quiet/sysd-mail-once -10 btrfsmaintstop /a/bin/ds/btrfsmaint check
+ExecStart=/usr/local/bin/sysd-mail-once -10 btrfsmaintstop /usr/local/bin/btrfsmaint check
index 84c461581c63f95e4c39eb1d6e6e5703487718d1..48c3d447cd7ff2214e8ac18686f43303d7c3b80a 100644 (file)
@@ -4,4 +4,4 @@ After=multi-user.target
 
 [Service]
 Type=oneshot
-ExecStart=/a/bin/log-quiet/sysd-mail-once -40 dynamicipupdate /a/bin/ds/dynamic-ip-update
+ExecStart=/usr/local/bin/sysd-mail-once -40 dynamicipupdate /usr/local/bin/dynamic-ip-update
diff --git a/filesystem/etc/systemd/system/systemstatus.service b/filesystem/etc/systemd/system/systemstatus.service
new file mode 100644 (file)
index 0000000..23afb89
--- /dev/null
@@ -0,0 +1,11 @@
+[Unit]
+Description=systemstatus
+After=multi-user.target
+
+[Service]
+Type=oneshot
+ExecStart=/usr/local/bin/sysd-mail-once -3 systemstatus /usr/local/bin/system-status
+IOSchedulingClass=idle
+CPUSchedulingPolicy=idle
+User=iank
+Group=iank
diff --git a/filesystem/etc/systemd/system/systemstatus.timer b/filesystem/etc/systemd/system/systemstatus.timer
new file mode 100644 (file)
index 0000000..80e2f74
--- /dev/null
@@ -0,0 +1,11 @@
+[Unit]
+Description=systemstatus
+
+[Timer]
+# for initial run. required.
+OnActiveSec=10
+# for subsequent runs.
+OnUnitInactiveSec=20
+
+[Install]
+WantedBy=timers.target
diff --git a/gen-amy-fstab b/gen-amy-fstab
new file mode 100755 (executable)
index 0000000..7a1ce46
--- /dev/null
@@ -0,0 +1,54 @@
+#!/bin/bash
+# Copyright (C) 2019 Ian Kelling
+# SPDX-License-Identifier: Apache-2.0
+
+if ! test "$BASH_VERSION"; then echo "error: shell is not bash" >&2; exit 1; fi
+shopt -s inherit_errexit 2>/dev/null ||: # ignore fail in bash < 4.4
+set -eE -o pipefail
+trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" exit status: $?, PIPESTATUS: ${PIPESTATUS[*]}" >&2' ERR
+# alternatively, using https://iankelling.org/git/?p=errhandle;a=tree
+# source /path/errhandle/err
+# on my machine
+source /a/bin/errhandle/err
+
+[[ $EUID == 0 ]] || exec sudo -E "${BASH_SOURCE[0]}" "$@"
+
+subvol=$1 # eg ubuntubionic
+nr=$2 # new root
+
+if (( $# != 2 )); then
+  echo $0: error expected 2 arguments
+  exit 1
+fi
+
+if (($(nproc) > 2)); then
+  mopts=,compress=zstd
+fi
+
+rm -f $nr/etc/{fs,crypt}tab
+while read -r line; do
+  printf "%s none  keyscript=decrypt_keyctl,discard,luks,initramfs\n" "$line" >>$nr/etc/crypttab
+done < <(awk '{print $1,$2}' /mnt/root/root2-crypttab)
+awk '$3 == "/dev/urandom" {print}' /etc/crypttab >>$nr/etc/crypttab
+
+
+rootdev=$(awk '$2 == "/mnt/root2" {print $1}' /mnt/root/root2-fstab)
+fstabstd=x-systemd.device-timeout=30s,x-systemd.mount-timeout=30s
+bootdev=$(awk '$2 == "/mnt/boot2" {print $1}' /mnt/root/root2-fstab)
+
+
+cat >> $nr/etc/fstab <<EOF
+$rootdev  /  btrfs $fstabstd,noatime,subvol=root_$subvol$mopts  0 0
+$rootdev  /mnt/root  btrfs  $fstabstd,noatime,subvolid=0$mopts  0 0
+$bootdev  /boot btrfs  nofail,$fstabstd,noatime,subvol=boot_$subvol  0 0
+$bootdev  /mnt/boot  btrfs  nofail,$fstabstd,noatime,subvolid=0  0 0
+tmpfs     /tmp tmpfs     nodev,nosuid,size=50%,mode=1777   0    0
+EOF
+awk '$2 == "/boot/efi" {print}' /etc/fstab >>$nr/etc/fstab
+
+
+while read -r mdname; do
+  cat >> $nr/etc/fstab <<EOF
+/dev/mapper/$mdname  none  swap  nofail,$fstabstd,sw  0 0
+EOF
+done < <(awk '$3 == "/dev/urandom" {print $1}' /etc/crypttab)
index 85e4af2c46e246f90dc0e73347246cc5752ea762..b2a0a7dcbd66b388ae6623c122bdae956faa77f0 100644 (file)
@@ -1,5 +1,5 @@
 [Unit]
-Description=Run btrbk-run once every 20 mins
+Description=Run btrbk-run hourly
 
 [Timer]
 OnCalendar=hourly
index 1391daa0168015ab41b6b940dc92601625dbc12e..053bed5dda23b749eb34e2584d625ae7056ce3f1 100644 (file)
@@ -4,4 +4,4 @@ After=multi-user.target
 
 [Service]
 Type=oneshot
-ExecStart=/a/bin/log-quiet/sysd-mail-once btrbkrust btrbk -c /etc/btrbk/rust.conf run
+ExecStart=/usr/local/bin/sysd-mail-once btrbkrust btrbk -c /etc/btrbk/rust.conf run
index 7faa5e1759524727ddaa843975c6052d26ccaad0..a42040748c62080aa1c5d40cd6ab19c951ec6fd5 100755 (executable)
@@ -3,9 +3,6 @@
 # Copyright (C) 2019 Ian Kelling
 # SPDX-License-Identifier: AGPL-3.0-or-later
 
-# todo: if we fail in the middle and rerun we can mistakenly
-# have reload=false.
-
 # todo: auto restart of je on checkrestart
 
 # todo: run mailping test after running, or otherwise
@@ -265,7 +262,12 @@ pre="${0##*/}:"
 m() { printf "$pre %s\n"  "$*"; "$@"; }
 e() { printf "$pre %s\n"  "$*"; }
 err() { printf "$pre %s\n"  "$*" >&2; exit 1; }
+
 reload=false
+# This file is so if we fail in the middle and rerun, we dont lose state
+if [[ -e /var/local/mail-setup-reload ]]; then
+  reload=true
+fi
 i() { # install file
   local tmp tmpdir dest="$1"
   local base="${dest##*/}"
@@ -278,6 +280,7 @@ i() { # install file
     printf "%s\n" "$tmp"
     ir=true
     if [[ $dest == /etc/systemd/system/* ]]; then
+      touch /var/local/mail-setup-reload
       reload=true
     fi
   fi
@@ -420,7 +423,7 @@ After=multi-user.target
 [Service]
 User=$u
 Type=oneshot
-ExecStart=/a/bin/log-quiet/sysd-mail-once mailclean /a/bin/distro-setup/mailclean
+ExecStart=/usr/local/bin/sysd-mail-once mailclean /a/bin/distro-setup/mailclean
 EOF
 
 # * postgrey
@@ -710,7 +713,7 @@ After=multi-user.target
 
 [Service]
 Type=oneshot
-ExecStart=/a/bin/log-quiet/sysd-mail-once mailcert /usr/local/bin/mail-cert-cron
+ExecStart=/usr/local/bin/sysd-mail-once mailcert /usr/local/bin/mail-cert-cron
 EOF
 i /etc/systemd/system/mailcert.timer <<'EOF'
 [Unit]
@@ -1869,7 +1872,7 @@ To: alerts@iankelling.org
 From: root@$(hostname -f)
 Subject: failed nextcloud update for $ncbase
 
-For logs, run: jru $ncbase
+For logs, run: jr -u $ncbase
 EOF
 fi
 EOFOUTER
@@ -2428,6 +2431,10 @@ case $HOSTNAME in
     ;;&
 esac
 
+# last use of $reload happens in previous block
+rm -f /var/local/mail-setup-reload
+
+
 case $HOSTNAME in
   $MAIL_HOST|bk|je) : ;;
   *)
@@ -2469,7 +2476,7 @@ MAILTO=alerts@iankelling.org
 # for now. It looks like a dns failure.
 #5-59/5 * * * *   root mailtest-check |& log-once -1 mailtest-check
 #0 * * * *   root mailtest-check slow |& log-once -1 mailtest-slow
-*/5 * * * *   root mailtest-check slow |& log-once -1 mailtest-check
+*/5 * * * *   root mailtest-check slow |& log-once -12 mailtest-check
 EOF
     m sudo rsync -ahhi --chown=root:root --chmod=0755 \
       /b/ds/mailtest-check /b/ds/check-remote-mailqs /usr/local/bin/
index 7764b75ff3f788112d53469222b791f99ea694d4..5458a953b8e103359a299f5e2b23853eb635afff 100644 (file)
@@ -24,6 +24,8 @@ usage() {
 Usage: ${0##*/} [OPTIONS]
 
 -h|--help  Print help and exit.
+-f|--force  Use kill -9 to try fixing unmount errors
+-v|--verbose  Be more verbose
 
 
 Note, at source location, intentionally not executable, run and read
@@ -42,6 +44,11 @@ tu() {
     grep -xFq "$line" "$file" || tee -a "$file"<<<"$line"
   done
 }
+d() {
+  if $verbose; then
+    printf "%s\n" "$*"
+  fi
+}
 m() {
   if $verbose; then
     printf "%s\n" "$*"
@@ -148,16 +155,42 @@ done
 ret=0
 
 ##### begin setup fstab for subvols we care about ######
-root_dev=$(awk '$2 == "/" {print $1}' /etc/mtab)
-if [[ $root_dev == /dev/dm-* ]]; then
-  for d in /dev/mapper/*; do
-    if [[ $(readlink -f $d) == "$root_dev" ]]; then
-      root_dev=$d
-      break
+
+if [[ -e /mnt/root/root2-crypttab ]]; then
+  tu /etc/crypttab </mnt/root/root2-crypttab
+  while read -r mapper_dev _; do
+    if [[ ! -e /dev/mapper/$mapper_dev ]]; then
+      m cryptdisks_start $mapper_dev
     fi
-  done
+  done < <(cat /mnt/root/root2-crypttab)
+fi
+if [[ -e /mnt/root/root2-fstab ]]; then
+  tu /etc/fstab </mnt/root/root2-fstab
+  mnt /mnt/root2
+  mnt /mnt/boot2
 fi
 
+mapper-dev() {
+  local -n devref=$1
+  if [[ $devref == /dev/dm-* ]]; then
+    for d in /dev/mapper/*; do
+      if [[ $(readlink -f $d) == "$root_dev" ]]; then
+        devref=$d
+        break
+      fi
+    done
+  fi
+}
+
+root_dev=$(awk '$2 == "/" {print $1}' /etc/mtab)
+mapper-dev root_dev
+
+# root2_dev=$(awk '$2 == "/mnt/root2" {print $1}' /etc/mtab)
+# mapper-dev root2_dev
+# # dont bother with the above for crypt2_dev
+# crypt2_dev=$root2_dev
+
+
 if cryptsetup status $root_dev &>/dev/null; then
   crypt_dev=$root_dev
 else # if we are in a recovery boot, find the next best crypt device
@@ -170,6 +203,9 @@ else # if we are in a recovery boot, find the next best crypt device
     fi
   done
 fi
+
+
+
 # dont tax the cpus of old laptops
 if ((`nproc` > 2)); then
   mopts+=,compress=zstd
@@ -206,9 +242,12 @@ if [[ $HOSTNAME == frodo ]]; then
 $crypt_dev  /i  btrfs  noatime,subvol=i$mopts  0 0
 EOF
 fi
+
+
+
 ##### end setup fstab for subvols we care about ######
 
-# get pids that this program depends on so we dont kill them
+### begin get pids that this program depends on so we dont kill them
 my_pids=($$ $PPID)
 loop_limit=30
 count=0
@@ -220,11 +259,11 @@ while [[ ${my_pids[-1]} != 1 && ${my_pids[-1]} != ${my_pids[-2]} && $count -lt $
   fi
   my_pids+=($p)
 done
+### end get pids that this program depends on so we dont kill them
 
 for vol in q a o i; do
   d=/$vol
   if ! awk '{print $2}' /etc/fstab | grep -xF $d &>/dev/null; then
-
     continue
   fi
 
@@ -285,8 +324,26 @@ for vol in q a o i; do
   fi
 
   #### begin dealing with leaf vols ####
-  # todo: decipher /mnt/root, like we do in check-subvol-stale
-  cd /mnt/root
+
+  ### begin getting root_dir
+  ### this is duplicated in check-subvol-stale
+  # note, we need $dev because $d might not be mounted, and we do this loop
+  # because the device in fstab for the rootfs can be different.
+  for devx in $(btrfs fil show $dev| sed -rn 's#.*path (/\S+)$#\1#p'); do
+    d devx=$devx
+    root_dir=$(sed -rn "s,^\s*$devx\s+(\S+).*\bsubvolid=[05]\b.*,\1,p" /etc/mtab /etc/fstab|head -n1)
+    if [[ $root_dir ]]; then
+      d root_dir=$root_dir
+      break
+    fi
+  done
+  if [[ ! $root_dir ]]; then
+    echo "$0: error could not find root subvol mount for $dev" >&2
+    exit 1
+  fi
+  ### end getting root_dir
+
+  cd $root_dir
   if [[ -e $vol ]]; then
     leaf=$vol.leaf.$(date +%Y-%m-%dT%H:%M:%S%z)
     m mv $vol $leaf
@@ -369,7 +426,72 @@ for vol in q a o i; do
   fi
   stale_dir=/nocow/btrfs-stale
   rm -f $stale_dir/$d
+done
 
+
+
+for dir in /mnt/r7/amy/{root,boot}_ubuntubionic /mnt/{root2/root,boot2/boot}_ubuntubionic; do
+  vol=${dir##*/}
+  root_dir=${dir%/*}
+  if [[ ! -d $root_dir ]]; then
+    # this only exists on host kd currently
+    continue
+  fi
+  # if latest is already mounted, make sure binds are mounted and move on
+  m check-subvol-stale -p $dir
+  # populated by check-subvol-stale if stale
+  if ! fresh_snap=$(cat /nocow/btrfs-stale/$vol 2>/dev/null); then
+    continue
+  fi
+  if [[ -d $dir ]]; then
+    if ! kill-dir TERM TERM TERM INT INT HUP HUP TERM TERM TERM INT INT HUP HUP; then
+      if $force; then  kill-dir KILL; fi
+    fi
+    m btrfs sub del $dir
+  fi
+  m btrfs sub snapshot $fresh_snap $dir
+  rm -f /nocow/btrfs-stale/$vol
 done
 
 exit $ret
+
+
+# Explaining this whole thing. The host amy is used by someone else,
+# i back it up to my extra big partition on one computer.
+# But I also want to restore it and test out the restoration on
+# a computer I usually use. For this, I created a separate partition
+# that has the amy encryption password, and a separate boot so
+# that I could encrypt my own boot partition if I want. Then,
+# I backup from this big partition into that partition in order
+# to boot and run it.
+#
+# In order to boot and run it:
+
+# mount -o bind /mnt/root2/root_ubuntubionic /mnt/1
+# cd /mnt/1
+# /b/ds/gen-amy-fstab ubuntubionic .
+# teeu /mnt/1/etc/default/grub <<<'GRUB_DISABLE_OS_PROBER=true'
+# mount -o bind /mnt/boot2/boot_ubuntubionic boot
+# mount -o bind /dev dev
+# mount -o bind /proc proc
+# mount -o bind /sys sys
+# mkdir -p boot/efi
+# mount $(awk '$2 == "/boot/efi" {print $1}' /etc/mtab) boot/efi
+# chroot .
+# apt install grub-efi
+
+# ssds=()
+# for disk in $(lsblk -do name,tran -n | awk '$2 ~ "^(sata|nvme)$" { print $1 }'); do
+#   case $(cat /sys/block/$disk/queue/rotational) in
+#     0) ssds+=(/dev/$disk) ;;
+#     1) : ;; # hdd
+#     *) echo "$0: error: unknown /sys/block/$disk/queue/rotational: \
+# $(cat $disk/queue/rotational)" ;;
+#   esac
+# done
+
+# GROOT=$(grub-probe -tdrive -d ${ssds[@]})
+# echo "GROOT=$GROOT"
+# grub-install --no-floppy --modules=part_gpt "$GROOT"
+# update-grub
+# update-initramfs -u
index 30c38023ea278bed67f7d5528e46712ed7b9db30..31d8a1273ce591279089cadc7d44aa87c3bece96 100644 (file)
@@ -12,6 +12,7 @@ status_file=/dev/shm/iank-status
 
 shopt -s nullglob
 shopt -s dotglob
+shopt -s extglob
 
 for p in ~/.gem/ruby/*/bin; do
   PATH="$PATH:$p"
@@ -63,7 +64,9 @@ write-status() {
     bouncemsg="message in /m/md/bounces/new"
   fi
   lo -1 bounce $bouncemsg
-  glob=(/m/md/alerts/{new,cur}/*)
+  # emails without the S (seen) flag. this only checks the last flag,
+  # but its good enough for me.
+  glob=(/m/md/alerts/{new,cur}/!(*,S))
   if [[ -e ${glob[0]} ]]; then
     chars+=("A")
   fi
@@ -247,7 +250,9 @@ fi
 if ! $power; then
   exit 0
 fi
-for ((i=1; i<=3; i++)); do
+
+# about 15 minutes
+for ((i=1; i<=60; i++)); do
   sleep 15
   write-status
 done