#!/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 # Kovács Zoltán # 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! :)