host info updates
[distro-setup] / system-status
index 9d9049ef93a30bd59a9d64bae545dcbb7e49b9f2..d6269d9c825f89b30a67cc5cb7e1f3512f278dfa 100755 (executable)
@@ -1,6 +1,22 @@
 #!/bin/bash
-# Copyright (C) 2019 Ian Kelling
-# SPDX-License-Identifier: AGPL-3.0-or-later
+
+# Basic system status on on Ian's computers
+# Copyright (C) 2024  Ian Kelling
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# SPDX-License-Identifier: GPL-3.0-or-later
 
 # usage: runs once every 15 seconds unless any args are passed, or we
 # then just runs once and have verbose output. On battery power, run
@@ -13,7 +29,7 @@ if [[ $EUID != 1000 ]]; then
   exit 1
 fi
 
-source /a/bin/errhandle/err
+source /a/bin/bash-bear-trap/bash-bear
 status_file=/dev/shm/iank-status
 
 shopt -s nullglob
@@ -127,31 +143,26 @@ write-status() {
 
   ## check if last snapshot was recent
   old_snap_limit=$(( 3 * 60 * 60 ))
-  for vol in a o q; do
-    case $vol in
-      o) btrbk_root=/mnt/o/btrbk ;;
-      *) btrbk_root=/mnt/root/btrbk ;;
-    esac
-    # this section generally copied from btrbk scripts, but
-    # this part modified to speed things up by about half a second.
-    # I'm not sure if its quite as reliable, but it looks pretty safe.
-    # Profiled it using time and also adding to the top of the file:
-    # set -x
-    # PS4='+ $(date "+%2N") '
-    # allow failure in case there are no snapshots yet.
-    # shellcheck disable=SC2012
-    shopt -s nullglob
-    files=($btrbk_root/$vol.20*)
-    shopt -u nullglob
-    if (( ! ${#files[@]} )); then
-      continue
-    fi
-    snaps=($(ls -1avdr "${files[@]}" 2>/dev/null |head -n1 || : ))
+  vol=o
+  btrbk_root=/mnt/o/btrbk
+  # this section generally copied from btrbk scripts, but
+  # this part modified to speed things up by about half a second.
+  # I'm not sure if its quite as reliable, but it looks pretty safe.
+  # Profiled it using time and also adding to the top of the file:
+  # set -x
+  # PS4='+ $(date "+%2N") '
+  # allow failure in case there are no snapshots yet.
+  shopt -s nullglob
+  files=($btrbk_root/$vol.20*)
+  shopt -u nullglob
+  if (( ${#files[@]} )); then
+    # shellcheck disable=SC2012 # using ls version sort. not sure this is needed.
+    snaps=("$(ls -1avdr "${files[@]}" 2>/dev/null |head -n1 || : )")
     now=$EPOCHSECONDS
     maxtime=0
     for s in ${snaps[@]}; do
       file=${s##*/}
-      t=$(date -d $(sed -r  's/(.{4})(..)(.{5})(..)(.*)/\1-\2-\3:\4:\5/' <<<${file#$vol.}) +%s)
+      t=$(date -d "$(sed -r  's/(.{4})(..)(.{5})(..)(.*)/\1-\2-\3:\4:\5/' <<<${file#"$vol."})" +%s)
       if (( t > maxtime )); then
         maxtime=$t
       fi
@@ -166,9 +177,8 @@ write-status() {
         p "$snapshotmsg" | lo -1 old-snapshot
       fi
       # not bothering to get info on all volumes if we find an old one.
-      break
     fi
-  done
+  fi
 
 
   if [[ $MAIL_HOST == "$HOSTNAME" ]]; then
@@ -263,13 +273,36 @@ write-status() {
   fi
   p $var_mail_msg | loday -1 var_mail
 
-  # early in install process, we dont have permission yet for exiqgrep.
-  # 1100 helps allow for system restarts
-  qlen=$(/usr/sbin/exiqgrep -o 1100 -c -b | awk '{print $1}') ||:
+  # Note, early in install process, we dont have permission yet for exiqgrep.
+  #
+  # todo: don't do this every 15 seconds, more like once every 2 minutes to
+  # save cpu cycles.
+  #
+  # 2400 = 40 mins. This should allow for system restarts, and
+  # 30 minute message delay plus 10 minute queu runs.
+  qlen=$(/usr/sbin/exiqgrep -o 2400 -c -b | awk '{print $1}') ||:
   qmsg=
   if ((qlen)); then
-    qmsg="queue length $qlen"
-    chars+=("q $qlen")
+    # Do sending of long delayed messages, and dont count them in our queue warnings.
+    for mid in $(exiqgrep -o 2400 -zi); do
+      if exim -Mvh $mid | awk 'tolower($2) == "fdate:"' | grep -q .; then
+        qlen=$(( qlen - 1 ))
+        # shellcheck disable=SC2016 # exim var, not a bash bar
+        if (( $(date -d "$(exim -Mset $mid -be <<<'$h_date:' | sed -n 's/^> *//;/./p')" +%s) < EPOCHSECONDS )); then
+          if ip a show veth0-mail &>/dev/null; then
+            pid=$(pgrep -f "/usr/sbin/exim4 -bd -q30m -C /etc/exim4/my.conf"|head -n1);
+            nsenter -t $pid -n -m /usr/sbin/exim4 -C /etc/exim4/my.conf -M $mid
+          else
+            /usr/sbin/exim4 -M $mid
+          fi
+        fi
+      fi
+    done
+
+    if ((qlen)); then
+      qmsg="queue length $qlen"
+      chars+=("q $qlen")
+    fi
   fi
   case $HOSTNAME in
     # No point in emailing about the mailq on a host where we don't
@@ -325,8 +358,10 @@ write-status() {
           if grep -qxF $HOSTNAME $x; then all_dirs+=( ${x%.hosts} ); fi
         done
 
+        script_files=("${my_service_scripts[@]}" "${my_bin_files[@]}" $my_lib_files)
+
         # Just because i forget a lot, -mmin -NUM means files modified <= NUM minutes ago
-        if (( fmin < 0 )) && [[ $(find ${all_my_scripts[@]} ${all_dirs[@]} -mmin $fmin -type f -print -quit 2>/dev/null) ]]; then
+        if (( fmin < 0 )) && [[ $(find "${script_files[@]}" ${all_dirs[@]} -mmin $fmin -type f -print -quit 2>/dev/null) ]]; then
           v conflink newer filesystem files
           chars+=(CONFLINK)
           break
@@ -372,6 +407,23 @@ write-status() {
     # leave it up to epanic-clean to send email notification
   fi
 
+  mprom=/var/lib/prometheus/node-exporter/mailtest-check.prom
+  if [[ -s $mprom ]]; then
+    if grep -qE 'mailtest_check_(unexpected|missing).*[^ ][^0]$' $mprom; then
+      chars+=("MTEST_SPAM")
+    fi
+    mtest_found=false
+    # shellcheck disable=SC2013 # these are words
+    for t in $(grep -E ^mailtest_check_last_usec $mprom | awk '{print $NF}'); do
+      if (( t + 60 * 20 < EPOCHSECONDS )); then
+        mtest_found=true
+      fi
+    done
+    if $mtest_found; then
+      chars+=("MTEST_AGE")
+    fi
+  fi
+
   if [[ ! -e $status_file || -w $status_file ]]; then
     if [[ -e /a/bin/bash_unpublished/source-state ]]; then
       cat /a/bin/bash_unpublished/source-state >$status_file
@@ -388,7 +440,7 @@ mute() {
   local locked
   export DISPLAY=:0
   locked=false
-  if lock_info=$(xscreensaver-command -timer); then
+  if lock_info=$(xscreensaver-command -time); then
     if [[ $lock_info != *non-blanked* ]]; then
       locked=true
     fi
@@ -397,16 +449,20 @@ mute() {
   fi
   midnight=$(date -d 00:00 +%s)
   mdiff=$(( EPOCHSECONDS - midnight ))
-  if $locked && (( mdiff < 6 || mdiff > 21 )); then
+  if $locked && (( mdiff < 6 *60*60 || mdiff > 21 *60*60 )); then
     case $(pactl get-sink-mute @DEFAULT_SINK@ | awk '{print $2}') in
       no)
+        # for log purposes
+        echo muted
         pactl set-sink-mute @DEFAULT_SINK@ true
         ;;
     esac
   fi
-  if ! $locked && ((  mdiff > 6 || mdiff < 12  )) && [[ ! -e /tmp/ianknap ]]; then
+  if ! $locked && ((  mdiff > 6 *60*60 || mdiff < 12 *60*60 )) && [[ ! -e /tmp/ianknap ]]; then
     case $(pactl get-sink-mute @DEFAULT_SINK@ | awk '{print $2}') in
       yes)
+        # for log purposes
+        echo unmuted
         pactl set-sink-mute @DEFAULT_SINK@ false
         ;;
     esac
@@ -422,6 +478,7 @@ if [[ $1 ]]; then
   exit 0
 fi
 
+loop_count=0
 main-loop() {
   while true; do
     power=true
@@ -429,16 +486,30 @@ main-loop() {
       power=false
     fi
     wait=15
-    if ! $power; then
-      if systemctl -q is-active bitcoind; then
-        bitcoinoff
+
+    if $power; then
+      if (( loop_count  % 10 == 0 )); then
+        if [[ -r /sys/class/power_supply/BAT0/capacity ]]; then
+          bat=$(cat /sys/class/power_supply/BAT0/capacity)
+        else
+          bat=100
+        fi
+        case $bat in
+          100|9?)
+          :
+          bitcoinon &
+          ;;
+        esac
       fi
+    else
+      bitcoinoff
       wait=60
     fi
 
     sleep $wait
     write-status
     mute
+    loop_count=$(( loop_count + 1 ))
   done
 }