mirror of https://github.com/kubernetes/kops.git
Allow nodeup (and others) to replace in-use files
By creating a tempfile and then moving the file into place, we both write more atomically and we can overwrite in-use files. Issue #10122
This commit is contained in:
parent
e109c9c583
commit
acb247fa5f
|
|
@ -19,8 +19,10 @@ package fi
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
|
|
@ -49,22 +51,48 @@ func WriteFile(destPath string, contents Resource, fileMode os.FileMode, dirMode
|
||||||
func writeFileContents(destPath string, src Resource, fileMode os.FileMode) error {
|
func writeFileContents(destPath string, src Resource, fileMode os.FileMode) error {
|
||||||
klog.Infof("Writing file %q", destPath)
|
klog.Infof("Writing file %q", destPath)
|
||||||
|
|
||||||
out, err := os.OpenFile(destPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, fileMode)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error opening destination file %q: %v", destPath, err)
|
|
||||||
}
|
|
||||||
defer out.Close()
|
|
||||||
|
|
||||||
in, err := src.Open()
|
in, err := src.Open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error opening source resource for file %q: %v", destPath, err)
|
return fmt.Errorf("error opening source resource for file %q: %v", destPath, err)
|
||||||
}
|
}
|
||||||
defer SafeClose(in)
|
defer SafeClose(in)
|
||||||
|
|
||||||
_, err = io.Copy(out, in)
|
dir := filepath.Dir(destPath)
|
||||||
|
|
||||||
|
tempFile, err := ioutil.TempFile(dir, ".writefile")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error writing file %q: %v", destPath, err)
|
return fmt.Errorf("error creating temp file in %q: %w", dir, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
closeTempFile := true
|
||||||
|
deleteTempFile := true
|
||||||
|
defer func() {
|
||||||
|
if closeTempFile {
|
||||||
|
if err := tempFile.Close(); err != nil {
|
||||||
|
klog.Warningf("error closing tempfile %q: %v", tempFile.Name(), err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if deleteTempFile {
|
||||||
|
if err := os.Remove(tempFile.Name()); err != nil {
|
||||||
|
klog.Warningf("error removing tempfile %q: %v", tempFile.Name(), err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
if _, err := io.Copy(tempFile, in); err != nil {
|
||||||
|
return fmt.Errorf("error writing file %q: %v", tempFile.Name(), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := tempFile.Close(); err != nil {
|
||||||
|
return fmt.Errorf("error closing temp file %q: %w", tempFile.Name(), err)
|
||||||
|
}
|
||||||
|
closeTempFile = false
|
||||||
|
|
||||||
|
if err := os.Rename(tempFile.Name(), destPath); err != nil {
|
||||||
|
return fmt.Errorf("error renaming temp file %q -> %q: %w", tempFile.Name(), destPath, err)
|
||||||
|
}
|
||||||
|
deleteTempFile = false
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue