Skip to content

fix PXAR parallel collection, test coverage, and CI hardening#220

Merged
tis24dev merged 13 commits into
mainfrom
dev
May 26, 2026
Merged

fix PXAR parallel collection, test coverage, and CI hardening#220
tis24dev merged 13 commits into
mainfrom
dev

Conversation

@tis24dev
Copy link
Copy Markdown
Owner

@tis24dev tis24dev commented May 26, 2026

  • Bump x/crypto to v0.52.0
  • ci: download modules before govulncheck
  • Preserve legacy manifest parse causes
  • Align remote legacy manifest parsing
  • Propagate legacy scanner failures
  • Expand test coverage
  • Fix staged apply tests to use injectable root checks.
  • test: expand PVE collector coverage
  • fix(backup): isolate PXAR per-datastore errors in parallel step
  • test: expand system collector probe and collection coverage

Summary by CodeRabbit

  • Bug Fixes

    • Manifest loading now reports combined causes and surfaces legacy parsing/scan failures.
    • Backup collection better propagates cancellations/deadlines and avoids swallowing parent-context errors.
    • Legacy metadata targets and version fields are now recognized and merged into manifests.
  • Tests

    • Expanded unit/integration test coverage across collectors, restore/apply flows, and edge/error branches.
  • Chores

    • Updated module dependencies and CI workflow action pins.

Review Change Stack

Greptile Summary

This PR addresses PXAR parallel collection isolation, improves manifest error reporting, expands test coverage, and hardens the CI pipeline. It touches three functional areas: the backup collection layer, the orchestrator's legacy metadata parsing, and GitHub Actions workflow hardening.

  • PXAR parallel isolation: runPBSPXARStep no longer cancels the shared context on the first per-datastore error; it now collects all per-datastore failures with errors.Join and the new handlePBSPXARStepError helper treats datastore errors as best-effort warnings unless the parent context itself is done.
  • Manifest error improvements: LoadManifest now surfaces both the JSON parse cause and the legacy parse cause in its combined error message; parseLegacyMetadata now propagates bufio.Scanner errors instead of silently succeeding.
  • Legacy remote manifest parsing: inspectRcloneMetadataManifest in decrypt.go now handles BACKUP_TARGETS, PROXMOX_TARGETS, PROXMOX_VERSION, PVE_VERSION, and PBS_VERSION fields with deduplication logic for targets.

Confidence Score: 5/5

Safe to merge — all changed production paths are well-covered by new tests and the behavior changes are intentional and consistent with the PR description.

The core PXAR concurrency fix (collecting all per-datastore errors instead of canceling on first failure) is thoroughly exercised across six new targeted test cases. The manifest error-reporting changes are backwards-compatible (callers only check err != nil). The orchestrator's legacy metadata parsing additions are additive and tested. No existing contract is broken.

No files require special attention; the test coverage for collector_pbs_datastore.go is particularly thorough.

Important Files Changed

Filename Overview
internal/backup/collector_pbs_datastore.go Rewrites runPBSPXARStep to collect all per-datastore errors instead of canceling on first failure; uses errors.Join for the final result and respects parent context cancellation.
internal/backup/collector_bricks_pbs_features.go Adds handlePBSPXARStepError to uniformly treat per-datastore errors as best-effort warnings unless the parent context is done; replaces ad-hoc log+return-nil patterns across all PXAR brick functions.
internal/backup/collector_bricks.go Adds isParentContextError — a stricter variant of isContextCancellationError that only matches when the error equals the parent context's current error.
internal/backup/checksum.go LoadManifest now reports both JSON and legacy parse causes in the error message; parseLegacyMetadata now returns an error and propagates bufio.Scanner failures instead of silently succeeding.
internal/orchestrator/decrypt.go inspectRcloneMetadataManifest now parses BACKUP_TARGETS, PROXMOX_TARGETS, PROXMOX_VERSION, PVE_VERSION, and PBS_VERSION from legacy manifests with target deduplication.
.github/workflows/security-ultimate.yml Adds go mod download before govulncheck and updates pinned SHA hashes for codeql-action actions.
internal/backup/collector_pxar_datastore_test.go Replaces old cancel-on-first-error test with six new tests covering: all-datastores-continue, partial failure, pre-canceled context, deadline exceeded, local cancellation kept, and parent+datastore error joining.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[runPBSPXARStep] -->|pre-check| B{ctx.Err?}
    B -->|yes| C[return ctxErr]
    B -->|no| D[launch goroutines per datastore]
    D --> E{acquire semaphore}
    E -->|ctx.Done| F[goroutine exits]
    E -->|acquired| G[fn ctx ds state]
    G -->|err = nil| H[no-op]
    G -->|err != nil| I{isParentContextError?}
    I -->|yes| J[goroutine exits silently]
    I -->|no| K[Debug log + append to errs]
    H & J & K --> L[wg.Wait]
    L --> M{ctx.Err after wait?}
    M -->|ctxErr + errs| N[errors.Join both]
    M -->|ctxErr only| O[return ctxErr]
    M -->|no ctxErr| P[errors.Join errs or nil]
