backup.py

changeset 6
46c89e5a219f
parent 5
4c5514b2fa76
child 7
e189d4a6cb8c
equal deleted inserted replaced
5:4c5514b2fa76 6:46c89e5a219f
6 import logging 6 import logging
7 import time 7 import time
8 from instance import BorgInstance 8 from instance import BorgInstance
9 from queue import Queue 9 from queue import Queue
10 from threading import Thread, Lock 10 from threading import Thread, Lock
11
12 loglevel_translation={
13 'CRITICAL': logging.CRITICAL,
14 'ERROR': logging.ERROR,
15 'WARNING': logging.WARNING,
16 'DEBUG': logging.DEBUG,
17 'INFO': logging.INFO
18 }
19
20 def translate_loglevel(x):
21 if x in loglevel_translation:
22 return loglevel_translation[x]
23 else:
24 return logging.ERROR
11 25
12 class Backup: 26 class Backup:
13 27
14 def __decode_config(self, cfg): 28 def __decode_config(self, cfg):
15 loc0='backup target %d' % self.identifier 29 loc0='backup target %d' % self.identifier
35 'Retry interval', self.loc, 49 'Retry interval', self.loc,
36 config.defaults['retry_interval']) 50 config.defaults['retry_interval'])
37 51
38 self.paths=config.check_nonempty_list_of_strings(cfg, 'paths', 'Paths', self.loc) 52 self.paths=config.check_nonempty_list_of_strings(cfg, 'paths', 'Paths', self.loc)
39 53
40 self.create_parameters=config.check_list_of_dicts(cfg, 'create_parameters', 54 self.common_parameters=config.check_list_of_dicts(cfg, 'common_parameters',
41 'Borg parameters', self.loc, 55 'Borg parameters', self.loc,
42 default=[]) 56 default=[])
43 57
58 self.create_parameters=config.check_list_of_dicts(cfg, 'create_parameters',
59 'Create parameters', self.loc,
60 default=[])
61
44 self.prune_parameters=config.check_list_of_dicts(cfg, 'prune_parameters', 62 self.prune_parameters=config.check_list_of_dicts(cfg, 'prune_parameters',
45 'Borg parameters', self.loc, 63 'Prune parameters', self.loc,
46 default=[]) 64 default=[])
47 65
48 66
49 def __init__(self, identifier, cfg): 67 def __init__(self, identifier, cfg):
50 self.identifier=identifier 68 self.identifier=identifier
63 with self.lock: 81 with self.lock:
64 not_running=self.borg_instance is None and self.thread is None 82 not_running=self.borg_instance is None and self.thread is None
65 assert(not_running) 83 assert(not_running)
66 84
67 def __listener(self): 85 def __listener(self):
68 success=True 86 success=False
69 for status in iter(self.borg_instance.read, None): 87 for status in iter(self.borg_instance.read, None):
88 logging.info(str(status))
70 t=status['type'] 89 t=status['type']
71 if t=='progress_percent': 90 if t=='progress_percent':
72 pass 91 pass
73 elif t=='archive_progress': 92 elif t=='archive_progress':
74 pass 93 pass
75 elif t=='progress_message': 94 elif t=='progress_message':
76 # handle errors 95 if 'finished' in status:
77 pass 96 logging.info('Borg subprocess finished succesfully')
97 success=status['finished']
78 elif t=='progress_percent': 98 elif t=='progress_percent':
99 # Temporary output
100 print('%d / %d', status['current'], status['total'])
79 pass 101 pass
80 elif t=='file_status': 102 elif t=='file_status':
81 pass 103 pass
82 elif t=='log_message': 104 elif t=='log_message':
83 pass 105 if 'levelname' not in status:
106 status['levelname']='ERROR'
107 if 'message' not in status:
108 status['message']='UNKNOWN'
109 if 'name' not in status:
110 status['name']='borg'
111 logging.log(translate_loglevel(status['levelname']),
112 status['name'] + ': ' + status['message'])
84 elif t=='exception': 113 elif t=='exception':
85 success=False
86 pass 114 pass
87 elif t=='unparsed_error': 115 elif t=='unparsed_error':
88 success=False
89 pass 116 pass
90 # What to do?
91 print(status)
92 117
93 logging.info('Borg subprocess finished; terminating listener thread') 118 logging.info('Waiting for borg subprocess to terminate')
119
120 self.borg_instance.wait()
121
122 logging.info('Borg subprocess terminated; terminating listener thread')
94 123
95 with self.lock: 124 with self.lock:
96 if self.current_operation=='create': 125 if self.current_operation=='create':
97 self.lastrun=self.time_started 126 self.lastrun=self.time_started
98 self.lastrun_success=success 127 self.lastrun_success=success
123 archive="%s::%s%s" % (self.repository, 152 archive="%s::%s%s" % (self.repository,
124 self.archive_prefix, 153 self.archive_prefix,
125 self.archive_template) 154 self.archive_template)
126 155
127 self.__launch(queue, 'create', archive, 156 self.__launch(queue, 'create', archive,
128 self.create_parameters, self.paths) 157 self.common_parameters+self.create_parameters,
158 self.paths)
129 159
130 def prune(self, queue): 160 def prune(self, queue):
131 self.__block_when_running() 161 self.__block_when_running()
132 self.__launch(queue, 'prune', self.repository, 162 self.__launch(queue, 'prune', self.repository,
133 [{'prefix': self.archive_prefix}] + self.prune_parameters) 163 ([{'prefix': self.archive_prefix}] +
164 self.common_parameters +
165 self.prune_parameters))
134 166
135 # TODO: Decide exact (manual) abort mechanism. Perhaps two stages 167 # TODO: Decide exact (manual) abort mechanism. Perhaps two stages
136 def abort(self): 168 def abort(self):
137 with self.lock: 169 with self.lock:
138 if self.borg_instance: 170 if self.borg_instance:

mercurial