== REQUIREMENTS
- Go, for `nsscash`
- * github.com/pkg/errors
* github.com/BurntSushi/toml
+ * github.com/google/renameio
+ * github.com/pkg/errors
- C compiler, for `libnss_cash.so.2`
- HTTP(S) server to provide the passwd/group/etc. files
"syscall"
"time"
+ "github.com/google/renameio"
"github.com/pkg/errors"
)
return fmt.Errorf("refusing to write empty file")
}
- // Write the file in an atomic fashion by creating a temporary file
- // and renaming it over the target file
-
- dir := filepath.Dir(file.Path)
- name := filepath.Base(file.Path)
-
- f, err := ioutil.TempFile(dir, "tmp-"+name+"-")
+ f, err := renameio.TempFile(filepath.Dir(file.Path), file.Path)
if err != nil {
return err
}
- defer os.Remove(f.Name())
- defer f.Close()
+ defer f.Cleanup()
// Apply permissions/user/group from the target file but remove the
// write permissions to discourage manual modifications, use Stat
if err != nil {
return err
}
- err = f.Sync()
- if err != nil {
- return err
- }
- return os.Rename(f.Name(), file.Path)
+ return f.CloseAtomicallyReplace()
}
require (
github.com/BurntSushi/toml v0.3.1
+ github.com/google/renameio v0.1.1-0.20200217212219-353f81969824
github.com/pkg/errors v0.8.1
)
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/google/renameio v0.1.1-0.20200217212219-353f81969824 h1:9q700G0beHecUuiZOuKgNqNsGQixTeDLnzVZ5nsW3lc=
+github.com/google/renameio v0.1.1-0.20200217212219-353f81969824/go.mod h1:t/HQoYBZSsWSNK35C6CO/TpPLDVWvxOHboWUAweKUpk=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
"log"
"os"
"path/filepath"
+
+ "github.com/google/renameio"
)
func main() {
return fmt.Errorf("unsupported file type %v", t)
}
- dstDir := filepath.Dir(dstPath)
- dstName := filepath.Base(dstPath)
-
// We must create the file first or deployFile() will abort; this is
// ugly because deployFile() already performs an atomic replacement
// but the simplest solution with the least duplicate code
- f, err := ioutil.TempFile(dstDir, "tmp-"+dstName+"-")
+ f, err := renameio.TempFile(filepath.Dir(dstPath), dstPath)
if err != nil {
return err
}
- tmpPath := f.Name()
- defer os.Remove(tmpPath)
- f.Close()
+ defer f.Cleanup()
err = deployFile(&File{
Type: t,
Url: srcPath,
- Path: tmpPath,
+ Path: f.Name(),
body: x.Bytes(),
})
if err != nil {
return err
}
- return os.Rename(tmpPath, dstPath)
+ return f.CloseAtomicallyReplace()
}
"os"
"path/filepath"
"time"
+
+ "github.com/google/renameio"
)
type State struct {
return err
}
- // Write the file in an atomic fashion by creating a temporary file
- // and renaming it over the target file
-
- dir := filepath.Dir(path)
- name := filepath.Base(path)
-
- f, err := ioutil.TempFile(dir, "tmp-"+name+"-")
+ f, err := renameio.TempFile(filepath.Dir(path), path)
if err != nil {
return err
}
- defer os.Remove(f.Name())
- defer f.Close()
+ defer f.Cleanup()
_, err = f.Write(x)
if err != nil {
return err
}
- err = f.Sync()
- if err != nil {
- return err
- }
- return os.Rename(f.Name(), path)
+ return f.CloseAtomicallyReplace()
}