Commit Graph

282 Commits

Author SHA1 Message Date
admin c789a00b2d v0.12.5: drive-type-aware cross-drive backup validation
Fix cross-drive backup failing for system-drive destinations. The
/mnt/hdd_placeholder folder is on the internal SSD, so IsMountPoint()
returned false and the old code hard-blocked it.

- ValidateDestination() (crossdrive.go): onSystemDrive flag replaces
  boolean-only check; system drives require ≥10 GB free and <90% usage
  to protect OS stability; external drives just need ≥100 MB free.
- CheckBackupDestination() (mounts_linux.go): Tier 4 now branches on
  h.SystemDrive; system drive blocks at <10 GB free or ≥90% usage
  (matches runner enforcement); external drive unchanged (warn 90%,
  block 95%). Removes the && h.Severity == "ok" guard that was
  preventing system-drive critical messages from overriding warnings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-18 08:14:08 +01:00
admin da576deac5 TASK.md — Cross-Drive Backup Validation Fix (v0.12.5) 2026-02-18 08:10:37 +01:00
admin d160c6c06d v0.12.4 — 15 bug fixes (CRITICAL/HIGH/MEDIUM)
CRITICAL:
- C1: SetAppBackupBulk data loss + nil map panic (settings.go)
- C2: UpdateStackConfig nil Env map panic (deploy.go)
- C3: ValidateDump missing scanner.Err() check (dbdump.go)

HIGH:
- H1: nextDailyRun DST bug — use time.Date(day+1) not Add(24h)
- H2: Cache Europe/Budapest timezone with sync.Once in scheduler
- H3: settings.save() leaks .tmp file on WriteFile failure
- H4: SetNotificationPrefs nil pointer panic
- H5: appDirSize + getDirSizeBytes ignore Sscanf return value
- H6: getDirSizeBytes has no timeout — add 30s context
- H7: dbdump.go tmpFile not using defer Close
- H8: UpdateCrossDriveStatus misleading comment

MEDIUM:
- M1: Replace custom containsBytes with strings.Contains
- M2: scheduler.Every() validates interval > 0
- M3: executeJob panic recovery now sets LastRun
- M4: logPostStartStatus copies env slice before goroutine
- M5: Cache timezone in web package via getTimezone() sync.Once

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-18 07:50:02 +01:00
admin 731cca15a8 aded prompt 2026-02-18 07:44:06 +01:00
admin 9c340433b2 Bug Fix Plan for Sonnet 4.5 (Session 2) 2026-02-18 07:40:40 +01:00
admin 93d9b474f1 v0.12.3 — Security & correctness bug fixes (33 bugs)
CRITICAL: 10 data race and security fixes — backup.go mutex coverage
(C1-C4), IsSystemDisk 12-bit major/minor (C5), /dev/ path validation
(C6), extractName traversal (C7), TargetPath/DestinationPath against
registered paths (C8-C9), ParseComposeHDDMounts Clean-before-prefix (C10).

HIGH: 17 logic/resource fixes — ValidateDump bufio.Scanner (H1), single
appDirSize() with 30s timeout (H2/H3), snapshot ID regex (H4), cross-drive
restic prune (H5), temp file order (H6), dirSizeBytes errors (H7), atomic
fstab (H8), IsDeviceMounted suffix check (H9), eMMC partition mapping (H10),
bytesCopied mutex (H11), separator-aware migrate prefix (H13), DeleteStack
error on compose-down (H14), docker 60s timeout (H16), NotificationPrefs
deep-copy (H17), wipefs warning (H18), fstab rollback on mount fail (H19).

