From dae2a25f787f250c264d7e658af79f161170a67d Mon Sep 17 00:00:00 2001 From: William Hirigoyen Date: Wed, 24 Jan 2024 17:25:20 +0100 Subject: [PATCH] check_free_space: add role; evolinux-base: install check_free_space by default --- CHANGELOG.md | 1 + check_free_space/defaults/main.yml | 6 + check_free_space/files/check_free_space.sh | 166 ++++++++++++++++++ check_free_space/files/check_free_space.tpl | 24 +++ check_free_space/tasks/main.yml | 37 ++++ check_free_space/tasks/shell_script.yml | 30 ++++ .../templates/cron_check_free_space.j2 | 4 + evolinux-base/defaults/main.yml | 4 + evolinux-base/tasks/main.yml | 5 + 9 files changed, 277 insertions(+) create mode 100644 check_free_space/defaults/main.yml create mode 100755 check_free_space/files/check_free_space.sh create mode 100644 check_free_space/files/check_free_space.tpl create mode 100644 check_free_space/tasks/main.yml create mode 100644 check_free_space/tasks/shell_script.yml create mode 100644 check_free_space/templates/cron_check_free_space.j2 diff --git a/CHANGELOG.md b/CHANGELOG.md index 8de4ddd6..4a7d57a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ The **patch** part changes is incremented if multiple releases happen the same m * webapps/nextcloud: Set ownership and permissions of data directory * webapps/nextcloud: Add condition for archive tasks * fail2ban: add script unban_ip +* check_free_space: added role ### Changed diff --git a/check_free_space/defaults/main.yml b/check_free_space/defaults/main.yml new file mode 100644 index 00000000..c699ad91 --- /dev/null +++ b/check_free_space/defaults/main.yml @@ -0,0 +1,6 @@ +--- +check_free_space_partitions: + - "/home" + - "/srv" +check_free_space_max_percent: 70 +check_free_space_mailto: Null diff --git a/check_free_space/files/check_free_space.sh b/check_free_space/files/check_free_space.sh new file mode 100755 index 00000000..f1b89d8c --- /dev/null +++ b/check_free_space/files/check_free_space.sh @@ -0,0 +1,166 @@ +#!/bin/sh + +# This script verifies if the specified partitions on a machine are filled +# at more than x%. +# +# If so, it sends a mail to the admin of that machine, warning him/her +# that mesures should be taken. +# +# Two outputs are provided to the recipient of the mail: +# * some general infos with `df` +# * a more indepth inspection with `duc` +# +# This script takes 3 (mandatory) arguments: +# * a list of the partitions to check (space separated) +# * the maximum allowed percentage +# * the email template to use +# +# This script should be ran by cron @daily. +# +# +# Copyright (C) 2016 Louis-Philippe Véronneau +# +# This program is licensed under GPLv3 + + + +# Check argument sanity + +PID_FILE='/var/run/check_free_space.pid' + +if test -f "$PID_FILE" +then + pid=$(cat "$PID_FILE") + ps -p "$pid" > /dev/null + if test $? -eq 0 + then + echo "$0 already run !" >&2 + exit 1 + else + rm $PID_FILE + fi +fi + +echo $$ > $PID_FILE + +if test -z "$1" || test -z "$2" || test -z "$3" # is non null +then + echo "Some arguments are missing. Please issue a partition list, a" \ + "maximum percentage and an email template." + exit 1 +elif ! [ "$2" -le 100 -a "$2" -ge 0 ] # is a percentage +then + echo "Please enter a maximum percentage value between 0 and 100." + exit 1 +fi + +# Argument processing + +partition_list=$1 +max_percentage=$((100-$2)) +email_template=$3 + +HOSTNAME=$(hostname) +debian_version=$(lsb_release -c) + +check_disk='/usr/lib/nagios/plugins/check_disk' + +test -f /etc/evomaintenance.cf && . /etc/evomaintenance.cf + + +# Test what version of df we have + +old_df=false + +case "$debian_version" in + *squeeze* ) old_df=true ;; + *wheezy* ) old_df=true ;; +esac + + +# Check disk space + +df_options="size,avail,pcent,itotal,iavail,ipcent" + +for partition in $partition_list +do + if ! $check_disk -w $max_percentage% -W $max_percentage% $partition > /dev/null + then + # the 'newline' is a hack to make sed behave + PARTITION_DATA="$PARTITION_DATA newline $partition newline" + if [ $old_df ] + then + PARTITION_DATA="$PARTITION_DATA $(/bin/df -h $partition) newline" + PARTITION_DATA="$PARTITION_DATA newline $(df -ih $partition) newlinenewline" + else + PARTITION_DATA="$PARTITION_DATA $(/bin/df -h --output=$df_options $partition) newline" + fi + full_partitions="$full_partitions $partition" + partname=$(echo $partition|tr -s '/' '-') + graph_list="$graph_list -a /home/duc${partname}.png" + fi +done + + +# Exit if everything is OK + +if test -z "$PARTITION_DATA" +then + exit 0 +fi + + +# If there is indeed a problem, get more infos with duc + +/usr/bin/ionice -c3 /usr/bin/duc index -H -d /home/duc.idx -x $full_partitions -q + +for partition in $full_partitions +do + duc_temp=$(/usr/bin/duc ls -d /home/duc.idx -Fg $partition) + duc_temp=$(printf "$duc_temp" | sed -e "s@]@]newline@" | grep -v "lost+found") + DUC_OUTPUT="$DUC_OUTPUT newline$partition newline$duc_temp" + partname=$(echo $partition|tr -s '/' '-') + duc graph -d /home/duc.idx -o /home/duc${partname}.png -l8 -s 1024 $partition +done + + +# Replace placeholders & send the mail ! + +PARTITION_DATA="$(echo "$PARTITION_DATA"|tr -d $'\n')" # make sed accept the input +DUC_OUTPUT="$(echo "$DUC_OUTPUT"|tr -d $'\n')" + +if [ $old_df ] +then + sed -e "s/__TO__/$EVOMAINTMAIL/" \ + -e "s/__HOSTNAME__/$HOSTNAME/" \ + -e "s@__PARTITION_DATA__@$PARTITION_DATA@" \ + -e "s@__DUC_OUTPUT__@$DUC_OUTPUT@" \ + -e "s/newline/\n/g" \ + -e "s/IUse%/IUse%\n/g" \ + -e "s/ Use%/ Use%\n/g" \ + -e "s@Filesystem \{12\}@@g" \ + -e "s@Mounted on\/dev\/[a-z]\{3\}[0-9]\+ \{13\}@@g" \ + -e "s@% \/[a-z]\+@%@g" \ + -e "s/__MAX_PERCENTAGE__/$max_percentage/" \ + -e "s/__FULLFROM__/$FULLFROM/" \ + -e "s/__FROM__/$FROM/" \ + -e "s/__URGENCYFROM__/$URGENCYFROM/" \ + -e "s/__URGENCYTEL__/$URGENCYTEL/" \ + $email_template | \ + /usr/bin/mutt -H - $graph_list +else + sed -e "s/__TO__/$EVOMAINTMAIL/" \ + -e "s/__HOSTNAME__/$HOSTNAME/" \ + -e "s@__PARTITION_DATA__@$PARTITION_DATA@" \ + -e "s@__DUC_OUTPUT__@$DUC_OUTPUT@" \ + -e "s/newline/\n/g" \ + -e "s/IUse%/IUse%\n/g" \ + -e "s/__MAX_PERCENTAGE__/$max_percentage/" \ + -e "s/__FULLFROM__/$FULLFROM/" \ + -e "s/__FROM__/$FROM/" \ + -e "s/__URGENCYFROM__/$URGENCYFROM/" \ + -e "s/__URGENCYTEL__/$URGENCYTEL/" \ + $email_template | \ + /usr/bin/mutt -H - $graph_list +fi + +rm -f $PID_FILE diff --git a/check_free_space/files/check_free_space.tpl b/check_free_space/files/check_free_space.tpl new file mode 100644 index 00000000..15ce5635 --- /dev/null +++ b/check_free_space/files/check_free_space.tpl @@ -0,0 +1,24 @@ +From: __FULLFROM__ +Content-Type: text/plain; charset=UTF-8 +MIME-Version: 1.0 +Content-Transfer-Encoding: 8bit +To: __TO__ +Subject: [WARNING] Espace disque faible sur __HOSTNAME__ + +Bonjour, + +Ceci est un message automatique pour vous informer qu'il y a un +souci d'espace disque sur votre serveur __HOSTNAME__ + +Voici les informations sur l'espace disque qui pose problème : +__PARTITION_DATA__ +Détails sur les partitions problématiques : +__DUC_OUTPUT__ +Un graphe par partition problématique est disponible en pièce jointe. + +Nous vous recommandons d'effectuer du ménage pour maintenir +chaque partition avec un minimum de __MAX_PERCENTAGE__% d'espace disque libre. + +Cordialement, +-- +__FULLFROM__ diff --git a/check_free_space/tasks/main.yml b/check_free_space/tasks/main.yml new file mode 100644 index 00000000..b2b4aa07 --- /dev/null +++ b/check_free_space/tasks/main.yml @@ -0,0 +1,37 @@ +--- +- ansible.builtin.include_role: + name: evolix/remount-usr + +- name: Copy check_free_space.sh script + ansible.builtin.copy: + src: files/check_free_space.sh + dest: /usr/share/scripts/check_free_space + owner: root + group: root + mode: "0750" + +- name: Copy email template + ansible.builtin.copy: + src: files/check_free_space.tpl + dest: /usr/share/scripts/check_free_space.tpl + owner: root + group: root + mode: "0644" + +# not using the cron_module for this since it is buggy +- name: check_free_space.sh is run by cron + ansible.builtin.template: + src: templates/cron_check_free_space.j2 + dest: /etc/cron.d/check_free_space + owner: root + group: root + mode: "0644" + force: false + +- name: Duc and Mutt are installed + ansible.builtin.apt: + pkg: + - mutt + - duc + state: present + diff --git a/check_free_space/tasks/shell_script.yml b/check_free_space/tasks/shell_script.yml new file mode 100644 index 00000000..716304a1 --- /dev/null +++ b/check_free_space/tasks/shell_script.yml @@ -0,0 +1,30 @@ +--- + +- include_role: + name: evolix/remount-usr + +- name: shell script + copy: + src: files/check_free_space.sh + dest: /usr/share/scripts/check_free_space + owner: root + group: root + mode: "0750" + +- name: email template + copy: + src: files/check_free_space.tpl + dest: /usr/share/scripts/check_free_space.tpl + owner: root + group: root + mode: "0644" + +# not using the cron_module for this since it is buggy +- name: cron + template: + src: templates/cron_check_free_space.j2 + dest: /etc/cron.d/check_free_space + owner: root + group: root + mode: "0644" + force: false diff --git a/check_free_space/templates/cron_check_free_space.j2 b/check_free_space/templates/cron_check_free_space.j2 new file mode 100644 index 00000000..5017a67b --- /dev/null +++ b/check_free_space/templates/cron_check_free_space.j2 @@ -0,0 +1,4 @@ +{% if check_free_space_mailto and check_free_space_mailto != "" %} +MAILTO={{ check_free_space_mailto }} +{% endif %} +30 4 * * 1 root /usr/share/scripts/check_free_space "{{ check_free_space_partitions | join(' ') }}" {{ check_free_space_max_percent }} /usr/share/scripts/check_free_space.tpl diff --git a/evolinux-base/defaults/main.yml b/evolinux-base/defaults/main.yml index bf56d6de..7811ae89 100644 --- a/evolinux-base/defaults/main.yml +++ b/evolinux-base/defaults/main.yml @@ -211,6 +211,10 @@ evolinux_munin_include: True evolinux_nagios_nrpe_include: True +# check_free_space + +evolinux_check_free_space_include: True + # fail2ban evolinux_fail2ban_include: False diff --git a/evolinux-base/tasks/main.yml b/evolinux-base/tasks/main.yml index d482981a..b8f64844 100644 --- a/evolinux-base/tasks/main.yml +++ b/evolinux-base/tasks/main.yml @@ -127,6 +127,11 @@ name: evolix/nagios-nrpe when: evolinux_nagios_nrpe_include | bool +- name: check_free_space + ansible.builtin.include_role: + name: evolix/check_free_space + when: evolinux_check_free_space_include | bool + - name: Autosysadmin ansible.builtin.include_role: name: 'evolix/autosysadmin'