Commit Graph

293 Commits

Author SHA1 Message Date
admin 563cf07ec8 feat(deploy): async compose-up for instant UI feedback (v0.28.2)
Deploy API now returns immediately after validation + config save.
docker compose up -d runs in a background goroutine so the UI shows
progress during image pulls instead of blocking for 30-60s.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 12:08:08 +01:00
admin 4a6ab4d61c feat(debug): add Telemetria teszt section to debug page (v0.28.1)
- New GET /api/debug/telemetry endpoint runs full telemetry pipeline on-demand
- GetTelemetryPreview callback added to DebugCallbacks, wired in main.go
- BuildAppTelemetryForDebug() exported wrapper in report/telemetry.go
- Debug page: new collapsible section with per-app table (memory, CPU, log errors/warnings, issues) and raw JSON viewer
- Available regardless of hub configuration

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-23 11:09:06 +01:00
admin 6d9937bdc1 Add Telemetry Debug Section to Controller Debug Page 2026-02-23 11:04:34 +01:00
admin 05ecd65412 feat(telemetry): add per-app metrics and log telemetry to hub reports (v0.28.0)
- New internal/metrics/telemetry.go: MetricsStore.GetContainerTelemetry()
  aggregates container memory/CPU from SQLite over the last 15 min
- New internal/metrics/logscanner.go: ScanContainerLogs() scans docker logs
  for errors/warnings, deduplicates via fingerprinting (strips timestamps,
  replaces 6+ digit numbers, hex strings, UUIDs)
- New internal/report/telemetry.go: buildAppTelemetrySection() assembles
  per-stack AppTelemetry by aggregating container metrics and log summaries
- internal/report/types.go: added AppTelemetry field to Report struct plus
  AppTelemetry type with memory/CPU/log fields and LogIssue references
- internal/report/builder.go: calls buildAppTelemetrySection() in BuildReport()
- Backward-compatible: old Hub versions silently ignore app_telemetry field

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-23 10:46:27 +01:00
admin 981c473d57 TASK: App Telemetry & Analytics 2026-02-23 10:31:19 +01:00
admin ac5e3cb14e fix(monitoring): read used_mem_mb from nested system object in API response
The /api/system/info response wraps SystemInfo under data.system,
not directly under data.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 10:13:08 +01:00
admin ad4c005e01 v0.27.3: Use real system memory everywhere, add monitoring memory bar
Deploy page, pre-start check, and deploy validation now use actual
/proc/meminfo usage instead of declared mem_request sums. New
GetMemoryMB() helper for lightweight real-time memory reads. Monitoring
page gains a stacked memory distribution bar showing per-container
usage, OS overhead, and free memory.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 10:06:03 +01:00
admin c33247abc1 docs: update README for v0.27.2 architectural changes
- Memory validation: stopped apps excluded from CommittedMemory()
- Pre-start memory check (409 Conflict) on stack start
- hungarian_ui metadata field in resources
- USB badge on storage cards
- Manual Tier2 triggers now push infra backup to Hub
- showAlert() replaces native alert() for copyable error text

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 09:40:21 +01:00
admin e99067ca60 v0.27.2 — copyable error popups, Tier2 hub reporting, memory bar fixes, new labels
- Replace native alert() with custom showAlert() modal (text selectable)
- Manual Tier2 backup now pushes infra backup to Hub
- CommittedMemory() excludes stopped/exited apps
- Pre-start memory check blocks start if insufficient RAM
- Add hungarian_ui metadata field + "Magyar felület" badge
- Add "USB" badge on storage cards in settings page

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 09:28:29 +01:00
admin b8ab9264f4 fix: SyncFileBrowserMounts reads domain from controller config instead of missing .env
The filebrowser stack has no .env file — domain is baked into compose labels
by docker-setup.sh. The sync always bailed with a WARN and storage paths
were never applied to FileBrowser's config.yaml or docker-compose.yml.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 18:01:43 +01:00
admin 64072f1936 style: subdomain suffix as plain text instead of bordered box
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 15:48:44 +01:00
admin 002c388f9f fix(deploy): polish subdomain field UI
- Remove "Automatikusan generálva" badge from domain field (it's not
  generated, it's the customer's configured domain)