MEDIUM: 7 code quality fixes — formatBytes dedup (M1), .tmp filter order
(M2), sizeBytes string type (M3), elapsed in message (M6), LoadLocation
fallback (M7), pathCovers separator (M10), cancelEditLabel textContent (M11).

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-17 21:10:55 +01:00
admin 20b3a22c88 Bug hunt and TASK.md for Sonnet 2026-02-17 20:46:50 +01:00
admin 62992e0e04 v0.12.2: restore section simplification — snapshot filtering, auto-stop/restart, UI cleanup
- StackDataProvider interface extended with StopStack/StartStack
- backup.Manager.GetStackHDDMounts() delegates to stackProvider
- RestoreApp() auto-stops app before restic restore, restarts after (even on failure)
- stackAdapter in main.go wires StopStack/StartStack through to stacks.Manager
- GET /api/backup/snapshots?stack={name} filters snapshots by app HDD paths via filterSnapshotsByPaths()
- Restore section simplified: no path list, per-app filtered snapshots, human-friendly timestamp format, single calm warning, empty-result inline message

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-17 19:19:23 +01:00
admin fde8e84d82 0.12.2 - Bug 4: Restore Section ("Visszaállítás") Simplification — TASK.md 2026-02-17 19:11:52 +01:00
admin 4961c75408 v0.12.1: fix vv version display, HDD default path, backup status colors, button contrast
- Bug 1: Remove hardcoded 'v' prefix from templates (layout.html, settings.html); version tag already contains 'v'
- Bug 2: primaryHDDPath() and metrics collector now use GetDefaultStoragePath() instead of paths[0].Path so the real HDD is used, not the first (SSD) path
- Bug 3: Apps without HDD data show green/yellow based on volumeLastStatus instead of always gray
- Bug 5: Add default background rgba(255,255,255,0.1) to .btn to fix white-on-transparent readability

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-17 18:54:56 +01:00
admin eb83bd8612 0.12.1 Bug Fixes 2026-02-17 18:48:29 +01:00
admin 1de244646b v0.12.0 — Backup page overhaul: unified app rows, bug fixes, sequential chaining
Bug fixes:
- GetFullStatus() returns deep copy; CrossDriveSummary/UnconfiguredApps/CrossDriveWarnings
  are always nil in the copy so the handler builds them fresh (fixes duplicate-apps bug)
- Replace binary IsMountPoint check with tiered CheckBackupDestination() — path-not-exist,
  not-writable, system-drive (warning), disk >90-95% full; shown as warning vs critical
- Remove dead settingsAppBackupHandler / POST /settings/app-backup route (toggle wrote
  to settings.json but nothing consumed the flag)

Architecture:
- Unified per-app backup rows: new AppBackupRow struct + buildAppBackupRows() replaces
  the two old sections with expandable rows showing all 3 layers per app
- Sequential backup chaining: cross-drive runs immediately after restic (removed
  independent cross-drive-daily/cross-drive-weekly scheduler jobs)
- Deploy page: remove "Csak kézi indítás" schedule option; add weekly consistency note

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-17 17:56:28 +01:00
admin e002d712cf Backup Page Overhaul — Unified App Backup Status & Bug Fixes 2026-02-17 17:47:21 +01:00
admin 2b01e09579 v0.12.0: simplify backup page app data section
Replace the complex "Alkalmazás adatok" form (checkboxes, paths, volumes,
save button) with a clean read-only status list. Each app shows its name
(linked to its deploy page) and a simple status: Aktív / Inaktív / N/A.

Also include ALL deployed stacks in the list (not just HDD-capable ones),
so apps without user data appear with N/A status.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-17 16:35:26 +01:00
admin 6b27753b40 Simplify Backup Page "Alkalmazás adatok" Section 2026-02-17 16:31:36 +01:00
admin a4713c054b v0.11.9 UI Polish Fixes for backup section
- Fix 1: margin-bottom 1rem→1.5rem on .deploy-cross-drive
- Fix 2: info tooltip on "Módszer"; rename restic to "Titkosított mentés"
- Fix 3: replace disabled checkbox with green/gray dot status indicator
- Fix 4: progressive disclosure — dest/method/schedule selects disabled
  until "Engedélyezve" checked; backend preserves config when disabling
- Fix 5: remove all emoji from deploy.html and backups.html backup sections

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-17 16:12:06 +01:00
admin a56448f7c9 v0.11.9 UI Polish Fixes 2026-02-17 16:06:16 +01:00
admin 1a8036d055 v0.11.8 — Per-App Cross-Drive Backup (3-2-1 rule)
New feature: backup app data to a secondary storage drive to satisfy
the "different media" requirement of the 3-2-1 backup rule.

- settings.go: CrossDriveBackup struct, AppBackupPrefs.CrossDrive field,
  getter/setter methods, GetOrCreateCrossDrivePassword, preserves
  cross-drive config when toggling nightly backup

