1 # |
1 # |
2 # Borgend Backup instance |
2 # Borgend Backup instance |
3 # |
3 # |
4 |
4 |
5 import config |
5 import config |
|
6 import logging |
6 from instance import BorgInstance |
7 from instance import BorgInstance |
7 from queue import Queue |
8 from queue import Queue |
8 from threading import Thread |
9 from threading import Thread, Lock |
9 |
10 |
10 class Backup: |
11 class Backup: |
11 |
12 |
12 def __decode_config(self, cfg): |
13 def __decode_config(self, cfg): |
13 loc0='backup target %d' % self.identifier |
14 loc0='backup target %d' % self.identifier |
51 |
52 |
52 self.config=config |
53 self.config=config |
53 self.lastrun=None |
54 self.lastrun=None |
54 self.borg_instance=None |
55 self.borg_instance=None |
55 self.thread=None |
56 self.thread=None |
|
57 self.lock=Lock() |
56 |
58 |
57 def __block_when_running(self): |
59 def __block_when_running(self): |
58 assert(self.borg_instance is None and self.thread is None) |
60 self.lock.acquire() |
|
61 not_running=self.borg_instance is None and self.thread is None |
|
62 self.lock.release() |
|
63 assert(not_running) |
59 |
64 |
60 def __listener(self): |
65 def __listener(self): |
61 for status in iter(self.borg_instance.read, None): |
66 for status in iter(self.borg_instance.read, None): |
|
67 t=status['type'] |
|
68 if t=='progress_percent': |
|
69 pass |
|
70 elif t=='archive_progress': |
|
71 pass |
|
72 elif t=='progress_message': |
|
73 pass |
|
74 elif t=='progress_percent': |
|
75 pass |
|
76 elif t=='file_status': |
|
77 pass |
|
78 elif t=='log_message': |
|
79 pass |
|
80 elif t=='exception': |
|
81 pass |
|
82 elif t=='unparsed_error': |
|
83 pass |
62 # What to do? |
84 # What to do? |
63 print(status) |
85 print(status) |
64 # What to do on error |
86 |
65 # queue.put({'identifier': instance.identifier, |
87 logging.info('Borg subprocess finished; terminating listener thread') |
66 # 'operation': instance.operation, |
88 |
67 # 'status': status}) |
89 self.lock.acquire() |
|
90 self.borg_instance=None |
|
91 self.thread=None |
|
92 self.lock.release() |
68 |
93 |
69 def __launch(self, queue, operation, archive_or_repository, *args): |
94 def __launch(self, queue, operation, archive_or_repository, *args): |
70 |
95 |
71 inst=BorgInstance(operation, archive_or_repository, *args) |
96 inst=BorgInstance(operation, archive_or_repository, *args) |
72 inst.launch() |
97 inst.launch() |
93 def prune(self, queue): |
118 def prune(self, queue): |
94 self.__block_when_running() |
119 self.__block_when_running() |
95 self.__launch(queue, 'prune', self.repository, |
120 self.__launch(queue, 'prune', self.repository, |
96 [{'prefix': self.archive_prefix}] + self.prune_parameters) |
121 [{'prefix': self.archive_prefix}] + self.prune_parameters) |
97 |
122 |
|
123 # TODO: Decide exact (manual) abort mechanism. Perhaps two stages |
|
124 def abort(self): |
|
125 self.lock.acquire() |
|
126 if self.borg_instance: |
|
127 self.borg_instance.terminate() |
|
128 if self.thread: |
|
129 self.thread.terminate() |
|
130 self.lock.release() |
|
131 |
98 def join(self): |
132 def join(self): |
99 if self.thread: |
133 if self.thread: |
100 self.thread.join() |
134 self.thread.join() |
101 |
135 |
102 |
136 |