This repository has been archived by the owner on Oct 16, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
231 lines (194 loc) · 10 KB
/
main.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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
package main
import (
"fmt"
"github.com/klauspost/cpuid/v2"
"github.com/tbhaxor/syncbit/utils"
"os"
"path"
"sync"
)
// HandleTransfer is used to take backup, execute hooks and restore the zip file
func HandleTransfer(file utils.File, conn utils.SSHConnections, wg *sync.WaitGroup, conf utils.Config) {
// when complete, mark it done
defer wg.Done()
// getting adopter details
adaptors := []*utils.Adaptor{utils.GetAdaptorFromName(file.Src.Adaptor, conf), utils.GetAdaptorFromName(file.Dest.Adaptor, conf)}
utils.Log.Infof("Backing up %s@%s:%s", adaptors[0].User, adaptors[0].Host, file.Src.Path)
// ------ Source Transfer Begin ------
utils.Log.Tracef("Executing global pre backup hooks")
for _, step := range conf.Global.Hooks.PreBackup {
if _, err := conn[file.Src.Adaptor].Run(step); err != nil {
utils.Log.Tracef("Error while executing '%s' global pre backup hook. Error message: %s", step, err.Error())
}
}
utils.Log.Tracef("Completed global pre backup hooks")
utils.Log.Tracef("Executing scoped pre backup hooks")
for _, step := range file.Src.PreBackup {
if _, err := conn[file.Src.Adaptor].Run(fmt.Sprintf("cd %s && %s", file.Src.Path, step)); err != nil {
utils.Log.Tracef("Error while executing '%s' global pre backup hook. Error message: %s", step, err.Error())
}
}
utils.Log.Tracef("Completed scoped pre backup hooks")
utils.Log.Tracef("Starting to zip %s@%s:%s", adaptors[0].User, adaptors[0].Host, file.Src.Path)
// zip file in the directory
if _, err := conn[file.Src.Adaptor].Run(fmt.Sprintf("cd %s && zip dump.zip -r .", file.Src.Path)); err != nil {
utils.Log.Warnf("Skipping %s@%s:%s because zipping failed due to error: %s", adaptors[0].User, adaptors[0].Host, file.Src.Path, err.Error())
return
}
utils.Log.Tracef("Completed zipping %s@%s:%s", adaptors[0].User, adaptors[0].Host, file.Src.Path)
utils.Log.Tracef("Executing global post backup hooks")
for _, step := range conf.Global.Hooks.PostBackup {
if _, err := conn[file.Src.Adaptor].Run(step); err != nil {
utils.Log.Tracef("Error while executing '%s' global post backup hook. Error message: %s", step, err.Error())
}
}
utils.Log.Tracef("Completed global post backup hooks")
utils.Log.Tracef("Executing scoped post backup hooks")
for _, step := range file.Src.PostBackup {
if _, err := conn[file.Src.Adaptor].Run(fmt.Sprintf("cd %s && %s", file.Src.Path, step)); err != nil {
utils.Log.Tracef("Error while executing '%s' scoped post backup hook. Error message: %s", step, err.Error())
}
}
utils.Log.Tracef("Completed scoped post backup hooks")
utils.Log.Tracef("Executing global pre download hooks")
for _, step := range conf.Global.Hooks.PreDownload {
if _, err := conn[file.Src.Adaptor].Run(step); err != nil {
utils.Log.Tracef("Error while executing '%s' global pre download hook. Error message: %s", step, err.Error())
}
}
utils.Log.Tracef("Completed global pre download hooks")
utils.Log.Tracef("Executing scoped pre download hooks")
for _, step := range file.Src.PreDownload {
if _, err := conn[file.Src.Adaptor].Run(fmt.Sprintf("cd %s && %s", file.Src.Path, step)); err != nil {
utils.Log.Tracef("Error while executing '%s' scoped pre download hook. Error message: %s", step, err.Error())
}
}
utils.Log.Tracef("Completed scoped pre download hooks")
// download the file to local staging
srcZip := fmt.Sprintf("%s/dump.zip", file.Src.Path)
stagerName := utils.GetStagingFileName() + ".zip"
destZip := path.Join(os.TempDir(), stagerName)
// clean the files when the function is over
defer os.Remove(destZip)
defer utils.Log.Tracef("Removing %s", destZip)
defer conn[file.Src.Adaptor].Run(fmt.Sprintf("rm -rf %s", srcZip))
defer utils.Log.Tracef("Removing %s@%s:%s", adaptors[0].User, adaptors[0].Host, srcZip)
defer conn[file.Src.Adaptor].Run(fmt.Sprintf("rm -rf /tmp/%s", stagerName))
defer utils.Log.Tracef("Removing %s@%s:/tmp/%s", adaptors[1].User, adaptors[1].Host, stagerName)
utils.Log.Tracef("Downloaded %s@%s:%s to %s in local", adaptors[0].User, adaptors[0].Host, srcZip, destZip)
// finally download file to staging
if err := conn[file.Src.Adaptor].Download(srcZip, destZip); err != nil {
utils.Log.Warnf("Skipping %s@%s:%s because downloading zip failed due to error: %s", adaptors[0].User, adaptors[0].Host, file.Src.Path, err.Error())
return
}
utils.Log.Tracef("Downloaded %s@%s:%s to %s in local", adaptors[0].User, adaptors[0].Host, srcZip, destZip)
utils.Log.Tracef("Executing global post download hooks")
for _, step := range conf.Global.Hooks.PostDownload {
if _, err := conn[file.Src.Adaptor].Run(step); err != nil {
utils.Log.Tracef("Error while executing '%s' global post download hook. Error message: %s", step, err.Error())
}
}
utils.Log.Tracef("Completed global post download hooks")
utils.Log.Tracef("Executing scoped post download hooks")
for _, step := range file.Src.PostDownload {
if _, err := conn[file.Src.Adaptor].Run(fmt.Sprintf("cd %s && %s", file.Src.PostDownload, step)); err != nil {
utils.Log.Tracef("Error while executing '%s' scoped post download hook. Error message: %s", step, err.Error())
}
}
utils.Log.Tracef("Completed scoped post download hooks")
// ------ Destination Transfer Begins -------
utils.Log.Infof("Restoring %s to %s@%s:%s", destZip, adaptors[1].User, adaptors[1].Host, file.Dest.Path)
utils.Log.Tracef("Executing global pre upload hooks")
for _, step := range conf.Global.Hooks.PreUpload {
if _, err := conn[file.Dest.Adaptor].Run(step); err != nil {
utils.Log.Tracef("Error while executing '%s' global pre upload hook. Error message: %s", step, err.Error())
}
}
utils.Log.Tracef("Completed global pre upload hooks")
utils.Log.Tracef("Executing scoped pre upload hooks")
for _, step := range file.Dest.PreUpload {
if _, err := conn[file.Dest.Adaptor].Run(step); err != nil {
utils.Log.Tracef("Error while executing '%s' scoped pre upload hook. Error message: %s", step, err.Error())
}
}
utils.Log.Tracef("Completed scoped pre upload hooks")
utils.Log.Tracef("Uploading file from %s of local to %s@%s:/tmp/%s", destZip, adaptors[1].User, adaptors[1].Host, stagerName)
// upload file to temporary directory
if err := conn[file.Dest.Adaptor].Upload(destZip, fmt.Sprintf("/tmp/%s", stagerName)); err != nil {
utils.Log.Warnf("Skipping %s@%s:%s because uploading zip failed due to error: %s", adaptors[1].User, adaptors[1].Host, file.Dest.Path, err.Error())
return
}
utils.Log.Tracef("Uploaded file from %s of local to %s@%s:/tmp/%s", destZip, adaptors[1].User, adaptors[1].Host, stagerName)
utils.Log.Tracef("Executing global post upload hooks")
for _, step := range conf.Global.Hooks.PostUpload {
if _, err := conn[file.Dest.Adaptor].Run(step); err != nil {
utils.Log.Tracef("Error while executing '%s' global post upload hook. Error message: %s", step, err.Error())
}
}
utils.Log.Tracef("Completed global post upload hooks")
utils.Log.Tracef("Executing scoped post upload hooks")
for _, step := range file.Dest.PostUpload {
if _, err := conn[file.Dest.Adaptor].Run(step); err != nil {
utils.Log.Tracef("Error while executing '%s' scoped post upload hook. Error message: %s", step, err.Error())
}
}
utils.Log.Tracef("Completed scoped post upload hooks")
utils.Log.Tracef("Executing global pre restore hooks")
for _, step := range conf.Global.Hooks.PreRestore {
if _, err := conn[file.Dest.Adaptor].Run(step); err != nil {
utils.Log.Tracef("Error while executing '%s' global pre restore hook. Error message: %s", step, err.Error())
}
}
utils.Log.Tracef("Completed global pre restore hooks")
utils.Log.Tracef("Executing scoped pre restore hooks")
for _, step := range file.Dest.PreRestore {
if _, err := conn[file.Dest.Adaptor].Run(step); err != nil {
utils.Log.Tracef("Error while executing '%s' scoped pre restore hook. Error message: %s", step, err.Error())
}
}
utils.Log.Tracef("Completed scoped pre restore hooks")
utils.Log.Tracef("Unzipping file from %s@%s:/tmp/%s to %s@%s:%s", adaptors[1].User, adaptors[1].Host, stagerName, adaptors[1].User, adaptors[1].Host, file.Dest.Path)
// unzip the temp file to location in Dest.Path
if _, err := conn[file.Dest.Adaptor].Run(fmt.Sprintf("unzip -o /tmp/%s -d %s", stagerName, file.Dest.Path)); err != nil {
utils.Log.Warnf("Skipping %s@%s:%s because uploading zip failed due to error: %s", adaptors[1].User, adaptors[1].Host, file.Dest.Path, err.Error())
return
}
utils.Log.Tracef("Done unzipping file from %s@%s:/tmp/%s to %s@%s:%s", adaptors[1].User, adaptors[1].Host, stagerName, adaptors[1].User, adaptors[1].Host, file.Dest.Path)
utils.Log.Tracef("Executing global post restore hooks")
for _, step := range conf.Global.Hooks.PostRestore {
if _, err := conn[file.Dest.Adaptor].Run(step); err != nil {
utils.Log.Tracef("Error while executing '%s' global post restore hook. Error message: %s", step, err.Error())
}
}
utils.Log.Tracef("Completed global post restore hooks")
utils.Log.Tracef("Executing scoped post restore hooks")
for _, step := range file.Dest.PostRestore {
if _, err := conn[file.Dest.Adaptor].Run(fmt.Sprintf("cd %s && %s", file.Dest.Path, step)); err != nil {
utils.Log.Tracef("Error while executing '%s' scoped post restore hook. Error message: %s", step, err.Error())
}
}
utils.Log.Tracef("Completed scoped post restore hooks")
utils.Log.Infof("%s@%s:%s has been successfully restored to %s@%s:%s", adaptors[0].User, adaptors[0].Host, file.Src.Path, adaptors[1].User, adaptors[1].Host, file.Dest.Path)
}
func main() {
// get parsed config
conf := utils.GetConfig()
// get ssh connection
conn := utils.GetSSHConnections(conf)
// when this function call complete disconnect all ssh connections
defer utils.DisconnectSSHConnections(conn)
nThreads := cpuid.CPU.ThreadsPerCore * cpuid.CPU.PhysicalCores
if nThreads > len(conf.Files) {
utils.Log.Infof("Using %d workers", len(conf.Files))
} else {
utils.Log.Infof("Using %d workers", nThreads)
}
for _, chunk := range utils.ChunkifyFiles(conf.Files, nThreads) {
var wg sync.WaitGroup
for _, file := range chunk {
wg.Add(1)
go HandleTransfer(file, conn, &wg, conf)
}
wg.Wait()
}
}