- Shrink subdomain input width (8rem) so the .domain suffix appears
  directly next to it on the same line
- Suppress redundant "Az alkalmazás aldomainje" description hint for
  subdomain fields (the warning hint is sufficient)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 15:21:01 +01:00
admin 66817709ad v0.27.0 — user-configurable app subdomains
Users can now customize the subdomain for each app during deployment
instead of using a fixed value. The deploy page shows an editable text
input with the default pre-filled and the base domain as a suffix.

New "subdomain" deploy field type with DNS-safe format validation,
reserved name blocklist, and uniqueness check across deployed stacks.
Locked after deploy — changing requires Remove + Redeploy.

Backward compatible: InjectMissingFields() auto-fills SUBDOMAIN from
.felhom.yml defaults for existing deployed apps on next sync/restart.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 15:06:22 +01:00
admin f7556b0dad v0.26.2 — show full app URL on deploy page
Domain field now displays subdomain.base_domain (e.g. wiki.demo-felhom.eu)
instead of just the base domain, matching the app card display.
Applies to both pre-deploy and post-deploy settings pages.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 13:51:39 +01:00
admin f95f570670 v0.26.1 — show auto-generated values on deploy page
- Pre-generate domain + secret field values when deploy page loads,
  so user sees actual domain and masked passwords (with reveal button)
  before deploying. Same values submitted as hidden inputs → saved to app.yaml.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 13:42:15 +01:00
admin ad3c84d03a fix(felhom-wipe): detect drives via .felhom-infra-backup, clean empty /mnt/ dirs
- detect_storage_paths(): also matches drives that have .felhom-infra-backup/
  so sys_drive-style mounts (internal SSD partitions with DR markers) are
  detected even when settings.json is gone and felhom-data/ doesn't exist.
