docs: add v0.30.3 changelog entry for comprehensive bug hunt fixes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-25 13:48:47 +01:00
parent 45f75a916c
commit 72ab145b41
+64
View File
@@ -1,5 +1,69 @@
## Changelog
### v0.30.3 — Comprehensive Bug Hunt Fixes (2026-02-25)
#### Fixed (Critical — P0)
- **Encrypted env vars** — `UpdateStackConfig` now uses decrypted values when building compose env, preventing `ENC:...` literals in containers (C01)
- **Silent decrypt failures** — `DecryptMap` now logs warnings on decrypt failure instead of silently returning empty values (C02)
- **Deploy race condition** — `Deployed = false` flag now set inside the mutex lock in `runComposeDeploy` (C03)
- **Shared state mutation** — `GetStack`/`GetStacks` now return deep copies preventing callers from mutating cached state (C04)
- **Watchdog races** — Added per-state mutex to `pathProbeState` for thread-safe probe state access (C05)
- **Metrics double-start** — `MetricsCollector.Start()` guarded with `sync.Once` (C06)
- **Raw mount race** — `diskJobMu` now held across entire cleanup+mount+set operation (C07)
- **Encryption key race** — Added mutex to `SetEncryptionKey` (C08)
#### Fixed (High — P1)
- **Restic lock detection** — `Snapshot()` now extracts stderr from `*exec.ExitError` and checks `unlockCmd.Run()` error (H01)
- **Disconnected drives in backup** — `activeDrives()` now skips disconnected/decommissioned drives (H02)
- **Template rendering** — Buffered via `bytes.Buffer` to prevent partial HTML on error (H07)
- **Sync stop panic** — `Stop()` uses `sync.Once` for safe channel close (H08)
- **Sync race** — `syncing = true` set before releasing lock in `TriggerSync` (H09)
- **Cloudflare context** — Threaded `context.Context` through all Cloudflare API calls for cancellation support (H10)
- **Cross-drive collision** — Replaced flawed leaf-name dedup with proper `seen` map (H15)
- **CSRF bypass** — Bearer token now validated against Hub API key before skipping CSRF (H16)
- **Nil pointer** — Added nil check for `crossDriveRunner` in handlers (H17)
- **Selftest panic** — Replaced `out[:len(out)-1]` with `strings.TrimSpace` (H18)
- **Stderr goroutine** — Added `sync.WaitGroup` in `MigrateDrive` (H19)
- **UUID slice** — Guarded `uuid[:8]` with length check (H20)
- **Fstab matching** — Parse fields exactly instead of loose `strings.Contains` (H21)
- **Atomic save** — `SaveAppConfig` writes to `.tmp` then renames (H04)
- **Deploy failure** — `SaveAppConfig` on failure now includes `encKey` (H05)
- **Encryption migration** — Uses write lock instead of read lock (H03)
- **Deep copy** — `GetFullStatus` deep-copies `lastDBDump`/`lastBackup` (H11)
- **IPv6** — TCP health probe uses `net.JoinHostPort` for IPv6 compatibility
- **Backup path validation** — `RemoveStack` validates paths under expected directory (M12)
- **Updater race** — `SetBackupRunningCheck` protected by mutex (M18)
#### Fixed (Medium — P2)
- **Config env overrides** — `LoadFromBytes` now calls `applyEnvOverrides` (M05)
- **Selfupdate state** — Compose-up failure now sets `state.Status = "failed"` (M16)
- **Memory check** — `usableMB` clamped to min 0 (M22)
- **Cross-backup trigger** — Removed invalid "manual" schedule from `triggerAllCrossBackups` (M23)
- **mmcblk support** — Partition path and `stripPartition` now handle mmcblk devices (M21, L25)
- **Scheduler** — `Start()` guarded against double-start, `Stop()` acquires mutex (M14, L24)
- **Pending events** — Events restored on save failure in `DrainPendingEvents` (M03)
- **Duplicate storage** — `AddStoragePath` rejects already-registered paths (M04)
- **Setup scan** — `CleanupTempMounts` called after drive scan (H13)
- **Setup state** — `SetStep` now logs save errors (M25)
#### Fixed (Low — P3)
- **UTF-8 truncation** — `TruncateStr` now operates on runes and handles negative maxLen (L05/L06)
- **AllDone** — Returns false for empty restore plans (L14)
- **PushOnce** — Returns actual errors instead of swallowing them (L39)
- **CSRF token** — Panics on `crypto/rand.Read` failure instead of using static fallback (L40)
- **Logout** — Requires POST method (L32)
- **Server.Close** — Uses `sync.Once` to prevent double-close panic (L49)
- **Log cap** — `lines` query parameter capped at 10000 (L31)
- **Hash function** — Replaced custom `simpleHash` with `crc32.ChecksumIEEE` (L48)
- **hasPrefix** — Replaced custom implementation with `strings.HasPrefix` (L13)
- **DefaultEnabledEvents** — Copied in `GetNotificationPrefs` early return (L09)
- **Variable shadowing** — Renamed `copy` to `cp` in `SetNotificationPrefs` (L07)
#### Removed
- Dead `imageName` function in selfupdate (L02)
- Dead `detectHostIPViaRoute` function in setup (L03)
- Custom `hasPrefix` function in restore_scan (L13)
### v0.30.2 — Report geo-restriction + logo/favicon update (2026-02-25)
#### Added