From aee27314eb3734bf7e7284891a79639530e5c46c Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 5 Mar 2015 13:15:14 -0800 Subject: [PATCH] state/remote: add undocumented file backend for remote state --- state/remote/file.go | 64 +++++++++++++++++++++++++++++++++++++++ state/remote/file_test.go | 29 ++++++++++++++++++ state/remote/remote.go | 3 ++ 3 files changed, 96 insertions(+) create mode 100644 state/remote/file.go create mode 100644 state/remote/file_test.go diff --git a/state/remote/file.go b/state/remote/file.go new file mode 100644 index 000000000..f3cbdb45e --- /dev/null +++ b/state/remote/file.go @@ -0,0 +1,64 @@ +package remote + +import ( + "bytes" + "crypto/md5" + "fmt" + "io" + "os" +) + +func fileFactory(conf map[string]string) (Client, error) { + path, ok := conf["path"] + if !ok { + return nil, fmt.Errorf("missing 'path' configuration") + } + + return &FileClient{ + Path: path, + }, nil +} + +// FileClient is a remote client that stores data locally on disk. +// This is only used for development reasons to test remote state... locally. +type FileClient struct { + Path string +} + +func (c *FileClient) Get() (*Payload, error) { + var buf bytes.Buffer + f, err := os.Open(c.Path) + if err != nil { + if os.IsNotExist(err) { + return nil, nil + } + + return nil, err + } + defer f.Close() + + if _, err := io.Copy(&buf, f); err != nil { + return nil, err + } + + md5 := md5.Sum(buf.Bytes()) + return &Payload{ + Data: buf.Bytes(), + MD5: md5[:], + }, nil +} + +func (c *FileClient) Put(data []byte) error { + f, err := os.Create(c.Path) + if err != nil { + return err + } + defer f.Close() + + _, err = f.Write(data) + return err +} + +func (c *FileClient) Delete() error { + return os.Remove(c.Path) +} diff --git a/state/remote/file_test.go b/state/remote/file_test.go new file mode 100644 index 000000000..352d787db --- /dev/null +++ b/state/remote/file_test.go @@ -0,0 +1,29 @@ +package remote + +import ( + "io/ioutil" + "os" + "testing" +) + +func TestFileClient_impl(t *testing.T) { + var _ Client = new(FileClient) +} + +func TestFileClient(t *testing.T) { + tf, err := ioutil.TempFile("", "tf") + if err != nil { + t.Fatalf("err: %s", err) + } + tf.Close() + defer os.Remove(tf.Name()) + + client, err := fileFactory(map[string]string{ + "path": tf.Name(), + }) + if err != nil { + t.Fatalf("bad: %s", err) + } + + testClient(t, client) +} diff --git a/state/remote/remote.go b/state/remote/remote.go index fe730531e..19632a9fd 100644 --- a/state/remote/remote.go +++ b/state/remote/remote.go @@ -39,4 +39,7 @@ var BuiltinClients = map[string]Factory{ "atlas": atlasFactory, "consul": consulFactory, "http": httpFactory, + + // This is used for development purposes only. + "_local": fileFactory, }