Loading

Comments Outside Diff (1)

  1. internal/backup/checksum.go, line 116-120 (link)

    P2 JSON parse error is no longer wrapped

    The previous message used %w to wrap err, so callers could do errors.As(returnedErr, &*json.SyntaxError{}) or similar. The new format uses %v for both err and legacyErr, so neither is reachable via errors.Is/errors.As. The existing callers in backup_sources.go and storage/local.go only check err != nil, so there is no current breakage, but the semantic change is worth calling out if future callers ever need to distinguish parse failure causes.

Reviews (2): Last reviewed commit: "test(orchestrator): use unique per-run s..." | Re-trigger Greptile

tis24dev added 10 commits May 25, 2026 09:53
Fix GO-2026-5018 by updating golang.org/x/crypto and related checksums.
Ensure module checksums are fetched before vulnerability scanning.
Return both JSON and legacy parse errors from LoadManifest and cover the missing-archive metadata path in tests.
Parse legacy targets and version fields in inspectRcloneMetadataManifest to match local manifest handling.
Return scanner errors from parseLegacyMetadata and fail fast when legacy metadata scanning is truncated.
Add broader coverage for safeexec and staged/orchestrated restore flows.
Use accessControlApplyGeteuid and mountGuardGeteuid in maybeApply paths so CI tests can exercise error branches without real root, matching hooks used elsewhere in orchestrator.
Stop runPBSPXARStep from canceling sibling datastores on the first failure.
Add isParentContextError and handlePBSPXARStepError so parent cancel/deadline
propagates while datastore errors remain best-effort. Stabilizes race CI.
Add branch and integration tests for systemctl, sensors, dmidecode,
and related system collection paths in collector_system_test.go.
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 26, 2026

Dependency Review

The following issues were found:
  • ✅ 0 vulnerable package(s)
  • ✅ 0 package(s) with incompatible licenses
  • ✅ 0 package(s) with invalid SPDX license definitions
  • ⚠️ 2 package(s) with unknown licenses.
See the Details below.

License Issues

go.mod

PackageVersionLicenseIssue Type
golang.org/x/crypto0.52.0NullUnknown License
golang.org/x/sys0.45.0NullUnknown License
Allowed Licenses: MIT, Apache-2.0, BSD-2-Clause, BSD-3-Clause, ISC, LicenseRef-scancode-google-patent-license-golang

OpenSSF Scorecard

PackageVersionScoreDetails
actions/github/codeql-action/analyze 7211b7c8077ea37d8641b6271f6a365a22a5fbfa UnknownUnknown
actions/github/codeql-action/init 7211b7c8077ea37d8641b6271f6a365a22a5fbfa UnknownUnknown
actions/github/codeql-action/upload-sarif 7211b7c8077ea37d8641b6271f6a365a22a5fbfa UnknownUnknown
gomod/golang.org/x/crypto 0.52.0 UnknownUnknown
gomod/golang.org/x/sys 0.45.0 UnknownUnknown

Scanned Files

  • .github/workflows/security-ultimate.yml
  • go.mod

@qodo-code-review
Copy link
Copy Markdown

Review Summary by Qodo

Fix PXAR parallel collection, enhance error handling, and expand test coverage

🐞 Bug fix 🧪 Tests ✨ Enhancement

Grey Divider

Walkthroughs

Description
• **Fix PXAR parallel collection error handling**: Isolate per-datastore errors in parallel PXAR
  backup step to continue processing all datastores instead of stopping at first error, while properly
  distinguishing parent context cancellations from local failures
• **Preserve legacy manifest parse causes**: Improve error messages to include both JSON and legacy
  parse failures, with scanner errors properly propagated through the parsing chain
• **Align remote legacy manifest parsing**: Add support for BACKUP_TARGETS, PROXMOX_TARGETS, and
  version metadata fields (PROXMOX_VERSION, PVE_VERSION, PBS_VERSION) with target deduplication
