#!/bin/bash
#
# Maintenence operations once by day.
# This script called usually by the cron - in this case the CRON variable
# must be set in crontab and exported to the script.
#
# Author: Kovács Zoltán <kovacs.zoltan@smartfront.hu>
#         Kovács Zoltán <kovacsz@marcusconsulting.hu>
# License: GNU/GPL v3+ (https://www.gnu.org/licenses/gpl-3.0.en.html)
# 2023-06-18 v1.0
# new: forked from the "SMARTERP_skeleton" repository.
# mod: "instance" => "service"
# 2023-02-12 v0.9
# new: shows the ZFS disk partitions (if any) as well.
# 2023-01-20 v0.8
# fix: doesn't try to reload non-existing or stopped web servers.
# 2021-10-08 v0.7
# fix: tries to reload the web server(s) to get in effect the renewed SSL
#      certificates (if any).
# 2021-06-02 v0.6
# fix: more accurate egrep for df -h output.
# fix: typo => 98-fsck-at-rebooz
# 2021-02-15 v0.5
# fix: omits the error message when there is no services at all
# 2021-02-05 v0.4
# fix: proper $PATH settings in Debian environment as well
# 2021-02-04 v0.3
# fix: decimal point trouble in non-english environments (eg. Hungarian)
# 2021-01-05 v0.2
# fix: LANG=C and LC_ALL=C initialisations have removed, because these may
#      interfere with UTF-8 file name encoding in Java calls:
#      https://ogris.de/howtos/java-utf8-filenames.html
# fix: Missing message.
# 2020-11-12 v0.1 Initial release

# Accepted environment variables and their defaults.
#
CRON=${CRON-""}                                         # Does it run from cron?
SERVICE_BASE=${SERVICE_BASE-"$HOME/services"}		# Services' folder path
SLEEP_BETWEEN=${SLEEP_BETWEEN-"120"}			# Secs between forks

# There is nothing to configure below (I hope).
###############################################

# Messages.
#
MSG_MISSINGDEP="Fatal: missing dependency"

# Basic environment settings.
#
# Corrects the PATH if the operating system didn't loaded yet;
# it is a bug with cron pam_env, I think.
if [ -n "$CRON" ]; then
    [[ -r  "/etc/profile" ]] && source "/etc/profile"
    # Ubuntu gets the initial environment from a separate file.
    if [ -r "/etc/environment" ]; then
        # Extracts from this file, strips the right part w/o quotes.
        includepath=$(cat "/etc/environment" | $(which egrep) '^PATH=')
        includepath=${includepath:5}
        includepath="${includepath%\"}"; includepath="${includepath#\"}"
        [[ -n "$includepath" ]] && PATH="$PATH:$includepath"
        unset includepath
    fi
    # We need the $HOME/bin as well.
    PATH="$HOME/bin:$PATH"
fi
# We need also the sbin directories.
if ! [[ "$PATH" =~ '/sbin:' ]]; then PATH="$PATH:/usr/local/sbin:/usr/sbin:/sbin"; fi

# Checks the dependencies.
#
TR=$(which tr 2>/dev/null)
if [ -z "$TR" ]; then echo "$MSG_MISSINGDEP tr."; exit 1 ; fi
for item in basename cut df egrep head mail printf sleep
do
    if [ -n "$(which $item)" ]
    then export $(echo $item | "$TR" '[:lower:]' '[:upper:]')=$(which $item)
    else echo "$MSG_MISSINGDEP $item." >&2; exit 1; fi
done
# All dependencies are available via "$THECOMMAND" (upper case) call.

# Checks and sanitizations.
#
if [ -z "$SERVICE_BASE" -o ! -d "$SERVICE_BASE" ]; then exit 1; fi
SLEEP_BETWEEN=$("$PRINTF" '%.2f' "$SLEEP_BETWEEN" 2>/dev/null)	# To float

# Sends a mail report to the Linux user itself.
# Hopes the appropriate message forward rule has been set.
if [ -x "$MAIL" ]; then
    subject="[Maintenance] $HOSTNAME daily report"
    message="This is a report from $("$BASENAME" "$0") script on $HOSTNAME.\n\n"
    [[ -x "/etc/update-motd.d/00-header" ]] \
    && message+="$("/etc/update-motd.d/00-header")\n\n"
    message+="$("$DF" -h | "$HEAD" -n1)\n"
    message+="$("$DF" -h | "$EGREP" '^/dev/' | "$EGREP" -v 'loop')\n"
    if [ -n "$(which zpool)" -a -x "$(which zpool)" ]; then
	# Includes ZFS partitions (if any).
	for pool in $("$(which zpool)" list -H | "$CUT" -f1) "" #"
	do [[ -n "$pool" ]] && message+="$("$DF" -h | "$EGREP" "^$pool/")\n"; done
    fi
    [[ -x "/etc/update-motd.d/90-updates-available" ]] \
    && message+="$("/etc/update-motd.d/90-updates-available")\n"
    [[ -x "/etc/update-motd.d/98-fsck-at-reboot" ]] \
    && message+="$("/etc/update-motd.d/98-fsck-at-reboot")\n"
    [[ -x "/etc/update-motd.d/99-reboot-required" ]] \
    && message+="$("/etc/update-motd.d/99-reboot-required")\n"
    message+="\nBest regards: the Maintenance Bot"
    echo -e "$message" | "$MAIL" -s  "$subject" "$USER"
fi
# Done with mail.

# Tries to reload the webserver(s) to get in effect
# the renewed SSL certificates (if any).
if [ -n "$(which sudo)" -a -n "$(which systemctl)" ]; then
    for webserver in apache2 nginx
    do
        if [[ $( systemctl status $webserver >/dev/null 2>&1; echo $? ) -eq 0 ]]; then
            sudo -n systemctl reload $webserver >/dev/null 2>&1
        fi
    done
fi
# Done with the webserver(s).

# Launches the worker scripts with the same name, one for every services.
# Services are subfolders of the $SERVICE_BASE folder set above.
TOOLS_BASE="tools"			# Relative path to worker scripts
WORKERFILE="$("$BASENAME" "$0")"	# Same filename
# Gets the service folders, give up if none.
SERVICES="$(cd "$SERVICE_BASE"; ls -d */ 2>/dev/null)"
[[ -z "$SERVICES" ]] && exit
# Eumerates the service folders.
for service in $SERVICES ""
do
    # Safety first...
    if [ -n "$service" ]; then
	# Forks the worker if it does exist and does runnable.
	# Passes all remaining command line parameters.
	if [ -x "$SERVICE_BASE/$service$TOOLS_BASE/$WORKERFILE" ]; then
            [[ -n "$CRON" ]] && export PATH USER
	    "$SERVICE_BASE/$service$TOOLS_BASE/$WORKERFILE" "$@" &
	    # Optionally reduces the fork frequency.
	    "$SLEEP" ${SLEEP_BETWEEN//,/.}	# decimal point need
	fi
    fi
done
# Done with workers.

# That's all, Folks! :)
