github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/lib/file/atomic.go (about) 1 package file 2 3 import ( 4 "fmt" 5 "os" 6 "path/filepath" 7 8 "github.com/hashicorp/go-uuid" 9 ) 10 11 // WriteAtomicWithPerms creates a temp file with specific permissions and then renames and 12 // moves it to the path. 13 func WriteAtomicWithPerms(path string, contents []byte, dirPerms, filePerms os.FileMode) error { 14 15 uuid, err := uuid.GenerateUUID() 16 if err != nil { 17 return err 18 } 19 tempPath := fmt.Sprintf("%s-%s.tmp", path, uuid) 20 21 // Make a directory within the current one. 22 if err := os.MkdirAll(filepath.Dir(path), dirPerms); err != nil { 23 return err 24 } 25 26 // File opened with write only permissions. Will be created if it does not exist 27 // file is given specific permissions 28 fh, err := os.OpenFile(tempPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, filePerms) 29 if err != nil { 30 return err 31 } 32 33 defer os.RemoveAll(tempPath) // clean up 34 35 if _, err := fh.Write(contents); err != nil { 36 fh.Close() 37 return err 38 } 39 // Commits the current state of the file to disk 40 if err := fh.Sync(); err != nil { 41 fh.Close() 42 return err 43 } 44 if err := fh.Close(); err != nil { 45 return err 46 } 47 if err := os.Rename(tempPath, path); err != nil { 48 return err 49 } 50 return nil 51 }