• **Expand test coverage significantly**: Add comprehensive tests for system collector probes, PVE
  collector operations, access control restoration, PVE staged apply, safeexec command validation, and
  legacy metadata parsing with error scenarios
• **Improve testability**: Inject geteuid() functions in mount guard and access control modules
  for better test isolation
• **Bump dependencies**: Update golang.org/x/crypto to v0.52.0 and golang.org/x/sys to v0.45.0
• **CI hardening**: Add module download step before govulncheck execution to ensure proper
  dependency caching
Diagram
flowchart LR
  A["PXAR Parallel<br/>Collection"] -->|"isolate errors"| B["Per-Datastore<br/>Error Handling"]
  B -->|"distinguish"| C["Parent Context<br/>vs Local Errors"]
  C -->|"propagate"| D["Combined Error<br/>Results"]
  E["Legacy Manifest<br/>Parsing"] -->|"preserve causes"| F["Enhanced Error<br/>Messages"]
  F -->|"include"| G["JSON + Legacy<br/>Failures"]
  H["Remote Manifest<br/>Parsing"] -->|"align with"| I["Additional Metadata<br/>Fields"]
  I -->|"deduplicate"| J["Targets & Versions"]
  K["Test Coverage"] -->|"expand"| L["System, PVE, ACL,<br/>SafeExec Tests"]

Loading

Grey Divider

File Changes

1. internal/backup/collector_system_test.go 🧪 Tests +2130/-0

Expand system collector probe and collection coverage

• Added comprehensive test coverage for system probe availability checks (systemctlProbeAvailable,
 sensorsProbeAvailable, dmidecodeProbeAvailable)
• Added tests for ZFS usage detection and best-effort probe collection with various error conditions
• Added extensive test coverage for static file collection across network, identity, apt, cron,
 services, logging, SSL, sysctl, kernel modules, ZFS, and firewall configurations
• Added tests for runtime collection including leases, core runtime info, network details, storage,
 compute, services, packages, and LVM operations with cancellation and error handling
• Added tests for additional file collection including critical files, custom paths, script
 directories, SSH keys, root/user homes, and kernel/hardware info
• Added helper functions (writeRootFile, writeFileAt, assertFileExists,
 prepareStaticCopyErrorPath) and custom context type (errAfterContext) for test support

internal/backup/collector_system_test.go


2. internal/backup/collector_pxar_datastore_test.go 🧪 Tests +177/-4

Fix PXAR parallel collection and improve error handling

• Renamed test from TestRunPBSPXARStepCancelsPendingWorkersOnFirstError to
 TestRunPBSPXARStepContinuesAllDatastoresOnError with updated concurrency and assertion
 expectations
• Added TestRunPBSPXARStepPartialFailure to verify partial datastore failures are handled
 correctly while continuing other datastores
• Added TestRunPBSPXARStepRespectsParentContextCancellation to verify parent context cancellation
 is respected
• Added TestRunPBSPXARStepPropagatesParentDeadlineExceeded to verify deadline exceeded errors
 propagate correctly
• Added TestRunPBSPXARStepKeepsLocalCancellationError to verify local cancellation errors are
 preserved
• Added TestRunPBSPXARStepJoinsParentCancellationWithDatastoreErrors to verify parent cancellation
 joins with datastore errors
• Added TestPBSPXARBrickPropagatesParentCancellation to verify brick-level cancellation
 propagation
• Added TestHandlePBSPXARStepErrorOnlyPropagatesParentContext to verify error handling
 distinguishes parent vs local context errors

internal/backup/collector_pxar_datastore_test.go


3. internal/backup/collector_bricks_pbs_features.go 🐞 Bug fix +21/-14

Isolate PXAR per-datastore errors in parallel step

• Added handlePBSPXARStepError method to distinguish between parent context errors and local
 datastore errors
• Updated all PXAR brick error handlers to use handlePBSPXARStepError instead of logging and
 returning nil
• Changed error handling to propagate parent context cancellations while treating local errors as
 best-effort warnings

internal/backup/collector_bricks_pbs_features.go


View more (16)
4. internal/orchestrator/decrypt_test.go 🧪 Tests +47/-0

Expand legacy manifest parsing test coverage

• Added TestInspectRcloneMetadataManifest_LegacyIncludesTargetsAndVersions to verify legacy
 manifest parsing correctly extracts targets and versions
• Test validates that PROXMOX_TARGETS and BACKUP_TARGETS are properly merged and
 ProxmoxTargets contains all unique targets
