Releases: tis24dev/proxsave
v0.16.0
ProxSave v0.16.0
🛡️ Restore integrity enforcement, symlink/path hardening, and bounded IO for safer recovery
This release significantly strengthens restore/decrypt safety and integrity. It hardens decision-making against untrusted metadata, enforces checksum verification before any restore/decrypt proceeds, and closes multiple symlink and path-validation bypasses (including staged apply overlays). It also bounds filesystem and input timeout wrappers to prevent goroutine buildup, improves PBS override handling and output key disambiguation, and delivers major test coverage expansion (including ~99% coverage for network rollback/apply logic).
-
Restore integrity: checksum verification is now mandatory
- Enforced staged backup archive checksum verification before any restore/decrypt begins.
- Added strict SHA256 parsing/normalization and enforced agreement between manifest and sidecar checksum sources.
- Rejected raw backup candidates without a verifiable integrity source.
- Centralized shared prepare-path verification for bundle and raw inputs, preserving both source-artifact checksum and prepared-archive checksum distinctly.
- Validated and normalized raw backup checksums during discovery (local + rclone), rejecting malformed/conflicting checksums up front.
- Bounded checksum sidecar reads (local + rclone) with streaming caps and clear errors for oversized/empty checksum files.
- Rclone checksum probing now uses its own fresh timeout budget (matches documented per-command timeout behavior).
- Surfaced decompressor Close() errors during restore archive inspection (archives are no longer silently accepted if Close fails).
-
Restore planning hardening: trust archive-backed facts, not spoofable metadata
- Derived restore compatibility, cluster gating, and hostname warnings from archive-backed facts instead of candidate manifest metadata.
- Added restore archive analysis of internal backup metadata with category-based fallback paths.
- When analysis fails in UI workflows, now validate compatibility first before falling back to full restore (compat warnings still shown).
-
Symlink + path security: close escape/bypass classes across restore and staged apply
- Replaced restore path safety checks with a shared FS-aware resolver that walks components using Lstat/Readlink:
- Rejects intermediate symlink escapes, loops, and symlinked restore roots.
- Distinguishes security violations from operational failures so in-root permission/ENOTDIR errors surface normally.
- Preserved staged network symlinks by using Lstat (no dereference copy), rejected symlinked staged network directories, and extended FS abstraction with Lstat.
- Validated staged network symlink targets before recreating them:
- Rewrote safe absolute targets into relative links.
- Rejected absolute/relative targets that escape the allowed subtree.
- Applied the same symlink-target validation to firewall/SDN staged sync (syncDirExact), with safe rewrites and escape rejection.
- Fixed overlay symlink rewriting when destination parents are symlinks (rewrite relative to resolved parent, not lexical parent).
- Added post-creation overlay symlink revalidation (read back created link, ensure effective target stays within restore root; remove on failure).
- Safety restore symlink handling now fails on operational validation errors (still warns/skips only for true root-escape targets).
- Replaced restore path safety checks with a shared FS-aware resolver that walks components using Lstat/Readlink:
-
Resource safety and robustness: bounded IO/timeouts and race fixes
- Prevented unbounded goroutine accumulation in timed filesystem wrappers by limiting in-flight safefs operations.
- Normalized safefs deadline handling so deadline expiry maps consistently to TimeoutError/ErrTimeout (while preserving context.Canceled semantics).
- Improved safefs timeout test cleanup to avoid leaks and races (local capture of limiter/hooks, drain blocked workers safely).
- Input package now reuses a single in-flight read per reader/FD, preserves completed results across retries until consumed, and avoids holding the state mutex across blocking waits (with extensive deterministic regression tests).
-
Backup output safety: sanitize path segments to prevent traversal/collisions
- Introduced path-safe keys for PBS datastore names and PVE storage names when building collector output paths.
- Prevented path traversal and filename collisions from raw config values while keeping raw names unchanged in metadata and command invocations.
-
PBS datastore overrides: safer semantics and collision-proof output keys
- Separated override scan roots from real datastore identities with explicit metadata (source, CLI identity, output key).
- Derived stable path-based output keys for
PBS_DATASTORE_PATHoverrides while preserving existing names for real CLI-discovered datastores. - Guaranteed stable unique datastore output keys across CLI + overrides (fixes real collisions, keeps inventory aligned with written files).
- Always applied absolute-path overrides even when proxmox-backup-manager is missing/failing/invalid (except ctx cancellation).
- Rejected relative
PBS_DATASTORE_PATHoverrides (warn + skip). - Improved inventory merge precedence so runtime CLI paths override datastore.cfg for the same identity.
- Kept override-only entries out of datastore.cfg fallback restore for safety; added broad regression coverage (basename collisions, status filename collisions, restore safety).
-
Network and restore UX/test reliability
- Added extensive network_apply tests (rollback arm/disarm, NIC repair CLI overrides/conflicts, snapshot IP parsing, command selection, and error paths), bringing coverage to ~99% with no production behavior changes.
- Improved PVE datastore skip logging:
- Disabled storages logged as SKIP, offline storages as actionable WARNING, and always emit DEBUG skip details with runtime flags and explicit reason.
- Fixed detected-datastores report header and extended runtime flag parsing tests.
-
Compatibility and correctness fixes
- Compatibility parser now recognizes full Proxmox names like “Proxmox VE”, “Proxmox Backup”, and “Proxmox Backup Server” (plus existing acronym/hyphenated forms), with regression tests.
- Trimmed and normalized whitespace-padded manifest EncryptionMode (“ age ” now correctly triggers decryption).
- Validated prepared archive paths against encryption mode and suffix:
- Rejects inconsistent mode/suffix combinations and prevents identical input/output paths by generating unique output names when needed.
-
CI, build, and maintenance
- Updated GitHub Actions (goreleaser-action v7, attest-build-provenance v4).
- Updated go.mod and ensured Makefile coverage targets honor the go.mod toolchain via GOTOOLCHAIN.
- Webhook Discord content fallback was introduced and then reverted (no net behavior change).
Overall: materially safer restores and decrypts (integrity required, spoof-resistant decisions), hardened symlink/path handling across restore and staged apply, bounded IO/input wrappers to prevent resource buildup, and improved PBS override safety and observability with strong regression coverage.
Changelog
v0.15.1
ProxSave v0.15.1
📨 Telegram pairing in the installer, non-interactive upgrade confirmations, and improved privilege-context detection
This release improves first-time setup and automation by adding an optional Telegram pairing step to the installer, enabling non-interactive upgrade confirmations, and expanding privilege-context detection so limited-privilege environments are identified once at startup and reused consistently by collectors.
-
Installer: optional Telegram pairing (CLI + TUI):
- Added an optional Telegram pairing/verification step for centralized bot mode.
- New TUI wizard with retry/skip behavior, identity detection, status feedback, and persistence checks.
- CLI now shows the Server ID and runs an interactive verification loop via
notify.CheckTelegramRegistration. - Added logging hooks to record non-blocking failures and user choices, plus extensive unit tests.
- Updated docs (CONFIGURATION, INSTALL, CLI_REFERENCE) to document the pairing flow and installer log behavior.
-
Upgrades: non-interactive auto-confirm support:
- The
--upgradeflow can now be auto-confirmed by passing a trailingy(example:--upgrade y). - Introduced
Args.UpgradeAutoYesandextractUpgradeAutoYesArgsto preprocessos.Args; parser updated accordingly. - Upgrade now skips the interactive prompt when auto-yes is enabled (with a debug log).
- Added unit tests and updated documentation examples.
- The
-
Privilege context: earlier detection + broader limited-privilege coverage:
- Privilege-context detection now runs once early at startup (right after the Environment log) and emits a single INFO summary (
Privilege context: ...) with full evidence in DEBUG. - The cached result is injected into the orchestrator so collectors reuse it for privilege-sensitive SKIP handling without re-reading
/proc. - Extended detection beyond shifted user namespaces to cover more limited-privilege signals: container markers (systemd container, env markers, docker/podman hints, cgroup hints) and non-root EUID.
- Updated SKIP hint wording and aligned docs/tests with the broader “limited privileges” semantics.
- Privilege-context detection now runs once early at startup (right after the Environment log) and emits a single INFO summary (
Overall: smoother Telegram setup, easier scripted upgrades, and more accurate, consistent behavior in containerized or otherwise constrained environments.
Changelog
v0.15.0
ProxSave v0.15.0
🧪 Installer UX upgrades, optional post install audit, and major testability expansion across restore paths
This release focuses on making installation and upgrades easier to operate while greatly expanding unit test coverage for critical restore workflows. It adds a guided post install audit that can disable unused collectors, improves the TUI wizard when editing existing configs, removes obsolete legacy compatibility layers, and introduces extensive dependency injection hooks so mount guards, firewall, access control, NIC mapping, and PBS staged apply can be tested thoroughly without touching the real system.
-
Installer and wizard improvements
- TUI install wizard can now prefill fields from an existing env template when editing, with tighter validation and preserved delivery preferences for Telegram and Email
- Clearer behavior when a config file already exists, with refined prompts and updated docs for both CLI and TUI flows
- Documentation updates to clarify prompts, cloud guidance, and installer flow details
-
Optional post install audit using dry run
- Added an optional post install audit that runs a proxsave dry run to detect unused BACKUP collectors and offers to disable them
- CLI flow supports per key decisions and writes changes atomically only after explicit confirmation
- TUI flow provides an interactive review UI, with improved logging, result summaries, and error surfacing
- Installer session logs are documented, including where to find them under /tmp
-
Removal of obsolete legacy compatibility
- Removed the ENABLE_GO_BACKUP flag and related dead code and wrappers
- Removed the prefilter manual command and cleaned up associated docs and tests
- Consolidated bundle creation by routing callers to Orchestrator.createBundle and simplified legacy identity and orchestrator helpers
-
Major restore testability and coverage expansion
- Mount guards are now mockable via injectable function variables, enabling extensive unit tests for guard creation, mount detection, bind and remount behavior, unmount flows, fstab fallbacks, and timeout handling
- PBS API apply root privilege checks are now injectable to enable full test coverage of service checks, error paths, and API apply behavior
- Firewall restore flow is now fully mockable with broad new tests covering rollback arming and disarming, markers, prompts, file operations, fallbacks, and error branches
- Access control apply and rollback flows are now mockable, with comprehensive tests for scripts, mounting checks, prompt timeouts, commit and abort paths, and failure handling
- NIC mapping logic now supports a configurable sys class net path for tests, with a large new test suite covering inventory parsing, mapping computation, and repair planning and apply
- PBS staged apply adds hookable functions for all key operations, with two new comprehensive test suites covering parsing, validation, fallbacks, deferral logic, atomic write errors, job and tape apply paths, permission checks, and edge cases
-
Dependencies
- Bumped filippo.io/edwards25519 from 1.1.0 to 1.1.1
Behavior changes to note
- ENABLE_GO_BACKUP support has been removed along with its legacy wrappers
- The prefilter manual command has been removed
Overall: a much smoother install experience, an optional guided audit to keep configs lean, and significantly stronger regression protection for the riskiest restore paths through deep testability improvements.
Changelog
v0.14.1
ProxSave v0.14.1
🧷 Rootless-friendly collection: privilege-sensitive failures become SKIPs (with clearer hints)
- Rootless/LXC detection + safer reporting: Detect unprivileged/shifted user-namespace environments (rootless, LXC) and downgrade known privilege-sensitive command failures to non-critical SKIP instead of warnings.
- Targeted command handling: Collector now treats failures from
dmidecode,blkid,sensors, andsmartctlas SKIPs when matching expected permission patterns, reducing false-positive noise in constrained environments. - Better diagnostics and testability: Added environment detection via
/proc/self/{uid_map,gid_map}and/run/systemd/container, plus a deps hook for overrides; expanded unit tests for detection and failure matching. - Clearer operator guidance: Logging now includes SKIP lines with concise hints (e.g. “fstab remap may be limited”), and docs were updated to explain the behavior and restore implications.
- Message cleanup: Standardized and shortened blkid/unprivileged skip wording, centralized the reason text, simplified Skip logging, and updated tests/docs accordingly.
Overall: cleaner logs and more predictable behavior when running ProxSave in rootless or user-namespace environments, without masking genuinely actionable issues.
Changelog
v0.14.0
ProxSave v0.14.0
🧭 PBS API-first restores, chunked artifacts, safer staging, and bounded IO across backups/restores
This release is a major step forward in restore safety, scalability, and operator control. It introduces an API-first, UI-driven PBS staged restore flow (with explicit Merge vs Clean behavior), adds chunking + reassembly to handle large artifacts and improve selective restores, hardens restore staging directory lifecycle and permissions, and makes several key operations cancellable and bounded (streaming category analysis, PVESH timeouts, filesystem IO timeouts). It also improves compatibility diagnostics, rollback handling, and test robustness.
-
PBS staged restore: API-first + UI-driven reconciliation (Merge vs Clean 1:1):
- Added PBS notifications backup/restore, including
notifications.cfg/notifications-priv.cfgand a generatednotifications_summary.json. - Implemented API-based PBS apply (
proxmox-backup-manager) with strict 1:1 reconciliation support and controlled fallbacks. - Moved PBS restore reconciliation out of
backup.envand into an interactive restore-time choice:- Merge: non-destructive behavior; skips destructive/API-unavailable actions.
- Clean (1:1): strict reconcile allowed; file-based fallbacks are permitted when needed.
- Introduced a dedicated final staged phase for PBS API-backed applies (node, datastores, remotes, jobs, notifications):
- File-based config apply runs while PBS services remain stopped.
- The final API phase may temporarily start services, applies API-backed categories, and then attempts to stop services again.
- Improved PBS API/UI error reporting: capture and surface API availability errors, and return a descriptive error when Merge mode skips API-applied categories.
- Hardened PBS list parsing (sanitized keys, stricter rows, descriptive errors with row indexes and available keys).
- Improved deterministic cleanup ordering for notifications in strict mode (matchers cleaned before endpoints to avoid reference-blocked cleanup).
- Added PBS notifications backup/restore, including
-
Chunking + reassembly for large artifacts (and better selective restore matching):
- Implemented smart file chunking with metadata (SHA256,
.chunkedmarkers) and robust chunk write logic. - Added
ReassembleChunkedFilesafter extract:- Discovers chunks (numeric sort), concatenates, validates integrity, reapplies
chmod/chown/mtime, and restores metadata.
- Discovers chunks (numeric sort), concatenates, validates integrity, reapplies
- Improved selective restore path matching and mapping of chunk artifacts back to original paths (
originalPathFromChunk) to reduce missed matches. - Added extensive unit test coverage for chunking, discovery, validation, and reassembly behavior.
- Implemented smart file chunking with metadata (SHA256,
-
Backup prefiltering + structured-config safety (less damage, better stats):
- Enhanced backup prefiltering with detailed stats, symlink skipping, and safer normalization rules.
- Avoids normalization of known structured config roots:
/etc/proxmox-backup,/etc/pve,/etc/ssh,/etc/pam.d,/etc/systemd/system.
- Normalization helpers now return
(changed bool)and normalization is limited to safe text normalization (no sorting). - Added recovery for malformed/flattened PBS
datastore.cfg:- Detect duplicate keys and attempt to restore content from
pbs_datastore_inventory.jsonusing a lightweight inventory parser.
- Detect duplicate keys and attempt to restore content from
- Added a new
prefilter-manualCLI command to run the prefilter standalone (custom root/max-size/log-level).
-
Restore staging dirs: secure lifecycle, cleanup, and safer defaults:
- Added secure staging directory creation under
/tmp/proxsave/restore-stage-*:0700permissions, PID-aware naming, unique creation viaMkdirTempwith timestamp/pid pattern.
- Added
cleanupOldRestoreStageDirs()and wired it into orchestrator startup/UI paths to remove aged staging dirs. - Added
PROXSAVE_PRESERVE_RESTORE_STAGINGand preserve-on-warnings behavior (including staged installs/network), plus auto-removal after successful clean restores. - Improved logs around staging creation/cleanup and documented the behavior.
- Added secure staging directory creation under
-
Streamed + cancellable category analysis with safe fallback:
AnalyzeBackupCategoriesnow accepts a context and scans archives streaming (O(1) memory), enabling cancellation and better error handling.- Avoids double-closing underlying files from decompression readers.
- Detects category availability on-the-fly and exposes an injectable analysis function for testing.
- Falls back to a safe full restore with a user-facing message when analysis fails; added tests (including truncated-tar error handling).
-
Broader context cancellation support and restore code hardening:
- Added
ctx.Err()checks in long-running loops (backup history/replication aggregation) for early cancellation. - Ensured restore apply paths handle nil contexts safely (createBundle, decrypt TUI, guardMountPoint, access control applies).
- Introduced a context-aware reader (
contextReader) so largeio.Copyoperations can be cancelled cleanly. - Refactored many restore internals: tighter error checks, reduced unused parameters, improved confirm/preview messaging, and clearer restore destination warnings.
- Added
-
PVE service management and restore ordering correctness:
- Centralized PVE cluster service management into a single ordered list.
- Stop order is now correct and tested (reverse order:
pvestatd → pveproxy → pvedaemon → pve-cluster), start uses forward order. - Updated docs/diagrams to reflect the corrected stop sequence.
-
Security hardening and rollback artifact robustness:
- Hardened permissions for rollback artifacts and markers to 0600 (archive, scripts, marker/location files).
- Ensured rollback log files are created before writing markers/scripts.
- Removed redundant shebang lines from generated rollback scripts.
- Ensured firewall rollback disarm cleans up scripts, logging failures without failing the flow; added tests.
-
Compatibility messaging, warnings, and UX improvements:
ValidateCompatibilitynow produces clearer warnings/errors when backup/system type cannot be detected (includes type info where available).- Final restore summary now reflects logged warnings (
logger.HasWarnings()), with unit test coverage. - Fixed category toggle/deselection logic so deselecting truly removes entries from the selection map; selection counts now reflect
len(selected). - Improved
logStepmessages to include step index for clearer progress tracing.
-
Bounded execution to avoid hangs: PVESH and filesystem IO timeouts:
- Added
PVESH_TIMEOUTand applied per-call timeouts topveshoperations. - Extended PVE storage parsing to capture runtime fields (
active,enabled,status) with tolerant parsing of bool/int/string forms:- Includes runtime info in logs and can skip storages that appear unavailable to reduce hangs.
- Added
FS_IO_TIMEOUTand a newinternal/safefsbounded probe layer (stat,readdir,statfs) to avoid blocking on unreachable mounts. - Propagated IO timeouts through datastore/storage sampling, directory/file sampling, PXAR metadata collection, and report generation; timeouts are handled gracefully with warnings/skips.
- Fixed
pveshcontext cancellation handling and tightened deps signatures for command/run/lookpath to accept contexts/timeouts.
- Added
-
Collector refactor: bounded filesystem sampler replaces legacy PXAR sampling:
- Replaced the complex fanout-based PXAR sampling implementation with a simpler bounded sampler (
fs_sampling_bounded). - Removed deprecated PXAR tuning options and related code paths/fields from
CollectorConfig. - Updated docs/templates:
- Cleaned up legacy env mappings for PXAR knobs.
- Simplified public config examples and clarified sampling semantics.
- Noted include/exclude pattern reuse for PVE datastore sampling.
- Replaced the complex fanout-based PXAR sampling implementation with a simpler bounded sampler (
-
Lock-file correctness and CI hygiene:
- Lock checks now parse pid/host/time metadata, perform same-host PID liveness checks (injectable
killFunc), and remove stale locks when appropriate. - Prevented tests from creating a
--progressartifact; removed stale artifacts before runs. - Hardened rclone-copy stubs to reject empty or flag-like destinations (starting with
--) to avoid accidental writes. - General test cleanup and refactors to accommodate new context/timeouts and API behavior.
- Lock checks now parse pid/host/time metadata, perform same-host PID liveness checks (injectable
-
Build/versioning improvements:
- Makefile VERSION derivation now produces stable dev-style version strings (tag + dev count + sha +
.dirtyhandling) for bothbuildandbuild-release.
- Makefile VERSION derivation now produces stable dev-style version strings (tag + dev count + sha +
-
Dependencies:
- Bumped
golang.org/x/termto 0.40.0. - Bumped
golang.org/x/cryptoto 0.48.0.
- Bumped
Breaking/behavior changes to note:
- PBS restore reconciliation is now selected interactively (Merge vs Clean 1:1). The previous env-driven
RESTORE_PBS_APPLY_MODE/RESTORE_PBS_STRICTsettings were removed. - Several legacy PXAR tuning knobs were removed as the collector moved to a bounded sampling implementation.
Overall: more reliable PBS restores (API-first with explicit operator intent), better handling of large artifacts via chunking, safer staging with stronger permissions and cleanup, and fewer hangs thanks to bounded IO and cancellable workflows.
Changelog
v0.13.6
ProxSave v0.13.6
🧱 Quieter PVE ACL logging, atomic staged restores, and more reliable tests
- PVE ACL clarity + less log noise: Expanded docs around
BACKUP_PVE_ACL(users/roles/groups/ACL; domains/realms optional) and madedomains.cfgoptional so it’s not warned/counted as missing on default standalone PVE installs. - Atomic writes for staged restores: Introduced a centralized atomic write + inherited metadata utility (
fs_atomic) and switched staged-apply paths (network, PBS, PVE, firewall, HA, notifications) to write atomically while enforcing final ownership/permissions (avoids umask-related issues). Removed duplicate atomic write implementation. - Ownership/permissions inheritance improvements: Staged restores now inherit uid/gid/mode from the nearest existing parent (including repairing common
root:rootgroup regressions) with additional unit tests and updated docs. - Durability hardening:
writeFileAtomicnow fsyncs file data and fsyncs the parent directory (treating unsupported dir fsync as non-fatal). Added a safe default case in rclone discovery to skip unsupported switch branches. - Test reliability: Orchestrator tests now use isolated temp dirs via a fully populated
CheckerConfig, avoid repo lock-file reliance, and include better cleanup. Added FS operation hooks to make atomic-write tests hermetic without requiring root. - Docs/README updates: Updated RESTORE/TROUBLESHOOTING guidance for atomic/staged behavior and PBS permission recovery; refreshed README and credits; updated
.backup.lockmetadata.
Overall: cleaner PVE ACL reporting, safer staged restores via durable atomic writes with correct ownership, and a sturdier, less flaky test suite.
Changelog
v0.13.5
ProxSave v0.13.5
🧩 Config var expansion, clearer docs, and correct PVE ACL collection
- Config var expansion: Added
${VAR}/$VARexpansion for scalar config values (config keys first, then environment) with caching + cycle protection; preserves historicalBASE_DIRbehavior. Includes unit tests. - Docs/templates updated: Documented expansion behavior and clarified
backup.envvalues are resolved by ProxSave without requiring export. - PVE ACL correctness: Aligned collection and docs with Proxmox behavior (ACLs live in
user.cfg), updated collector logic and tests accordingly.
Overall: more flexible configuration, clearer guidance, and more accurate PVE ACL handling.
Changelog
v0.13.4
ProxSave v0.13.4
🧰 More granular collectors, clearer end-of-run summaries, and safer restore UX refinements
This release tightens operational clarity and configurability across backup and restore workflows. It adds issue capture with end-of-run summaries, introduces finer PBS collection toggles with clearer logging, improves PVE manifest/cluster handling, prunes deprecated env keys during upgrades, and refines restore interaction and network rollback UX for more reliable operation on constrained terminals (IPMI/serial). It also improves notifier ergonomics with automatic email recipient detection and bumps the Go toolchain.
- End-of-run issue capture and summary reporting:
- Logger now captures WARNING/ERROR/CRITICAL lines as sanitized single-line “issue entries” for later reporting.
- Added thread-safe accessors for warning/error counts and collected issue lines.
- Final-run summaries can now print the captured issue lines to surface root causes quickly.
- Granular PBS collection toggles + clearer logs:
- Added fine-grained PBS flags to independently enable/disable subcomponents (S3 endpoints, node config, ACME accounts/plugins, metric servers, traffic control, PBS network config).
- Collector/orchestrator logic now respects these flags (exclude files, skip commands/snapshots when disabled), with clearer per-file status messages via disable hints.
- Updated docs, tests, and env templates to reflect the new options.
- Improved PVE manifest logging and cluster handling:
populatePVEManifestnow always initializes the manifest and uses structured logging options for consistent, descriptive output.- Better “not found” accounting and richer record descriptions (including disable hints) for PVE config items.
- Refined cluster logic to separate BACKUP_CLUSTER_CONFIG gating from node/cluster-specific actions; improved copy/skip logging and tuned log levels for firewall, VZDump, and Ceph detection.
- Added a template note explaining that enabled-but-unconfigured features may emit warnings and can be disabled via
BACKUP_*flags.
- Config/upgrade cleanup: prune deprecated keys and fully populate results:
- Removed
BASE_DIRandCRON_*from generatedbackup.env(BASE_DIR is auto-detected; cron is managed via crontab). - Config upgrade now prunes deprecated keys (
BASE_DIR,CRON_SCHEDULE,CRON_HOUR,CRON_MINUTE), emits a warning, and avoids rewriting unless missing keys were added or deprecated lines were removed. - Even when no content changes occur,
UpgradeResultis now fully populated (MissingKeys, ExtraKeys, CaseConflictKeys, PreservedValues, Warnings) for consistent caller behavior.
- Removed
- Network parsing and rollback UI improvements:
- Network snapshot IP extraction now robustly returns the primary address with CIDR, handles whitespace/tokenization safely, and prefers IPv4 when available (with unit tests for IPv4/IPv6/CIDR and missing snapshots).
- Added
suppressPVEChecksfor cluster restores to skip PVE-specific health checks and adjust network health options. - Restore UI messaging improved with observed/original IP context and reconnect-host guidance.
applyNetworkWithRollbackWithUInow returns a constructedNetworkApplyNotCommittedErrorfor richer downstream reporting.
- Prompt UX reliability on constrained terminals:
- Removed live-updating countdown prompts in CLI/TUI and replaced them with a single-line deadline display (HH:MM:SS + total seconds).
- Simplified input handling to use
ReadLineWithContextdirectly, avoiding carriage-return update issues on IPMI/serial consoles while preserving timeout/cancel behavior.
- Email notifier: recipient auto-detection:
- Implemented automatic recipient discovery for
root@pamacross Proxmox platforms:- Try
pveshfirst, fall back topveum/proxmox-backup-manager, and finally parseuser.cfgfrom PVE/PBS locations.
- Try
- Added helpers for redaction and truncated diagnostics, improved debug logging, expanded tests, and updated CONFIGURATION/TROUBLESHOOTING docs with quick verification steps.
- Implemented automatic recipient discovery for
- Maintenance and tooling:
- Cleaned up duplicated parse comments above
Config.parse. - Bumped Go toolchain to 1.25.7.
- Cleaned up duplicated parse comments above
Overall: more configurable backups (especially PBS), clearer and more actionable run summaries, cleaner env upgrades with deprecated-key pruning, and a more robust restore/operator experience—especially on real-world consoles and clustered restores.
Changelog
v0.13.3
ProxSave v0.13.3
🧩 Cleaner config upgrade diffs, smarter key insertion, and clearer upgrade reporting
This maintenance release improves the configuration upgrade experience by making upgrades more readable and less disruptive: missing template keys are inserted in a way that respects the user’s existing ordering, unanchored keys are grouped into a dedicated upgrade section, and upgrade results expose clearer summaries (including case-only conflicts). It also improves operator visibility by logging exactly which keys were added, and completes additional Italian → English comment/template text translations.
- Better visibility after upgrades: When an upgrade adds missing keys, ProxSave now logs an Info message showing the count and a comma-separated list of newly introduced keys (
cfgUpgradeResult.MissingKeys). - Insert missing template keys without reshuffling user config:
- Config upgrade logic now preserves user key positions and inserts missing template entries near related “anchor” keys to avoid unnecessary rewrites.
parseEnvValuesrecords per-key source ranges andcomputeConfigUpgradebuilds ordered insert operations (sorted) to merge template lines into the original file with minimal diffs.- Improved handling for block (multi-line) values while preserving extra keys and casing-related warnings.
- Dedicated upgrade section for unanchored keys:
- Missing entries that have no nearby anchor are collected and appended under a single
# Added by upgradesection (with appropriate spacing) instead of being inserted arbitrarily. - Template order is tracked via an index field to keep appended entries stable and predictable.
- Missing entries that have no nearby anchor are collected and appended under a single
- Clearer casing conflict behavior and reporting:
- Improved warning wording for case-only differences (“preserved with original casing”).
- Added
CaseConflictKeysto the upgrade result and preserved case-conflict keys in place instead of treating them as extra keys. - Updated CLI output to print case-conflict summaries for dry-run and upgrade flows.
- Consistent upgrade result state:
MissingKeysis now always populated (empty slice when none are missing) to avoid inconsistent result handling by callers. - Documentation and comment language consistency: Translated remaining Italian comments and user-facing template/docs text to English (including
backup.envtemplate comments), with no functional behavior changes.
Overall: config upgrades are now more predictable and operator-friendly—minimal diffs, stable ordering, clearer summaries (including case conflicts), and better post-upgrade visibility of what changed.
Changelog
v0.13.2
ProxSave v0.13.2
🧾 Config upgrade fidelity, comment/case preservation, and actionable upgrade warnings
This fix release hardens the backup.env parsing and upgrade pipeline to be much more faithful to real-world configs. It improves handling of comments (inline and block), key casing, legacy export prefixes (with arbitrary whitespace), and multiline values, while adding non-fatal warnings that surface potential issues during plan/upgrade runs. The result is safer upgrades with fewer surprises and clearer operator feedback.
- More faithful env rewriting (
SetEnvValue):- Skips commented lines and preserves indentation and inline comments when replacing values.
- Detects and preserves an optional leading
exporttoken, normalizing whitespace (e.g.export FOO=...) instead of dropping it.
- Stronger parsing for real-world env files:
parseEnvFile/parseEnvValuesnow ignores comment-only lines inside multiline block values, and stores comment text alongside parsed values.splitKeyValueRawhandles legacyexportprefixes, extracts quoted/unquoted values more robustly, and returns parsed inline comments.- Normalizes env keys to uppercase for consistent lookups while remaining compatible with legacy/lowercase configs (including multiline and multi-value keys).
- Upgrade logic correctness and no-op detection:
computeConfigUpgradeuses case-insensitive lookups, tracks processed user keys, preserves original user casing for extra keys, and counts preserved values correctly.- Detects no-op upgrades by comparing rendered content to the original file content.
- Ensures case-insensitive handling of block-value keys in the upgrade logic.
- Non-fatal upgrade warnings (surfaced in CLI):
- Added
Warnings []stringto the upgrade result and propagated warnings end-to-end so they print during plan/upgrade operations. - Warns about duplicate template keys that differ only by case, case-collisions between user keys and template keys, and ignored non-
KEY=VALUElines (multiline behavior preserved).
- Added
- New shared parsing utilities + unified behavior:
- Introduced string helpers (
FindInlineCommentIndex,FindClosingQuoteIndex,SetEnvValue) to centralize handling of inline comments, escaped#, and quoted values. - Replaced local
setEnvValueimplementations to use the unified utility function across the codebase.
- Introduced string helpers (
- Legacy
exportwhitespace edge cases fixed:- Export detection now uses a Fields-based parse so
export\t\tKEY=...works correctly and keys likeexporter=...are not misidentified. - Added coverage for tabbed whitespace and multiple spacing variants.
- Export detection now uses a Fields-based parse so
- Preservation tests and regression coverage:
- Added tests verifying inline comments are preserved through upgrades (including quoted
#cases). - Added tests verifying block-style comment lines inside multiline variables are preserved.
- Added tests for lowercase-key normalization across multiline and multi-value accumulation.
- Added tests verifying inline comments are preserved through upgrades (including quoted
- Minor housekeeping:
- Updated internal/orchestrator/.backup.lock (pid/time) as part of the changeset.
Overall: config upgrades are now safer and more predictable—comments and formatting are preserved, casing and legacy export syntax are handled correctly, and potential pitfalls are reported as clear, non-fatal warnings.