feat(docker): container log viewer + Settings controls [M79 step 5]
The user-facing half (rule 27). Per-container log viewer + admin controls, so container logs are something the operator can actually touch. Viewer (plugins/docker): - /container/<host>/<name>/logs full page + /logs/lines HTMX fragment polled every 5s (near-live follow); stream filter (all/stdout/stderr) + case-insensitive text search; newest-first so the latest lines survive the poll's scroll reset; empty/loading states; a "View logs" link from the container detail page. Jinja auto-escapes log content (no markup injection). Settings (Thresholds & Retention tab): - global on/off toggle, comma-separated exclude list, retention days + max MB per container — DB-backed, no restart. The toggle + exclude are enforced authoritatively at ingest (_persist_logs drops disabled/excluded lines), since the push model has no channel to tell an agent to stop. Tests: route-defined smoke; template-parse covers the new templates; integration test for the ingest-time toggle + exclude enforcement. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CAGR73DUowdVFVvYzLXC5C
This commit is contained in:
@@ -35,6 +35,12 @@ def test_disk_prune_view_defined():
|
||||
assert callable(r.disk_prune)
|
||||
|
||||
|
||||
def test_container_log_views_defined():
|
||||
# M79 per-container log viewer + its HTMX-polled line fragment.
|
||||
assert callable(r.container_logs)
|
||||
assert callable(r.container_logs_lines)
|
||||
|
||||
|
||||
def test_prune_extra_vars_mapping():
|
||||
"""The prune buttons drive one playbook via prune_target; only 'images'
|
||||
widens to ALL unused images (docker image prune -a), system stays -f."""
|
||||
|
||||
Reference in New Issue
Block a user