• Test verifies version fields (ProxmoxVersion, PVEVersion, PBSVersion) are correctly parsed
 from legacy metadata

internal/orchestrator/decrypt_test.go


5. internal/backup/collector_pve_coverage_test.go 🧪 Tests +1173/-0

Expand PVE collector test coverage with comprehensive edge cases

• Adds comprehensive test coverage for PVE collector functionality with 1173 lines of new tests
• Tests PVE manifest helpers, runtime command execution, job scheduling, replication, and snapshot
 collection
• Covers storage scanning, metadata collection, backup analysis, and Ceph integration
• Tests error handling, context cancellation, and edge cases across all PVE collector operations

internal/backup/collector_pve_coverage_test.go


6. internal/orchestrator/restore_access_control_additional_test.go 🧪 Tests +1144/-0

Add extensive access control restoration test coverage

• Adds 1144 lines of comprehensive test coverage for access control restoration functionality
• Tests PBS and PVE access control application from staged files with various error scenarios
• Covers ACL parsing, user filtering, token/TFA/shadow file handling, and configuration merging
• Tests utility functions for realm detection, user identification, and configuration rendering

internal/orchestrator/restore_access_control_additional_test.go


7. internal/backup/collector_pbs_datastore.go 🐞 Bug fix +17/-21

Fix PXAR parallel collection to isolate per-datastore errors

• Refactors runPBSPXARStep to collect all per-datastore errors instead of stopping at first error
• Replaces firstErr and cancel() pattern with errs slice to accumulate errors
• Uses isParentContextError() to distinguish parent context cancellation from datastore-specific
 failures
• Returns combined errors via errors.Join() to preserve all failure information

internal/backup/collector_pbs_datastore.go


8. internal/backup/checksum.go Error handling +13/-3

Preserve legacy manifest parse causes in error messages

• Improves manifest parsing error messages to include both JSON and legacy parse failures
• Adds error handling to parseLegacyMetadata() to return scanner errors
• Changes parseLegacyMetadata() signature from void to error-returning function
• Wraps scanner errors with context for better debugging

internal/backup/checksum.go


9. internal/orchestrator/decrypt.go ✨ Enhancement +27/-0

Align remote legacy manifest parsing with additional fields

• Adds parsing for BACKUP_TARGETS and PROXMOX_TARGETS metadata fields with deduplication
• Adds support for PROXMOX_VERSION, PVE_VERSION, and PBS_VERSION metadata fields
• Implements target deduplication logic to avoid duplicate entries when merging targets
• Aligns remote legacy manifest parsing with additional metadata fields

internal/orchestrator/decrypt.go


10. internal/orchestrator/pve_staged_apply_additional_test.go 🧪 Tests +910/-0

Comprehensive PVE staged apply test coverage expansion

• Adds comprehensive test coverage for PVE configuration staging and application functions
• Tests early returns, safe flows, and error handling for vzdump, storage, datacenter configs
• Tests backup job application with create/update fallback logic and mount guard functionality
• Covers storage mount guard candidates filtering, item generation, and activation/guard branching

internal/orchestrator/pve_staged_apply_additional_test.go


11. internal/safeexec/safeexec_test.go 🧪 Tests +109/-23

Expand safeexec command and path validation test coverage

• Expands TestCommandContextAllowlist to dynamically iterate over allowedCommandFactories and
 validate command arguments
• Adds new test TestCommandWrappers covering Output and CombinedOutput wrapper functions with
 valid and invalid commands
• Adds new test TestTrustedCommandContext validating trusted command execution with path and
 argument validation
• Expands TestValidateTrustedExecutablePath with additional edge cases (empty path, missing file,
 directory, non-executable)
• Updates TestValidateRemoteRelativePath to include "/" as valid and ".." as invalid path
• Expands TestProcPath to test multiple proc file types (status, comm, exe)

internal/safeexec/safeexec_test.go


12. internal/backup/checksum_additional_test.go 🧪 Tests +17/-1

Add legacy metadata parsing error propagation tests

• Adds error handling check to TestParseLegacyMetadata_AllFieldsAndTargetMerge to validate
 parseLegacyMetadata return value
• Adds new test TestParseLegacyMetadata_PropagatesScannerErrors to verify scanner errors are
 properly propagated with token-too-long failure

internal/backup/checksum_additional_test.go


13. internal/backup/checksum_legacy_test.go 🧪 Tests +16/-0

Add legacy manifest error cause inclusion test

• Adds new test TestLoadManifestMetadataErrorIncludesLegacyCause to verify error messages include
 legacy stat cause information

