639 lines
19 KiB
Bash
Executable File
639 lines
19 KiB
Bash
Executable File
#!/bin/bash
|
|
# Pi-Kit DietPi image prep + check script
|
|
# Cleans host-unique data and optionally verifies the image state.
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_PATH="$(readlink -f "${BASH_SOURCE[0]}")"
|
|
SCRIPT_NAME="$(basename "$SCRIPT_PATH")"
|
|
|
|
PIKIT_HOST="${PIKIT_HOST:-pikit.local}"
|
|
PIKIT_USER="${PIKIT_USER:-dietpi}"
|
|
PIKIT_SSH_KEY="${PIKIT_SSH_KEY:-$HOME/.ssh/pikit}"
|
|
PIKIT_SSH_OPTS="${PIKIT_SSH_OPTS:-}"
|
|
PIKIT_REMOTE_TMP="${PIKIT_REMOTE_TMP:-/tmp/pikit-prep.sh}"
|
|
PIKIT_SELF_DELETE="${PIKIT_SELF_DELETE:-0}"
|
|
PIKIT_FORCE_PASSWORD_CHANGE="${PIKIT_FORCE_PASSWORD_CHANGE:-1}"
|
|
|
|
MODE="both"
|
|
LOCAL_ONLY=0
|
|
|
|
ERRORS=0
|
|
WARNINGS=0
|
|
|
|
usage() {
|
|
cat <<'USAGE'
|
|
Usage: pikit-prep.sh [--prep-only|--check-only] [--local]
|
|
|
|
Defaults to prep + check (combined). When run on a non-DietPi host, it will
|
|
copy itself to the Pi (/tmp) and run with sudo, then clean up.
|
|
|
|
Options:
|
|
--prep-only Run prep only (no check)
|
|
--check-only Run checks only (no prep)
|
|
--local Force local execution (no SSH copy)
|
|
--help Show this help
|
|
|
|
Env:
|
|
PIKIT_FORCE_PASSWORD_CHANGE=0 Skip forcing a password change (default is on)
|
|
USAGE
|
|
}
|
|
|
|
status() {
|
|
local level="$1"
|
|
shift
|
|
printf '[%s] %s\n' "$level" "$*"
|
|
case "$level" in
|
|
FAIL) ERRORS=$((ERRORS + 1)) ;;
|
|
WARN) WARNINGS=$((WARNINGS + 1)) ;;
|
|
esac
|
|
}
|
|
|
|
section() {
|
|
printf '\n== %s ==\n' "$1"
|
|
}
|
|
|
|
is_dietpi() {
|
|
grep -qi "dietpi" /etc/os-release 2>/dev/null
|
|
}
|
|
|
|
require_root() {
|
|
if [ "${EUID:-$(id -u)}" -ne 0 ]; then
|
|
echo "[FAIL] This script must run as root (use sudo)." >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
parse_args() {
|
|
for arg in "$@"; do
|
|
case "$arg" in
|
|
--prep-only) MODE="prep" ;;
|
|
--check-only) MODE="check" ;;
|
|
--local) LOCAL_ONLY=1 ;;
|
|
--help|-h) usage; exit 0 ;;
|
|
*)
|
|
echo "[FAIL] Unknown argument: $arg" >&2
|
|
usage
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
run_remote() {
|
|
local forward=()
|
|
for arg in "$@"; do
|
|
[ "$arg" = "--local" ] && continue
|
|
forward+=("$arg")
|
|
done
|
|
if ! command -v scp >/dev/null 2>&1 || ! command -v ssh >/dev/null 2>&1; then
|
|
echo "[FAIL] ssh/scp not available for remote prep" >&2
|
|
exit 1
|
|
fi
|
|
scp -i "$PIKIT_SSH_KEY" $PIKIT_SSH_OPTS "$SCRIPT_PATH" "${PIKIT_USER}@${PIKIT_HOST}:${PIKIT_REMOTE_TMP}"
|
|
ssh -i "$PIKIT_SSH_KEY" $PIKIT_SSH_OPTS "${PIKIT_USER}@${PIKIT_HOST}" \
|
|
"sudo PIKIT_SELF_DELETE=1 bash ${PIKIT_REMOTE_TMP} --local ${forward[*]}; rc=\$?; rm -f ${PIKIT_REMOTE_TMP}; exit \$rc"
|
|
exit $?
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
clean_home_dir() {
|
|
local dir="$1"
|
|
shift
|
|
local keep=("$@")
|
|
if [ -d "$dir" ]; then
|
|
shopt -s dotglob nullglob
|
|
for entry in "$dir"/*; do
|
|
local base
|
|
base="$(basename "$entry")"
|
|
case "$base" in
|
|
.|..) continue ;;
|
|
esac
|
|
local keep_it=0
|
|
for k in "${keep[@]}"; do
|
|
if [ "$base" = "$k" ]; then
|
|
keep_it=1
|
|
break
|
|
fi
|
|
done
|
|
if [ "$keep_it" -eq 0 ]; then
|
|
rm -rf "$entry" && status CLEANED "$dir/$base" || status FAIL "$dir/$base"
|
|
fi
|
|
done
|
|
shopt -u dotglob nullglob
|
|
else
|
|
status SKIP "$dir (missing)"
|
|
fi
|
|
}
|
|
|
|
prep_image() {
|
|
section "Prep"
|
|
|
|
# --- Identity ---
|
|
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"
|
|
|
|
# --- Default login ---
|
|
if id -u dietpi >/dev/null 2>&1; then
|
|
echo "dietpi:pikit" | chpasswd && status CLEANED "reset dietpi password" || status FAIL "reset dietpi password"
|
|
mkdir -p /var/lib/pikit
|
|
rm -f /var/lib/pikit/first-login.notice
|
|
case "${PIKIT_FORCE_PASSWORD_CHANGE,,}" in
|
|
1|true|yes|on)
|
|
chage -d 0 dietpi && status CLEANED "force dietpi password change on next login" || status FAIL "force dietpi password change"
|
|
:> /var/lib/pikit/first-login.notice && chmod 644 /var/lib/pikit/first-login.notice \
|
|
&& status CLEANED "first-login notice armed" || status FAIL "first-login notice"
|
|
;;
|
|
*) ;;
|
|
esac
|
|
else
|
|
status SKIP "dietpi user missing"
|
|
fi
|
|
|
|
# --- 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"
|
|
|
|
# --- Home directories ---
|
|
clean_home_dir /home/dietpi .bashrc .bash_logout .profile .ssh RESCUE.md
|
|
clean_home_dir /root .bashrc .bash_logout .profile .ssh RESCUE.md
|
|
|
|
# --- Ready flag ---
|
|
clean_file /var/run/pikit-ready
|
|
|
|
# --- First-boot state + TLS ---
|
|
clean_dir_files /var/lib/pikit/firstboot "*"
|
|
clean_file /var/lib/pikit/firstboot/firstboot.done
|
|
clean_file /var/lib/pikit/firstboot/state.json
|
|
clean_file /var/lib/pikit/firstboot/firstboot.log
|
|
clean_file /var/lib/pikit/firstboot/firstboot.error
|
|
clean_file /var/lib/pikit/firstboot/firstboot.lock
|
|
clean_file /etc/pikit/certs/pikit-ca.crt
|
|
clean_file /etc/pikit/certs/pikit-ca.key
|
|
clean_file /etc/pikit/certs/pikit-ca.srl
|
|
clean_file /etc/pikit/certs/pikit.local.crt
|
|
clean_file /etc/pikit/certs/pikit.local.key
|
|
clean_file /etc/pikit/certs/pikit.local.csr
|
|
clean_file /var/www/pikit-web/assets/pikit-ca.crt
|
|
clean_file /var/www/pikit-web/assets/pikit-ca.sha256
|
|
clean_file /var/lib/pikit-update/state.json
|
|
clean_file /var/run/pikit-update.lock
|
|
|
|
# --- 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 "*"
|
|
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
|
|
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
|
|
|
|
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
|
|
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 '*'
|
|
|
|
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 '*'
|
|
|
|
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
|
|
|
|
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
|
|
|
|
# --- DietPi RAMlog store (preserve log dir structure) ---
|
|
if [ -d /var/log ]; then
|
|
local log_group="adm"
|
|
if ! getent group "$log_group" >/dev/null 2>&1; then
|
|
log_group="root"
|
|
fi
|
|
install -d -m 0755 -o root -g "$log_group" /var/log/nginx \
|
|
&& status CLEANED "/var/log/nginx (ensured)" \
|
|
|| status FAIL "/var/log/nginx"
|
|
else
|
|
status SKIP "/var/log (missing)"
|
|
fi
|
|
if [ -x /boot/dietpi/func/dietpi-ramlog ]; then
|
|
/boot/dietpi/func/dietpi-ramlog 1 >/dev/null 2>&1 \
|
|
&& status CLEANED "DietPi RAMlog store" \
|
|
|| status FAIL "DietPi RAMlog store"
|
|
else
|
|
status SKIP "DietPi RAMlog (missing)"
|
|
fi
|
|
|
|
# --- 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"
|
|
}
|
|
|
|
check_home_dir() {
|
|
local dir="$1"
|
|
shift
|
|
local keep=("$@")
|
|
if [ -d "$dir" ]; then
|
|
local extra=()
|
|
shopt -s dotglob nullglob
|
|
for entry in "$dir"/*; do
|
|
local base
|
|
base="$(basename "$entry")"
|
|
case "$base" in
|
|
.|..) continue ;;
|
|
esac
|
|
local keep_it=0
|
|
for k in "${keep[@]}"; do
|
|
if [ "$base" = "$k" ]; then
|
|
keep_it=1
|
|
break
|
|
fi
|
|
done
|
|
if [ "$keep_it" -eq 0 ]; then
|
|
extra+=("$base")
|
|
fi
|
|
done
|
|
shopt -u dotglob nullglob
|
|
if [ "${#extra[@]}" -gt 0 ]; then
|
|
status WARN "extra files in $dir: ${extra[*]}"
|
|
else
|
|
status OK "home clean: $dir"
|
|
fi
|
|
else
|
|
status FAIL "missing home dir: $dir"
|
|
fi
|
|
}
|
|
|
|
check_file_missing() {
|
|
local path="$1"
|
|
if [ -e "$path" ]; then
|
|
status FAIL "unexpected file exists: $path"
|
|
else
|
|
status OK "missing as expected: $path"
|
|
fi
|
|
}
|
|
|
|
check_file_empty_or_missing() {
|
|
local path="$1"
|
|
if [ -e "$path" ]; then
|
|
if [ -s "$path" ]; then
|
|
status FAIL "file not empty: $path"
|
|
else
|
|
status OK "empty file: $path"
|
|
fi
|
|
else
|
|
status OK "missing (ok): $path"
|
|
fi
|
|
}
|
|
|
|
check_image() {
|
|
section "Check"
|
|
|
|
section "Identity files"
|
|
if [ -e /etc/machine-id ]; then
|
|
if [ -s /etc/machine-id ]; then
|
|
status FAIL "/etc/machine-id not empty"
|
|
else
|
|
status OK "/etc/machine-id empty"
|
|
fi
|
|
else
|
|
status FAIL "/etc/machine-id missing"
|
|
fi
|
|
if [ -L /var/lib/dbus/machine-id ]; then
|
|
status OK "/var/lib/dbus/machine-id symlink present"
|
|
else
|
|
status WARN "dbus machine-id missing or not a symlink"
|
|
fi
|
|
check_file_missing /var/lib/systemd/random-seed
|
|
|
|
section "SSH host keys"
|
|
if ls /etc/ssh/ssh_host_* >/dev/null 2>&1; then
|
|
status FAIL "SSH host keys still present"
|
|
else
|
|
status OK "no SSH host keys"
|
|
fi
|
|
|
|
section "SSH client traces"
|
|
check_file_empty_or_missing /root/.ssh/known_hosts
|
|
check_file_empty_or_missing /home/dietpi/.ssh/known_hosts
|
|
check_file_empty_or_missing /home/dietpi/.ssh/authorized_keys
|
|
check_file_empty_or_missing /root/.ssh/authorized_keys
|
|
|
|
section "Home directories"
|
|
check_home_dir /home/dietpi .bashrc .bash_logout .profile .ssh RESCUE.md
|
|
check_home_dir /root .bashrc .bash_logout .profile .ssh RESCUE.md
|
|
|
|
section "Ready flag"
|
|
check_file_missing /var/run/pikit-ready
|
|
|
|
section "Firstboot state"
|
|
if [ -d /var/lib/pikit/firstboot ]; then
|
|
local count
|
|
count="$(find /var/lib/pikit/firstboot -type f 2>/dev/null | wc -l | tr -d ' ')"
|
|
if [ "$count" -gt 0 ]; then
|
|
status WARN "firstboot files still present: $count"
|
|
else
|
|
status OK "firstboot dir empty"
|
|
fi
|
|
else
|
|
status OK "firstboot dir missing (ok)"
|
|
fi
|
|
|
|
section "TLS certs"
|
|
check_file_missing /etc/pikit/certs/pikit-ca.crt
|
|
check_file_missing /etc/pikit/certs/pikit-ca.key
|
|
check_file_missing /etc/pikit/certs/pikit.local.crt
|
|
check_file_missing /etc/pikit/certs/pikit.local.key
|
|
check_file_missing /var/www/pikit-web/assets/pikit-ca.crt
|
|
check_file_missing /var/www/pikit-web/assets/pikit-ca.sha256
|
|
check_file_missing /var/lib/pikit-update/state.json
|
|
check_file_missing /var/run/pikit-update.lock
|
|
|
|
section "Logs"
|
|
if [ -d /var/log ]; then
|
|
local nonempty
|
|
nonempty="$(find /var/log -type f -size +0c 2>/dev/null | wc -l | tr -d ' ')"
|
|
if [ "$nonempty" -gt 0 ]; then
|
|
status WARN "/var/log has non-empty files: $nonempty"
|
|
else
|
|
status OK "/var/log empty"
|
|
fi
|
|
else
|
|
status WARN "/var/log missing"
|
|
fi
|
|
if [ -d /var/log/nginx ]; then
|
|
local nginx_nonempty
|
|
nginx_nonempty="$(find /var/log/nginx -type f -size +0c 2>/dev/null | wc -l | tr -d ' ')"
|
|
if [ "$nginx_nonempty" -gt 0 ]; then
|
|
status WARN "/var/log/nginx has non-empty files: $nginx_nonempty"
|
|
else
|
|
status OK "/var/log/nginx empty"
|
|
fi
|
|
else
|
|
status WARN "/var/log/nginx missing"
|
|
fi
|
|
|
|
section "DietPi RAM logs"
|
|
if [ -d /var/tmp/dietpi/logs/dietpi-ramlog_store ]; then
|
|
status OK "DietPi RAMlog store present"
|
|
else
|
|
status FAIL "DietPi RAMlog store missing"
|
|
fi
|
|
|
|
section "Caches"
|
|
du -sh /var/cache/apt /var/lib/apt/lists /var/cache/debconf 2>/dev/null || true
|
|
|
|
section "Temp dirs"
|
|
local tmp_extra
|
|
tmp_extra="$(find /tmp /var/tmp -maxdepth 1 -mindepth 1 ! -name 'systemd-private-*' ! -path '/var/tmp/dietpi' 2>/dev/null | wc -l | tr -d ' ')"
|
|
if [ "$tmp_extra" -gt 0 ]; then
|
|
status WARN "temp dirs not empty"
|
|
else
|
|
status OK "temp dirs empty"
|
|
fi
|
|
|
|
section "DHCP lease"
|
|
check_file_missing /var/lib/dhcp/dhclient.eth0.leases
|
|
|
|
section "Nginx cache dirs"
|
|
if [ -d /var/lib/nginx ]; then
|
|
local nginx_cache
|
|
nginx_cache="$(find /var/lib/nginx -mindepth 1 -maxdepth 1 -type d 2>/dev/null | wc -l | tr -d ' ')"
|
|
if [ "$nginx_cache" -gt 0 ]; then
|
|
status WARN "nginx cache dirs present: $nginx_cache"
|
|
else
|
|
status OK "/var/lib/nginx empty"
|
|
fi
|
|
else
|
|
status OK "/var/lib/nginx missing (ok)"
|
|
fi
|
|
}
|
|
|
|
finalize() {
|
|
section "Summary"
|
|
status OK "warnings: $WARNINGS"
|
|
status OK "errors: $ERRORS"
|
|
if [ "$ERRORS" -gt 0 ]; then
|
|
echo "[FAIL] Prep/check completed with errors."
|
|
exit 1
|
|
fi
|
|
echo "[OK] Prep/check completed."
|
|
}
|
|
|
|
maybe_self_delete() {
|
|
if [ "$PIKIT_SELF_DELETE" -eq 1 ] && [[ "$SCRIPT_PATH" == /tmp/* ]]; then
|
|
rm -f "$SCRIPT_PATH" || true
|
|
fi
|
|
}
|
|
|
|
main() {
|
|
parse_args "$@"
|
|
|
|
if [ "$LOCAL_ONLY" -eq 0 ] && ! is_dietpi; then
|
|
run_remote "$@"
|
|
fi
|
|
|
|
require_root
|
|
|
|
case "$MODE" in
|
|
prep) prep_image ;;
|
|
check) check_image ;;
|
|
both)
|
|
prep_image
|
|
check_image
|
|
;;
|
|
esac
|
|
|
|
finalize
|
|
maybe_self_delete
|
|
}
|
|
|
|
main "$@"
|