/
operation.go
135 lines (115 loc) · 4.14 KB
/
operation.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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
Copyright 2019 The OpenEBS Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package clouduploader
import "github.com/aws/aws-sdk-go/service/s3/s3manager"
const (
// backupDir is remote storage-bucket directory
backupDir = "backups"
)
// Upload will perform upload operation for given file.
// It will create a TCP server through which client can
// connect and upload data to cloud blob storage file
func (c *Conn) Upload(file string, fileSize int64) bool {
c.Log.Infof("Uploading snapshot to '%s' with provider{%s} to bucket{%s}", file, c.provider, c.bucketname)
c.file = file
if c.partSize == 0 {
// MaxUploadParts is limited to 10k
// 100 is arbitrary value considering snapshot metadata
partSize := (fileSize / s3manager.MaxUploadParts) + 100
if partSize < s3manager.MinUploadPartSize {
partSize = s3manager.MinUploadPartSize
}
c.partSize = partSize
}
s := &Server{
Log: c.Log,
cl: c,
}
err := s.Run(OpBackup)
if err != nil {
c.Log.Errorf("Failed to upload snapshot to bucket: %s", err.Error())
if c.bucket.Delete(c.ctx, file) != nil {
c.Log.Errorf("Failed to delete uncompleted snapshot{%s} from cloud", file)
}
return false
}
c.Log.Infof("successfully uploaded object{%s} to {%s}", file, c.provider)
return true
}
// Delete will delete file from cloud blob storage
func (c *Conn) Delete(file string) bool {
c.Log.Infof("Removing snapshot:'%s' from bucket{%s} provider{%s}", file, c.bucketname, c.provider)
if c.bucket.Delete(c.ctx, file) != nil {
c.Log.Errorf("Failed to remove snapshot{%s} from cloud", file)
return false
}
return true
}
// Download will perform restore operation for given file.
// It will create a TCP server through which client can
// connect and download data from cloud blob storage file
func (c *Conn) Download(file string) bool {
c.file = file
s := &Server{
Log: c.Log,
cl: c,
}
err := s.Run(OpRestore)
if err != nil {
c.Log.Errorf("Failed to receive snapshot from bucket: %s", err.Error())
return false
}
c.Log.Infof("successfully restored object{%s} from {%s}", file, c.provider)
return true
}
// Write will write data to cloud blob storage file
func (c *Conn) Write(data []byte, file string) bool {
c.Log.Infof("Writing to {%s} with provider{%v} to bucket{%v}", file, c.provider, c.bucketname)
w, err := c.bucket.NewWriter(c.ctx, file, nil)
if err != nil {
c.Log.Errorf("Failed to obtain writer: %s", err.Error())
return false
}
_, err = w.Write(data)
if err != nil {
c.Log.Errorf("Failed to write data to file{%s} : %s", file, err.Error())
if err = c.bucket.Delete(c.ctx, file); err != nil {
c.Log.Warnf("Failed to delete file {%v} : %s", file, err.Error())
}
return false
}
if err = w.Close(); err != nil {
c.Log.Errorf("Failed to close cloud conn : %s", err.Error())
return false
}
c.Log.Infof("successfully writtern object{%s} to {%s}", file, c.provider)
return true
}
// Read will return content of file from cloud blob storage
func (c *Conn) Read(file string) ([]byte, bool) {
c.Log.Infof("Reading from {%s} with provider{%s} to bucket{%s}", file, c.provider, c.bucketname)
data, err := c.bucket.ReadAll(c.ctx, file)
if err != nil {
c.Log.Errorf("Failed to read data from file{%s} : %s", file, err.Error())
return nil, false
}
c.Log.Infof("successfully read object{%s} to {%s}", file, c.provider)
return data, true
}
// GenerateRemoteFilename will create a file-name specific for given backup
func (c *Conn) GenerateRemoteFilename(file, backup string) string {
if c.backupPathPrefix == "" {
return backupDir + "/" + backup + "/" + c.prefix + "-" + file + "-" + backup
}
return c.backupPathPrefix + "/" + backupDir + "/" + backup + "/" + c.prefix + "-" + file + "-" + backup
}