internal/backup/checksum_legacy_test.go


14. internal/backup/collector_bricks.go ✨ Enhancement +8/-0

Add parent context error detection helper function

• Adds new helper function isParentContextError to check if an error matches parent context
 cancellation
• Function mirrors existing isContextCancellationError pattern for context error detection

internal/backup/collector_bricks.go


15. internal/orchestrator/pve_staged_apply.go ✨ Enhancement +1/-1

Inject geteuid function for mount guard testing

• Replaces direct os.Geteuid() call with injected mountGuardGeteuid() function for testability

internal/orchestrator/pve_staged_apply.go


16. internal/orchestrator/restore_access_control.go ✨ Enhancement +1/-1

Inject geteuid function for access control testing

• Replaces direct os.Geteuid() call with injected accessControlApplyGeteuid() function for
 testability

internal/orchestrator/restore_access_control.go


17. go.mod Dependencies +2/-2

Bump x/crypto and x/sys dependencies

• Bumps golang.org/x/crypto from v0.51.0 to v0.52.0
• Bumps golang.org/x/sys from v0.44.0 to v0.45.0 (indirect dependency)

go.mod


18. go.sum Dependencies +4/-0

Update dependency checksums for crypto and sys

• Adds checksums for golang.org/x/crypto v0.52.0
• Adds checksums for golang.org/x/sys v0.45.0

go.sum


19. .github/workflows/security-ultimate.yml ⚙️ Configuration changes +3/-0

Download modules before govulncheck execution

• Adds go mod download step before running govulncheck to ensure modules are cached

.github/workflows/security-ultimate.yml


Grey Divider

Qodo Logo

@qodo-code-review
Copy link
Copy Markdown

qodo-code-review Bot commented May 26, 2026

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider

Great, no issues found!

Qodo reviewed your code and found no material issues that require review

Grey Divider

Qodo Logo

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 26, 2026

📝 Walkthrough

Walkthrough

Refactors PXAR datastore concurrency and parent-context error handling; surfaces legacy manifest and scanner errors; injects privilege-get hooks for testability; updates CI/action pins and module versions; and adds large suites of tests for PVE, system collectors, PXAR behavior, and access-control staged-apply flows.

Changes

Infrastructure and Baseline Dependency Updates

Layer / File(s) Summary
Dependency and workflow updates
go.mod, .github/workflows/codecov.yml, .github/workflows/release.yml, .github/workflows/security-ultimate.yml
golang.org/x/crypto and golang.org/x/sys bumped; codecov, goreleaser, and CodeQL action SHAs pinned to newer commits; go mod download step added to security workflow before govulncheck.

Legacy manifest parsing and error reporting

Layer / File(s) Summary
Manifest parsing and scanner error propagation
internal/backup/checksum.go, internal/backup/checksum_additional_test.go, internal/backup/checksum_legacy_test.go
LoadManifest records JSON unmarshal error and includes legacy parse failures; loadLegacyManifest and parseLegacyMetadata now return/wrap scanner and parse errors; tests assert propagated scanner/legacy errors.

PXAR Context Propagation and Datastore Concurrency

Layer / File(s) Summary
Context error detection helpers
internal/backup/collector_bricks.go
New isParentContextError(ctx, err) helper to detect parent-context cancellation errors.
PXAR step error handler and brick integration
internal/backup/collector_bricks_pbs_features.go
New handlePBSPXARStepError(ctx, message, err) centralizes PXAR step error handling; PXAR bricks now propagate parent-context errors and suppress/log non-parent local errors.
PXAR datastore step concurrency refactor
internal/backup/collector_pbs_datastore.go
runPBSPXARStep accumulates worker errors (mutex+slice), avoids cancelling on first local error, and returns joined errors with parent-context handling.
PXAR datastore test rewiring
internal/backup/collector_pxar_datastore_test.go
Tests updated to expect all datastores are attempted on local failures; added tests for partial failures, parent cancellation/deadlines, local cancellation preservation, combined errors, and brick propagation.

Orchestrator Testability and Refactoring

