/
remote.go
84 lines (78 loc) · 2.12 KB
/
remote.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package state
import (
"context"
"encoding/json"
"fmt"
"gocloud.dev/blob"
"io/ioutil"
// Import the blob packages we want to be able to open.
_ "gocloud.dev/blob/azureblob"
_ "gocloud.dev/blob/gcsblob"
_ "gocloud.dev/blob/s3blob"
log "github.com/sirupsen/logrus"
)
// RemoteBackend is an implementation of State that performs all operations
// in a cloud storage container e.g s3
type RemoteBackend struct {
state *State
Path string
Bucket string
BlobType string
Region string
}
// GetState returns state from remote source
func (s RemoteBackend) GetState() *State {
bucket, ctx := s.getBucket()
defer bucket.Close()
if s.state.Empty() {
if exist, _ := bucket.Exists(ctx, s.Path); !exist {
log.Debug("State file not found, using empty state")
return s.state
}
stateFile, err := bucket.NewReader(ctx, s.Path, nil)
if err != nil {
log.Fatalf("Could not open state bucket: %s", err)
}
defer stateFile.Close()
byteValue, err := ioutil.ReadAll(stateFile)
if err != nil {
log.Fatalf("Failed to read data from remote state file %s", s.Path)
}
json.Unmarshal(byteValue, &s.state)
}
return s.state
}
// WriteState writes state to remote path
func (s RemoteBackend) WriteState(st *State) error {
log.Debugf("Writing state to remote %s\n", s.Path)
data, err := json.MarshalIndent(st, "", " ")
if err != nil {
log.Fatal("Failed to Load State for Writing")
}
bucket, ctx := s.getBucket()
defer bucket.Close()
stateFile, err := bucket.NewWriter(ctx, s.Path, nil)
if err != nil {
log.Fatalf("Could not open state bucket: %s", err)
}
defer stateFile.Close()
_, writeErr := stateFile.Write(data)
if writeErr != nil {
log.Fatal("Failed to write state to file")
}
return nil
}
func (s RemoteBackend) getBucket() (*blob.Bucket, context.Context) {
ctx := context.Background()
// Open a connection to the bucket.
bucketURL := fmt.Sprintf("%s://%s",
s.BlobType, s.Bucket)
if s.BlobType == "s3" {
bucketURL = fmt.Sprintf("%s?region=%s", bucketURL, s.Region)
}
bucket, err := blob.OpenBucket(ctx, bucketURL)
if err != nil {
log.Fatalf("Failed to setup bucket: %s", err)
}
return bucket, ctx
}