- do_nuclear_wipe(): rmdir all empty /mnt/*/ dirs at end of nuclear wipe
  to clean up leftover mount point directories (e.g. /mnt/hdd_1 when the
  raw mount was already cleaned by a prior wipe run). rmdir is safe — it
  refuses non-empty directories.
- print_plan(): show per-drive .felhom-infra-backup entries for nuclear level.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 12:10:34 +01:00
admin 5c455755a5 fix(felhom-wipe): remove empty bind mount point dirs after nuclear wipe
After unmounting /mnt/hdd_1 (bind) and /mnt/.felhom-raw/hdd_1 (raw),
the /mnt/hdd_1 directory remained as an empty directory. Now rmdir is
called on each bind target after unmounting so the mount point is fully
cleaned up. rmdir (not rm -rf) ensures we only remove truly empty dirs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 12:06:19 +01:00
admin a2848f6d67 fix(felhom-wipe): nuclear wipe stops early due to set -e + missing state files
[ -f "$f" ] && rm -f "$f" && info "..." returns exit code 1 when the
file doesn't exist, triggering set -euo pipefail. Nuclear wipe was
silently stopping after settings.json and metrics.db (the only two
state files present), never reaching the controller/full/nuclear steps.

Fix: if [ -f "$f" ]; then rm -f "$f" && info "..."; fi

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 12:03:56 +01:00
admin 49b3611f39 scripts: FileBrowser volumes controller-managed, remove drive auto-discovery
- docker-setup.sh install_filebrowser(): removed /mnt/* auto-discovery;
  FileBrowser now installed with no drive volumes. Initial config.yaml
  written with /srv fallback. Controller's SyncFileBrowserMounts() takes
  over on first startup and manages volumes/config going forward.
- Added ./config.yaml bind mount to initial docker-compose.yml so
  FileBrowser starts correctly before controller syncs.
- Fixed ((step_num++)) → step_num=$(( step_num + 1 )) to prevent
  set -euo pipefail trap when var starts at 0 (same class of bug as
  the found_mounts fix in the previous commit).
- scripts/README.md: step 7 updated to reflect controller-managed volumes.
- CHANGELOG.md: added entry for all scripts changes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 11:53:46 +01:00
admin 8f340c211b fix(docker-setup): avoid set -e trap in FileBrowser mount discovery
((found_mounts++)) with found_mounts=0 evaluates the post-increment
expression to 0, which bash treats as exit code 1 under set -e,
silently killing the script on the first mount discovered.

Use arithmetic assignment instead to avoid the zero-exit trap.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 11:32:24 +01:00
admin 45cf527050 fix(docker-setup): yaml_get handles 4-space YAML indentation
Hub YAML is generated by Go's yaml.v3 which uses 4-space indentation.
The yaml_get helper was matching "  key:" (2 spaces) so all extractions
silently returned empty — BASE_DOMAIN stayed as homeserver.local and
CF_TUNNEL_TOKEN was never set from hub config.

Strip leading whitespace before key matching, making yaml_get
indentation-agnostic.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 11:27:44 +01:00
admin c085de45dd updated scripts 2026-02-22 11:18:38 +01:00
admin 1fb2ff0516 docker-setup.sh fixed for hub config 2026-02-22 10:43:45 +01:00
admin ed3970b5fd fix(felhom-wipe): nuclear level now removes infra config directories
After docker system prune, the nuclear wipe now also removes:
- /opt/docker/felhom-controller/ (compose + .env)
- /opt/docker/traefik/ (configs + acme.json)
- /opt/docker/cloudflared/ (configs)
- /opt/docker/stacks/ (empty dir)

These were left behind previously, preventing a clean redeploy since
docker-setup.sh checks for existing installations and skips steps
if directories already exist.

Also updated print_plan to show these deletions in the dry-run output.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 10:35:44 +01:00
admin 4a9ed71b7a fix(felhom-wipe): detect sys_drive and other backups-only storage paths
Two bugs prevented /mnt/sys_drive (and similar drives) from being detected:

1. controller.yaml is root-owned (permission denied from host), so data_dir
   could not be read. Settings.json was never loaded, falling back to /mnt/*
   scan only. Fix: also try `docker volume inspect felhom-controller_controller-data`
   to locate the actual settings.json in the Docker volume.

2. Fallback /mnt/* scan only checked for felhom-data/ or appdata/, missing
   drives that only have backups/ (e.g. sys_drive pre-v0.26.0). Fix: also
   check for backups/ in the scan condition.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 10:31:12 +01:00
admin a5f8c7a76c docs: clarify felhom-wipe.sh full level preserves infra containers
'full' was ambiguously described as 'Controller + felhom-data/' making
it sound like the controller container is removed. Clarified that 'full'
runs controller-level cleanup (app containers only) and infra containers
(felhom-controller, traefik, etc.) are preserved throughout.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 10:25:19 +01:00
admin 7abd1c5954 v0.26.0: Storage namespace felhom-data/ + test node wipe script
All felhom-managed data on external drives now lives under felhom-data/
subdirectory, cleanly separating controller data from user files.

- backup/paths.go: add FelhomDataDir constant, update 8 path helpers
- stacks/delete.go: add local felhomDataDir constant (circular import
  boundary), update ProtectedHDDPaths + GetStackBackupData
- storage/migrate_drive.go: import backup pkg, fix conflict check, verify,
  rsync excludes (felhom-data/backups/*/restic/), size estimation
- storage/migrate.go: import backup pkg, fix DB dump paths
- web/handlers.go: fix legacy 'storage' path -> backup.AppDataDir()
- storage/format_linux.go: create felhom-data/ instead of storage/
- storage/attach_linux.go: create felhom-data/ instead of storage/
- scripts/felhom-wipe.sh: new multi-level test node wipe script
  (soft/controller/full/nuclear)
