netbird/util/file.go
Maycon Santos 5546eba36a
Write to temp file before saving data (#238)
* Create temp file before saving data

On the event of full disk, we may encounter the case where the
destination file get replaced by an empty file as the
ioutil.WriteFile truncates the destination before write.

* Close the tempFile instance before moving it

* Blacklist Wireguard interfaces for ICE checks
2022-02-20 19:03:16 +01:00

104 lines
1.8 KiB
Go

package util
import (
"encoding/json"
"io"
"io/ioutil"
"os"
"path/filepath"
)
// WriteJson writes JSON config object to a file creating parent directories if required
// The output JSON is pretty-formatted
func WriteJson(file string, obj interface{}) error {
configDir, configFileName := filepath.Split(file)
err := os.MkdirAll(configDir, 0750)
if err != nil {
return err
}
// make it pretty
bs, err := json.MarshalIndent(obj, "", " ")
if err != nil {
return err
}
tempFile, err := ioutil.TempFile(configDir, ".*"+configFileName)
if err != nil {
return err
}
tempFileName := tempFile.Name()
// closing file ops as windows doesn't allow to move it
err = tempFile.Close()
if err != nil {
return err
}
defer func() {
_, err = os.Stat(tempFileName)
if err == nil {
os.Remove(tempFileName)
}
}()
err = ioutil.WriteFile(tempFileName, bs, 0600)
if err != nil {
return err
}
err = os.Rename(tempFileName, file)
if err != nil {
return err
}
return nil
}
// ReadJson reads JSON config file and maps to a provided interface
func ReadJson(file string, res interface{}) (interface{}, error) {
f, err := os.Open(file)
if err != nil {
return nil, err
}
defer f.Close()
bs, err := ioutil.ReadAll(f)
if err != nil {
return nil, err
}
err = json.Unmarshal(bs, &res)
if err != nil {
return nil, err
}
return res, nil
}
// CopyFileContents copies contents of the given src file to the dst file
func CopyFileContents(src, dst string) (err error) {
in, err := os.Open(src)
if err != nil {
return
}
defer in.Close()
out, err := os.Create(dst)
if err != nil {
return
}
defer func() {
cErr := out.Close()
if err == nil {
err = cErr
}
}()
if _, err = io.Copy(out, in); err != nil {
return
}
err = out.Sync()
return
}