diff --git a/.env b/.env new file mode 100644 index 0000000..ba65873 --- /dev/null +++ b/.env @@ -0,0 +1,28 @@ + +###### User-definable Parameters +### Email Address +email="you_email@email.com" + +### FreeNAS config backup settings +configBackup="true" # Change to "false" to skip config backup (which renders next two options meaningless); "true" to keep config backups enabled +saveBackup="true" # Change to "false" to delete FreeNAS config backup after mail is sent; "true" to keep it in dir below +backupLocation="/path/to/config/backup" # Directory in which to save FreeNAS config backups + +### Global table colors +okColor="#c9ffcc" # Hex code for color to use in SMART Status column if drives pass (default is light green, #c9ffcc) +warnColor="#ffd6d6" # Hex code for WARN color (default is light red, #ffd6d6) +critColor="#ff0000" # Hex code for CRITICAL color (default is bright red, #ff0000) +altColor="#f4f4f4" # Table background alternates row colors between white and this color (default is light gray, #f4f4f4) + +### zpool status summary table settings +usedWarn=90 # Pool used percentage for CRITICAL color to be used +scrubAgeWarn=30 # Maximum age (in days) of last pool scrub before CRITICAL color will be used + +### SMART status summary table settings +includeSSD="true" # [NOTE: Currently this is pretty much useless] Change to "true" to include SSDs in SMART status summary table; "false" to disable +tempWarn=40 # Drive temp (in C) at which WARNING color will be used +tempCrit=45 # Drive temp (in C) at which CRITICAL color will be used +sectorsCrit=10 # Number of sectors per drive with errors before CRITICAL color will be used +testAgeWarn=5 # Maximum age (in days) of last SMART test before CRITICAL color will be used +powerTimeFormat="ymdh" # Format for power-on hours string, valid options are "ymdh", "ymd", "ym", or "y" (year month day hour) + diff --git a/README.md b/README.md index b2a81ab..2e7a920 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,23 @@ Original script by joeschmuck, modified by Bidelu0hm, then by melp Preview of the output here: http://i.imgur.com/t9Mtqyt.png +## Installation + +### Requirements + +Your Truenas installation needs to be able to send emails. Please check the SMTP/Email config in the Truenas General settings. + +### Core + +TODO - add core specific configuration + +### Scale + + - Clone this repo at the location of your choice on your Scale system + - Add a cron job to run report.sh, under System settings -> Advanced -> Cron Jobs + - In the command field, use bash to invoke report.sh: ```(cd your/git/rpo/location/ && bash report.sh)``` + - Run as root, as of Dragonfish + **At a minimum, you will need to enter your email address in user-definable parameter section.** Feel free to edit other user parameters as needed. **Version: v1.3** diff --git a/email-writing b/email-writing new file mode 100644 index 0000000..de14ba3 --- /dev/null +++ b/email-writing @@ -0,0 +1,18 @@ +#!/bin/bash +# +host=$(hostname -s) +#logfile="/tmp/smart_report.tmp" +subject="Status Report and Configuration Backup for ${host}" +boundary="gc0p4Jq0M2Yt08jU534c0p" + +function write_email_header () { + ###### Email pre-formatting + ### Set email headers + ( + echo "From: ${email}" + echo "To: ${email}" + echo "Subject: ${subject}" + echo "MIME-Version: 1.0" + echo "Content-Type: multipart/mixed; boundary=${boundary}" + ) > "$1" +} diff --git a/report.sh b/report.sh index 0b7f098..2b4b36e 100644 --- a/report.sh +++ b/report.sh @@ -1,4 +1,5 @@ #!/bin/bash +shopt -s expand_aliases ###### ZPool & SMART status report with FreeNAS config backup ### Original script by joeschmuck, modified by Bidelu0hm, then by melp (me) @@ -37,340 +38,310 @@ ### TODO: # - Fix SSD SMART reporting # - Add support for conveyance test +# +source .env +source ./system-specific-aliases -###### User-definable Parameters -### Email Address -email="email@address.com" - -### Global table colors -okColor="#c9ffcc" # Hex code for color to use in SMART Status column if drives pass (default is light green, #c9ffcc) -warnColor="#ffd6d6" # Hex code for WARN color (default is light red, #ffd6d6) -critColor="#ff0000" # Hex code for CRITICAL color (default is bright red, #ff0000) -altColor="#f4f4f4" # Table background alternates row colors between white and this color (default is light gray, #f4f4f4) - -### zpool status summary table settings -usedWarn=90 # Pool used percentage for CRITICAL color to be used -scrubAgeWarn=30 # Maximum age (in days) of last pool scrub before CRITICAL color will be used - -### SMART status summary table settings -includeSSD="false" # [NOTE: Currently this is pretty much useless] Change to "true" to include SSDs in SMART status summary table; "false" to disable -tempWarn=40 # Drive temp (in C) at which WARNING color will be used -tempCrit=45 # Drive temp (in C) at which CRITICAL color will be used -sectorsCrit=10 # Number of sectors per drive with errors before CRITICAL color will be used -testAgeWarn=5 # Maximum age (in days) of last SMART test before CRITICAL color will be used -powerTimeFormat="ymdh" # Format for power-on hours string, valid options are "ymdh", "ymd", "ym", or "y" (year month day hour) - -### FreeNAS config backup settings -configBackup="true" # Change to "false" to skip config backup (which renders next two options meaningless); "true" to keep config backups enabled -saveBackup="true" # Change to "false" to delete FreeNAS config backup after mail is sent; "true" to keep it in dir below -backupLocation="/path/to/config/backup" # Directory in which to save FreeNAS config backups +function drives_lookup () { + if [ "$includeSSD" == "true" ]; then + drives=$(for drive in $(list_drives); do + if [ "$(smartctl -i /dev/"${drive}" | grep "SMART support is: Enabled")" ]; then + printf "%s " "${drive}" + fi + done | awk '{for (i=NF; i!=0 ; i--) print $i }') +else + drives=$(for drive in $(list_drives); do + if [ "$(smartctl -i /dev/"${drive}" | grep "SMART support is: Enabled")" ] && ! [ "$(smartctl -i /dev/"${drive}" | grep "Solid State Device")" ]; then + printf "%s " "${drive}" + fi +done | awk '{for (i=NF; i!=0 ; i--) print $i }') + fi + echo ${drives} +} ###### Auto-generated Parameters -host=$(hostname -s) logfile="/tmp/smart_report.tmp" -subject="Status Report and Configuration Backup for ${host}" -boundary="gc0p4Jq0M2Yt08jU534c0p" -if [ "$includeSSD" == "true" ]; then - drives=$(for drive in $(sysctl -n kern.disks); do - if [ "$(smartctl -i /dev/"${drive}" | grep "SMART support is: Enabled")" ]; then - printf "%s " "${drive}" - fi - done | awk '{for (i=NF; i!=0 ; i--) print $i }') -else - drives=$(for drive in $(sysctl -n kern.disks); do - if [ "$(smartctl -i /dev/"${drive}" | grep "SMART support is: Enabled")" ] && ! [ "$(smartctl -i /dev/"${drive}" | grep "Solid State Device")" ]; then - printf "%s " "${drive}" - fi - done | awk '{for (i=NF; i!=0 ; i--) print $i }') -fi -pools=$(zpool list -H -o name) +drives=$(drives_lookup) +pools=$(zpool list -H -o name) -###### Email pre-formatting -### Set email headers -( - echo "From: ${email}" - echo "To: ${email}" - echo "Subject: ${subject}" - echo "MIME-Version: 1.0" - echo "Content-Type: multipart/mixed; boundary=${boundary}" -) > "$logfile" - +source ./email-writing +write_email_header $logfile ###### Config backup (if enabled) if [ "$configBackup" == "true" ]; then - # Set up file names, etc for later - tarfile="/tmp/config_backup.tar.gz" - filename="$(date "+FreeNAS_Config_%Y-%m-%d")" - ### Test config integrity - if ! [ "$(sqlite3 /data/freenas-v1.db "pragma integrity_check;")" == "ok" ]; then - # Config integrity check failed, set MIME content type to html and print warning - ( - echo "--${boundary}" - echo "Content-Type: text/html" - echo "Automatic backup of FreeNAS configuration has failed! The configuration file is corrupted!" - echo "You should correct this problem as soon as possible!" - echo "
" - ) >> "$logfile" - else - # Config integrity check passed; copy config db, generate checksums, make .tar.gz archive - cp /data/freenas-v1.db "/tmp/${filename}.db" - md5 "/tmp/${filename}.db" > /tmp/config_backup.md5 - sha256 "/tmp/${filename}.db" > /tmp/config_backup.sha256 - ( - cd "/tmp/" || exit; - tar -czf "${tarfile}" "./${filename}.db" ./config_backup.md5 ./config_backup.sha256; - ) - ( - # Write MIME section header for file attachment (encoded with base64) - echo "--${boundary}" - echo "Content-Type: application/tar+gzip" - echo "Content-Transfer-Encoding: base64" - echo "Content-Disposition: attachment; filename=${filename}.tar.gz" - base64 "$tarfile" - # Write MIME section header for html content to come below - echo "--${boundary}" - echo "Content-Type: text/html" - ) >> "$logfile" - # If logfile saving is enabled, copy .tar.gz file to specified location before it (and everything else) is removed below - if [ "$saveBackup" == "true" ]; then - cp "${tarfile}" "${backupLocation}/${filename}.tar.gz" - fi - rm "/tmp/${filename}.db" - rm /tmp/config_backup.md5 - rm /tmp/config_backup.sha256 - rm "${tarfile}" - fi + # Set up file names, etc for later + tarfile="/tmp/config_backup.tar.gz" + filename="$(date "+FreeNAS_Config_%Y-%m-%d")" + ### Test config integrity + if ! [ "$(sqlite3 /data/freenas-v1.db "pragma integrity_check;")" == "ok" ]; then + # Config integrity check failed, set MIME content type to html and print warning + ( + echo "--${boundary}" + echo "Content-Type: text/html" + echo "Automatic backup of FreeNAS configuration has failed! The configuration file is corrupted!" + echo "You should correct this problem as soon as possible!" + echo "
" + ) >> "$logfile" + else + # Config integrity check passed; copy config db, generate checksums, make .tar.gz archive + cp /data/freenas-v1.db "/tmp/${filename}.db" + md5 "/tmp/${filename}.db" > /tmp/config_backup.md5 + sha256 "/tmp/${filename}.db" > /tmp/config_backup.sha256 + ( + cd "/tmp/" || exit; + tar -czf "${tarfile}" "./${filename}.db" ./config_backup.md5 ./config_backup.sha256; + ) + ( + # Write MIME section header for file attachment (encoded with base64) + echo "--${boundary}" + echo "Content-Type: application/tar+gzip" + echo "Content-Transfer-Encoding: base64" + echo "Content-Disposition: attachment; filename=${filename}.tar.gz" + base64 "$tarfile" + # Write MIME section header for html content to come below + echo "--${boundary}" + echo "Content-Type: text/html" + ) >> "$logfile" + # If logfile saving is enabled, copy .tar.gz file to specified location before it (and everything else) is removed below + if [ "$saveBackup" == "true" ]; then + cp "${tarfile}" "${backupLocation}/${filename}.tar.gz" + fi + rm "/tmp/${filename}.db" + rm /tmp/config_backup.md5 + rm /tmp/config_backup.sha256 + rm "${tarfile}" + fi else - # Config backup enabled; set up for html-type content - ( - echo "--${boundary}" - echo "Content-Type: text/html" - ) >> "$logfile" + # Config backup enabled; set up for html-type content + ( + echo "--${boundary}" + echo "Content-Type: text/html" + ) >> "$logfile" fi ###### Report Summary Section (html tables) ### zpool status summary table ( - # Write HTML table headers to log file; HTML in an email requires 100% in-line styling (no CSS or