- crossdrive.go (new): CrossDriveRunner with rsync and restic backends.
  Validates destination (mount point, writable), prevents source/dest
  overlap, per-app concurrency lock, persists last_run/status/size.

- main.go: wire CrossDriveRunner, register cross-drive-daily (03:30)
  and cross-drive-weekly (04:30 Sundays) scheduler jobs

- router.go: 4 new API endpoints — save config, trigger run, get status,
  run-all. Router now accepts Settings and CrossDriveRunner.

- server.go: Server struct accepts CrossDriveRunner, new web route
  POST /settings/cross-backup/{name}

- handlers.go: deployHandler populates CrossDriveConfig, BackupDestPaths,
  BackupDestWarning, AppBackupEnabled. settingsCrossBackupHandler saves
  config. backupsHandler builds CrossDriveSummary, UnconfiguredApps,
  CrossDriveWarnings for backup page.

- deploy.html: "Biztonsági mentés" card with destination/method/schedule
  dropdowns, last-run status, manual trigger button, flash messages.

- backups.html: "Másolatok másik meghajtóra" section with per-app
  status rows, unconfigured app warnings, "Összes futtatása most" button.

- style.css: margin-bottom fix for .deploy-stale-data, new cross-drive
  card and list styles.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-17 15:45:31 +01:00
admin d4da3e6ea2 Per-App Cross-Drive Backup — Design & Task Document 2026-02-17 15:31:24 +01:00
admin fba2eb3631 feat: 0.11.7 — Stale data cleanup + FileBrowser sync after migration + deploy title fix
- Detect stale data on non-active storage paths after migration; show on
  deploy/settings page with size info and two-step delete confirmation
- Add POST /api/storage/stale-cleanup handler with safety checks (active
  path protection, registered-path validation, ProtectedHDDPaths guard)
- Export ProtectedHDDPaths() from stacks package for reuse in web handlers
- Sync FileBrowser mounts after successful app data migration
- Deploy page title/h2 now shows "Beállítások" for already-deployed apps
  instead of always showing "Telepítés"
- Also add delete-old-data button on migration-done card in migrate.html

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-17 12:45:08 +01:00
admin 264855fb0d 0.11.7 — Stale Data Cleanup + FileBrowser Sync + UI Title Fix 2026-02-17 12:33:47 +01:00
admin 3d598feb34 docs: update CHANGELOG and CONTEXT for v0.11.6 2026-02-17 12:05:55 +01:00
admin 12eaf5b47e feat(v0.11.6): FileBrowser auto-mount sync + UI polish
- Add syncFileBrowserMounts() and generateFileBrowserCompose() to handlers.go
- Call syncFileBrowserMounts() after storage path add (storage init) and remove
- settings.html: red 'Nincs csatolva!' badge → yellow 'Rendszermeghajtón' (badge-warn)
- settings.html: 'Alapértelmezett' button → 'Legyen alapértelmezett' (action clarity)
- storage_init.html: replace disk-usage zone gradient bar with clean progress-bar-task
- style.css: add .badge-warn and .progress-bar-task CSS classes

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-17 12:04:06 +01:00
admin d42a676522 FileBrowser Auto-Mount on New Storage + UI Polish (3 fixes) 2026-02-17 12:00:27 +01:00
admin f6444945ca docs: update CHANGELOG and CONTEXT for v0.11.4
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-17 11:41:30 +01:00
admin 2064f32199 fix(storage): fix FormatAndMount for container environment
Bug 1 (sfdisk): Add wipefs before sfdisk; change partition type from
,,,L (unsupported GPT shorthand) to ,, (default Linux GUID); add
--force --wipe always flags to handle existing partition tables.

Bug 2 (mount): Replace fstab-lookup mount with explicit device path:
  mount -t ext4 -o defaults,noatime /host-dev/sdb1 /mnt/hdd_1
Container's /etc/fstab is Docker's auto-generated one, not the host's.

Bug 3 (mount propagation): Change /mnt volume to long-form bind with
propagation: rshared so mounts created inside container propagate to
the host. Requires mount --make-rshared /mnt on host before restart.

Safety: Use req.MountName (ASCII) for ext4 -L label (16-byte limit;
UTF-8 display label stays in settings.json). Add findmnt verification
after mount. Improve progress messages with command details.

