test/ponytail #14

Merged
elirtf merged 7 commits from test/ponytail into master 2026-06-24 19:37:47 +00:00
Owner
No description provided.
Replace the RECORDING_RECYCLE_HEADROOM_GB env knob with a module
constant (nobody tunes it; the env parse even disagreed with its own
default), and dedupe the policy comment now that _emergency_min_free_gb's
docstring carries the full explanation. No behavior change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The global recordings_dir setting already drives every recording/clip/
retention path, so it doubles as the "store on a NAS" knob. But it was
only checked to start with "/", so pointing it at an unmounted or
read-only NAS path saved fine and then silently dropped all recordings.

Add check_writable_dir() (writes a temp file — the only reliable test for
a stale NAS mount) and enforce it on both first-run setup and the settings
PUT. Surface live writability via setup-status (recordings_dir_writable /
_error) and flag a dropped mount in Configuration > System.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The _emergency_cleanup circular-buffer logic deletes recordings to keep
recording when the disk fills — a data-loss path that had no coverage.
Adds tests for oldest-first recycling to target, no-op when above target,
and delete-everything when the target is unreachable.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Emergency disk-full recycle deleted the globally-oldest footage by age, but
only checks free space on recordings_dir. With per-camera custom storage
(e.g. a NAS), footage on another filesystem was deleted without freeing the
disk that's actually full — churning through everything before reporting
'storage undersized'. Now skip rows whose file is on a different st_dev.

Also replace silent 'except: pass' on per-segment deletes in the tier and
max-storage retention loops with logger.exception, so a wedged delete
(locked file, perms) is visible instead of vanishing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The /api/health/diagnostics handler is documented 'admin-only' but had no
auth decorator, so anyone could read host CPU/RAM/disk/FFmpeg details
unauthenticated. Add @require_admin to match its stated intent; the only
caller (admin config page) already runs authenticated.

Register the health blueprint in the test app and add auth-gate tests
(anon 401, viewer 403, admin 200).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
get_ice_servers() fell back to Google + Cloudflare STUN whenever only the
default 'stun:8555' candidate was set (the common LAN case). The browser then
blocked ICE gathering on STUN round-trips that time out — webrtc-internals
showed ~70 STUN requests with 0 responses — delaying the offer (sent only at
gathering-complete) and the first frame. The working path is host-to-host and
needs no STUN.

Return an empty list when nothing real is configured; a stun:/turn: candidate
is still passed through for remote access across NAT.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
WebRTC candidate validation only accepted stun:/turn: URIs, so you couldn't
set your machine's LAN address in the UI — yet that's exactly what go2rtc
needs to advertise for local WebRTC (the stun: default advertises the public
IP, which a LAN browser can only reach via slow NAT hairpin: ~10-15s to first
frame). Accept go2rtc's static candidate form (host:port / ip:port / port).

This is the same setup Frigate documents. MSE stays the live-view default;
WebRTC is opt-in for those who want sub-second latency and set their LAN IP.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
elirtf merged commit 5acb9cd84e into master 2026-06-24 19:37:47 +00:00
elirtf deleted branch test/ponytail 2026-06-24 19:37:48 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
elirtf/opus!14
No description provided.