51336e346a
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>
141 lines
3.3 KiB
Bash
Executable File
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
|