@@ -79,6 +79,7 @@ func (s *server) backupHandler(w http.ResponseWriter, r *http.Request) {
7979
8080 w .Header ().Set ("Content-Type" , "application/octet-stream" )
8181 w .Header ().Set ("Connection" , "keep-alive" )
82+ w .Header ().Set ("Trailer" , "Success" )
8283
8384 // nolint: gosec
8485 xtrabackup := exec .Command ("xtrabackup" , "--backup" , "--slave-info" , "--stream=xbstream" ,
@@ -112,13 +113,15 @@ func (s *server) backupHandler(w http.ResponseWriter, r *http.Request) {
112113 return
113114 }
114115
115- flusher .Flush ()
116-
117116 if err := xtrabackup .Wait (); err != nil {
118117 log .Error (err , "failed waiting for xtrabackup to finish" )
119118 http .Error (w , "xtrabackup failed" , http .StatusInternalServerError )
120119 return
121120 }
121+
122+ // success
123+ w .Header ().Set ("Success" , "true" )
124+ flusher .Flush ()
122125}
123126
124127func (s * server ) isAuthenticated (r * http.Request ) bool {
@@ -137,3 +140,49 @@ func maxClients(h http.Handler, n int) http.Handler {
137140 h .ServeHTTP (w , r )
138141 })
139142}
143+
144+ // requestABackup connects to specified host and endpoint and gets the backup
145+ func requestABackup (cfg * Config , host , endpoint string ) (* http.Response , error ) {
146+ log .Info ("initialize a backup" , "host" , host , "endpoint" , endpoint )
147+
148+ req , err := http .NewRequest ("GET" , fmt .Sprintf (
149+ "http://%s:%d%s" , host , serverPort , endpoint ), nil )
150+
151+ if err != nil {
152+ return nil , fmt .Errorf ("fail to create request: %s" , err )
153+ }
154+
155+ // set authentification user and password
156+ req .SetBasicAuth (cfg .BackupUser , cfg .BackupPassword )
157+
158+ client := & http.Client {}
159+
160+ resp , err := client .Do (req )
161+ if err != nil || resp .StatusCode != 200 {
162+ status := "unknown"
163+ if resp != nil {
164+ status = resp .Status
165+ }
166+ return nil , fmt .Errorf ("fail to get backup: %s, code: %s" , err , status )
167+ }
168+
169+ return resp , nil
170+ }
171+
172+ func checkBackupTrailers (resp * http.Response ) error {
173+ if values , ok := resp .Trailer ["Success" ]; ! ok || ! stringInSlice ("true" , values ) {
174+ // backup is failed, remove from remote
175+ return fmt .Errorf ("backup failed to be taken: no 'Success' trailer found" )
176+ }
177+
178+ return nil
179+ }
180+
181+ func stringInSlice (a string , list []string ) bool {
182+ for _ , b := range list {
183+ if b == a {
184+ return true
185+ }
186+ }
187+ return false
188+ }
0 commit comments