- CHANGELOG.md, controller/README.md, scripts/README.md: updated docs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 10:10:51 +01:00
admin e238474b33 Storage Namespace (felhom-data/) + Test Node Wipe Script (v0.26.0) 2026-02-22 09:58:57 +01:00
admin 7f48786312 v0.25.0 — Debug page: operator testing & diagnostics dashboard
Debug-mode-only dashboard (/debug) with 8 collapsible sections:
system diagnostics, notification testing, backup triggers, storage
simulation, hub & connectivity, self-update dry-run, DR/setup wizard,
and in-memory log viewer. Migrates debug dump from API router to web
server. Adds ring buffer log capture, storage disconnect simulation,
event history tracking, and cross-drive/self-update test methods.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 20:18:57 +01:00
admin be7803c0ac v0.24.0 — Pre-testing observability: debug logging, diagnostic dump, startup self-test
- Add [DEBUG] logging across all modules (backup, storage, sync, selfupdate,
  monitor, notify, report, assets, setup) gated behind logging.level: "debug"
- Add /api/debug/dump endpoint returning full controller state JSON (debug only)
- Add startup self-test validating 9 subsystems (Docker, dirs, storage, hub,
  restic repos, metrics DB) with pass/warn/fail summary
- New packages: internal/selftest, internal/util
- Constructor/signature changes: debug bool params, logger params on
  RunHealthCheck and BuildReport, smart watchdog probe logging

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 18:32:26 +01:00
admin 6f02536243 updated version in readme 2026-02-21 17:16:26 +01:00
admin fc97199fe2 restore.html fix 2026-02-21 17:05:04 +01:00
admin 51617f55d0 Fix build: rename _ to r in handler signatures for executeTemplate
dashboardHandler, stacksHandler, monitoringHandler used blank identifier
for the request param but now call executeTemplate(w, r, ...).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-21 16:40:40 +01:00
admin 02650e3202 v0.23.0 — CSRF protection on all browser-facing POST endpoints
Controller:
- internal/web/csrf.go (new): CsrfProtect middleware, csrfToken/csrfField helpers
- auth.go: per-session CSRF token (csrfToken field, csrfTokenForSession method)
- server.go: executeTemplate wrapper auto-injects CSRFField+CSRFToken
- main.go: wire CsrfProtect on all routes; bump to v0.23.0
- handlers.go, storage_handlers.go, handler_restore.go: executeTemplate
- All templates: CSRFField in forms, meta csrf-token, csrfHeaders() JS helper,
  fetch calls updated; sendBeacon→fetch+keepalive in storage_attach.html

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-21 16:38:56 +01:00
admin ade01470d0 cleared task.md 2026-02-21 16:05:59 +01:00
admin aa167b43f5 updated readme 2026-02-21 15:45:40 +01:00
admin 538d367cc4 feat(controller): Hub asset syncer for logos and screenshots
Add internal/assets package that downloads and caches app assets from
Hub API with SHA-256 change detection. Assets resolve from synced cache
first, falling back to baked-in directory. Daily sync schedule +
on-demand POST /api/assets/sync endpoint.

Config: assets.sync_enabled + assets.sync_schedule (default 05:00)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 15:29:23 +01:00
admin a5fec20d31 fix: setup wizard logo not loading
The logo handler tried os.ReadFile() on a non-existent filesystem path.
The SVG only exists as an embedded string constant in the web package.
Export FelhomLogoSVG and serve it directly in the setup handler.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 15:08:45 +01:00
admin 296fdbfdcb v0.22.1: Fix setup wizard bugs (detection, CSRF panic, version display, IP)
- NeedsSetup: only check for empty customer.id (not "demo-felhom")
- renderError: pass *http.Request to ensureCSRFToken (was nil → panic)
- Welcome template: remove redundant "v" prefix from version display
- IP detection: read HOST_IP env var for Docker container awareness
- docker-setup.sh: inject HOST_IP into generated docker-compose.yml
- Add logging for Hub config download in setup wizard

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 13:30:32 +01:00
admin 6eb75204b6 v0.22.0: First-run setup wizard, local infra backup, hub verification
New controller features:
- Web-based setup wizard replaces docker-setup.sh interactive config
  - Dual listener: :8080 (Traefik) + :8081 (direct HTTP for LAN)
  - Drive scanner finds .felhom-infra-backup/ on all block devices
  - Hub recovery pull (GET /api/v1/recovery/{id}) with retrieval password
  - Fresh install: Hub config download or manual wizard
  - CSRF protection, state persistence, Hungarian UI
