1
0
mirror of https://github.com/rancher/os.git synced 2025-09-11 03:31:04 +00:00

Atomic writes

This commit is contained in:
Josh Curl
2016-06-02 14:32:26 -07:00
parent 97344cc535
commit 4f48569cb2
6 changed files with 34 additions and 20 deletions

View File

@@ -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))

View File

@@ -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
}

View File

@@ -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)
}

View File

@@ -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
}

View File

@@ -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) {

View File

@@ -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 {