Commit b967f927 authored by Derek Nola's avatar Derek Nola

Replace os.Write with AtomicWrite function

parent ced330c6
...@@ -777,7 +777,7 @@ func genEncryptionConfigAndState(controlConfig *config.Control) error { ...@@ -777,7 +777,7 @@ func genEncryptionConfigAndState(controlConfig *config.Control) error {
if err != nil { if err != nil {
return err return err
} }
if err := os.WriteFile(runtime.EncryptionConfig, b, 0600); err != nil { if err := util.AtomicWrite(runtime.EncryptionConfig, b, 0600); err != nil {
return err return err
} }
encryptionConfigHash := sha256.Sum256(b) encryptionConfigHash := sha256.Sum256(b)
......
...@@ -8,6 +8,7 @@ import ( ...@@ -8,6 +8,7 @@ import (
"os" "os"
"github.com/k3s-io/k3s/pkg/daemons/config" "github.com/k3s-io/k3s/pkg/daemons/config"
"github.com/k3s-io/k3s/pkg/util"
"github.com/k3s-io/k3s/pkg/version" "github.com/k3s-io/k3s/pkg/version"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
...@@ -106,7 +107,7 @@ func WriteEncryptionConfig(runtime *config.ControlRuntime, keys []apiserverconfi ...@@ -106,7 +107,7 @@ func WriteEncryptionConfig(runtime *config.ControlRuntime, keys []apiserverconfi
if err != nil { if err != nil {
return err return err
} }
return os.WriteFile(runtime.EncryptionConfig, jsonfile, 0600) return util.AtomicWrite(runtime.EncryptionConfig, jsonfile, 0600)
} }
func GenEncryptionConfigHash(runtime *config.ControlRuntime) (string, error) { func GenEncryptionConfigHash(runtime *config.ControlRuntime) (string, error) {
......
...@@ -2,6 +2,7 @@ package util ...@@ -2,6 +2,7 @@ package util
import ( import (
"os" "os"
"path/filepath"
"strings" "strings"
"time" "time"
...@@ -37,3 +38,28 @@ func ReadFile(path string) (string, error) { ...@@ -37,3 +38,28 @@ func ReadFile(path string) (string, error) {
return "", errors.New("Timeout while trying to read the file") 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)
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment