Files
pi-kit/pikit-prep.sh
2025-12-10 18:51:31 -05:00

246 lines
8.2 KiB
Bash

#!/bin/bash
# Pi-Kit DietPi image prep script
# Cleans host-unique data, logs, caches, and temp files per pikit-prep-spec.
set -euo pipefail
status() { printf '[%s] %s\n' "$1" "$2"; }
clean_logs_dir() {
local dir="$1" pattern="${2:-*}"
if [ -d "$dir" ]; then
find "$dir" -type f -name "$pattern" -print -delete 2>/dev/null | sed 's/^/[CLEANED] /' || true
status CLEANED "logs $pattern in $dir"
else
status SKIP "$dir (missing)"
fi
}
truncate_file() {
local file="$1"
if [ -e "$file" ]; then
:> "$file" && status CLEANED "truncated $file" || status FAIL "truncate $file"
else
status SKIP "$file (missing)"
fi
}
clean_file() {
local path="$1"
if [ -e "$path" ]; then
rm -f "$path" && status CLEANED "$path" || status FAIL "$path"
else
status SKIP "$path (missing)"
fi
}
clean_dir_files() {
local dir="$1" pattern="$2"
if [ -d "$dir" ]; then
find "$dir" -type f -name "$pattern" -print -delete 2>/dev/null | sed 's/^/[CLEANED] /' || true
status CLEANED "files $pattern in $dir"
else
status SKIP "$dir (missing)"
fi
}
truncate_dir() {
local dir="$1"
if [ -d "$dir" ]; then
# keep systemd-private dirs intact while services run
find "$dir" -mindepth 1 -maxdepth 1 ! -path "$dir/systemd-private-*" -exec rm -rf {} + 2>/dev/null
status CLEANED "$dir"
else
status SKIP "$dir (missing)"
fi
}
clean_backups() {
local dir="$1"
if [ -d "$dir" ]; then
find "$dir" -type f \( -name '*~' -o -name '*.bak*' -o -name '*.orig*' \) -print -delete 2>/dev/null | sed 's/^/[CLEANED] /' || true
status CLEANED "backup/editor files in $dir"
else
status SKIP "$dir (missing)"
fi
}
# --- Identity ---
# Keep machine-id file present but empty so systemd regenerates cleanly on next boot.
truncate -s 0 /etc/machine-id && status CLEANED /etc/machine-id || status FAIL /etc/machine-id
mkdir -p /var/lib/dbus || true
rm -f /var/lib/dbus/machine-id
ln -s /etc/machine-id /var/lib/dbus/machine-id && status CLEANED "/var/lib/dbus/machine-id -> /etc/machine-id" || status FAIL "/var/lib/dbus/machine-id"
clean_file /var/lib/systemd/random-seed
# --- SSH host keys ---
if ls /etc/ssh/ssh_host_* >/dev/null 2>&1; then
rm -f /etc/ssh/ssh_host_* && status CLEANED "SSH host keys" || status FAIL "SSH host keys"
else
status SKIP "SSH host keys (none)"
fi
# --- SSH client traces ---
:> /root/.ssh/known_hosts 2>/dev/null && status CLEANED "/root/.ssh/known_hosts" || status SKIP "/root/.ssh/known_hosts"
:> /home/dietpi/.ssh/known_hosts 2>/dev/null && status CLEANED "/home/dietpi/.ssh/known_hosts" || status SKIP "/home/dietpi/.ssh/known_hosts"
:> /home/dietpi/.ssh/authorized_keys 2>/dev/null && status CLEANED "/home/dietpi/.ssh/authorized_keys" || status SKIP "/home/dietpi/.ssh/authorized_keys"
:> /root/.ssh/authorized_keys 2>/dev/null && status CLEANED "/root/.ssh/authorized_keys" || status SKIP "/root/.ssh/authorized_keys"
# --- Shell history ---
:> /root/.bash_history 2>/dev/null && status CLEANED "/root/.bash_history" || status SKIP "/root/.bash_history"
:> /home/dietpi/.bash_history 2>/dev/null && status CLEANED "/home/dietpi/.bash_history" || status SKIP "/home/dietpi/.bash_history"
# --- Ready flag ---
clean_file /var/run/pikit-ready
# --- Backup/editor cruft ---
clean_backups /var/www/pikit-web
clean_backups /usr/local/bin
# --- Logs ---
clean_dir_files /var/log "*"
clean_dir_files /var/log/nginx "*"
# systemd journal (persistent) if present
if [ -d /var/log/journal ]; then
find /var/log/journal -type f -print -delete 2>/dev/null | sed 's/^/[CLEANED] /' || true
status CLEANED "/var/log/journal"
else
status SKIP "/var/log/journal (missing)"
fi
# crash dumps
if [ -d /var/crash ]; then
find /var/crash -type f -print -delete 2>/dev/null | sed 's/^/[CLEANED] /' || true
status CLEANED "/var/crash"
else
status SKIP "/var/crash (missing)"
fi
# Service-specific logs (best-effort, skip if absent)
if command -v pihole >/dev/null 2>&1; then
pihole -f >/dev/null 2>&1 && status CLEANED "pihole logs via pihole -f" || status FAIL "pihole -f"
clean_logs_dir /var/log/pihole '*'
clean_file /etc/pihole/pihole-FTL.db # resets long-term query history; leave gravity.db untouched
fi
if [ -x /opt/AdGuardHome/AdGuardHome ]; then
clean_logs_dir /var/opt/AdGuardHome/data/logs '*'
clean_file /opt/AdGuardHome/data/querylog.db
fi
if command -v ufw >/dev/null 2>&1; then
truncate_file /var/log/ufw.log
fi
if command -v fail2ban-client >/dev/null 2>&1; then
truncate_file /var/log/fail2ban.log
fi
clean_logs_dir /var/log/unbound '*'
clean_logs_dir /var/log/dnsmasq '*'
clean_logs_dir /var/log/powerdns '*'
clean_logs_dir /var/lib/technitium-dns/Logs '*'
clean_logs_dir /var/log/jellyfin '*'
clean_logs_dir /var/lib/jellyfin/log '*'
clean_logs_dir /var/log/jellyseerr '*'
clean_logs_dir /opt/jellyseerr/logs '*'
clean_logs_dir /var/log/ustreamer '*'
clean_logs_dir /var/log/gitea '*'
clean_logs_dir /var/lib/gitea/log '*'
clean_logs_dir /var/log/fmd '*'
clean_logs_dir /var/log/uptime-kuma '*'
clean_logs_dir /opt/uptime-kuma/data/logs '*'
clean_logs_dir /var/log/romm '*'
clean_logs_dir /var/log/privatebin '*'
clean_logs_dir /var/log/crafty '*'
clean_logs_dir /var/log/rustdesk '*'
clean_logs_dir /var/log/memos '*'
clean_logs_dir /var/lib/memos/logs '*'
clean_logs_dir /var/log/traccar '*'
clean_logs_dir /var/log/webmin '*'
clean_logs_dir /var/log/homarr '*'
clean_logs_dir /var/log/termix '*'
clean_logs_dir /var/log/syncthing '*'
clean_logs_dir /var/log/netdata '*'
clean_logs_dir /var/lib/netdata/dbengine '*'
clean_logs_dir /var/log/AdGuardHome '*'
# DB / metrics / web stacks
clean_logs_dir /var/log/mysql '*'
clean_logs_dir /var/log/mariadb '*'
clean_logs_dir /var/log/postgresql '*'
truncate_file /var/log/redis/redis-server.log
clean_logs_dir /var/log/influxdb '*'
clean_logs_dir /var/log/prometheus '*'
clean_logs_dir /var/log/grafana '*'
clean_logs_dir /var/log/loki '*'
clean_logs_dir /var/log/caddy '*'
clean_logs_dir /var/log/apache2 '*'
clean_logs_dir /var/log/lighttpd '*'
clean_logs_dir /var/log/samba '*'
clean_logs_dir /var/log/mosquitto '*'
clean_logs_dir /var/log/openvpn '*'
clean_logs_dir /var/log/wireguard '*'
clean_logs_dir /var/log/node-red '*'
truncate_file /var/log/nodered-install.log
clean_logs_dir /var/log/transmission-daemon '*'
clean_logs_dir /var/log/deluge '*'
clean_logs_dir /var/log/qbittorrent '*'
clean_logs_dir /var/log/paperless-ngx '*'
clean_logs_dir /var/log/photoprism '*'
clean_logs_dir /var/log/navidrome '*'
clean_logs_dir /var/log/minio '*'
clean_logs_dir /var/log/nzbget '*'
clean_logs_dir /var/log/sabnzbd '*'
clean_logs_dir /var/log/jackett '*'
clean_logs_dir /var/log/radarr '*'
clean_logs_dir /var/log/sonarr '*'
clean_logs_dir /var/log/lidarr '*'
clean_logs_dir /var/log/prowlarr '*'
clean_logs_dir /var/log/bazarr '*'
clean_logs_dir /var/log/overseerr '*'
clean_logs_dir /var/log/emby-server '*'
# App-specific logs stored with app data (truncate, keep structure)
truncate_file /home/homeassistant/.homeassistant/home-assistant.log
clean_logs_dir /home/homeassistant/.homeassistant/logs '*'
truncate_file /var/www/nextcloud/data/nextcloud.log
truncate_file /var/www/owncloud/data/owncloud.log
# Docker container JSON logs
if [ -d /var/lib/docker/containers ]; then
find /var/lib/docker/containers -type f -name '*-json.log' -print0 2>/dev/null | while IFS= read -r -d '' f; do
:> "$f" && status CLEANED "truncated $f" || status FAIL "truncate $f"
done
else
status SKIP "/var/lib/docker/containers (missing)"
fi
clean_file /var/log/wtmp.db
clean_dir_files /var/tmp/dietpi/logs "*"
# --- Caches ---
apt-get clean >/dev/null 2>&1 && status CLEANED "apt cache" || status FAIL "apt cache"
rm -rf /var/lib/apt/lists/* /var/cache/apt/* 2>/dev/null && status CLEANED "apt lists/cache" || status FAIL "apt lists/cache"
find /var/cache/debconf -type f -print -delete 2>/dev/null | sed 's/^/[CLEANED] /' || true
status CLEANED "/var/cache/debconf files"
# --- Temp directories ---
truncate_dir /tmp
truncate_dir /var/tmp
# --- DHCP leases ---
clean_file /var/lib/dhcp/dhclient.eth0.leases
# --- Nginx caches ---
if [ -d /var/lib/nginx ]; then
find /var/lib/nginx -mindepth 1 -maxdepth 1 -type d -exec rm -rf {} + 2>/dev/null
status CLEANED "/var/lib/nginx/*"
else
status SKIP "/var/lib/nginx"
fi
status DONE "Prep complete"
# Self-delete to avoid leaving the prep tool on the image.
rm -- "$0"