diff --git a/README.md b/README.md deleted file mode 100644 index e69de29..0000000 diff --git a/fundtracker/mutual-fund-tracker (5).zip b/fundtracker/mutual-fund-tracker (5).zip new file mode 100644 index 0000000..6012675 Binary files /dev/null and b/fundtracker/mutual-fund-tracker (5).zip differ diff --git a/zfs/nas16_zfs_scrub-1.sh b/zfs/nas16_zfs_scrub-1.sh deleted file mode 100644 index 917a1c8..0000000 --- a/zfs/nas16_zfs_scrub-1.sh +++ /dev/null @@ -1,322 +0,0 @@ -#!/bin/bash -# ============================================================================= -# ZFS Pool Scrub & Email Report — NAS16 -# Location: /usr/scripts/zfs/nas16_zfs_scrub.sh -# Schedule via OMV Scheduler (cron) -# ============================================================================= - -# ── Configuration ───────────────────────────────────────────────────────────── -HOSTNAME="NAS16" -REPORT_TO="rufus.king@kingdezigns.com" -REPORT_FROM="zfs-monitor@nas16.local" # Display only — Postfix uses your Gmail relay -SCRUB_WAIT_SECONDS=28800 # Max wait per pool scrub (8 hrs for large pools) -CAPACITY_WARN_THRESHOLD=80 # % capacity to flag as WARNING -SCRUB_AGE_WARN_DAYS=8 # Days since last scrub before flagging stale -LOG_FILE="/var/log/zfs_scrub_nas16.log" -# Note: Email is sent via OMV-configured Postfix (Gmail relay). No SMTP config needed here. -# ────────────────────────────────────────────────────────────────────────────── - -REPORT_TIME=$(date "+%Y-%m-%d %H:%M:%S") -POOLS=$(zpool list -H -o name) -POOL_COUNT=$(echo "$POOLS" | wc -l) - -log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG_FILE"; } - -log "===== ZFS Scrub started on $HOSTNAME =====" - -# ── Run scrubs sequentially ─────────────────────────────────────────────────── -for pool in $POOLS; do - log "Starting scrub on pool: $pool" - zpool scrub "$pool" - - ELAPSED=0 - while true; do - SCRUB_STATE=$(zpool status "$pool" | grep -E "scan:" | awk '{print $2}') - [[ "$SCRUB_STATE" == "scrub" ]] || break - sleep 30 - ELAPSED=$((ELAPSED + 30)) - if [[ $ELAPSED -ge $SCRUB_WAIT_SECONDS ]]; then - log "WARNING: Scrub on $pool exceeded wait time. Moving on." - break - fi - done - log "Scrub complete (or timed out) for pool: $pool" -done - -# ── Gather data & build pool cards ─────────────────────────────────────────── - -OVERALL_STATUS="HEALTHY" # HEALTHY | WARNING | CRITICAL -POOLS_WITH_ISSUES=0 -POOL_CARDS_HTML="" - -for pool in $POOLS; do - STATUS_RAW=$(zpool list -H -o health "$pool") - SIZE=$(zpool list -H -o size "$pool") - USED=$(zpool list -H -o alloc "$pool") - FREE=$(zpool list -H -o free "$pool") - CAP=$(zpool list -H -o cap "$pool" | tr -d '%') - FRAG=$(zpool list -H -o frag "$pool") - SCRUB_LINE=$(zpool status "$pool" | grep -E "scan:") - ERRORS_LINE=$(zpool status "$pool" | grep "errors:") - CONFIG_BLOCK=$(zpool status "$pool" | awk '/config:/,/errors:/' | head -n -1) - FAULTED_LINES=$(echo "$CONFIG_BLOCK" | grep -E "FAULTED|DEGRADED|UNAVAIL|REMOVED" | grep -v "^$") - - # Per-pool severity - POOL_SEVERITY="HEALTHY" - ISSUE_DETAIL="" - - if [[ "$STATUS_RAW" == "DEGRADED" || "$STATUS_RAW" == "FAULTED" || "$STATUS_RAW" == "UNAVAIL" ]]; then - POOL_SEVERITY="CRITICAL" - OVERALL_STATUS="CRITICAL" - ISSUE_DETAIL="$FAULTED_LINES" - elif [[ "$CAP" -ge "$CAPACITY_WARN_THRESHOLD" ]]; then - POOL_SEVERITY="WARNING" - [[ "$OVERALL_STATUS" != "CRITICAL" ]] && OVERALL_STATUS="WARNING" - fi - - # Scrub error count - SCRUB_ERRORS=$(echo "$SCRUB_LINE" | grep -oP '\d+ errors' | head -1) - [[ -z "$SCRUB_ERRORS" ]] && SCRUB_ERRORS="0 errors" - - # Scrub date - SCRUB_DATE=$(echo "$SCRUB_LINE" | grep -oP '[A-Z][a-z]{2} \d+ \d+:\d+:\d+ \d{4}' | head -1) - [[ -z "$SCRUB_DATE" ]] && SCRUB_DATE="No scrub data" - - # Scrub age warning - SCRUB_AGE_NOTE="" - if [[ -n "$SCRUB_DATE" && "$SCRUB_DATE" != "No scrub data" ]]; then - SCRUB_EPOCH=$(date -d "$SCRUB_DATE" +%s 2>/dev/null) - NOW_EPOCH=$(date +%s) - DIFF_DAYS=$(( (NOW_EPOCH - SCRUB_EPOCH) / 86400 )) - if [[ $DIFF_DAYS -ge $SCRUB_AGE_WARN_DAYS ]]; then - SCRUB_AGE_NOTE=" — ⚠️ Last scrub was ${DIFF_DAYS} days ago" - [[ "$POOL_SEVERITY" == "HEALTHY" ]] && POOL_SEVERITY="WARNING" - [[ "$OVERALL_STATUS" != "CRITICAL" ]] && OVERALL_STATUS="WARNING" - fi - fi - - [[ "$POOL_SEVERITY" != "HEALTHY" ]] && POOLS_WITH_ISSUES=$((POOLS_WITH_ISSUES + 1)) - - # Colors - case "$STATUS_RAW" in - ONLINE) HEALTH_COLOR="#1a7f4b" ;; - DEGRADED) HEALTH_COLOR="#b91c1c" ;; - FAULTED) HEALTH_COLOR="#b91c1c" ;; - *) HEALTH_COLOR="#b45309" ;; - esac - - case "$POOL_SEVERITY" in - CRITICAL) CARD_BORDER="#fca5a5"; CARD_HEADER_BG="#fff1f2"; POOL_BADGE_BG="#b91c1c"; POOL_BADGE_LABEL="$STATUS_RAW" ;; - WARNING) CARD_BORDER="#fcd34d"; CARD_HEADER_BG="#fffbeb"; POOL_BADGE_BG="#b45309"; POOL_BADGE_LABEL="WARNING" ;; - *) CARD_BORDER="#86efac"; CARD_HEADER_BG="#f0fdf4"; POOL_BADGE_BG="#1a7f4b"; POOL_BADGE_LABEL="HEALTHY" ;; - esac - - CAP_COLOR="#111827" - [[ "$CAP" -ge "$CAPACITY_WARN_THRESHOLD" ]] && CAP_COLOR="#b45309" - [[ "$CAP" -ge 90 ]] && CAP_COLOR="#b91c1c" - - # Issue block - ISSUE_BLOCK="" - if [[ -n "$ISSUE_DETAIL" ]]; then - ESCAPED_DETAIL=$(echo "$ISSUE_DETAIL" | sed 's/\</g; s/>/\>/g') - ISSUE_BLOCK=" -
| - 🗄️ $pool - pool - | -- $POOL_BADGE_LABEL - | -
|
- Total
- $SIZE
- |
- - |
- Used
- $USED
- |
- - |
- Free
- $FREE
- |
- - |
- Capacity
- ${CAP}%
- |
- - |
- Frag
- $FRAG
- |
- - |
- Health
- $STATUS_RAW
- |
-
$ESCAPED_CONFIG-
-
| ||||||||||||||||||||||||||||||||
|
- Total Size
- $SIZE
+ | + 🗄️ $pool + pool | -- |
- Used
- $USED
- |
- - |
- Free
- $FREE
- |
- - |
- Capacity
- ${CAP}%
- |
- - |
- Fragmentation
- $FRAG
- |
- - |
- Health
- $STATUS_RAW
+ | + $POOL_BADGE_LABEL |
|
+ Total
+ $SIZE
+ |
+ + |
+ Used
+ $USED
+ |
+ + |
+ Free
+ $FREE
+ |
+ + |
+ Capacity
+ ${CAP}%
+ |
+ + |
+ Frag
+ $FRAG
+ |
+ + |
+ Health
+ $STATUS_RAW
+ |
+
$ESCAPED_CONFIG
| ||||||||||||||||