Smart partition: In storageInitAPIHandler, if disk already has exactly
1 empty partition (no filesystem), skip wipefs+sfdisk and format the
existing partition directly.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-17 11:38:52 +01:00
admin 252058aec0 Bugfix — Storage Initialization (FormatAndMount) 2026-02-17 11:35:52 +01:00
admin 4f3401dc4c docs: update CHANGELOG and CONTEXT for v0.11.3
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-17 11:17:28 +01:00
admin 042486fe14 fix(dockerfile): add fdisk package for sfdisk (partition table writing)
sfdisk is in the fdisk package on Debian bookworm, not util-linux.
util-linux provides lsblk/blkid/mount; fdisk provides sfdisk/fdisk/cfdisk.
Without this, FormatAndMount fails at the partitioning step.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-17 11:15:39 +01:00
admin ba67d6d4e7 BUGFIX: Missing disk tools (sfdisk, mkfs.ext4, etc.) 2026-02-17 11:14:34 +01:00
admin 3fb9a58cec docs: update CHANGELOG and CONTEXT for v0.11.2
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-17 11:04:53 +01:00
admin c9de193a9d fix(storage): use /host-dev for block device access inside container
Docker always creates a fresh tmpfs at /dev, silently dropping any
/dev:/dev bind mount. Block devices must be accessed via /host-dev
where the host /dev is actually mounted.

Changes:
- docker-compose.yml: /dev:/dev → /dev:/host-dev:rw
- safety.go: add HostDevPath constant + HostDevicePath() helper
- format_linux.go: all device ops (stat, sfdisk, partprobe, mkfs.ext4,
  blkid) use HostDevicePath() to resolve /dev/sdb → /host-dev/sdb