Layer / File(s) Summary
Legacy metadata targets and versions
internal/orchestrator/decrypt.go, internal/orchestrator/decrypt_test.go
inspectRcloneMetadataManifest recognizes BACKUP_TARGETS/PROXMOX_TARGETS and PROXMOX_VERSION/PVE_VERSION/PBS_VERSION, merging and deduplicating targets.
Privilege-check injection
internal/orchestrator/pve_staged_apply.go, internal/orchestrator/restore_access_control.go
Replaced direct os.Geteuid() calls with injectable mountGuardGeteuid() and accessControlApplyGeteuid() to enable tests to override effective-UID checks.
PVE staged configuration tests
internal/orchestrator/pve_staged_apply_additional_test.go
Comprehensive staged-apply tests for vzdump/storage/datacenter/job application, mount-guard candidate extraction/filtering, activation/fallback sequencing, and guard edge cases.
Access control restoration tests
internal/orchestrator/restore_access_control_additional_test.go
Extensive tests for staged sensitive files, PBS/PVE ACLs and secrets, utility helpers, real-FS path behavior, and write-error propagation.

Comprehensive Backup Collection Test Coverage

Layer / File(s) Summary
PVE collector edge-case and branch coverage
internal/backup/collector_pve_coverage_test.go
New test file (1100+ lines) adding many PVE collector edge and error-branch tests across manifest/runtime/snapshot/storage/analysis/finalization and cluster detection.
System collector test coverage and dependency override
internal/backup/collector_system_test.go
Adds 2100+ lines of system collector tests (system probes, ZFS detection, best-effort probes, static/runtime collection branches); test helper now allows overriding DetectUnprivilegedContainer.
PXAR and system tests
internal/backup/collector_pxar_datastore_test.go
Adds PXAR datastore tests for continuing across datastores on errors, deadline/cancellation semantics, local vs parent cancellation behavior, and joined errors.
Enhanced safeexec validation tests
internal/safeexec/safeexec_test.go
Safeexec tests extended to use factory-driven allowlists, context-aware wrappers, trusted-command validations, remote path checks, and proc-leaf iteration tests.

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly Related PRs

  • tis24dev/proxsave#210: Both PRs touch the PXAR datastore step execution logic—internal/backup/collector_pbs_datastore.go (runPBSPXARStep)—to adjust parent-context cancellation and error joining behavior.
  • tis24dev/proxsave#212: Modifies the same PXAR datastore step runner's concurrency/error-handling behavior in runPBSPXARStep.

"🐰 I nibbled logs and stitched small seams,
Contexts now whisper, not split at the seams.
Tests hop in thickets, catching each bug,
CI pins are tidy — a rabbit's snug hug."

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 3.57% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main changes: PXAR parallel collection fix (error handling refactor), test coverage expansion, and CI hardening (workflow updates and dependency bumps).
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Bumps the actions-updates group with 3 updates: [codecov/codecov-action](https://github.com/codecov/codecov-action), [goreleaser/goreleaser-action](https://github.com/goreleaser/goreleaser-action) and [github/codeql-action](https://github.com/github/codeql-action).


Updates `codecov/codecov-action` from 6.0.0 to 6.0.1
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md)
- [Commits](codecov/codecov-action@57e3a13...e79a696)

Updates `goreleaser/goreleaser-action` from 7.2.1 to 7.2.2
- [Release notes](https://github.com/goreleaser/goreleaser-action/releases)
- [Commits](goreleaser/goreleaser-action@1a80836...5daf1e9)

Updates `github/codeql-action` from 4.35.5 to 4.36.0
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](github/codeql-action@9e0d7b8...7211b7c)

---
updated-dependencies:
- dependency-name: codecov/codecov-action
  dependency-version: 6.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions-updates
- dependency-name: goreleaser/goreleaser-action
  dependency-version: 7.2.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions-updates
- dependency-name: github/codeql-action
  dependency-version: 4.36.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
@codecov
Copy link
Copy Markdown

codecov Bot commented May 26, 2026

Comment on lines +324 to +330
func isParentContextError(ctx context.Context, err error) bool {
if err == nil || ctx == nil {
return false
}
ctxErr := ctx.Err()
return ctxErr != nil && errors.Is(err, ctxErr)
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Near-duplicate of isContextCancellationError with distinct but subtle semantics

isParentContextError and isContextCancellationError differ in one critical way: the existing function short-circuits on any context.Canceled or context.DeadlineExceeded value regardless of the parent context's state, while the new one only returns true when the parent context is already done and the error matches its current error. This distinction is load-bearing (it's what lets handlePBSPXARStepError treat a locally-cancelled child context as a warning rather than a propagated error), but the names give no hint of it. Consider a comment or a name like isContextDoneError / matchesParentContextCause to make the distinction self-documenting.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — the distinction is intentional.
isContextCancellationError is broad, while this helper is intentionally strict: it returns true only when the error matches the current parent context cause (ctx.Err()).
We use this to avoid swallowing locally returned context.Canceled values in PXAR best-effort paths.
I agree the naming can be clearer; I’ll either rename it to something like matchesParentContextCause or add an explicit comment.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (1)
internal/backup/checksum_legacy_test.go (1)

104-106: ⚡ Quick win

Assert both parse causes in this test.

This test only validates the legacy cause. Please also assert the JSON parse cause so regressions in combined-error construction are caught.

Proposed test hardening
 	if !strings.Contains(err.Error(), "cannot stat archive") {
 		t.Fatalf("error=%v; want legacy stat cause", err)
 	}
+	if !strings.Contains(err.Error(), "failed to parse manifest as JSON") {
+		t.Fatalf("error=%v; want json parse cause", err)
+	}
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/backup/checksum_legacy_test.go` around lines 104 - 106, The test
currently only asserts the legacy cause by checking
strings.Contains(err.Error(), "cannot stat archive"); update the test to also
assert the JSON parse cause is present in the combined error (e.g. assert that
err.Error() contains a JSON-related substring such as "json" or "parse" or the
specific parse message your code produces) so both causes are validated; modify
the block around the existing check to require both
strings.Contains(err.Error(), "cannot stat archive") and
strings.Contains(err.Error(), "<your JSON parse substring>") (use the exact
parse message emitted by your code) and fail the test if either is missing.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/backup/checksum.go`:
- Around line 171-175: The LoadManifest function currently shadows the outer err
when calling json.Unmarshal, causing the final fmt.Errorf to report the wrong
JSON parse error; change the json.Unmarshal call to assign its error to a new
variable (e.g., unmarshalErr) or reuse the outer err (do not ":=") so you
capture the real JSON error, then use that variable (unmarshalErr) in the
combined error message alongside legacyErr in the fmt.Errorf call; locate
json.Unmarshal, os.ReadFile, legacyErr and the final fmt.Errorf in LoadManifest
to implement this fix.

