borgend/backup.py

Tue, 14 Aug 2018 22:57:48 -0500

author
Tuomo Valkonen <tuomov@iki.fi>
date
Tue, 14 Aug 2018 22:57:48 -0500
changeset 116
4a56dda09745
parent 115
df0de44d2c4b
child 119
e5f29271089d
permissions
-rw-r--r--

Pruning scheduling fix

1
4cdc9c1f6b28 basic scheduler structure draft, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1 #
89
51cc2e25af38 Added author information headers and content information to source files
Tuomo Valkonen <tuomov@iki.fi>
parents: 88
diff changeset
2 # Borgend by Tuomo Valkonen, 2018
51cc2e25af38 Added author information headers and content information to source files
Tuomo Valkonen <tuomov@iki.fi>
parents: 88
diff changeset
3 #
51cc2e25af38 Added author information headers and content information to source files
Tuomo Valkonen <tuomov@iki.fi>
parents: 88
diff changeset
4 # This file implements the scheduling, running, and borg output processing
51cc2e25af38 Added author information headers and content information to source files
Tuomo Valkonen <tuomov@iki.fi>
parents: 88
diff changeset
5 # for a specific configured backup.
1
4cdc9c1f6b28 basic scheduler structure draft, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
6 #
4cdc9c1f6b28 basic scheduler structure draft, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
7
4
d72c4844e791 Better borg output processing and some logging
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
8 import logging
5
4c5514b2fa76 basic schedule calculation
Tuomo Valkonen <tuomov@iki.fi>
parents: 4
diff changeset
9 import time
85
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
10 import datetime
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
11 import re
61
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
12 from enum import IntEnum
49
db33dfa64ad6 Improved scheduler
Tuomo Valkonen <tuomov@iki.fi>
parents: 48
diff changeset
13 from threading import Thread, Lock, Condition
80
a409242121d5 Better package-like organisation
Tuomo Valkonen <tuomov@iki.fi>
parents: 79
diff changeset
14
a409242121d5 Better package-like organisation
Tuomo Valkonen <tuomov@iki.fi>
parents: 79
diff changeset
15 from . import config
a409242121d5 Better package-like organisation
Tuomo Valkonen <tuomov@iki.fi>
parents: 79
diff changeset
16 from . import repository
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
17 from .dreamtime import MonotonicTime, DreamTime, RealTime
80
a409242121d5 Better package-like organisation
Tuomo Valkonen <tuomov@iki.fi>
parents: 79
diff changeset
18 from .instance import BorgInstance
a409242121d5 Better package-like organisation
Tuomo Valkonen <tuomov@iki.fi>
parents: 79
diff changeset
19 from .scheduler import TerminableThread
106
a7bdc239ef62 Added exeption protection decorators to callbacks.
Tuomo Valkonen <tuomov@iki.fi>
parents: 104
diff changeset
20 from .exprotect import protect_noreturn
2
e343594c0014 basic config processing
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
21
86
2fe66644c50d Can use logging.getLogger directly now after proper packageisation
Tuomo Valkonen <tuomov@iki.fi>
parents: 85
diff changeset
22 _logger=logging.getLogger(__name__)
31
b4b4bb7a2ec5 More logging detail
Tuomo Valkonen <tuomov@iki.fi>
parents: 30
diff changeset
23
98
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
24 JOIN_TIMEOUT=10
64
6cfe6a89e810 Repository queuing fixes
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
25
62
b7d13b2ad67e Turned Status and Operation into classes instead of dictionaries
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
26 #
b7d13b2ad67e Turned Status and Operation into classes instead of dictionaries
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
27 # State and operation related helper classes
b7d13b2ad67e Turned Status and Operation into classes instead of dictionaries
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
28 #
b7d13b2ad67e Turned Status and Operation into classes instead of dictionaries
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
29
61
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
30 class State(IntEnum):
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
31 # State
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
32 INACTIVE=0
98
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
33 PAUSED=1
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
34 SCHEDULED=2
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
35 QUEUED=3
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
36 ACTIVE=4
61
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
37
104
d33e2d7dbeb1 Added some debug log messages
Tuomo Valkonen <tuomov@iki.fi>
parents: 100
diff changeset
38 def __str__(self):
d33e2d7dbeb1 Added some debug log messages
Tuomo Valkonen <tuomov@iki.fi>
parents: 100
diff changeset
39 return _statestring[self]
61
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
40
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
41 class Errors(IntEnum):
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
42 OK=0
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
43 BUSY=1
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
44 OFFLINE=2
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
45 ERRORS=3
45
aa2a95dc6093 Further improvements to state reporting; indicate busyness if repository lock cannot be acquired
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
46
61
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
47 def combine(self, other):
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
48 return max(self, other)
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
49
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
50 def ok(self):
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
51 return self==self.OK
45
aa2a95dc6093 Further improvements to state reporting; indicate busyness if repository lock cannot be acquired
Tuomo Valkonen <tuomov@iki.fi>
parents: 38
diff changeset
52
61
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
53 def __str__(self):
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
54 return _errorstring[self]
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
55
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
56 _errorstring={
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
57 Errors.OK: 'ok',
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
58 Errors.BUSY: 'busy',
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
59 Errors.OFFLINE: 'offline',
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
60 Errors.ERRORS: 'errors'
6
46c89e5a219f subprocess improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 5
diff changeset
61 }
46c89e5a219f subprocess improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 5
diff changeset
62
104
d33e2d7dbeb1 Added some debug log messages
Tuomo Valkonen <tuomov@iki.fi>
parents: 100
diff changeset
63 _statestring={
d33e2d7dbeb1 Added some debug log messages
Tuomo Valkonen <tuomov@iki.fi>
parents: 100
diff changeset
64 State.INACTIVE: 'inactive',
d33e2d7dbeb1 Added some debug log messages
Tuomo Valkonen <tuomov@iki.fi>
parents: 100
diff changeset
65 State.PAUSED: 'paused',
d33e2d7dbeb1 Added some debug log messages
Tuomo Valkonen <tuomov@iki.fi>
parents: 100
diff changeset
66 State.SCHEDULED: 'scheduled',
d33e2d7dbeb1 Added some debug log messages
Tuomo Valkonen <tuomov@iki.fi>
parents: 100
diff changeset
67 State.QUEUED: 'queued',
d33e2d7dbeb1 Added some debug log messages
Tuomo Valkonen <tuomov@iki.fi>
parents: 100
diff changeset
68 State.ACTIVE: 'active'
d33e2d7dbeb1 Added some debug log messages
Tuomo Valkonen <tuomov@iki.fi>
parents: 100
diff changeset
69 }
d33e2d7dbeb1 Added some debug log messages
Tuomo Valkonen <tuomov@iki.fi>
parents: 100
diff changeset
70
62
b7d13b2ad67e Turned Status and Operation into classes instead of dictionaries
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
71 class Operation:
b7d13b2ad67e Turned Status and Operation into classes instead of dictionaries
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
72 CREATE='create'
b7d13b2ad67e Turned Status and Operation into classes instead of dictionaries
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
73 PRUNE='prune'
85
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
74 INFO='info'
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
75 LIST='list'
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
76
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
77 def __init__(self, type, start_time, **kwargs):
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
78 self.type=type
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
79 self.start_time=start_time
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
80 self.finish_time=None
62
b7d13b2ad67e Turned Status and Operation into classes instead of dictionaries
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
81 self.detail=kwargs
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
82 self.errors=Errors.OK
62
b7d13b2ad67e Turned Status and Operation into classes instead of dictionaries
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
83
b7d13b2ad67e Turned Status and Operation into classes instead of dictionaries
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
84 def when(self):
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
85 return self.start_time.realtime()
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
86
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
87 def ok(self):
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
88 return self.errors.ok()
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
89
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
90 def add_error(self, error):
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
91 self.errors=self.errors.combine(error)
62
b7d13b2ad67e Turned Status and Operation into classes instead of dictionaries
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
92
104
d33e2d7dbeb1 Added some debug log messages
Tuomo Valkonen <tuomov@iki.fi>
parents: 100
diff changeset
93 def name(self):
d33e2d7dbeb1 Added some debug log messages
Tuomo Valkonen <tuomov@iki.fi>
parents: 100
diff changeset
94 if 'reason' in self.detail:
d33e2d7dbeb1 Added some debug log messages
Tuomo Valkonen <tuomov@iki.fi>
parents: 100
diff changeset
95 return str(self.type) + '.' + self.detail['reason']
d33e2d7dbeb1 Added some debug log messages
Tuomo Valkonen <tuomov@iki.fi>
parents: 100
diff changeset
96 else:
d33e2d7dbeb1 Added some debug log messages
Tuomo Valkonen <tuomov@iki.fi>
parents: 100
diff changeset
97 return str(self.type)
d33e2d7dbeb1 Added some debug log messages
Tuomo Valkonen <tuomov@iki.fi>
parents: 100
diff changeset
98
62
b7d13b2ad67e Turned Status and Operation into classes instead of dictionaries
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
99
b7d13b2ad67e Turned Status and Operation into classes instead of dictionaries
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
100 class Status(Operation):
b7d13b2ad67e Turned Status and Operation into classes instead of dictionaries
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
101 def __init__(self, backup, op=None):
108
6409aa77ddd5 Error status wasn't correctly transmitted to UI after recent changes.
Tuomo Valkonen <tuomov@iki.fi>
parents: 107
diff changeset
102 op=backup.current_operation
109
246190bfd501 Better error reporting logic.
Tuomo Valkonen <tuomov@iki.fi>
parents: 108
diff changeset
103 errorsop=backup.current_operation
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
104
108
6409aa77ddd5 Error status wasn't correctly transmitted to UI after recent changes.
Tuomo Valkonen <tuomov@iki.fi>
parents: 107
diff changeset
105 if not op:
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
106 op=backup.scheduled_operation
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
107
109
246190bfd501 Better error reporting logic.
Tuomo Valkonen <tuomov@iki.fi>
parents: 108
diff changeset
108 if not errorsop:
246190bfd501 Better error reporting logic.
Tuomo Valkonen <tuomov@iki.fi>
parents: 108
diff changeset
109 errorsop=backup.previous_operation
246190bfd501 Better error reporting logic.
Tuomo Valkonen <tuomov@iki.fi>
parents: 108
diff changeset
110
62
b7d13b2ad67e Turned Status and Operation into classes instead of dictionaries
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
111 if op:
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
112 super().__init__(op.type, op.start_time, **op.detail)
62
b7d13b2ad67e Turned Status and Operation into classes instead of dictionaries
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
113 else:
b7d13b2ad67e Turned Status and Operation into classes instead of dictionaries
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
114 super().__init__(None, None)
b7d13b2ad67e Turned Status and Operation into classes instead of dictionaries
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
115
108
6409aa77ddd5 Error status wasn't correctly transmitted to UI after recent changes.
Tuomo Valkonen <tuomov@iki.fi>
parents: 107
diff changeset
116 if errorsop:
6409aa77ddd5 Error status wasn't correctly transmitted to UI after recent changes.
Tuomo Valkonen <tuomov@iki.fi>
parents: 107
diff changeset
117 self.errors=errorsop.errors
6409aa77ddd5 Error status wasn't correctly transmitted to UI after recent changes.
Tuomo Valkonen <tuomov@iki.fi>
parents: 107
diff changeset
118
62
b7d13b2ad67e Turned Status and Operation into classes instead of dictionaries
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
119 self.name=backup.name
b7d13b2ad67e Turned Status and Operation into classes instead of dictionaries
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
120 self.state=backup.state
b7d13b2ad67e Turned Status and Operation into classes instead of dictionaries
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
121
b7d13b2ad67e Turned Status and Operation into classes instead of dictionaries
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
122 #
b7d13b2ad67e Turned Status and Operation into classes instead of dictionaries
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
123 # Miscellaneous helper routines
b7d13b2ad67e Turned Status and Operation into classes instead of dictionaries
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
124 #
b7d13b2ad67e Turned Status and Operation into classes instead of dictionaries
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
125
b7d13b2ad67e Turned Status and Operation into classes instead of dictionaries
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
126 loglevel_translation={
b7d13b2ad67e Turned Status and Operation into classes instead of dictionaries
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
127 'CRITICAL': logging.CRITICAL,
b7d13b2ad67e Turned Status and Operation into classes instead of dictionaries
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
128 'ERROR': logging.ERROR,
b7d13b2ad67e Turned Status and Operation into classes instead of dictionaries
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
129 'WARNING': logging.WARNING,
b7d13b2ad67e Turned Status and Operation into classes instead of dictionaries
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
130 'DEBUG': logging.DEBUG,
b7d13b2ad67e Turned Status and Operation into classes instead of dictionaries
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
131 'INFO': logging.INFO
b7d13b2ad67e Turned Status and Operation into classes instead of dictionaries
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
132 }
b7d13b2ad67e Turned Status and Operation into classes instead of dictionaries
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
133
6
46c89e5a219f subprocess improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 5
diff changeset
134 def translate_loglevel(x):
46c89e5a219f subprocess improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 5
diff changeset
135 if x in loglevel_translation:
46c89e5a219f subprocess improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 5
diff changeset
136 return loglevel_translation[x]
46c89e5a219f subprocess improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 5
diff changeset
137 else:
46c89e5a219f subprocess improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 5
diff changeset
138 return logging.ERROR
46c89e5a219f subprocess improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 5
diff changeset
139
15
aaf1a281a3fe More error reporting
Tuomo Valkonen <tuomov@iki.fi>
parents: 14
diff changeset
140 def safe_get_int(t, x):
aaf1a281a3fe More error reporting
Tuomo Valkonen <tuomov@iki.fi>
parents: 14
diff changeset
141 if x in t:
aaf1a281a3fe More error reporting
Tuomo Valkonen <tuomov@iki.fi>
parents: 14
diff changeset
142 tmp=t[x]
aaf1a281a3fe More error reporting
Tuomo Valkonen <tuomov@iki.fi>
parents: 14
diff changeset
143 if isinstance(tmp, int):
aaf1a281a3fe More error reporting
Tuomo Valkonen <tuomov@iki.fi>
parents: 14
diff changeset
144 return tmp
aaf1a281a3fe More error reporting
Tuomo Valkonen <tuomov@iki.fi>
parents: 14
diff changeset
145 return None
aaf1a281a3fe More error reporting
Tuomo Valkonen <tuomov@iki.fi>
parents: 14
diff changeset
146
85
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
147 def parse_borg_date(d, logger):
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
148 try:
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
149 res=datetime.datetime.strptime(d, '%Y-%m-%dT%H:%M:%S.%f')
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
150 except Exception:
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
151 logger.exception('Unable parse date from borg: "%s"' % d)
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
152 res=None
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
153 return res
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
154
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
155 _checkpoint_str='.checkpoint'
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
156 _checkpoint_str_len=len(_checkpoint_str)
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
157
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
158 def is_checkpoint(name):
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
159 i=name.rfind(_checkpoint_str);
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
160 return i>=0 and i+_checkpoint_str_len==len(name)
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
161
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
162 def get_archive_time(a, logger):
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
163 if not 'name' in a:
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
164 logger.error('Borg archive list entry missing name')
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
165 return None, False
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
166 if is_checkpoint(a['name']):
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
167 logger.debug('Skipping checkpoint in archive list')
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
168 return None, True
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
169
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
170 thistime=None
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
171 if 'start' in a:
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
172 thistime=parse_borg_date(a['start'], logger)
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
173 if not thistime and 'time' in a:
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
174 thistime=parse_borg_date(a['time'], logger)
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
175 if not thistime:
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
176 return None, False
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
177
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
178 return thistime, True
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
179
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
180 _prune_progress_re=re.compile(".*\(([0-9]+)/([0-9]+)\)$")
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
181 # Borg gives very little progress info in easy form, so try to extrat it
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
182 def check_prune_status(msg):
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
183 res=_prune_progress_re.match(msg)
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
184 if res:
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
185 c=res.groups()
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
186 try:
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
187 archive_no=int(c[0])
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
188 of_total=int(c[1])
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
189 except:
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
190 pass
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
191 else:
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
192 return archive_no, of_total
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
193 return None, None
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
194
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
195
62
b7d13b2ad67e Turned Status and Operation into classes instead of dictionaries
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
196 #
b7d13b2ad67e Turned Status and Operation into classes instead of dictionaries
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
197 # The Backup class
b7d13b2ad67e Turned Status and Operation into classes instead of dictionaries
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
198 #
15
aaf1a281a3fe More error reporting
Tuomo Valkonen <tuomov@iki.fi>
parents: 14
diff changeset
199
49
db33dfa64ad6 Improved scheduler
Tuomo Valkonen <tuomov@iki.fi>
parents: 48
diff changeset
200 class Backup(TerminableThread):
1
4cdc9c1f6b28 basic scheduler structure draft, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
201
2
e343594c0014 basic config processing
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
202 def __decode_config(self, cfg):
74
4f56142e7497 Separated repository configuration form backup configuration;
Tuomo Valkonen <tuomov@iki.fi>
parents: 71
diff changeset
203 loc0='Backup %d' % self.identifier
2
e343594c0014 basic config processing
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
204
74
4f56142e7497 Separated repository configuration form backup configuration;
Tuomo Valkonen <tuomov@iki.fi>
parents: 71
diff changeset
205 self.backup_name=config.check_string(cfg, 'name', 'Name', loc0)
2
e343594c0014 basic config processing
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
206
85
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
207 _logger.debug("Configuring backup '%s'" % self.backup_name)
55
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
208
85
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
209 self.logger=_logger.getChild(self.backup_name)
74
4f56142e7497 Separated repository configuration form backup configuration;
Tuomo Valkonen <tuomov@iki.fi>
parents: 71
diff changeset
210
4f56142e7497 Separated repository configuration form backup configuration;
Tuomo Valkonen <tuomov@iki.fi>
parents: 71
diff changeset
211 loc="Backup '%s'" % self.backup_name
2
e343594c0014 basic config processing
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
212
54
cfcaa5f6ba33 Basic repository queue
Tuomo Valkonen <tuomov@iki.fi>
parents: 50
diff changeset
213 reponame=config.check_string(cfg, 'repository',
74
4f56142e7497 Separated repository configuration form backup configuration;
Tuomo Valkonen <tuomov@iki.fi>
parents: 71
diff changeset
214 'Target repository', loc)
54
cfcaa5f6ba33 Basic repository queue
Tuomo Valkonen <tuomov@iki.fi>
parents: 50
diff changeset
215
74
4f56142e7497 Separated repository configuration form backup configuration;
Tuomo Valkonen <tuomov@iki.fi>
parents: 71
diff changeset
216 self.repository=repository.find_repository(reponame)
4f56142e7497 Separated repository configuration form backup configuration;
Tuomo Valkonen <tuomov@iki.fi>
parents: 71
diff changeset
217 if not self.repository:
4f56142e7497 Separated repository configuration form backup configuration;
Tuomo Valkonen <tuomov@iki.fi>
parents: 71
diff changeset
218 raise Exception("Repository '%s' not configured" % reponame)
2
e343594c0014 basic config processing
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
219
3
4cad934aa9ce Can launch borg now; output not yet processed
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
220 self.archive_prefix=config.check_string(cfg, 'archive_prefix',
74
4f56142e7497 Separated repository configuration form backup configuration;
Tuomo Valkonen <tuomov@iki.fi>
parents: 71
diff changeset
221 'Archive prefix', loc)
3
4cad934aa9ce Can launch borg now; output not yet processed
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
222
2
e343594c0014 basic config processing
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
223 self.archive_template=config.check_string(cfg, 'archive_template',
74
4f56142e7497 Separated repository configuration form backup configuration;
Tuomo Valkonen <tuomov@iki.fi>
parents: 71
diff changeset
224 'Archive template', loc)
2
e343594c0014 basic config processing
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
225
e343594c0014 basic config processing
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
226 self.backup_interval=config.check_nonneg_int(cfg, 'backup_interval',
74
4f56142e7497 Separated repository configuration form backup configuration;
Tuomo Valkonen <tuomov@iki.fi>
parents: 71
diff changeset
227 'Backup interval', loc,
2
e343594c0014 basic config processing
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
228 config.defaults['backup_interval'])
e343594c0014 basic config processing
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
229
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
230 self.prune_interval=config.check_nonneg_int(cfg, 'prune_interval',
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
231 'Prune interval', loc,
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
232 config.defaults['prune_interval'])
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
233
2
e343594c0014 basic config processing
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
234 self.retry_interval=config.check_nonneg_int(cfg, 'retry_interval',
74
4f56142e7497 Separated repository configuration form backup configuration;
Tuomo Valkonen <tuomov@iki.fi>
parents: 71
diff changeset
235 'Retry interval', loc,
2
e343594c0014 basic config processing
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
236 config.defaults['retry_interval'])
e343594c0014 basic config processing
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
237
76
4b08fca3ce34 Dreamtime scheduling: discount system sleep periods
Tuomo Valkonen <tuomov@iki.fi>
parents: 74
diff changeset
238
4b08fca3ce34 Dreamtime scheduling: discount system sleep periods
Tuomo Valkonen <tuomov@iki.fi>
parents: 74
diff changeset
239 scheduling=config.check_string(cfg, 'scheduling',
4b08fca3ce34 Dreamtime scheduling: discount system sleep periods
Tuomo Valkonen <tuomov@iki.fi>
parents: 74
diff changeset
240 'Scheduling mode', loc,
4b08fca3ce34 Dreamtime scheduling: discount system sleep periods
Tuomo Valkonen <tuomov@iki.fi>
parents: 74
diff changeset
241 default="dreamtime")
4b08fca3ce34 Dreamtime scheduling: discount system sleep periods
Tuomo Valkonen <tuomov@iki.fi>
parents: 74
diff changeset
242
4b08fca3ce34 Dreamtime scheduling: discount system sleep periods
Tuomo Valkonen <tuomov@iki.fi>
parents: 74
diff changeset
243 if scheduling=="dreamtime":
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
244 self.timeclass=DreamTime
76
4b08fca3ce34 Dreamtime scheduling: discount system sleep periods
Tuomo Valkonen <tuomov@iki.fi>
parents: 74
diff changeset
245 elif scheduling=="realtime":
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
246 self.timeclass=MonotonicTime
76
4b08fca3ce34 Dreamtime scheduling: discount system sleep periods
Tuomo Valkonen <tuomov@iki.fi>
parents: 74
diff changeset
247 elif scheduling=="manual":
4b08fca3ce34 Dreamtime scheduling: discount system sleep periods
Tuomo Valkonen <tuomov@iki.fi>
parents: 74
diff changeset
248 self.backup_interval=0
4b08fca3ce34 Dreamtime scheduling: discount system sleep periods
Tuomo Valkonen <tuomov@iki.fi>
parents: 74
diff changeset
249 else:
4b08fca3ce34 Dreamtime scheduling: discount system sleep periods
Tuomo Valkonen <tuomov@iki.fi>
parents: 74
diff changeset
250 logging.error("Invalid time class '%s' for %s" % (scheduling, loc))
4b08fca3ce34 Dreamtime scheduling: discount system sleep periods
Tuomo Valkonen <tuomov@iki.fi>
parents: 74
diff changeset
251
74
4f56142e7497 Separated repository configuration form backup configuration;
Tuomo Valkonen <tuomov@iki.fi>
parents: 71
diff changeset
252 self.paths=config.check_nonempty_list_of_strings(cfg, 'paths', 'Paths', loc)
32
06fc14211ba9 Error handling improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 31
diff changeset
253
74
4f56142e7497 Separated repository configuration form backup configuration;
Tuomo Valkonen <tuomov@iki.fi>
parents: 71
diff changeset
254 self.borg_parameters=config.BorgParameters.from_config(cfg, loc)
20
fdfbe5d7b677 Keychain support and random fixes
Tuomo Valkonen <tuomov@iki.fi>
parents: 17
diff changeset
255
2
e343594c0014 basic config processing
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
256
49
db33dfa64ad6 Improved scheduler
Tuomo Valkonen <tuomov@iki.fi>
parents: 48
diff changeset
257 def __init__(self, identifier, cfg, scheduler):
2
e343594c0014 basic config processing
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
258 self.identifier=identifier
55
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
259 self.__status_update_callback=None
98
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
260 self._pause=False
55
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
261 self.scheduler=scheduler
74
4f56142e7497 Separated repository configuration form backup configuration;
Tuomo Valkonen <tuomov@iki.fi>
parents: 71
diff changeset
262 self.logger=None # setup up in __decode_config once backup name is known
55
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
263
3
4cad934aa9ce Can launch borg now; output not yet processed
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
264 self.borg_instance=None
7
e189d4a6cb8c Also listen to stdout
Tuomo Valkonen <tuomov@iki.fi>
parents: 6
diff changeset
265 self.thread_log=None
8
7b2d2eac6a48 basic scheduling
Tuomo Valkonen <tuomov@iki.fi>
parents: 7
diff changeset
266 self.thread_res=None
55
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
267
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
268 self.previous_operation=None
55
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
269 self.current_operation=None
10
76dbfb06eba0 Semi-working menu items.
Tuomo Valkonen <tuomov@iki.fi>
parents: 8
diff changeset
270 self.scheduled_operation=None
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
271 self.previous_operation_of_type={}
61
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
272 self.state=State.INACTIVE
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
273 self.timeclass=DreamTime
116
4a56dda09745 Pruning scheduling fix
Tuomo Valkonen <tuomov@iki.fi>
parents: 115
diff changeset
274 self.start_time=self.timeclass.now()
49
db33dfa64ad6 Improved scheduler
Tuomo Valkonen <tuomov@iki.fi>
parents: 48
diff changeset
275
db33dfa64ad6 Improved scheduler
Tuomo Valkonen <tuomov@iki.fi>
parents: 48
diff changeset
276 self.__decode_config(cfg)
db33dfa64ad6 Improved scheduler
Tuomo Valkonen <tuomov@iki.fi>
parents: 48
diff changeset
277
74
4f56142e7497 Separated repository configuration form backup configuration;
Tuomo Valkonen <tuomov@iki.fi>
parents: 71
diff changeset
278 super().__init__(target = self.__main_thread, name = self.backup_name)
49
db33dfa64ad6 Improved scheduler
Tuomo Valkonen <tuomov@iki.fi>
parents: 48
diff changeset
279 self.daemon=True
3
4cad934aa9ce Can launch borg now; output not yet processed
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
280
7
e189d4a6cb8c Also listen to stdout
Tuomo Valkonen <tuomov@iki.fi>
parents: 6
diff changeset
281 def is_running(self):
49
db33dfa64ad6 Improved scheduler
Tuomo Valkonen <tuomov@iki.fi>
parents: 48
diff changeset
282 with self._cond:
8
7b2d2eac6a48 basic scheduling
Tuomo Valkonen <tuomov@iki.fi>
parents: 7
diff changeset
283 running=self.__is_running_unlocked()
7b2d2eac6a48 basic scheduling
Tuomo Valkonen <tuomov@iki.fi>
parents: 7
diff changeset
284 return running
7b2d2eac6a48 basic scheduling
Tuomo Valkonen <tuomov@iki.fi>
parents: 7
diff changeset
285
7b2d2eac6a48 basic scheduling
Tuomo Valkonen <tuomov@iki.fi>
parents: 7
diff changeset
286 def __is_running_unlocked(self):
7b2d2eac6a48 basic scheduling
Tuomo Valkonen <tuomov@iki.fi>
parents: 7
diff changeset
287 running=self.current_operation
7b2d2eac6a48 basic scheduling
Tuomo Valkonen <tuomov@iki.fi>
parents: 7
diff changeset
288 if not running:
7b2d2eac6a48 basic scheduling
Tuomo Valkonen <tuomov@iki.fi>
parents: 7
diff changeset
289 # Consistency check
7b2d2eac6a48 basic scheduling
Tuomo Valkonen <tuomov@iki.fi>
parents: 7
diff changeset
290 assert((not self.borg_instance and not self.thread_log and
7b2d2eac6a48 basic scheduling
Tuomo Valkonen <tuomov@iki.fi>
parents: 7
diff changeset
291 not self.thread_res))
7
e189d4a6cb8c Also listen to stdout
Tuomo Valkonen <tuomov@iki.fi>
parents: 6
diff changeset
292 return running
e189d4a6cb8c Also listen to stdout
Tuomo Valkonen <tuomov@iki.fi>
parents: 6
diff changeset
293
3
4cad934aa9ce Can launch borg now; output not yet processed
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
294 def __block_when_running(self):
7
e189d4a6cb8c Also listen to stdout
Tuomo Valkonen <tuomov@iki.fi>
parents: 6
diff changeset
295 running=self.is_running()
e189d4a6cb8c Also listen to stdout
Tuomo Valkonen <tuomov@iki.fi>
parents: 6
diff changeset
296 assert(not running)
2
e343594c0014 basic config processing
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
297
106
a7bdc239ef62 Added exeption protection decorators to callbacks.
Tuomo Valkonen <tuomov@iki.fi>
parents: 104
diff changeset
298 @protect_noreturn
7
e189d4a6cb8c Also listen to stdout
Tuomo Valkonen <tuomov@iki.fi>
parents: 6
diff changeset
299 def __log_listener(self):
55
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
300 self.logger.debug('Log listener thread waiting for entries')
7
e189d4a6cb8c Also listen to stdout
Tuomo Valkonen <tuomov@iki.fi>
parents: 6
diff changeset
301 success=True
61
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
302 for msg in iter(self.borg_instance.read_log, None):
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
303 self.logger.debug(str(msg))
61
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
304 t=msg['type']
15
aaf1a281a3fe More error reporting
Tuomo Valkonen <tuomov@iki.fi>
parents: 14
diff changeset
305
61
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
306 errormsg=None
15
aaf1a281a3fe More error reporting
Tuomo Valkonen <tuomov@iki.fi>
parents: 14
diff changeset
307 callback=None
aaf1a281a3fe More error reporting
Tuomo Valkonen <tuomov@iki.fi>
parents: 14
diff changeset
308
4
d72c4844e791 Better borg output processing and some logging
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
309 if t=='progress_percent':
61
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
310 current=safe_get_int(msg, 'current')
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
311 total=safe_get_int(msg, 'total')
85
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
312 operation_no=safe_get_int(msg, 'operation')
15
aaf1a281a3fe More error reporting
Tuomo Valkonen <tuomov@iki.fi>
parents: 14
diff changeset
313 if current is not None and total is not None:
49
db33dfa64ad6 Improved scheduler
Tuomo Valkonen <tuomov@iki.fi>
parents: 48
diff changeset
314 with self._cond:
62
b7d13b2ad67e Turned Status and Operation into classes instead of dictionaries
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
315 self.current_operation.detail['progress_current']=current
b7d13b2ad67e Turned Status and Operation into classes instead of dictionaries
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
316 self.current_operation.detail['progress_total']=total
85
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
317 self.current_operation.detail['operation_no']=operation_no
14
5a988a2c2624 UI: progress percentange support (Borg doesn't seem to be reporting) + error indicator in tray: B?
Tuomo Valkonen <tuomov@iki.fi>
parents: 12
diff changeset
318 status, callback=self.__status_unlocked()
15
aaf1a281a3fe More error reporting
Tuomo Valkonen <tuomov@iki.fi>
parents: 14
diff changeset
319
4
d72c4844e791 Better borg output processing and some logging
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
320 elif t=='archive_progress':
61
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
321 original_size=safe_get_int(msg, 'original_size')
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
322 compressed_size=safe_get_int(msg, 'compressed_size')
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
323 deduplicated_size=safe_get_int(msg, 'deduplicated_size')
15
aaf1a281a3fe More error reporting
Tuomo Valkonen <tuomov@iki.fi>
parents: 14
diff changeset
324 if original_size is not None and original_size is not None and deduplicated_size is not None:
49
db33dfa64ad6 Improved scheduler
Tuomo Valkonen <tuomov@iki.fi>
parents: 48
diff changeset
325 with self._cond:
62
b7d13b2ad67e Turned Status and Operation into classes instead of dictionaries
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
326 self.current_operation.detail['original_size']=original_size
b7d13b2ad67e Turned Status and Operation into classes instead of dictionaries
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
327 self.current_operation.detail['compressed_size']=compressed_size
b7d13b2ad67e Turned Status and Operation into classes instead of dictionaries
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
328 self.current_operation.detail['deduplicated_size']=deduplicated_size
15
aaf1a281a3fe More error reporting
Tuomo Valkonen <tuomov@iki.fi>
parents: 14
diff changeset
329 status, callback=self.__status_unlocked()
aaf1a281a3fe More error reporting
Tuomo Valkonen <tuomov@iki.fi>
parents: 14
diff changeset
330
aaf1a281a3fe More error reporting
Tuomo Valkonen <tuomov@iki.fi>
parents: 14
diff changeset
331 elif t=='progress_message':
4
d72c4844e791 Better borg output processing and some logging
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
332 pass
15
aaf1a281a3fe More error reporting
Tuomo Valkonen <tuomov@iki.fi>
parents: 14
diff changeset
333
4
d72c4844e791 Better borg output processing and some logging
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
334 elif t=='file_status':
d72c4844e791 Better borg output processing and some logging
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
335 pass
15
aaf1a281a3fe More error reporting
Tuomo Valkonen <tuomov@iki.fi>
parents: 14
diff changeset
336
4
d72c4844e791 Better borg output processing and some logging
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
337 elif t=='log_message':
61
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
338 if 'levelname' not in msg:
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
339 msg['levelname']='ERROR'
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
340 if 'message' not in msg:
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
341 msg['message']='UNKNOWN'
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
342 if 'name' not in msg:
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
343 msg['name']='borg'
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
344 lvl=translate_loglevel(msg['levelname'])
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
345 self.logger.log(lvl, msg['name'] + ': ' + msg['message'])
71
a8a5ebb64e02 Changed retry timing to start form end of previous attempt instead of beginning
Tuomo Valkonen <tuomov@iki.fi>
parents: 70
diff changeset
346 if lvl>=logging.ERROR:
61
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
347 errormsg=msg
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
348 errors=Errors.ERRORS
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
349 if ('msgid' in msg and
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
350 (msg['msgid']=='LockTimeout' or # observed in reality
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
351 msg['msgid']=='LockErrorT' or # in docs
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
352 msg['msgid']=='LockErrorT')): # in docs
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
353 errors=Errors.BUSY
49
db33dfa64ad6 Improved scheduler
Tuomo Valkonen <tuomov@iki.fi>
parents: 48
diff changeset
354 with self._cond:
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
355 self.current_operation.add_error(errors)
98
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
356 # Don't notify of errors if we are terminating or pausing
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
357 if not self._terminate_or_pause():
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
358 status, callback=self.__status_unlocked()
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
359 elif lvl==logging.INFO and self.current_operation.type==Operation.PRUNE:
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
360 # Borg gives very little progress info in easy form, so try to extrat it
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
361 archive_number, of_total=check_prune_status(msg['message'])
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
362 if archive_number!=None and of_total!=None:
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
363 self.current_operation.detail['progress_current_secondary']=archive_number
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
364 self.current_operation.detail['progress_total_secondary']=of_total
21
c36e549a7f12 Errors as rumps notifications
Tuomo Valkonen <tuomov@iki.fi>
parents: 20
diff changeset
365 status, callback=self.__status_unlocked()
88
dfd52898f175 Added dummy entries in log reader for question prompts from borg
Tuomo Valkonen <tuomov@iki.fi>
parents: 87
diff changeset
366
dfd52898f175 Added dummy entries in log reader for question prompts from borg
Tuomo Valkonen <tuomov@iki.fi>
parents: 87
diff changeset
367 elif t=='question_prompt' or t=='question_prompt_retry':
dfd52898f175 Added dummy entries in log reader for question prompts from borg
Tuomo Valkonen <tuomov@iki.fi>
parents: 87
diff changeset
368 self.logger.error('Did not expect to receive question prompt from borg')
dfd52898f175 Added dummy entries in log reader for question prompts from borg
Tuomo Valkonen <tuomov@iki.fi>
parents: 87
diff changeset
369 with self._cond:
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
370 self.current_operation.add_error(Errors.ERRORS)
88
dfd52898f175 Added dummy entries in log reader for question prompts from borg
Tuomo Valkonen <tuomov@iki.fi>
parents: 87
diff changeset
371 # TODO: terminate org? Send 'NO' reply?
dfd52898f175 Added dummy entries in log reader for question prompts from borg
Tuomo Valkonen <tuomov@iki.fi>
parents: 87
diff changeset
372
dfd52898f175 Added dummy entries in log reader for question prompts from borg
Tuomo Valkonen <tuomov@iki.fi>
parents: 87
diff changeset
373 elif (t=='question_invalid_answer' or t=='question_accepted_default'
dfd52898f175 Added dummy entries in log reader for question prompts from borg
Tuomo Valkonen <tuomov@iki.fi>
parents: 87
diff changeset
374 or t=='question_accepted_true' or t=='question_accepted_false'
dfd52898f175 Added dummy entries in log reader for question prompts from borg
Tuomo Valkonen <tuomov@iki.fi>
parents: 87
diff changeset
375 or t=='question_env_answer'):
dfd52898f175 Added dummy entries in log reader for question prompts from borg
Tuomo Valkonen <tuomov@iki.fi>
parents: 87
diff changeset
376 pass
dfd52898f175 Added dummy entries in log reader for question prompts from borg
Tuomo Valkonen <tuomov@iki.fi>
parents: 87
diff changeset
377
21
c36e549a7f12 Errors as rumps notifications
Tuomo Valkonen <tuomov@iki.fi>
parents: 20
diff changeset
378 else:
55
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
379 self.logger.debug('Unrecognised log entry %s' % str(status))
15
aaf1a281a3fe More error reporting
Tuomo Valkonen <tuomov@iki.fi>
parents: 14
diff changeset
380
aaf1a281a3fe More error reporting
Tuomo Valkonen <tuomov@iki.fi>
parents: 14
diff changeset
381 if callback:
87
a214d475aa28 Better recovery from errors; fixes to potential race conditions in scheduler and repository queue
Tuomo Valkonen <tuomov@iki.fi>
parents: 86
diff changeset
382 callback(status, errorlog=errormsg)
6
46c89e5a219f subprocess improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 5
diff changeset
383
55
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
384 self.logger.debug('Waiting for borg subprocess to terminate in log thread')
4
d72c4844e791 Better borg output processing and some logging
Tuomo Valkonen <tuomov@iki.fi>
parents: 3
diff changeset
385
6
46c89e5a219f subprocess improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 5
diff changeset
386 self.borg_instance.wait()
46c89e5a219f subprocess improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 5
diff changeset
387
55
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
388 self.logger.debug('Borg subprocess terminated; terminating log listener thread')
7
e189d4a6cb8c Also listen to stdout
Tuomo Valkonen <tuomov@iki.fi>
parents: 6
diff changeset
389
106
a7bdc239ef62 Added exeption protection decorators to callbacks.
Tuomo Valkonen <tuomov@iki.fi>
parents: 104
diff changeset
390 @protect_noreturn
7
e189d4a6cb8c Also listen to stdout
Tuomo Valkonen <tuomov@iki.fi>
parents: 6
diff changeset
391 def __result_listener(self):
55
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
392 self.logger.debug('Result listener thread waiting for result')
7
e189d4a6cb8c Also listen to stdout
Tuomo Valkonen <tuomov@iki.fi>
parents: 6
diff changeset
393
e189d4a6cb8c Also listen to stdout
Tuomo Valkonen <tuomov@iki.fi>
parents: 6
diff changeset
394 res=self.borg_instance.read_result()
e189d4a6cb8c Also listen to stdout
Tuomo Valkonen <tuomov@iki.fi>
parents: 6
diff changeset
395
55
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
396 self.logger.debug('Borg result: %s' % str(res))
7
e189d4a6cb8c Also listen to stdout
Tuomo Valkonen <tuomov@iki.fi>
parents: 6
diff changeset
397
85
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
398 if res is None:
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
399 with self._cond:
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
400 # Prune gives absolutely no result, so don't complain
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
401 if (self.current_operation.ok() and
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
402 self.current_operation.type!=Operation.PRUNE):
85
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
403 self.logger.error('No result from borg despite no error in log')
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
404 self.current_operation.add_error(Errors.ERRORS)
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
405 elif self.current_operation.type==Operation.LIST:
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
406 self.__handle_list_result(res)
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
407
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
408 # All other results are discarded
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
409
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
410 def __handle_list_result(self, res):
85
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
411 ok=True
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
412 latest=None
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
413 if 'archives' in res and isinstance(res['archives'], list):
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
414 archives=res['archives']
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
415 for a in archives:
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
416 if not isinstance(a, dict):
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
417 self.logger.error('Borg archive list entry not a dictionary')
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
418 ok=False
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
419 else:
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
420 thistime, this_ok=get_archive_time(a, self.logger)
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
421 if thistime and (not latest or thistime>latest):
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
422 latest=thistime
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
423 ok=ok and this_ok
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
424 else:
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
425 logger.error('Borg archive list missing "archives" entry')
7
e189d4a6cb8c Also listen to stdout
Tuomo Valkonen <tuomov@iki.fi>
parents: 6
diff changeset
426
85
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
427 if not ok:
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
428 with self._cond:
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
429 self.current_operation.add_error(Errors.ERRORS)
88
dfd52898f175 Added dummy entries in log reader for question prompts from borg
Tuomo Valkonen <tuomov@iki.fi>
parents: 87
diff changeset
430
85
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
431 if latest:
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
432 self.logger.info('borg info: Previous backup was on %s' % latest.isoformat())
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
433 when=MonotonicTime.from_realtime(time.mktime(latest.timetuple()))
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
434 op=Operation(Operation.CREATE, when, reason='listed')
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
435 op.finish_time=when
85
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
436 with self._cond:
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
437 self.previous_operation_of_type[Operation.CREATE]=op
85
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
438 else:
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
439 self.logger.info('borg info: Could not discover a previous backup')
7
e189d4a6cb8c Also listen to stdout
Tuomo Valkonen <tuomov@iki.fi>
parents: 6
diff changeset
440
74
4f56142e7497 Separated repository configuration form backup configuration;
Tuomo Valkonen <tuomov@iki.fi>
parents: 71
diff changeset
441 def __do_launch(self, op, archive_or_repository,
4f56142e7497 Separated repository configuration form backup configuration;
Tuomo Valkonen <tuomov@iki.fi>
parents: 71
diff changeset
442 common_params, op_params, paths=[]):
21
c36e549a7f12 Errors as rumps notifications
Tuomo Valkonen <tuomov@iki.fi>
parents: 20
diff changeset
443
87
a214d475aa28 Better recovery from errors; fixes to potential race conditions in scheduler and repository queue
Tuomo Valkonen <tuomov@iki.fi>
parents: 86
diff changeset
444 self.logger.debug('Creating BorgInstance')
a214d475aa28 Better recovery from errors; fixes to potential race conditions in scheduler and repository queue
Tuomo Valkonen <tuomov@iki.fi>
parents: 86
diff changeset
445
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
446 inst=BorgInstance(op.type, archive_or_repository,
74
4f56142e7497 Separated repository configuration form backup configuration;
Tuomo Valkonen <tuomov@iki.fi>
parents: 71
diff changeset
447 common_params, op_params, paths)
4f56142e7497 Separated repository configuration form backup configuration;
Tuomo Valkonen <tuomov@iki.fi>
parents: 71
diff changeset
448
87
a214d475aa28 Better recovery from errors; fixes to potential race conditions in scheduler and repository queue
Tuomo Valkonen <tuomov@iki.fi>
parents: 86
diff changeset
449 self.logger.debug('Launching BorgInstance via repository')
a214d475aa28 Better recovery from errors; fixes to potential race conditions in scheduler and repository queue
Tuomo Valkonen <tuomov@iki.fi>
parents: 86
diff changeset
450
74
4f56142e7497 Separated repository configuration form backup configuration;
Tuomo Valkonen <tuomov@iki.fi>
parents: 71
diff changeset
451 # Only the Repository object has access to the passphrase
4f56142e7497 Separated repository configuration form backup configuration;
Tuomo Valkonen <tuomov@iki.fi>
parents: 71
diff changeset
452 self.repository.launch_borg_instance(inst)
3
4cad934aa9ce Can launch borg now; output not yet processed
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
453
55
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
454 self.logger.debug('Creating listener threads')
31
b4b4bb7a2ec5 More logging detail
Tuomo Valkonen <tuomov@iki.fi>
parents: 30
diff changeset
455
7
e189d4a6cb8c Also listen to stdout
Tuomo Valkonen <tuomov@iki.fi>
parents: 6
diff changeset
456 t_log=Thread(target=self.__log_listener)
e189d4a6cb8c Also listen to stdout
Tuomo Valkonen <tuomov@iki.fi>
parents: 6
diff changeset
457 t_log.daemon=True
2
e343594c0014 basic config processing
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
458
7
e189d4a6cb8c Also listen to stdout
Tuomo Valkonen <tuomov@iki.fi>
parents: 6
diff changeset
459 t_res=Thread(target=self.__result_listener)
e189d4a6cb8c Also listen to stdout
Tuomo Valkonen <tuomov@iki.fi>
parents: 6
diff changeset
460 t_res.daemon=True
e189d4a6cb8c Also listen to stdout
Tuomo Valkonen <tuomov@iki.fi>
parents: 6
diff changeset
461
e189d4a6cb8c Also listen to stdout
Tuomo Valkonen <tuomov@iki.fi>
parents: 6
diff changeset
462 self.thread_log=t_log
e189d4a6cb8c Also listen to stdout
Tuomo Valkonen <tuomov@iki.fi>
parents: 6
diff changeset
463 self.thread_res=t_res
3
4cad934aa9ce Can launch borg now; output not yet processed
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
464 self.borg_instance=inst
64
6cfe6a89e810 Repository queuing fixes
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
465 self.current_operation=op
6cfe6a89e810 Repository queuing fixes
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
466 # Update scheduled time to real starting time to schedule
6cfe6a89e810 Repository queuing fixes
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
467 # next run relative to this
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
468 self.current_operation.start_time=MonotonicTime.now()
64
6cfe6a89e810 Repository queuing fixes
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
469 # Reset error status when starting a new operation
104
d33e2d7dbeb1 Added some debug log messages
Tuomo Valkonen <tuomov@iki.fi>
parents: 100
diff changeset
470 self.__update_status(State.ACTIVE)
3
4cad934aa9ce Can launch borg now; output not yet processed
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
471
7
e189d4a6cb8c Also listen to stdout
Tuomo Valkonen <tuomov@iki.fi>
parents: 6
diff changeset
472 t_log.start()
e189d4a6cb8c Also listen to stdout
Tuomo Valkonen <tuomov@iki.fi>
parents: 6
diff changeset
473 t_res.start()
3
4cad934aa9ce Can launch borg now; output not yet processed
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
474
74
4f56142e7497 Separated repository configuration form backup configuration;
Tuomo Valkonen <tuomov@iki.fi>
parents: 71
diff changeset
475
49
db33dfa64ad6 Improved scheduler
Tuomo Valkonen <tuomov@iki.fi>
parents: 48
diff changeset
476 def __launch(self, op):
115
df0de44d2c4b Changed one .debug message to .info
Tuomo Valkonen <tuomov@iki.fi>
parents: 109
diff changeset
477 self.logger.info("Launching '%s'" % str(op.type))
55
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
478
74
4f56142e7497 Separated repository configuration form backup configuration;
Tuomo Valkonen <tuomov@iki.fi>
parents: 71
diff changeset
479 params=(config.borg_parameters
4f56142e7497 Separated repository configuration form backup configuration;
Tuomo Valkonen <tuomov@iki.fi>
parents: 71
diff changeset
480 +self.repository.borg_parameters
4f56142e7497 Separated repository configuration form backup configuration;
Tuomo Valkonen <tuomov@iki.fi>
parents: 71
diff changeset
481 +self.borg_parameters)
4f56142e7497 Separated repository configuration form backup configuration;
Tuomo Valkonen <tuomov@iki.fi>
parents: 71
diff changeset
482
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
483 if op.type==Operation.CREATE:
74
4f56142e7497 Separated repository configuration form backup configuration;
Tuomo Valkonen <tuomov@iki.fi>
parents: 71
diff changeset
484 archive="%s::%s%s" % (self.repository.location,
55
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
485 self.archive_prefix,
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
486 self.archive_template)
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
487
74
4f56142e7497 Separated repository configuration form backup configuration;
Tuomo Valkonen <tuomov@iki.fi>
parents: 71
diff changeset
488 self.__do_launch(op, archive, params.common,
4f56142e7497 Separated repository configuration form backup configuration;
Tuomo Valkonen <tuomov@iki.fi>
parents: 71
diff changeset
489 params.create, self.paths)
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
490 elif op.type==Operation.PRUNE:
74
4f56142e7497 Separated repository configuration form backup configuration;
Tuomo Valkonen <tuomov@iki.fi>
parents: 71
diff changeset
491 self.__do_launch(op, self.repository.location, params.common,
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
492 [{'prefix': self.archive_prefix}] + params.prune)
74
4f56142e7497 Separated repository configuration form backup configuration;
Tuomo Valkonen <tuomov@iki.fi>
parents: 71
diff changeset
493
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
494 elif op.type==Operation.LIST:
85
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
495 self.__do_launch(op, self.repository.location, params.common,
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
496 [{'prefix': self.archive_prefix}])
8
7b2d2eac6a48 basic scheduling
Tuomo Valkonen <tuomov@iki.fi>
parents: 7
diff changeset
497 else:
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
498 raise NotImplementedError("Invalid operation '%s'" % str(op.type))
2
e343594c0014 basic config processing
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
499
61
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
500 # This must be called with self._cond held.
64
6cfe6a89e810 Repository queuing fixes
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
501 def __launch_and_wait(self):
55
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
502 op=self.scheduled_operation
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
503 if not op:
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
504 self.logger.debug("Queued operation aborted")
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
505 else:
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
506 self.scheduled_operation=None
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
507
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
508 self.__launch(op)
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
509
64
6cfe6a89e810 Repository queuing fixes
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
510 self.__wait_finish()
6cfe6a89e810 Repository queuing fixes
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
511
98
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
512 def _terminate_or_pause(self):
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
513 return self._terminate or self._pause
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
514
64
6cfe6a89e810 Repository queuing fixes
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
515 def __wait_finish(self):
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
516 current=self.current_operation
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
517
64
6cfe6a89e810 Repository queuing fixes
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
518 # Wait for main logger thread to terminate, or for us to be terminated
98
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
519 while not self._terminate_or_pause() and self.thread_res.is_alive():
64
6cfe6a89e810 Repository queuing fixes
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
520 self._cond.release()
116
4a56dda09745 Pruning scheduling fix
Tuomo Valkonen <tuomov@iki.fi>
parents: 115
diff changeset
521 # Maybe wait for borg instead?
64
6cfe6a89e810 Repository queuing fixes
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
522 self.thread_res.join(JOIN_TIMEOUT)
6cfe6a89e810 Repository queuing fixes
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
523 self._cond.acquire()
6cfe6a89e810 Repository queuing fixes
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
524
98
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
525 # If terminate or pause has been signalled, let outer termination handler
64
6cfe6a89e810 Repository queuing fixes
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
526 # take care of things (Within this Backup class, it would be cleanest
6cfe6a89e810 Repository queuing fixes
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
527 # to raise an exception instead, but in most other places it's better
6cfe6a89e810 Repository queuing fixes
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
528 # to just check self._terminate, so we don't complicate things with
6cfe6a89e810 Repository queuing fixes
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
529 # an extra exception.)
98
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
530 if self.thread_res.is_alive():
64
6cfe6a89e810 Repository queuing fixes
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
531 return
55
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
532
64
6cfe6a89e810 Repository queuing fixes
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
533 self.logger.debug('Waiting for borg and log subprocesses to terminate')
6cfe6a89e810 Repository queuing fixes
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
534
6cfe6a89e810 Repository queuing fixes
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
535 self._cond.release()
6cfe6a89e810 Repository queuing fixes
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
536 self.thread_log.join()
6cfe6a89e810 Repository queuing fixes
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
537 self._cond.acquire()
6cfe6a89e810 Repository queuing fixes
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
538
6cfe6a89e810 Repository queuing fixes
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
539 if not self.borg_instance.wait():
6cfe6a89e810 Repository queuing fixes
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
540 self.logger.error('Borg subprocess did not terminate')
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
541 curent.add_error(Errors.ERRORS)
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
542
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
543 current.finish_time=MonotonicTime.now()
64
6cfe6a89e810 Repository queuing fixes
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
544
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
545 self.previous_operation_of_type[current.type]=current
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
546 self.previous_operation=current
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
547 self.current_operation=None
64
6cfe6a89e810 Repository queuing fixes
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
548 self.thread_res=None
6cfe6a89e810 Repository queuing fixes
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
549 self.thread_log=None
6cfe6a89e810 Repository queuing fixes
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
550 self.borg_instance=None
55
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
551
106
a7bdc239ef62 Added exeption protection decorators to callbacks.
Tuomo Valkonen <tuomov@iki.fi>
parents: 104
diff changeset
552 @protect_noreturn
55
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
553 def __main_thread(self):
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
554 with self._cond:
87
a214d475aa28 Better recovery from errors; fixes to potential race conditions in scheduler and repository queue
Tuomo Valkonen <tuomov@iki.fi>
parents: 86
diff changeset
555 while not self._terminate:
a214d475aa28 Better recovery from errors; fixes to potential race conditions in scheduler and repository queue
Tuomo Valkonen <tuomov@iki.fi>
parents: 86
diff changeset
556 try:
64
6cfe6a89e810 Repository queuing fixes
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
557 assert(not self.current_operation)
6cfe6a89e810 Repository queuing fixes
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
558 self.__main_thread_wait_schedule()
100
b141bed9e718 macOS "sleep" signals / status are complete bollocks:
Tuomo Valkonen <tuomov@iki.fi>
parents: 98
diff changeset
559 if ((not self._terminate_or_pause()) and self.scheduled_operation
98
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
560 and self.scheduled_operation.start_time <= MonotonicTime.now()):
64
6cfe6a89e810 Repository queuing fixes
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
561 self.__main_thread_queue_and_launch()
87
a214d475aa28 Better recovery from errors; fixes to potential race conditions in scheduler and repository queue
Tuomo Valkonen <tuomov@iki.fi>
parents: 86
diff changeset
562 except Exception as err:
98
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
563 self.logger.exception("Exception in backup '%s'" % self.backup_name)
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
564 finally:
87
a214d475aa28 Better recovery from errors; fixes to potential race conditions in scheduler and repository queue
Tuomo Valkonen <tuomov@iki.fi>
parents: 86
diff changeset
565 self.__cleanup()
61
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
566
87
a214d475aa28 Better recovery from errors; fixes to potential race conditions in scheduler and repository queue
Tuomo Valkonen <tuomov@iki.fi>
parents: 86
diff changeset
567 def __cleanup(self):
a214d475aa28 Better recovery from errors; fixes to potential race conditions in scheduler and repository queue
Tuomo Valkonen <tuomov@iki.fi>
parents: 86
diff changeset
568 thread_log=self.thread_log
a214d475aa28 Better recovery from errors; fixes to potential race conditions in scheduler and repository queue
Tuomo Valkonen <tuomov@iki.fi>
parents: 86
diff changeset
569 thread_res=self.thread_res
a214d475aa28 Better recovery from errors; fixes to potential race conditions in scheduler and repository queue
Tuomo Valkonen <tuomov@iki.fi>
parents: 86
diff changeset
570 borg_instance=self.borg_instance
98
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
571 self.scheduled_operation=None
87
a214d475aa28 Better recovery from errors; fixes to potential race conditions in scheduler and repository queue
Tuomo Valkonen <tuomov@iki.fi>
parents: 86
diff changeset
572 self.thread_log=None
a214d475aa28 Better recovery from errors; fixes to potential race conditions in scheduler and repository queue
Tuomo Valkonen <tuomov@iki.fi>
parents: 86
diff changeset
573 self.thread_res=None
a214d475aa28 Better recovery from errors; fixes to potential race conditions in scheduler and repository queue
Tuomo Valkonen <tuomov@iki.fi>
parents: 86
diff changeset
574 self.borg_instance=None
55
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
575
87
a214d475aa28 Better recovery from errors; fixes to potential race conditions in scheduler and repository queue
Tuomo Valkonen <tuomov@iki.fi>
parents: 86
diff changeset
576 self._cond.release()
a214d475aa28 Better recovery from errors; fixes to potential race conditions in scheduler and repository queue
Tuomo Valkonen <tuomov@iki.fi>
parents: 86
diff changeset
577 try:
a214d475aa28 Better recovery from errors; fixes to potential race conditions in scheduler and repository queue
Tuomo Valkonen <tuomov@iki.fi>
parents: 86
diff changeset
578 if borg_instance:
a214d475aa28 Better recovery from errors; fixes to potential race conditions in scheduler and repository queue
Tuomo Valkonen <tuomov@iki.fi>
parents: 86
diff changeset
579 self.logger.debug("Terminating a borg instance")
a214d475aa28 Better recovery from errors; fixes to potential race conditions in scheduler and repository queue
Tuomo Valkonen <tuomov@iki.fi>
parents: 86
diff changeset
580 borg_instance.terminate()
8
7b2d2eac6a48 basic scheduling
Tuomo Valkonen <tuomov@iki.fi>
parents: 7
diff changeset
581
87
a214d475aa28 Better recovery from errors; fixes to potential race conditions in scheduler and repository queue
Tuomo Valkonen <tuomov@iki.fi>
parents: 86
diff changeset
582 if thread_log:
a214d475aa28 Better recovery from errors; fixes to potential race conditions in scheduler and repository queue
Tuomo Valkonen <tuomov@iki.fi>
parents: 86
diff changeset
583 self.logger.debug("Waiting for log thread to terminate")
a214d475aa28 Better recovery from errors; fixes to potential race conditions in scheduler and repository queue
Tuomo Valkonen <tuomov@iki.fi>
parents: 86
diff changeset
584 thread_log.join()
55
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
585
87
a214d475aa28 Better recovery from errors; fixes to potential race conditions in scheduler and repository queue
Tuomo Valkonen <tuomov@iki.fi>
parents: 86
diff changeset
586 if thread_res:
a214d475aa28 Better recovery from errors; fixes to potential race conditions in scheduler and repository queue
Tuomo Valkonen <tuomov@iki.fi>
parents: 86
diff changeset
587 self.logger.debug("Waiting for result thread to terminate")
a214d475aa28 Better recovery from errors; fixes to potential race conditions in scheduler and repository queue
Tuomo Valkonen <tuomov@iki.fi>
parents: 86
diff changeset
588 thread_res.join()
a214d475aa28 Better recovery from errors; fixes to potential race conditions in scheduler and repository queue
Tuomo Valkonen <tuomov@iki.fi>
parents: 86
diff changeset
589 finally:
a214d475aa28 Better recovery from errors; fixes to potential race conditions in scheduler and repository queue
Tuomo Valkonen <tuomov@iki.fi>
parents: 86
diff changeset
590 self._cond.acquire()
98
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
591 self.current_operation=None
55
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
592
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
593 # Main thread/2. Schedule next operation if there is no manually
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
594 # requested one
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
595 def __main_thread_wait_schedule(self):
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
596 op=None
98
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
597 if self._pause:
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
598 self.logger.info("Waiting for resume to be signalled")
55
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
599
104
d33e2d7dbeb1 Added some debug log messages
Tuomo Valkonen <tuomov@iki.fi>
parents: 100
diff changeset
600 self.__update_status(State.PAUSED)
61
bc6c3d74e6ea Made combination error-state into an error-state matrix, as well as Enum
Tuomo Valkonen <tuomov@iki.fi>
parents: 58
diff changeset
601
55
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
602 self._cond.wait()
98
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
603 else:
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
604 if not self.scheduled_operation:
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
605 op=self.__next_operation_unlocked()
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
606 if op:
104
d33e2d7dbeb1 Added some debug log messages
Tuomo Valkonen <tuomov@iki.fi>
parents: 100
diff changeset
607 self.scheduled_operation=op
98
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
608
104
d33e2d7dbeb1 Added some debug log messages
Tuomo Valkonen <tuomov@iki.fi>
parents: 100
diff changeset
609 self.__update_status(State.SCHEDULED)
98
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
610
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
611 # Wait under scheduled wait
104
d33e2d7dbeb1 Added some debug log messages
Tuomo Valkonen <tuomov@iki.fi>
parents: 100
diff changeset
612 eventname=op.name() + '@' + self.backup_name
d33e2d7dbeb1 Added some debug log messages
Tuomo Valkonen <tuomov@iki.fi>
parents: 100
diff changeset
613 self.scheduler.wait_until(op.start_time, self._cond, eventname)
98
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
614 else:
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
615 # Nothing scheduled - just wait
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
616 self.logger.info("Waiting for manual scheduling")
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
617
104
d33e2d7dbeb1 Added some debug log messages
Tuomo Valkonen <tuomov@iki.fi>
parents: 100
diff changeset
618 self.__update_status(State.INACTIVE)
98
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
619
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
620 self._cond.wait()
55
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
621
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
622 # Main thread/3. If there is a scheduled operation (it might have been
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
623 # changed manually from 'op' created in __main_thread_wait_schedule above),
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
624 # queue it on the repository, and launch the operation once repository
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
625 # available
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
626 def __main_thread_queue_and_launch(self):
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
627 if self.scheduled_operation:
104
d33e2d7dbeb1 Added some debug log messages
Tuomo Valkonen <tuomov@iki.fi>
parents: 100
diff changeset
628
d33e2d7dbeb1 Added some debug log messages
Tuomo Valkonen <tuomov@iki.fi>
parents: 100
diff changeset
629 self.__update_status(State.QUEUED)
d33e2d7dbeb1 Added some debug log messages
Tuomo Valkonen <tuomov@iki.fi>
parents: 100
diff changeset
630
64
6cfe6a89e810 Repository queuing fixes
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
631 res=self.repository.queue_action(self._cond,
6cfe6a89e810 Repository queuing fixes
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
632 action=self.__launch_and_wait,
74
4f56142e7497 Separated repository configuration form backup configuration;
Tuomo Valkonen <tuomov@iki.fi>
parents: 71
diff changeset
633 name=self.backup_name)
98
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
634 if not res:
64
6cfe6a89e810 Repository queuing fixes
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
635 self.logger.debug("Queueing aborted")
8
7b2d2eac6a48 basic scheduling
Tuomo Valkonen <tuomov@iki.fi>
parents: 7
diff changeset
636
7b2d2eac6a48 basic scheduling
Tuomo Valkonen <tuomov@iki.fi>
parents: 7
diff changeset
637 def __next_operation_unlocked(self):
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
638 listop=self.__next_operation_list()
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
639 if listop:
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
640 return listop
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
641
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
642 create=self.__next_operation_type(Operation.CREATE,
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
643 self.backup_interval,
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
644 important=True,
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
645 initial_reason='initial');
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
646
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
647 prune=self.__next_operation_type(Operation.PRUNE,
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
648 self.prune_interval,
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
649 important=False,
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
650 initial_reason=None);
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
651
116
4a56dda09745 Pruning scheduling fix
Tuomo Valkonen <tuomov@iki.fi>
parents: 115
diff changeset
652 if prune:
4a56dda09745 Pruning scheduling fix
Tuomo Valkonen <tuomov@iki.fi>
parents: 115
diff changeset
653 self.logger.debug("prune scheduled at %s " % prune.start_time.isoformat())
4a56dda09745 Pruning scheduling fix
Tuomo Valkonen <tuomov@iki.fi>
parents: 115
diff changeset
654 else:
4a56dda09745 Pruning scheduling fix
Tuomo Valkonen <tuomov@iki.fi>
parents: 115
diff changeset
655 self.logger.debug("no prune scheduled")
4a56dda09745 Pruning scheduling fix
Tuomo Valkonen <tuomov@iki.fi>
parents: 115
diff changeset
656
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
657 if not prune:
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
658 return create
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
659 elif not create:
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
660 return prune
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
661 elif create.start_time < prune.start_time:
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
662 return create
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
663 else:
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
664 return prune
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
665
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
666 def __next_operation_list(self):
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
667 reason='initial'
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
668 # Unless manual backup has been chosen (backup_interval<=0), perform
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
669 # repository listing if no previous create operation known, or if we
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
670 # just pruned the repository
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
671 if self.backup_interval<=0:
85
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
672 return None
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
673 elif (self.previous_operation and
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
674 self.previous_operation.type==Operation.PRUNE):
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
675 tm=MonotonicTime.now()
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
676 reason='post-prune'
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
677 elif Operation.LIST in self.previous_operation_of_type:
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
678 prev=self.previous_operation_of_type[Operation.LIST]
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
679 if prev.ok():
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
680 return None
107
f63835e9f29e Oops, a zero retry_interval check had gone missing in scheduling reorganisation.
Tuomo Valkonen <tuomov@iki.fi>
parents: 106
diff changeset
681 if self.retry_interval<=0:
f63835e9f29e Oops, a zero retry_interval check had gone missing in scheduling reorganisation.
Tuomo Valkonen <tuomov@iki.fi>
parents: 106
diff changeset
682 # Do not retry in case of errors if retry interval is <= 0
10
76dbfb06eba0 Semi-working menu items.
Tuomo Valkonen <tuomov@iki.fi>
parents: 8
diff changeset
683 return None
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
684 # Attempt after retry interval
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
685 tm=MonotonicTime.after_other(prev.finish_time, self.retry_interval)
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
686 else:
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
687 # Nothing has been attempted: run immediately
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
688 tm=MonotonicTime.now()
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
689 return Operation(Operation.LIST, tm, reason=reason)
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
690
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
691 def __next_operation_type(self, optype, standard_interval,
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
692 important=False,
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
693 initial_reason=None):
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
694 if optype not in self.previous_operation_of_type:
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
695 # No previous operation exists; perform immediately
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
696 # if important, otherwise after standard interval.
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
697 # Do not perform if manual operation selected by
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
698 # setting standard_interval<=0
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
699 if standard_interval<=0:
10
76dbfb06eba0 Semi-working menu items.
Tuomo Valkonen <tuomov@iki.fi>
parents: 8
diff changeset
700 return None
76dbfb06eba0 Semi-working menu items.
Tuomo Valkonen <tuomov@iki.fi>
parents: 8
diff changeset
701 else:
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
702 if important:
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
703 tm=MonotonicTime.now()
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
704 else:
116
4a56dda09745 Pruning scheduling fix
Tuomo Valkonen <tuomov@iki.fi>
parents: 115
diff changeset
705 tm=self.timeclass.after_other(self.start_time, standard_interval)
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
706 if initial_reason:
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
707 return Operation(optype, tm, reason=initial_reason)
96
de8ac6c470d8 Backup scheduling fixes in case of an initial backup
Tuomo Valkonen <tuomov@iki.fi>
parents: 89
diff changeset
708 else:
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
709 return Operation(optype, tm)
5
4c5514b2fa76 basic schedule calculation
Tuomo Valkonen <tuomov@iki.fi>
parents: 4
diff changeset
710 else:
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
711 # Previous operation has been performed; perform after
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
712 # retry interval if there were errors, otherwise after
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
713 # standard interval.
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
714 prev=self.previous_operation_of_type[optype]
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
715 if not prev.ok():
107
f63835e9f29e Oops, a zero retry_interval check had gone missing in scheduling reorganisation.
Tuomo Valkonen <tuomov@iki.fi>
parents: 106
diff changeset
716 # Do not retry in case of errors if retry interval is <= 0
f63835e9f29e Oops, a zero retry_interval check had gone missing in scheduling reorganisation.
Tuomo Valkonen <tuomov@iki.fi>
parents: 106
diff changeset
717 if self.retry_interval<=0:
f63835e9f29e Oops, a zero retry_interval check had gone missing in scheduling reorganisation.
Tuomo Valkonen <tuomov@iki.fi>
parents: 106
diff changeset
718 return None
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
719 tm=MonotonicTime.after_other(prev.start_time,
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
720 self.retry_interval)
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
721 return Operation(optype, tm, reason='retry')
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
722 elif standard_interval>0:
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
723 tm=self.timeclass.after_other(prev.start_time,
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
724 standard_interval)
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
725 return Operation(optype, tm)
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
726 else:
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
727 # Manual operation is standard_interval is zero.
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
728 return None
10
76dbfb06eba0 Semi-working menu items.
Tuomo Valkonen <tuomov@iki.fi>
parents: 8
diff changeset
729
76dbfb06eba0 Semi-working menu items.
Tuomo Valkonen <tuomov@iki.fi>
parents: 8
diff changeset
730 def __status_unlocked(self):
21
c36e549a7f12 Errors as rumps notifications
Tuomo Valkonen <tuomov@iki.fi>
parents: 20
diff changeset
731 callback=self.__status_update_callback
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
732 status=Status(self)
10
76dbfb06eba0 Semi-working menu items.
Tuomo Valkonen <tuomov@iki.fi>
parents: 8
diff changeset
733
76dbfb06eba0 Semi-working menu items.
Tuomo Valkonen <tuomov@iki.fi>
parents: 8
diff changeset
734 return status, callback
76dbfb06eba0 Semi-working menu items.
Tuomo Valkonen <tuomov@iki.fi>
parents: 8
diff changeset
735
104
d33e2d7dbeb1 Added some debug log messages
Tuomo Valkonen <tuomov@iki.fi>
parents: 100
diff changeset
736 def __update_status(self, state):
d33e2d7dbeb1 Added some debug log messages
Tuomo Valkonen <tuomov@iki.fi>
parents: 100
diff changeset
737 self.logger.debug("Entering %s state", str(state))
d33e2d7dbeb1 Added some debug log messages
Tuomo Valkonen <tuomov@iki.fi>
parents: 100
diff changeset
738 self.state=state
49
db33dfa64ad6 Improved scheduler
Tuomo Valkonen <tuomov@iki.fi>
parents: 48
diff changeset
739 status, callback = self.__status_unlocked()
db33dfa64ad6 Improved scheduler
Tuomo Valkonen <tuomov@iki.fi>
parents: 48
diff changeset
740 if callback:
55
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
741 #self._cond.release()
49
db33dfa64ad6 Improved scheduler
Tuomo Valkonen <tuomov@iki.fi>
parents: 48
diff changeset
742 try:
55
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
743 callback(status)
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
744 except Exception:
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
745 self.logger.exception("Status update error")
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
746 #finally:
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
747 # self._cond.acquire()
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
748
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
749 #
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
750 # Interface functions
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
751 #
49
db33dfa64ad6 Improved scheduler
Tuomo Valkonen <tuomov@iki.fi>
parents: 48
diff changeset
752
21
c36e549a7f12 Errors as rumps notifications
Tuomo Valkonen <tuomov@iki.fi>
parents: 20
diff changeset
753 def set_status_update_callback(self, callback):
49
db33dfa64ad6 Improved scheduler
Tuomo Valkonen <tuomov@iki.fi>
parents: 48
diff changeset
754 with self._cond:
21
c36e549a7f12 Errors as rumps notifications
Tuomo Valkonen <tuomov@iki.fi>
parents: 20
diff changeset
755 self.__status_update_callback=callback
10
76dbfb06eba0 Semi-working menu items.
Tuomo Valkonen <tuomov@iki.fi>
parents: 8
diff changeset
756
49
db33dfa64ad6 Improved scheduler
Tuomo Valkonen <tuomov@iki.fi>
parents: 48
diff changeset
757 def status(self):
db33dfa64ad6 Improved scheduler
Tuomo Valkonen <tuomov@iki.fi>
parents: 48
diff changeset
758 with self._cond:
db33dfa64ad6 Improved scheduler
Tuomo Valkonen <tuomov@iki.fi>
parents: 48
diff changeset
759 res=self.__status_unlocked()
db33dfa64ad6 Improved scheduler
Tuomo Valkonen <tuomov@iki.fi>
parents: 48
diff changeset
760 return res[0]
10
76dbfb06eba0 Semi-working menu items.
Tuomo Valkonen <tuomov@iki.fi>
parents: 8
diff changeset
761
55
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
762 def create(self):
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
763 op=Operation(Operation.CREATE, MonotonicTime.now(), reason='manual')
55
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
764 with self._cond:
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
765 self.scheduled_operation=op
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
766 self._cond.notify()
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
767
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
768 def prune(self):
97
96d5adbe0205 Pruning support
Tuomo Valkonen <tuomov@iki.fi>
parents: 96
diff changeset
769 op=Operation(Operation.PRUNE, MonotonicTime.now(), reason='manual')
55
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
770 with self._cond:
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
771 self.scheduled_operation=op
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
772 self._cond.notify()
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
773
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
774 # TODO: Decide exact (manual) abort mechanism. Perhaps two stages
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
775 def abort(self):
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
776 with self._cond:
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
777 if self.borg_instance:
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
778 self.borg_instance.terminate()
407af23d16bb Improved backup main thread loop, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 54
diff changeset
779
98
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
780 def is_paused(self):
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
781 with self._cond:
104
d33e2d7dbeb1 Added some debug log messages
Tuomo Valkonen <tuomov@iki.fi>
parents: 100
diff changeset
782 paused=(self.state==State.PAUSED)
98
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
783 return paused
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
784
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
785 def pause(self):
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
786 with self._cond:
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
787 self.logger.debug('Pause signalled')
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
788 self.scheduled_operation=None
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
789 self._pause=True
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
790 self._cond.notify()
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
791
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
792 def resume(self):
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
793 with self._cond:
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
794 self.logger.debug('Resume signalled')
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
795 self._pause=False
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
796 self._cond.notify()
9052e427ea39 Added pause feature
Tuomo Valkonen <tuomov@iki.fi>
parents: 97
diff changeset
797

mercurial