mirror of
https://github.com/rancher/os.git
synced 2025-09-11 03:31:04 +00:00
Atomic writes
This commit is contained in:
@@ -18,7 +18,6 @@ package cloudinit
|
||||
import (
|
||||
"errors"
|
||||
"flag"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -40,6 +39,7 @@ import (
|
||||
"github.com/coreos/coreos-cloudinit/system"
|
||||
"github.com/rancher/netconf"
|
||||
rancherConfig "github.com/rancher/os/config"
|
||||
"github.com/rancher/os/util"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -71,13 +71,13 @@ func saveFiles(cloudConfigBytes, scriptBytes []byte, metadata datasource.Metadat
|
||||
|
||||
if len(scriptBytes) > 0 {
|
||||
log.Infof("Writing to %s", rancherConfig.CloudConfigScriptFile)
|
||||
if err := ioutil.WriteFile(rancherConfig.CloudConfigScriptFile, scriptBytes, 500); err != nil {
|
||||
if err := util.WriteFileAtomic(rancherConfig.CloudConfigScriptFile, scriptBytes, 500); err != nil {
|
||||
log.Errorf("Error while writing file %s: %v", rancherConfig.CloudConfigScriptFile, err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := ioutil.WriteFile(rancherConfig.CloudConfigBootFile, cloudConfigBytes, 400); err != nil {
|
||||
if err := util.WriteFileAtomic(rancherConfig.CloudConfigBootFile, cloudConfigBytes, 400); err != nil {
|
||||
return err
|
||||
}
|
||||
log.Infof("Written to %s:\n%s", rancherConfig.CloudConfigBootFile, string(cloudConfigBytes))
|
||||
@@ -87,7 +87,7 @@ func saveFiles(cloudConfigBytes, scriptBytes []byte, metadata datasource.Metadat
|
||||
return err
|
||||
}
|
||||
|
||||
if err = ioutil.WriteFile(rancherConfig.MetaDataFile, metaDataBytes, 400); err != nil {
|
||||
if err = util.WriteFileAtomic(rancherConfig.MetaDataFile, metaDataBytes, 400); err != nil {
|
||||
return err
|
||||
}
|
||||
log.Infof("Written to %s:\n%s", rancherConfig.MetaDataFile, string(metaDataBytes))
|
||||
|
@@ -1,11 +1,11 @@
|
||||
package cloudinit
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
yaml "github.com/cloudfoundry-incubator/candiedyaml"
|
||||
"github.com/rancher/os/util"
|
||||
"google.golang.org/cloud/compute/metadata"
|
||||
)
|
||||
|
||||
@@ -111,7 +111,7 @@ func (cc *GceCloudConfig) getMergedUserData() ([]byte, error) {
|
||||
}
|
||||
|
||||
func writeFile(filename string, data []byte) error {
|
||||
if err := ioutil.WriteFile(filename, data, 400); err != nil {
|
||||
if err := util.WriteFileAtomic(filename, data, 400); err != nil {
|
||||
log.Errorf("Could not write file %v", err)
|
||||
return err
|
||||
}
|
||||
|
@@ -14,6 +14,7 @@ import (
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/util"
|
||||
)
|
||||
|
||||
func configSubcommands() []cli.Command {
|
||||
@@ -202,7 +203,7 @@ func export(c *cli.Context) error {
|
||||
if output == "" {
|
||||
fmt.Println(content)
|
||||
} else {
|
||||
err := ioutil.WriteFile(output, []byte(content), 0400)
|
||||
err := util.WriteFileAtomic(output, []byte(content), 0400)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/codegangsta/cli"
|
||||
machineUtil "github.com/docker/machine/utils"
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/util"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -79,11 +80,11 @@ func writeCerts(generateServer bool, hostname []string, cfg *config.CloudConfig,
|
||||
return err
|
||||
}
|
||||
|
||||
if err := ioutil.WriteFile(certPath, []byte(cfg.Rancher.Docker.ServerCert), 0400); err != nil {
|
||||
if err := util.WriteFileAtomic(certPath, []byte(cfg.Rancher.Docker.ServerCert), 0400); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return ioutil.WriteFile(keyPath, []byte(cfg.Rancher.Docker.ServerKey), 0400)
|
||||
return util.WriteFileAtomic(keyPath, []byte(cfg.Rancher.Docker.ServerKey), 0400)
|
||||
|
||||
}
|
||||
|
||||
@@ -117,11 +118,11 @@ func writeCaCerts(cfg *config.CloudConfig, caCertPath, caKeyPath string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := ioutil.WriteFile(caCertPath, []byte(cfg.Rancher.Docker.CACert), 0400); err != nil {
|
||||
if err := util.WriteFileAtomic(caCertPath, []byte(cfg.Rancher.Docker.CACert), 0400); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := ioutil.WriteFile(caKeyPath, []byte(cfg.Rancher.Docker.CAKey), 0400); err != nil {
|
||||
if err := util.WriteFileAtomic(caKeyPath, []byte(cfg.Rancher.Docker.CAKey), 0400); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@@ -239,7 +239,7 @@ func WriteToFile(data interface{}, filename string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
return ioutil.WriteFile(filename, content, 400)
|
||||
return util.WriteFileAtomic(filename, content, 400)
|
||||
}
|
||||
|
||||
func readConfig(bytes []byte, substituteMetadataVars bool, files ...string) (map[interface{}]interface{}, error) {
|
||||
|
28
util/util.go
28
util/util.go
@@ -2,8 +2,10 @@ package util
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
yaml "github.com/cloudfoundry-incubator/candiedyaml"
|
||||
@@ -29,23 +31,33 @@ func Contains(values []string, value string) bool {
|
||||
|
||||
type ReturnsErr func() error
|
||||
|
||||
func FileCopy(src, dest string) (err error) {
|
||||
in, err := os.Open(src)
|
||||
func FileCopy(src, dest string) error {
|
||||
data, err := ioutil.ReadFile(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() { err = in.Close() }()
|
||||
return WriteFileAtomic(dest, data, 0666)
|
||||
}
|
||||
|
||||
out, err := os.Create(dest)
|
||||
func WriteFileAtomic(filename string, data []byte, perm os.FileMode) error {
|
||||
dir, file := path.Split(filename)
|
||||
tempFile, err := ioutil.TempFile(dir, fmt.Sprintf(".%s", file))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() { err = out.Close() }()
|
||||
defer os.Remove(tempFile.Name())
|
||||
|
||||
if _, err := io.Copy(out, in); err != nil {
|
||||
if _, err := tempFile.Write(data); err != nil {
|
||||
return err
|
||||
}
|
||||
return
|
||||
if err := tempFile.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := os.Chmod(tempFile.Name(), perm); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return os.Rename(tempFile.Name(), filename)
|
||||
}
|
||||
|
||||
func Convert(from, to interface{}) error {
|
||||
|
Reference in New Issue
Block a user