working commit

This commit is contained in:
2026-03-13 19:02:42 +02:00
parent bebbf79c7a
commit 5c1da77f4c
1329 changed files with 314708 additions and 39 deletions
+50
View File
@@ -0,0 +1,50 @@
/*
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"
"path/filepath"
"helm.sh/helm/v4/internal/third_party/dep/fs"
)
// AtomicWriteFile atomically (as atomic as os.Rename allows) writes a file to a
// disk.
func AtomicWriteFile(filename string, reader io.Reader, mode os.FileMode) error {
tempFile, err := os.CreateTemp(filepath.Split(filename))
if err != nil {
return err
}
tempName := tempFile.Name()
if _, err := io.Copy(tempFile, reader); err != nil {
tempFile.Close() // return value is ignored as we are already on error path
return err
}
if err := tempFile.Close(); err != nil {
return err
}
if err := os.Chmod(tempName, mode); err != nil {
return err
}
return fs.RenameWithFallback(tempName, filename)
}
@@ -0,0 +1,32 @@
//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"
)
// PlatformAtomicWriteFile atomically writes a file to disk.
//
// On non-Windows platforms we don't need extra coordination, so this simply
// delegates to AtomicWriteFile to preserve the existing overwrite behaviour.
func PlatformAtomicWriteFile(filename string, reader io.Reader, mode os.FileMode) error {
return AtomicWriteFile(filename, reader, mode)
}
@@ -0,0 +1,54 @@
//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"
"github.com/gofrs/flock"
)
// PlatformAtomicWriteFile atomically writes a file to disk with file locking to
// prevent concurrent writes. This is particularly useful on Windows where
// concurrent writes to the same file can cause "Access Denied" errors.
//
// The function acquires a lock on the target file and performs an atomic write,
// preserving the existing behaviour of overwriting any previous content once
// the lock is obtained.
func PlatformAtomicWriteFile(filename string, reader io.Reader, mode os.FileMode) error {
// Use a separate lock file to coordinate access between processes
// We cannot lock the target file directly as it would prevent the atomic rename
lockFileName := filename + ".lock"
fileLock := flock.New(lockFileName)
// Lock() ensures serialized access - if another process is writing, this will wait
if err := fileLock.Lock(); err != nil {
return err
}
defer func() {
fileLock.Unlock()
// Clean up the lock file
// Ignore errors as the file might not exist or be in use by another process
os.Remove(lockFileName)
}()
// Perform the atomic write while holding the lock
return AtomicWriteFile(filename, reader, mode)
}