Replace os.Write with AtomicWrite function

Signed-off-by: Derek Nola <derek.nola@suse.com>
pull/8252/head
Derek Nola 2023-08-01 10:01:54 -07:00
parent ced330c66a
commit b967f92785
3 changed files with 29 additions and 2 deletions

View File

@ -777,7 +777,7 @@ func genEncryptionConfigAndState(controlConfig *config.Control) error {
if err != nil {
return err
}
if err := os.WriteFile(runtime.EncryptionConfig, b, 0600); err != nil {
if err := util.AtomicWrite(runtime.EncryptionConfig, b, 0600); err != nil {
return err
}
encryptionConfigHash := sha256.Sum256(b)

View File

@ -8,6 +8,7 @@ import (
"os"
"github.com/k3s-io/k3s/pkg/daemons/config"
"github.com/k3s-io/k3s/pkg/util"
"github.com/k3s-io/k3s/pkg/version"
corev1 "k8s.io/api/core/v1"
@ -106,7 +107,7 @@ func WriteEncryptionConfig(runtime *config.ControlRuntime, keys []apiserverconfi
if err != nil {
return err
}
return os.WriteFile(runtime.EncryptionConfig, jsonfile, 0600)
return util.AtomicWrite(runtime.EncryptionConfig, jsonfile, 0600)
}
func GenEncryptionConfigHash(runtime *config.ControlRuntime) (string, error) {

View File

@ -2,6 +2,7 @@ package util
import (
"os"
"path/filepath"
"strings"
"time"
@ -37,3 +38,28 @@ func ReadFile(path string) (string, error) {
return "", errors.New("Timeout while trying to read the file")
}
// AtomicWrite firsts writes data to a temp file, then renames to the destination file.
// This ensures that the destination file is never partially written.
func AtomicWrite(fileName string, data []byte, perm os.FileMode) error {
f, err := os.CreateTemp(filepath.Dir(fileName), filepath.Base(fileName)+".tmp")
if err != nil {
return err
}
tmpName := f.Name()
if _, err := f.Write(data); err != nil {
f.Close()
return err
}
if err := f.Chmod(perm); err != nil {
return err
}
if err := f.Sync(); err != nil {
return err
}
if err := f.Close(); err != nil {
return err
}
return os.Rename(tmpName, fileName)
}