init: clean history with no PII
Toto repo ma novou cistou historii (1 commit). Predchozi historie byla smazana, protoze obsahovala osobni udaje (IP, emaily, hesla, klice, tokeny, Volume cesty). Soubory v aktualnim commit uz tyto udaje neobsahuji (nahradeno placeholdery <server-ip>, CHANGE_ME, admin@example.com atd.). Pokud chces zpet kompletni seznam starych commitu, mas je ve svem lokalnim working tree - git log --all ukaze prazdno (protoze jsme smazali .git/ a zacali znovu).
This commit is contained in:
+185
@@ -0,0 +1,185 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# disk-watch.sh — sledování volného místa na Docker datech
|
||||
#
|
||||
# Kontroluje:
|
||||
# - <ssd-data-mount> (Docker data)
|
||||
# - <backup-disk-mount> (zálohy)
|
||||
# - Docker disk usage (images, containers, volumes, build cache)
|
||||
#
|
||||
# Při podkročení prahu pošle notifikaci (Telegram přes Hermes cron, nebo lokální alert).
|
||||
# V defaultu jen vypíše stav; s --alert pošle zprávu přes Hermes Telegram doručení.
|
||||
#
|
||||
# Použití:
|
||||
# ./disk-watch.sh # jen výpis
|
||||
# ./disk-watch.sh --alert # pošle notifikaci při podkročení
|
||||
# SSDDATA_THRESHOLD=80 ./disk-watch.sh # 80 % prah pro SSD-data
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SSD_DATA="${SSD_DATA:-<ssd-data-mount>}"
|
||||
SSD_BACKUP="${SSD_BACKUP:-<backup-disk-mount>}"
|
||||
SSD_DATA_THRESHOLD="${SSD_DATA_THRESHOLD:-85}" # %
|
||||
SSD_BACKUP_THRESHOLD="${SSD_BACKUP_THRESHOLD:-85}" # %
|
||||
DOCKER_THRESHOLD="${DOCKER_THRESHOLD:-80}" # %
|
||||
|
||||
ALERT=0
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
--alert|-a) ALERT=1 ;;
|
||||
--help|-h)
|
||||
sed -n '2,15p' "$0"
|
||||
exit 0
|
||||
;;
|
||||
*) echo "Unknown arg: $arg" >&2; exit 1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Barevné výstupy
|
||||
if [ -t 1 ]; then
|
||||
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; BLUE='\033[0;34m'; NC='\033[0m'
|
||||
else
|
||||
RED=''; GREEN=''; YELLOW=''; BLUE=''; NC=''
|
||||
fi
|
||||
|
||||
WARNINGS=()
|
||||
|
||||
check_disk() {
|
||||
local path="$1" threshold="$2" label="$3"
|
||||
if [ ! -d "$path" ]; then
|
||||
printf '%s%s%s %s — adresář neexistuje\n' "$YELLOW" "⚠" "$NC" "$label"
|
||||
return
|
||||
fi
|
||||
# df v macOS nevrací % použití přímo; parsujeme z výstupu
|
||||
local line used avail capacity
|
||||
line=$(df -h "$path" | tail -n +2 | head -n 1)
|
||||
capacity=$(echo "$line" | awk '{print $5}' | tr -d '%')
|
||||
used=$(echo "$line" | awk '{print $3}')
|
||||
avail=$(echo "$line" | awk '{print $4}')
|
||||
total=$(echo "$line" | awk '{print $2}')
|
||||
|
||||
if [ -z "$capacity" ]; then
|
||||
printf '%s%s%s %s — nelze přečíst\n' "$YELLOW" "⚠" "$NC" "$label"
|
||||
return
|
||||
fi
|
||||
|
||||
if [ "$capacity" -ge "$threshold" ]; then
|
||||
printf '%s●%s %s %s/%s (%s%%) — %sPŘEKROČEN PRAH%s (≥%s%%)\n' \
|
||||
"$RED" "$NC" "$label" "$used" "$total" "$capacity" "$RED" "$NC" "$threshold"
|
||||
WARNINGS+=("$label: ${capacity}% (prah ${threshold}%)")
|
||||
else
|
||||
printf '%s●%s %s %s/%s (%s%%) — OK\n' \
|
||||
"$GREEN" "$NC" "$label" "$used" "$total" "$capacity"
|
||||
fi
|
||||
}
|
||||
|
||||
check_docker_disk() {
|
||||
if ! docker info >/dev/null 2>&1; then
|
||||
printf '%s●%s Docker — není dostupný\n' "$YELLOW" "$NC"
|
||||
return
|
||||
fi
|
||||
|
||||
# Získat velikost images + containers + volumes
|
||||
local out
|
||||
out=$(docker system df --format '{{.Type}}\t{{.Size}}\t{{.Reclaimable}}' 2>/dev/null || true)
|
||||
|
||||
if [ -z "$out" ]; then
|
||||
printf '%s●%s Docker disk — nešlo přečíst\n' "$YELLOW" "$NC"
|
||||
return
|
||||
fi
|
||||
|
||||
# Spočítat celkové využití Dockeru (obtížné bez du -s na /var/lib/docker;
|
||||
# protože jsme na Docker Desktop macOS, kontrolujeme jen velikost images)
|
||||
local images_size_bytes
|
||||
images_size_bytes=$(docker system df --format '{{.Type}}\t{{.Size}}' \
|
||||
| awk -F'\t' '$1 == "Images" {print $2}')
|
||||
|
||||
printf '%s●%s Docker images: %s\n' "$BLUE" "$NC" "${images_size_bytes:-neznámé}"
|
||||
|
||||
# Velké images (>500 MB), které nejsou používané
|
||||
printf '%s●%s Velké images (>500 MB):\n' "$BLUE" "$NC"
|
||||
docker images --format '{{.Size}}\t{{.Repository}}:{{.Tag}}\t{{.ID}}' \
|
||||
| awk -F'\t' '{
|
||||
size = $1
|
||||
# převod na MB
|
||||
if (size ~ /GB/) {mb = size * 1024} else if (size ~ /MB/) {mb = size + 0} else if (size ~ /kB/) {mb = size / 1024} else {mb = 0}
|
||||
if (mb + 0 > 500) print $2, size
|
||||
}' \
|
||||
| head -10 | while read -r line; do
|
||||
printf ' %s\n' "$line"
|
||||
done
|
||||
|
||||
# Nepoužívané images (pozor, ne "používané" — bezpečnost)
|
||||
unused=$(docker images --format '{{.Size}}\t{{.Repository}}:{{.Tag}}' \
|
||||
| awk -F'\t' '
|
||||
/^([0-9.]+[kMG]B)\s/ {
|
||||
size = $1
|
||||
if (size ~ /GB/) mb = size * 1024
|
||||
else if (size ~ /MB/) mb = size + 0
|
||||
else if (size ~ /kB/) mb = size / 1024
|
||||
if (mb + 0 > 200) print size, $2
|
||||
}' | head -5)
|
||||
if [ -n "$unused" ]; then
|
||||
printf '%s●%s Kandidáti na vyčištění (>200 MB):\n' "$YELLOW" "$NC"
|
||||
echo "$unused" | while read -r line; do printf ' %s\n' "$line"; done
|
||||
fi
|
||||
}
|
||||
|
||||
check_top_offenders() {
|
||||
if [ ! -d "$SSD_DATA/Dockery" ]; then
|
||||
return
|
||||
fi
|
||||
printf '\n%s●%s Top 5 největších adresářů v <docker-projects-root>:\n' "$BLUE" "$NC"
|
||||
/bin/du -sh "$SSD_DATA"/Dockery/*/ 2>/dev/null \
|
||||
| /usr/bin/sort -rh \
|
||||
| /usr/bin/head -5 \
|
||||
| /usr/bin/sed 's/^/ /'
|
||||
}
|
||||
|
||||
printf '%s%s%s\n' "$BLUE" "=== DISK WATCH ===" "$NC"
|
||||
printf 'Prahy: SSD-data>%s%%, disk2-data>%s%%\n' "$SSD_DATA_THRESHOLD" "$SSD_BACKUP_THRESHOLD"
|
||||
printf 'Datum: %s\n\n' "$(date '+%Y-%m-%d %H:%M:%S')"
|
||||
|
||||
check_disk "$SSD_DATA" "$SSD_DATA_THRESHOLD" "SSD-data (Docker)"
|
||||
check_disk "$SSD_BACKUP" "$SSD_BACKUP_THRESHOLD" "disk2-data (zálohy)"
|
||||
|
||||
check_docker_disk
|
||||
check_top_offenders
|
||||
|
||||
if [ "${#WARNINGS[@]}" -gt 0 ]; then
|
||||
printf '\n%s●%s VAROVÁNÍ:\n' "$RED" "$NC"
|
||||
for w in "${WARNINGS[@]}"; do
|
||||
printf ' - %s\n' "$w"
|
||||
done
|
||||
fi
|
||||
|
||||
if [ "$ALERT" = "1" ] && [ "${#WARNINGS[@]}" -gt 0 ]; then
|
||||
# Alert přes Hermes Telegram cron
|
||||
MSG="⚠️ Disk Watch — překročen prah
|
||||
$(printf '%s\n' "${WARNINGS[@]}")
|
||||
|
||||
Datum: $(date '+%Y-%m-%d %H:%M:%S')
|
||||
Host: $(hostname)"
|
||||
|
||||
# Vytvoř one-shot cron pro doručení
|
||||
CRON_TS=$(date -u -v+1M +%Y-%m-%dT%H:%M:%S 2>/dev/null \
|
||||
|| date -u -d '+1 minute' +%Y-%m-%dT%H:%M:%S)
|
||||
PAYLOAD=$(printf '%s' "$MSG" | python3 -c 'import sys,json; print(json.dumps(sys.stdin.read()))')
|
||||
|
||||
if command -v hermes >/dev/null 2>&1; then
|
||||
hermes cron add \
|
||||
--name "disk-watch-alert-$(date +%s)" \
|
||||
--at "$CRON_TS" \
|
||||
--deliver all \
|
||||
--message "$MSG" 2>/dev/null \
|
||||
&& log "Alert naplánován na $CRON_TS" \
|
||||
|| err "Nepodařilo se naplánovat alert (hermes cron)"
|
||||
else
|
||||
# Fallback: jen vypiš, že by se měl alert poslat
|
||||
printf '\n%s[ALERT by se poslal:]%s\n' "$YELLOW" "$NC"
|
||||
printf '%s\n' "$MSG"
|
||||
fi
|
||||
fi
|
||||
|
||||
exit 0
|
||||
Reference in New Issue
Block a user