mirror of
https://github.com/helm/helm.git
synced 2026-03-01 04:51:00 -05:00
When DownloadTo runs in parallel for the same ref and version, both processes try to write the same target file, causing "Access Denied" errors on Windows. This change refactors the file locking mechanism based on maintainer feedback: - Add LockedAtomicWriteFile to internal/fileutil package to encapsulate locking logic - Use the new function for both chart and provenance files - Lock is cross-process safe and automatically released on process exit - Files are only written if they don't already exist (avoiding duplicate work) The TestParallelDownloadTo test verifies the fix works correctly. Fixes #31633 Signed-off-by: Orgad Shaneh <orgad.shaneh@audiocodes.com>
45 lines
1.3 KiB
Go
45 lines
1.3 KiB
Go
//go:build !windows
|
|
|
|
/*
|
|
Copyright The Helm Authors.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package fileutil
|
|
|
|
import (
|
|
"io"
|
|
"os"
|
|
)
|
|
|
|
// LockedAtomicWriteFile atomically writes a file to disk.
|
|
//
|
|
// On non-Windows platforms, this is a simple wrapper around AtomicWriteFile
|
|
// since concurrent file access errors are not an issue on Unix-like systems.
|
|
//
|
|
// Returns true if the file was written, false if it already existed.
|
|
func LockedAtomicWriteFile(filename string, reader io.Reader, mode os.FileMode) (bool, error) {
|
|
// Check if the file already exists
|
|
if _, err := os.Stat(filename); err == nil {
|
|
// File already exists, skip writing
|
|
return false, nil
|
|
}
|
|
|
|
// File doesn't exist, write it atomically
|
|
if err := AtomicWriteFile(filename, reader, mode); err != nil {
|
|
return false, err
|
|
}
|
|
|
|
return true, nil
|
|
}
|