- safety_linux.go: IsSystemDisk() stats device via /host-dev
- scan_linux.go: enrichWithBlkid() probes each partition individually
  via /host-dev/sdXN instead of batch blkid -o export (which can't
  find devices when /dev is Docker's minimal tmpfs)

Fixes "stat /dev/sdb: no such file or directory" in FormatAndMount.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-17 10:59:41 +01:00
admin 88776342e8 BUGFIX: /dev/sdb not accessible inside container 2026-02-17 10:56:30 +01:00
admin 39b0202d91 docs: update CHANGELOG and CONTEXT for v0.11.1 storage scan bugfix
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-17 10:44:33 +01:00
admin ec51ea5ac8 fix(storage): detect system disk via host fstab + enrich FSType via blkid
Bug 1: Inside container, lsblk reports container mount points not host's.
Parse /host-fstab (or /etc/fstab fallback) to find system partitions
(/, /boot, /boot/efi, swap), resolve UUIDs via blkid, and mark parent
disks as system — replaces unreliable mount-point string matching.

Bug 2: lsblk returns null fstype in containers (no udev cache). Run
blkid -o export after lsblk scan and enrich partitions with FSType,
UUID, and Label from direct device probing.

Fixes sda appearing as available disk and "nincs fájlrendszer" showing
for all partitions.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-17 10:42:50 +01:00
admin 0b23834e3c BUGFIX: Storage Scan — System Disk Detection & FSType in Container 2026-02-17 10:41:05 +01:00
admin 2fb2c6e1ae v0.11.0 — Phase C: Storage Init Wizard, Data Migration & Startup Fix
- Startup ping: fire heartbeat + health + hub report immediately on boot
  (5s delay after scheduler start, instead of waiting 5-15 min for first tick)

- Storage init wizard: new internal/storage/ package with disk scanning
  (lsblk -J), format+mount pipeline (sfdisk → mkfs.ext4 → blkid → fstab →
  mount → chown), safety guards (system disk detection, confirmation "FORMÁZÁS"),
  progress channel, auto-register in settings.json

- Data migration: MigrateAppData() with rsync --info=progress2 progress parsing,
  stop/rsync/update-config/start flow, rollback on failure, old data preserved

- New pages: /settings/storage/init (wizard), /stacks/{name}/migrate (migration)
- New API routes: /api/storage/{scan,init,init/status,migrate,migrate/status}
- Deploy page: storage info section for deployed apps (path, size, free, migrate link)
- Settings page: "Mozgatás" button per app in storage path details
- Container: privileged: true, /dev:/dev, /etc/fstab:/host-fstab, /run/udev:/run/udev:ro
- Dockerfile: add util-linux, e2fsprogs, rsync, parted for disk ops

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 10:27:18 +01:00
admin e7c27364bf Phase C — Storage Initialization, Data Migration & Startup Fixes 2026-02-17 10:10:35 +01:00
admin 69698a89e8 v0.10.0: Phase B — Storage Management UI Polish & Health Severity Fix
- Health severity fix: mount-point check downgraded from issue (FAIL) to warning (WARN)
- All storage health messages translated to Hungarian
- Success flash messages for all storage operations
- Edit storage path labels (inline edit UI + backend)
- App details per storage path on settings page (expandable list with names + sizes)
- Storage badge on stacks page showing which storage each app uses
- Deploy dropdown with free space display and low-space warning (<20%)
- Filesystem & disk info on settings page (ext4/btrfs, device, model via findmnt)
- Backup page storage context with per-app storage label badges

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 09:48:51 +01:00
admin 61d8451c69 Phase B — Storage Management UI Polish & Health Severity Fix 2026-02-17 09:35:15 +01:00
admin 82ef3b15cf updated .md files 2026-02-17 09:14:15 +01:00
admin aca3b8680a v0.9.0: Storage paths registry, per-app HDD_PATH resolution, storage management UI
- Fix backup toggles not appearing (read each app's own HDD_PATH from app.yaml)
- Storage paths registry in settings.json with auto-discovery from deployed apps
- Settings page "Adattárolók" section with disk usage, add/remove/default/schedulable
- Deploy page path field as dropdown of registered storage paths
- Health check storage monitoring (mount point, disk usage alerts)
- Mount-point validation utilities (Linux syscall + cross-platform stubs)
- Controller docker-compose mount changed to /mnt:/mnt:rw for multi-storage

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 09:04:28 +01:00
admin 465dec443f Phase A — Storage Paths Foundation & Backup Toggle Fix 2026-02-17 08:40:11 +01:00
admin 7d801d1094 Phase 3 complete: per-app backup toggles, restore, storage overview
- Storage overview on backup page (SSD/HDD bars, repo stats)
- Restic password visibility + hub sync for disaster recovery
- App data discovery (HDD bind mounts, Docker volumes)
- Per-app backup toggle checkboxes with settings persistence
- Dynamic backup paths: enabled app HDD data included in restic snapshots
- Limited app restore from snapshots (self-service recovery)
- Snapshots API endpoint for restore dropdown
- Version bump to 0.8.0

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 21:29:56 +01:00
admin a3af7c6a2d Phase 3 — Storage Overview & Per-App Backup Toggles 2026-02-16 21:05:51 +01:00
admin 2649297096 Controller v0.7.2: notification preferences sync to hub
- SyncPreferences() method on Notifier: POST to hub /api/v1/preferences
- IsEnabled() getter for hub connectivity check
- settingsNotificationsHandler: sync to hub after local save (3 flash message variants)
- Startup sync: non-blocking goroutine pushes prefs to hub on boot (DB rebuild recovery)
- Updated CONTEXT.md, README.md with v0.7.2 changes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 20:18:22 +01:00
admin 8f5962c47d Fix Notification Preferences Sync (Controller → Hub) 2026-02-16 20:11:39 +01:00
admin d1032a3a4f Update CONTEXT.md for session 23 — v0.7.1 Phase 2 summary
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 19:34:24 +01:00
admin 3eee330ed5 Phase 2: monitoring warnings, dashboard alerts & notification system
- Monitoring page: "Távoli monitoring" section showing healthcheck ping UUID
  configuration status (configured/not configured) for each of the 5 pings
- Alert manager: persistent dashboard banners on all pages generated from
  health check results, missing pings, and backup status
- Notification system: controller-side notifier sends events to hub relay,
  with cooldown tracking and event-type filtering
- Notification preferences UI: email, event checkboxes, cooldown settings
  on the settings page with test email functionality
- Settings refactored: shared settingsData() helper, NotificationPrefs
  struct with getter/setter and defaults

New files:
- controller/internal/web/alerts.go (AlertManager)
- controller/internal/notify/notifier.go (hub notification client)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 19:29:45 +01:00
admin ded59b687e 0.7.1 - Phase 2 — Monitoring Warnings, Dashboard Alerts & Notification System 2026-02-16 19:09:43 +01:00