diff --git a/internal/app/machined/pkg/controllers/files/etcfile.go b/internal/app/machined/pkg/controllers/files/etcfile.go index 39c413c8d8..3ba2ed116c 100644 --- a/internal/app/machined/pkg/controllers/files/etcfile.go +++ b/internal/app/machined/pkg/controllers/files/etcfile.go @@ -5,6 +5,7 @@ package files import ( + "bytes" "context" "errors" "fmt" @@ -132,7 +133,7 @@ func (ctrl *EtcFileController) Run(ctx context.Context, r controller.Runtime, lo logger.Debug("writing file contents", zap.String("dst", dst), zap.Stringer("version", spec.Metadata().Version())) - if err = os.WriteFile(dst, spec.TypedSpec().Contents, spec.TypedSpec().Mode); err != nil { + if err = updateFile(dst, spec.TypedSpec().Contents, spec.TypedSpec().Mode); err != nil { return fmt.Errorf("error updating %q: %w", dst, err) } @@ -190,3 +191,14 @@ func createBindMount(src, dst string, mode os.FileMode) (err error) { return nil } + +// updateFile is like `os.WriteFile`, but it will only update the file if the +// contents have changed. +func updateFile(filename string, contents []byte, mode os.FileMode) error { + oldContents, err := os.ReadFile(filename) + if err == nil && bytes.Equal(oldContents, contents) { + return nil + } + + return os.WriteFile(filename, contents, mode) +}