In `@internal/orchestrator/pve_staged_apply_additional_test.go`:
- Around line 13-20: Tests currently mutate fixed /mnt/pve paths and the helper
requireWritablePveMountRoot only MkdirAlls and ignores removal errors; change
requireWritablePveMountRoot to actually verify writability by creating a
uniquely named probe file (use a random/test-specific suffix), writing to it,
fsyncing if possible, then removing it and t.Skip on any error; stop using fixed
absolute storage names like "activate-ok"/"guard-ok" and instead generate
per-test unique storage IDs (e.g., proxsave-test-<rand>) and derive staged
configs and cleanup paths from those IDs; replace any os.RemoveAll calls that
target fixed /mnt/pve/* with removals scoped to the generated test-specific
paths and update the tests around requireWritablePveMountRoot plus the areas
referenced (near the other occurrences) to use the new helper and unique IDs.

In `@internal/orchestrator/restore_access_control_additional_test.go`:
- Line 537: The test is passing a nil context to applyPVEAccessControlFromStage
which violates Go conventions; replace the nil with a non-nil context such as
context.Background() when calling applyPVEAccessControlFromStage(nil,
newTestLogger(), "/stage") so update that call to use context.Background()
(ensure you import context if not already) to provide a proper context to the
function.
- Line 129: The test calls applyPBSAccessControlFromStage with a nil context
which violates Go conventions; update the call to pass context.Background()
instead of nil (e.g., replace the first argument in
applyPBSAccessControlFromStage(nil, logger, "/stage") with context.Background())
so the test uses a valid non-nil context while preserving existing behavior.

---

Nitpick comments:
In `@internal/backup/checksum_legacy_test.go`:
- Around line 104-106: The test currently only asserts the legacy cause by
checking strings.Contains(err.Error(), "cannot stat archive"); update the test
to also assert the JSON parse cause is present in the combined error (e.g.
assert that err.Error() contains a JSON-related substring such as "json" or
"parse" or the specific parse message your code produces) so both causes are
validated; modify the block around the existing check to require both
strings.Contains(err.Error(), "cannot stat archive") and
strings.Contains(err.Error(), "<your JSON parse substring>") (use the exact
parse message emitted by your code) and fail the test if either is missing.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: cdbaec5b-12ba-49fe-9918-e81b1b2a34fc

📥 Commits

Reviewing files that changed from the base of the PR and between 24b4c96 and 2a42192.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (20)
  • .github/workflows/codecov.yml
  • .github/workflows/release.yml
  • .github/workflows/security-ultimate.yml
  • go.mod
  • internal/backup/checksum.go
  • internal/backup/checksum_additional_test.go
  • internal/backup/checksum_legacy_test.go
  • internal/backup/collector_bricks.go
  • internal/backup/collector_bricks_pbs_features.go
  • internal/backup/collector_pbs_datastore.go
  • internal/backup/collector_pve_coverage_test.go
  • internal/backup/collector_pxar_datastore_test.go
  • internal/backup/collector_system_test.go
  • internal/orchestrator/decrypt.go
  • internal/orchestrator/decrypt_test.go
  • internal/orchestrator/pve_staged_apply.go
  • internal/orchestrator/pve_staged_apply_additional_test.go
  • internal/orchestrator/restore_access_control.go
  • internal/orchestrator/restore_access_control_additional_test.go
  • internal/safeexec/safeexec_test.go

Comment thread internal/backup/checksum.go
Comment thread internal/orchestrator/pve_staged_apply_additional_test.go
t.Fatalf("expected context.Canceled, got %v", err)
}

if err := applyPBSAccessControlFromStage(nil, logger, "/stage"); err != nil {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Replace nil context with context.Background().

Passing nil as a context violates Go conventions. Use context.Background() for testing scenarios where context behavior is not the focus.

🔧 Proposed fix
-	if err := applyPBSAccessControlFromStage(nil, logger, "/stage"); err != nil {
+	if err := applyPBSAccessControlFromStage(context.Background(), logger, "/stage"); err != nil {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if err := applyPBSAccessControlFromStage(nil, logger, "/stage"); err != nil {
if err := applyPBSAccessControlFromStage(context.Background(), logger, "/stage"); err != nil {
🧰 Tools
🪛 golangci-lint (2.12.2)

[error] 129-129: SA1012: do not pass a nil Context, even if a function permits it; pass context.TODO if you are unsure about which Context to use

(staticcheck)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/orchestrator/restore_access_control_additional_test.go` at line 129,
The test calls applyPBSAccessControlFromStage with a nil context which violates
Go conventions; update the call to pass context.Background() instead of nil
(e.g., replace the first argument in applyPBSAccessControlFromStage(nil, logger,
"/stage") with context.Background()) so the test uses a valid non-nil context
while preserving existing behavior.

t.Fatalf("expected context.Canceled, got %v", err)
}

if err := applyPVEAccessControlFromStage(nil, newTestLogger(), "/stage"); err != nil {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Replace nil context with context.Background().

Passing nil as a context violates Go conventions. Use context.Background() for testing scenarios where context behavior is not the focus.

🔧 Proposed fix
-	if err := applyPVEAccessControlFromStage(nil, newTestLogger(), "/stage"); err != nil {
+	if err := applyPVEAccessControlFromStage(context.Background(), newTestLogger(), "/stage"); err != nil {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if err := applyPVEAccessControlFromStage(nil, newTestLogger(), "/stage"); err != nil {
if err := applyPVEAccessControlFromStage(context.Background(), newTestLogger(), "/stage"); err != nil {
🧰 Tools
🪛 golangci-lint (2.12.2)

[error] 537-537: SA1012: do not pass a nil Context, even if a function permits it; pass context.TODO if you are unsure about which Context to use

(staticcheck)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/orchestrator/restore_access_control_additional_test.go` at line 537,
The test is passing a nil context to applyPVEAccessControlFromStage which
violates Go conventions; replace the nil with a non-nil context such as
context.Background() when calling applyPVEAccessControlFromStage(nil,
newTestLogger(), "/stage") so update that call to use context.Background()
(ensure you import context if not already) to provide a proper context to the
function.

tis24dev added 2 commits May 26, 2026 18:20
json.Unmarshal was called with :=, shadowing the outer err variable.
The combined error message reported JSON (<nil>) instead of the actual
parse failure. Rename to unmarshalErr to capture and propagate it.
Harden tests to assert both JSON and legacy causes in combined errors.
… tests

Replace fixed /mnt/pve/<name> storage IDs (activate-ok, proxsave-offline,
mkdir-fail, etc.) with unique per-run IDs using a proxsave-it-<hash>-<label>
prefix. Add safety helpers that refuse RemoveAll/Remove on paths not owned
by the test (no proxsave-it- prefix), preventing accidental collision with
real PVE storage IDs on privileged hosts.

Also add requireWritablePveMountRoot with a real write/remove probe and
TestPveMountIntegrationTestPathSafety to guard the path-ownership logic.
@tis24dev tis24dev merged commit c9c43c4 into main May 26, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant