done
fi
}
-pr() {
- if $doprom && [[ -e /var/lib/prometheus/node-exporter ]]; then
- cat >>/var/lib/prometheus/node-exporter/mailtest-check.prom.$$
- fi
-}
#### begin arg processing ####
fi
#### end arg processing ####
-
-if ! $int; then
- sleep 60
-fi
+# we put this in to avoid dns errors that happen on reboot,
+# but I want to debug them.
+# if ! $int; then
+# sleep 60
+# fi
# TODO, get je to deliver the local mailbox: /m/md/INBOX
main() {
+ local -a unexpected_spamd_results missing_dnswl last_usec
case $HOSTNAME in
bk)
folders=(/m/md/{expertpathologyreview.com,amnimal.ninja}/testignore)
folders=(/m/md/l/testignore)
froms=(testignore@je.b8.nz testignore@expertpathologyreview.com testignore@amnimal.ninja ian@iankelling.org z@zroe.org iank@gnu.org)
if ! $int; then
- timeout 120 rsync --chown iank:iank -e "ssh -oIdentitiesOnly=yes -F /dev/null -i /root/.ssh/jtuttle" -t --inplace -r 'jtuttle@fencepost.gnu.org:/home/j/jtuttle/Maildir/new/' /m/md/l/testignore/new
+ ### begin rsyncing fencepost email ###
+ # We dont want to exit if rsync fails, that will get caught by
+ # our later test by virtue of not having the latest email.
+ did_rsync=false
+ try_start_time=$EPOCHSECONDS
+ try_limit=140 # somewhat arbitrary value
+ while ! $did_rsync; do
+ try_left=$(( try_limit - ( EPOCHSECONDS - try_start_time) ))
+ timeout=120 # somewhat arbitrary value
+ if (( try_left < 0 )); then
+ echo "mailtest-check: failed to rsync fencepost > $try_limit seconds"
+ break
+ fi
+ if (( try_left < timeout )); then
+ timeout=$try_left
+ fi
+ if timeout $timeout rsync --chown iank:iank -e "ssh -oIdentitiesOnly=yes -F /dev/null -i /root/.ssh/jtuttle" -t --inplace -r 'jtuttle@fencepost.gnu.org:/home/j/jtuttle/Maildir/new/' /m/md/l/testignore/new; then
+ did_rsync=true
+ else
+ sleep 4
+ fi
+ done
+ if ! $did_rsync; then
+ echo mailtest-check: warning: fencepost rsync failed
+ fi
+ ### end rsyncing fencepost email ###
fi
;;
esac
declare -i unexpected=0
for folder in ${folders[@]}; do
for from in ${froms[@]}; do
+ declare -i missing_dnswl=0
+ declare -i dnsfail=0
+ declare -i unexpected=0
latest=
last_sec=0
fi
# webmail sends them to cur it seems
while read -r file; do
- if [[ $file -nt $latest ]]; then
+ file_sec=$(awk '/^Subject: / {print $4}' $file)
+ if [[ $file_sec ]] && (( file_sec > last_sec )); then
latest=$file
+ last_sec="$file_sec"
fi
done <$tmpfile
+ rm -f $tmpfile
to=$(awk '/^Envelope-to: / {print $2}' $latest)
- last_sec=$(awk '/^Subject: / {print $4}' $latest)
if $slow; then
if ! $int; then
if [[ $(readlink /proc/$$/ns/net) != "$(readlink /proc/$spamdpid/ns/net)" ]]; then
spamcpre="nsenter -t $spamdpid -n -m"
fi
-
+ unset results
declare -A results
# pyzor fails for our test message, so dont put useless load on their
# servers.
# example line that sed is parsing:
# (-0.1 / 5.0 requ) DKIM_SIGNED=0.1,DKIM_VALID=-0.1,DKIM_VALID_AU=-0.1,SPF_HELO_PASS=-0.001,SPF_PASS=-0.001,TVD_SPACE_RATIO=0.001 autolearn=_AUTOLEARN
- raw_results="$($spamcpre sudo -u Debian-exim spamassassin -t --cf='score PYZOR_CHECK 0' <"$latest" | tail -n2 | head -n1 | sed -r 's/^\([^)]*\) *//;s/=[^, ]*([, ]|$)/ /g')"
+ resultfile=$(mktemp)
+ $spamcpre sudo -u Debian-exim spamassassin -D -t --cf='score PYZOR_CHECK 0' <"$latest" &>$resultfile
+
+ # note: on some mail, its 1 line after the send-test-forward, on others its 2 with a blank inbetween.
+ # I use the sed -n to filter this.
+ raw_results="$(tail $resultfile | grep -A2 -Fx /usr/local/bin/send-test-forward | tail -n+2 | sed -nr 's/^\([^)]*\) *//;s/=[^, ]*([, ]|$)/ /gp')"
for r in $raw_results; do
case $r in
# got this in an update 2022-01. dun care
# eggs has RCVD_IN_DNSWL_MED
keys+=(RCVD_IN_DNSWL_MED)
elif [[ $from == *@gnu.org ]]; then
- # eggs has these
- keys+=(RCVD_IN_DNSWL_MED DKIMWL_WL_HIGH)
+ # eggs has this. it used to have DKIMWL_WL_HIGH sometime in 2022
+ keys+=(RCVD_IN_DNSWL_MED)
fi
for t in ${keys[@]}; do
fi
done
if (( ${#results[@]} || ${#missing[@]} )); then
- printf "$HOSTNAME spamtest %s/%s\n" "$latest"
+ printf "$HOSTNAME spamtest %s\n" "$latest"
if (( ${#results[@]} )); then
printf "unexpected %s" "${!results[*]} "
fi
printf "missing %s" "${missing[*]}"
fi
echo # ends our printf string buildup
-
+ cat $resultfile
+ echo mailtest-check: end of spam debug results
+ # lets just handle 1 failure at a time in interactive mode.
if $int; then
- echo mailtest-check: cat $latest:
- cat $latest
- echo mailtest-check: end of cat
- echo "$(tput setaf 5 2>/dev/null ||:)█$(tput sgr0 2>/dev/null||:)%.0s" $(eval echo "{1..${COLUMNS:-60}}")
+ echo mailtest-check: from: $from, to: $to
+ exit 0
fi
+
+ # less verbose debug output, commented since I might want it another time.
+ # if $int; then
+ # echo mailtest-check: cat $latest:
+ # cat $latest
+ # echo mailtest-check: end of cat
+ # echo "$(tput setaf 5 2>/dev/null ||:)█$(tput sgr0 2>/dev/null||:)%.0s" $(eval echo "{1..${COLUMNS:-60}}")
+ #fi
fi
+ rm -f $resultfile
+ for r in ${results[@]}; do
+ case $r in
+ # iank: for when we want to handle dns errors differently
+ # DKIM_INVALID|T_SPF_TEMPERROR|T_SPF_HELO_TEMPERROR)
+ # dnsfail+=1
+ # ;;
+ *)
+ unexpected=$(( unexpected + 1 ))
+ ;;
+ esac
+ done
+ for miss in ${missing[@]}; do
+ # We expect dns failures from time to time, so
+ # we count them separately and alert differently.
+ case $miss in
+ # iank: dns fail
+ # DKIM_VALID|DKIM_VALID_AU|DKIM_VALID_EF|SPF_HELO_PASS|SPF_PASS|
+ RCVD_IN_DNSWL_MED|DKIMWL_WL_HIGH)
+ missing_dnswl+=1
+ ;;
+ *)
+ unexpected+=1
+ ;;
+ esac
+ done
+ mapfile -O ${#missing_dnswl[@]} -t missing_dnswl <<EOF
+mailtest_check_missing_dnswl{folder="$folder",from="$from"} $missing_dnswl
+EOF
+ mapfile -O ${#unexpected_spamd_results[@]} -t unexpected_spamd_results <<EOF
+mailtest_check_unexpected_spamd_results{folder="$folder",from="$from"} $unexpected
+EOF
fi # if spamdpid
fi # if $slow
e $((age_sec / 60)):$(( age_sec % 60 )) ago. to:$to from:$from $latest
# usec = unix seconds
- pr <<EOF
+ mapfile -O ${#last_usec[@]} -t last_usec <<EOF
mailtest_check_last_usec{folder="$folder",from="$from"} $last_sec
EOF
- done
- unexpected=$(( unexpected + ${#results[@]} + ${#missing[@]} ))
- done
- if $slow; then
- pr <<EOF
-mailtest_check_unexpected_spamd_results $unexpected
-EOF
- fi
+ done # end for from in ${froms[@]}
+ done # end for folder in ${folders[@]}
dir=/var/lib/prometheus/node-exporter
- if [[ -e $dir ]]; then
- mv $dir/mailtest-check.prom.$$ $dir/mailtest-check.prom
+ path=$dir/mailtest-check.prom.$$
+ if $doprom && [[ -e $dir ]]; then
+ for l in "${unexpected_spamd_results[@]}"; do
+ printf "%s\n" "$l" >>$path
+ done
+ for l in "${missing_dnswl[@]}"; do
+ printf "%s\n" "$l" >>$path
+ done
+ for l in "${last_usec[@]}"; do
+ printf "%s\n" "$l" >>$path
+ done
+ mv $path $dir/mailtest-check.prom
# note: node_textfile_mtime_seconds will tell us when this last happened. useful for debugging.
fi
}
loop-main() {
+ # When running under systemd, the system just started. Ve nice and
+ # give programs some time to finish their startup.
+ sleep 10
while true; do
premain_sec=$EPOCHSECONDS
main
- sleep $(( 300 - ( $EPOCHSECONDS - premain_sec ) ))
+ sleep $(( 300 - ( EPOCHSECONDS - premain_sec ) ))
done
}