- Local infra backup written to all connected drives after each backup cycle
  - .felhom-infra-backup/backup.json + metadata.json with SHA256 checksum
- Hub verification: parse customer_blocked from report push response
  - Limited mode after 7 days without verification
- Recovery info page on Settings + recovery-info.txt file generation
- Pending events queue: DR events sent to Hub on next report push
- docker-setup.sh v6.0.0: removed interactive wizard, minimal controller.yaml only

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 12:33:17 +01:00
admin e217c3a445 v0.21.3: Push infra backup after config apply, fix double-v in events
After successful config apply, immediately push infra backup to Hub
so the config sync status updates right away. Also fix startup event
message that showed "vv0.21.2" instead of "v0.21.3".

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 20:26:17 +01:00
admin 7953f657cc v0.21.2: Fix config apply on Docker bind mounts
os.Rename() fails with "device or resource busy" on bind-mounted files.
Fall back to direct os.WriteFile when rename fails.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 20:11:33 +01:00
admin 7d69d96cf3 Remove ping_uuids from example config, update architecture diagram
- Comment out ping_uuids section in controller.yaml.example (deprecated)
- Architecture diagram: remove status.felhom.eu, update to Hub event system
- Mark Healthchecks references as deprecated throughout README

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 19:56:12 +01:00
admin e9dcba2473 v0.21.1: Add GET /api/config endpoint for live config content
New endpoint returns raw controller.yaml content (text/yaml) for Hub
live diff and pull operations. Same auth as other config endpoints.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 19:26:47 +01:00
admin 8aebbb8902 feat: Hub monitoring takeover — event push system + config cleanup (v0.21.0)
Replace external Healthchecks.io with Hub-native event system. Controller
now pushes structured events via POST /api/v1/event with typed detail
structs. Hub handles dead man's switch, notification dispatch, and cooldowns.

Phase 5: PushEvent() core method, 21 event types, expanded notification
settings (11 toggles), Hub connection monitoring on dashboard, alerts.
Phase 6: Deprecation log for ping UUIDs, pinger kept for transition.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 18:53:21 +01:00
admin 55abe401ee docs: update controller README and CHANGELOG for v0.20.0
Add config apply endpoint and config hash in reports to REST API
section, roadmap, and changelog.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 16:18:26 +01:00
admin 85d1f2f673 feat: add config apply endpoint and config hash in reports
- POST /api/config/apply: accepts YAML body from Hub, validates and
  writes controller.yaml atomically (tmp+rename)
- GET /api/config/hash: returns SHA256 hash of current config file
- Report payload now includes config_hash field for Hub comparison
- Config endpoints use same dual auth as self-update (session OR Bearer)
- config.LoadFromBytes() for validation without file I/O
- config.FileHash() helper for SHA256 computation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 16:13:35 +01:00
admin dc5209288b deleted hdd-setup.sh 2026-02-20 14:13:46 +01:00
admin 3c53f068ef docs: add scripts/README.md and scripts/CHANGELOG.md
- scripts/README.md: comprehensive docker-setup.sh documentation (CLI flags,
  installation steps, TLS modes, hub download, wizard, safety features)
- scripts/CHANGELOG.md: version history from v1.0.0 to v5.0.0

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 14:03:42 +01:00
admin ff8b42bfd8 docker-setup.sh: add --hub-customer/--hub-password flags for Hub config download
When both flags are provided, the wizard downloads a pre-configured
controller.yaml from the Hub API, extracts key variables for subsequent
setup steps, and skips the interactive wizard entirely. Falls back to
manual wizard on failure.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 13:36:44 +01:00