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:
2026-08-01 19:51:59 +02:00
commit 682f522cb9
10 changed files with 1560 additions and 0 deletions
+185
View File
@@ -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