Files
coruna-lab/scripts/check-write-perms.sh
T
hashbro 51336e346a Keep Tokenview and Telegram running when log files are not writable.
Daily logs created by root cron were blocking www from appending, which aborted webhook ingest and bot pushes. File channels now use 0664 plus exception-safe stacks, and writes go through SafeLog.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-15 11:40:44 +08:00

141 lines
3.3 KiB
Bash
Executable File

#!/usr/bin/env bash
# Probe whether the PHP-FPM user can create/append files in log and channel dirs.
# Usage (as root on the server):
# ./scripts/check-write-perms.sh
# RUN_USER=www APP_ROOT=/www/wwwroot/coruna-lab ./scripts/check-write-perms.sh
set -u
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
if [ -z "${APP_ROOT:-}" ]; then
APP_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
fi
RUN_USER="${RUN_USER:-www}"
if ! cd "$APP_ROOT"; then
echo "ERROR: cannot cd to APP_ROOT=$APP_ROOT" >&2
exit 2
fi
if ! id "$RUN_USER" >/dev/null 2>&1; then
echo "ERROR: user $RUN_USER does not exist" >&2
exit 2
fi
as_user() {
sudo -u "$RUN_USER" "$@"
}
fail=0
ok=0
miss=0
check_dir() {
local d="$1"
if [ ! -d "$d" ]; then
printf 'MISS %s\n' "$d"
miss=$((miss + 1))
return
fi
if as_user touch "$d/.permcheck" 2>/dev/null && as_user rm -f "$d/.permcheck"; then
printf 'OK create %s\n' "$d"
ok=$((ok + 1))
return
fi
printf 'FAIL create %s (%s)\n' "$d" "$(stat -c 'owner=%U:%G mode=%A' "$d" 2>/dev/null || echo '?')"
fail=$((fail + 1))
}
check_file() {
local f="$1"
[ -e "$f" ] || return
if as_user test -w "$f"; then
printf 'OK append %s\n' "$f"
ok=$((ok + 1))
return
fi
printf 'FAIL append %s (%s)\n' "$f" "$(stat -c 'owner=%U:%G mode=%A' "$f" 2>/dev/null || echo '?')"
fail=$((fail + 1))
}
echo "=== write-perm check ==="
echo "app : $APP_ROOT"
echo "user: $RUN_USER uid=$(id -u "$RUN_USER") gid=$(id -g "$RUN_USER")"
echo
echo "--- log dirs ---"
for d in \
storage/logs \
storage/logs/tokenview \
storage/logs/telegram \
public/log \
public/log/c2 \
public/log/xxbb \
public/log/transfer \
public/log/ds \
storage/framework \
storage/framework/sessions \
storage/framework/cache \
storage/framework/views \
bootstrap/cache
do
check_dir "$d"
done
echo
echo "--- existing log files ---"
found_log=0
while IFS= read -r f; do
found_log=1
check_file "$f"
done < <(find storage/logs public/log -type f \( -name '*.log' -o -name '*.json' \) 2>/dev/null | sort)
if [ "$found_log" -eq 0 ]; then
echo "(none yet)"
fi
echo
echo "--- channel / other write dirs ---"
for d in \
storage/app \
storage/app/channel-builder \
storage/app/channel-builder-new \
storage/app/c2 \
storage/app/c2/inbox \
storage/app/c2/photos \
public \
public/channel \
public/details \
public/web \
public/sync \
public/next-chain
do
check_dir "$d"
done
if command -v getfacl >/dev/null 2>&1; then
echo
echo "--- ACL (www / default:www) ---"
for d in \
storage/logs \
storage/logs/tokenview \
storage/logs/telegram \
public/channel \
public/details \
storage/app/channel-builder-new
do
[ -d "$d" ] || continue
getfacl -cp "$d" 2>/dev/null | grep -E '^(# file:|user:www|default:user:www|group:www|default:group:www)' || true
done
fi
echo
echo "RESULT: ok=$ok fail=$fail miss=$miss"
if [ "$fail" -gt 0 ]; then
echo "fix FAILs, e.g.:"
echo " chown -R $RUN_USER:$RUN_USER storage bootstrap/cache public/log public/channel public/details public/web public/sync public/next-chain"
echo " chmod -R ug+rwX storage bootstrap/cache public/log public/channel public/details public/web public/sync public/next-chain"
exit 1
fi
echo "all probed paths are writable by $RUN_USER"
exit 0