Skip to content

fix: add cross-process locking and refresh coordination for chart downloads#2301

Closed
aditmeno wants to merge 2 commits into
helmfile:mainfrom
aditmeno:fix/oci-chart-caching-and-registry-login
Closed

fix: add cross-process locking and refresh coordination for chart downloads#2301
aditmeno wants to merge 2 commits into
helmfile:mainfrom
aditmeno:fix/oci-chart-caching-and-registry-login

Conversation

@aditmeno

@aditmeno aditmeno commented Nov 26, 2025

Copy link
Copy Markdown
Contributor

Summary

This PR fixes race conditions and duplicate downloads when multiple helmfile processes run in parallel (e.g., helmfile.d with multiple release files).

Problem

When using helmfile.d/ with multiple release files that reference the same OCI chart:

  1. Each parallel helmfile process had its own in-memory cache flag
  2. Multiple processes would attempt to download the same chart simultaneously
  3. This caused race conditions ("file already exists" errors) and excessive downloads (56+ pulls for a single chart)
  4. OCI registry login was using the full URL with chart path instead of just the registry host

Solution

  1. OCI Registry Login URL Fix

    • Extract registry host from URL before helm registry login
    • e.g., account.dkr.ecr.region.amazonaws.com/chartsaccount.dkr.ecr.region.amazonaws.com
    • Fixes authentication issues with ECR and other registries
  2. Cross-Process Chart Locking

    • Add file-based locking (flock) to prevent race conditions
    • Serialize chart downloads across parallel helmfile processes
    • Applies to both OCI and non-OCI charts
  3. Refresh Mode Coordination

    • Use marker files with 60-second TTL to coordinate refresh across processes
    • First process to acquire lock performs refresh, others use cached version
    • Prevents duplicate downloads while still supporting --skip-refresh=false
  4. Code Refactoring

    • Extract common locking logic into acquireChartLock() helper function
    • Reduce code duplication between forcedDownloadChart() and getOCIChart()
    • Add unit tests for OCI registry login and SyncRepos

Files Changed

  • pkg/state/state.go - Main logic changes
  • pkg/state/state_test.go - New unit tests
  • pkg/exectest/helm.go - Mock updates for testing

Test Plan

  • Unit tests pass (Test_extractRegistryHost, TestHelmState_SyncRepos_OCI)
  • Build succeeds

…nloads

This commit fixes race conditions and duplicate downloads when multiple
helmfile processes run in parallel (e.g., helmfile.d with multiple release files).

Changes:
1. OCI Registry Login URL Fix:
   - Extract registry host from URL before helm registry login
   - e.g., "account.dkr.ecr.region.amazonaws.com/charts" -> "account.dkr.ecr.region.amazonaws.com"
   - Fixes authentication issues with ECR and other registries

2. Cross-Process Chart Locking:
   - Add file-based locking (flock) to prevent race conditions
   - Serialize chart downloads across parallel helmfile processes
   - Applies to both OCI and non-OCI charts

3. Refresh Mode Coordination:
   - Use marker files with 60-second TTL to coordinate refresh
   - First process to acquire lock performs refresh, others use cache
   - Prevents duplicate downloads while still supporting --skip-refresh=false

4. Code Refactoring:
   - Extract common locking logic into acquireChartLock() helper
   - Reduce code duplication between forcedDownloadChart and getOCIChart
   - Add unit tests for OCI registry login and SyncRepos
@aditmeno aditmeno marked this pull request as draft November 26, 2025 19:20
aditmeno added a commit to aditmeno/helmfile that referenced this pull request Nov 26, 2025
… chart locking

This merge integrates changes from PR helmfile#2301 into the issue fixes branch:

1. OCI Registry Login Fix:
   - Added extractRegistryHost() function to extract just the registry host
   - Fixed helm registry login to use host only, not full URL with path
   - e.g., "account.dkr.ecr.region.amazonaws.com/charts" → "account.dkr.ecr.region.amazonaws.com"

2. Refactored Chart Locking:
   - Introduced acquireChartLock() helper function for cleaner code
   - Added chartLockResult struct with action types
   - Added refresh marker coordination for cross-process cache management
   - Removed legacy OCI cache variables (downloadedOCICharts)

3. Test Fixes:
   - Removed debug log statements that polluted test output
   - All TestLint tests now pass

Files changed:
- pkg/state/state.go - Main logic changes
- pkg/state/state_test.go - New unit tests
- pkg/exectest/helm.go - Mock updates for testing
aditmeno added a commit to aditmeno/helmfile that referenced this pull request Nov 26, 2025
… chart locking

This merge integrates changes from PR helmfile#2301 into the issue fixes branch:

1. OCI Registry Login Fix:
   - Added extractRegistryHost() function to extract just the registry host
   - Fixed helm registry login to use host only, not full URL with path
   - e.g., "account.dkr.ecr.region.amazonaws.com/charts" → "account.dkr.ecr.region.amazonaws.com"

2. Refactored Chart Locking:
   - Introduced acquireChartLock() helper function for cleaner code
   - Added chartLockResult struct with action types
   - Added refresh marker coordination for cross-process cache management
   - Removed legacy OCI cache variables (downloadedOCICharts)

3. Test Fixes:
   - Removed debug log statements that polluted test output
   - All TestLint tests now pass

Files changed:
- pkg/state/state.go - Main logic changes
- pkg/state/state_test.go - New unit tests
- pkg/exectest/helm.go - Mock updates for testing

Signed-off-by: Aditya Menon <[email protected]>
@aditmeno aditmeno closed this Nov 26, 2025
@aditmeno aditmeno deleted the fix/oci-chart-caching-and-registry-login branch November 26, 2025 20:07
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