1
1
# -*- coding: utf-8 -*-
2
2
import _thread
3
+ import logging
3
4
import pickle
4
5
import shutil
5
6
import subprocess
7
+ import threading
8
+ import traceback
6
9
from datetime import datetime
7
10
from pathlib import Path
8
11
38
41
URL_BACKUP_PATCH_HASH , URL_BACKUP_PATCH_FILE , URL_RESTORE_FINISH
39
42
40
43
44
+ def clog ():
45
+ return logging .getLogger ('BACKUP_CLIENT' )
46
+
47
+
48
+ def slog ():
49
+ return logging .getLogger ('BACKUP_SERVER' )
50
+
51
+
41
52
class BackupClient :
42
- def __init__ (self , app , hive_setting ):
53
+ def __init__ (self , app = None , hive_setting = None ):
54
+ self .http = HttpClient ()
55
+ self .backup_thread = None
43
56
self .hive_setting = hive_setting
44
- self .mongo_host , self .mongo_port = self .hive_setting .MONGO_HOST , self .hive_setting .MONGO_PORT
57
+ self .mongo_host , self .mongo_port = None , None
58
+ if hive_setting :
59
+ self .mongo_host , self .mongo_port = self .hive_setting .MONGO_HOST , self .hive_setting .MONGO_PORT
45
60
self .auth = Auth (app , hive_setting )
46
- self .http = HttpClient ()
47
61
48
62
def check_backup_status (self , did ):
49
63
doc = cli .find_one_origin (DID_INFO_DB_NAME , VAULT_BACKUP_INFO_COL , {DID : did })
@@ -75,7 +89,10 @@ def execute_backup(self, did, credential_info, backup_service_info, access_token
75
89
if use_storage > backup_service_info [VAULT_BACKUP_SERVICE_MAX_STORAGE ]:
76
90
raise InsufficientStorageException (msg = 'Insufficient storage to execute backup.' )
77
91
78
- _thread .start_new_thread (self .__class__ .backup_main , (did , self ))
92
+ clog ().debug ('start new thread for backup processing.' )
93
+
94
+ self .backup_thread = threading .Thread (target = BackupClient .backup_main , args = (did , self ))
95
+ self .backup_thread .start ()
79
96
80
97
def update_backup_state (self , did , state , msg ):
81
98
cli .update_one_origin (DID_INFO_DB_NAME ,
@@ -102,20 +119,29 @@ def import_mongodb(self, did):
102
119
@staticmethod
103
120
def backup_main (did , client ):
104
121
try :
122
+ clog ().info (f'[backup_main] enter backup thread, { did } , { client } .' )
105
123
client .backup (did )
106
- except Exception as e :
124
+ except BaseException as e :
125
+ clog ().error (f'Failed to backup really: { traceback .format_exc ()} ' )
107
126
client .update_backup_state (did , VAULT_BACKUP_STATE_STOP , VAULT_BACKUP_MSG_FAILED )
127
+ clog ().info ('[backup_main] leave backup thread.' )
108
128
109
129
def backup (self , did ):
130
+ clog ().info ('[backup_main] enter backup().' )
110
131
self .export_mongodb_data (did )
132
+ clog ().info ('[backup_main] success to export mongodb data.' )
111
133
vault_root = get_vault_path (did )
112
134
doc = cli .find_one_origin (DID_INFO_DB_NAME , VAULT_BACKUP_INFO_COL , {DID : did })
135
+ clog ().info ('[backup_main] success to get backup info.' )
113
136
self .backup_really (vault_root , doc [VAULT_BACKUP_INFO_DRIVE ], doc [VAULT_BACKUP_INFO_TOKEN ])
137
+ clog ().info ('[backup_main] success to execute backup.' )
114
138
115
139
checksum_list = get_file_checksum_list (vault_root )
116
140
self .backup_finish (doc [VAULT_BACKUP_INFO_DRIVE ], doc [VAULT_BACKUP_INFO_TOKEN ], checksum_list )
141
+ clog ().info ('[backup_main] success to finish backup.' )
117
142
self .delete_mongodb_data (did )
118
143
self .update_backup_state (did , VAULT_BACKUP_STATE_STOP , VAULT_BACKUP_MSG_SUCCESS )
144
+ clog ().info ('[backup_main] success to backup really.' )
119
145
120
146
def restore (self , did ):
121
147
vault_root = get_vault_path (did )
@@ -148,7 +174,7 @@ def restore_really(self, vault_root, host_url, access_token):
148
174
self .restore_delete_files (host_url , access_token , delete_files )
149
175
150
176
def backup_finish (self , host_url , access_token , checksum_list ):
151
- self .http .post (host_url + URL_BACKUP_FINISH , access_token , {'checksum_list' : checksum_list })
177
+ self .http .post (host_url + URL_BACKUP_FINISH , access_token , {'checksum_list' : checksum_list }, is_body = False )
152
178
153
179
def diff_backup_files (self , remote_files , local_files , vault_root ):
154
180
remote_files_d = dict ((d [1 ], d [0 ]) for d in remote_files ) # name: checksum
@@ -169,10 +195,9 @@ def diff_restore_files(self, remote_files, local_files, vault_root):
169
195
return new_files , patch_files , delete_files
170
196
171
197
def backup_new_files (self , host_url , access_token , new_files ):
172
- for info in new_files :
173
- src_file , dst_file = info [0 ], info [1 ]
174
- with open (src_file , 'br' ) as f :
175
- self .http .put (host_url + URL_BACKUP_FILE + f'?file={ dst_file } ' , access_token , f )
198
+ for full_name , name in new_files :
199
+ with open (full_name , 'br' ) as f :
200
+ self .http .put (host_url + URL_BACKUP_FILE + f'?file={ name } ' , access_token , f , is_body = False )
176
201
177
202
def restore_new_files (self , host_url , access_token , new_files ):
178
203
for info in new_files :
@@ -206,7 +231,8 @@ def backup_patch_files(self, host_url, access_token, patch_files):
206
231
pickle .dump (patch_data , f )
207
232
208
233
with open (temp_file .as_posix (), 'rb' ) as f :
209
- self .http .post (host_url + URL_BACKUP_PATCH_FILE + f'?file={ full_name } ' , body = f , is_json = False )
234
+ self .http .post (host_url + URL_BACKUP_PATCH_FILE + f'?file={ full_name } ' ,
235
+ body = f , is_json = False , is_body = False )
210
236
211
237
temp_file .unlink ()
212
238
@@ -255,6 +281,7 @@ def restore_main(did, client):
255
281
try :
256
282
client .restore (did )
257
283
except Exception as e :
284
+ clog ().error (f'Failed to restore really: { traceback .format_exc ()} ' )
258
285
client .update_backup_state (did , VAULT_BACKUP_STATE_STOP , VAULT_BACKUP_MSG_FAILED )
259
286
260
287
def restore_finish (self , did , host_url , access_token ):
@@ -354,12 +381,12 @@ def backup_finish(self, checksum_list):
354
381
def backup_files (self ):
355
382
did , _ , _ = self .__check_auth_backup ()
356
383
357
- result = dict ()
384
+ backup_files = list ()
358
385
backup_root = get_vault_backup_path (did )
359
386
if backup_root .exists ():
360
387
md5_list = deal_dir (backup_root .as_posix (), get_file_md5_info )
361
- result [ ' backup_files' ] = [(md5 [0 ], Path (md5 [1 ]).relative_to (backup_root ).as_posix ()) for md5 in md5_list ]
362
- return result
388
+ backup_files = [(md5 [0 ], Path (md5 [1 ]).relative_to (backup_root ).as_posix ()) for md5 in md5_list ]
389
+ return { 'backup_files' : backup_files }
363
390
364
391
def backup_get_file (self , file_name ):
365
392
if not file_name :
0 commit comments