backup.py

changeset 32
06fc14211ba9
parent 31
b4b4bb7a2ec5
child 34
9fce700d42de
--- a/backup.py	Sun Jan 21 13:34:12 2018 +0000
+++ b/backup.py	Sun Jan 21 14:34:35 2018 +0000
@@ -78,16 +78,30 @@
                                                     'Keychain account', self.loc,
                                                     default='')
 
+        self.__passphrase=None
+
         if config.settings['extract_passphrases_at_startup']:
-            self.extract_passphrase()
+            try:
+                self.extract_passphrase()
+            except Exception:
+                pass
 
     def extract_passphrase(self):
         acc=self.__keychain_account
-        if acc and acc!='':
-            pw=keyring.get_password("borg-backup", acc)
-            self.__passphrase=pw
-        else:
-            self.__passphrase=None
+        if not self.__passphrase:
+            if acc and acc!='':
+                logger.debug('Requesting passphrase')
+                try:
+                    pw=keyring.get_password("borg-backup", acc)
+                except Exception as err:
+                    logger.error('Failed to retrieve password: %s' % str(err))
+                    raise err
+                else:
+                    logger.debug('Received passphrase')
+                self.__passphrase=pw
+            else:
+                self.__passphrase=None
+        return self.__passphrase
 
     def __init__(self, identifier, cfg):
         self.identifier=identifier
@@ -95,7 +109,7 @@
         self.__decode_config(cfg)
 
         self.config=config
-        self.lastrun=None
+        self.lastrun_when=None
         self.lastrun_success=None
         self.borg_instance=None
         self.current_operation=None
@@ -212,7 +226,7 @@
 
         with self.lock:
             if self.current_operation['operation']=='create':
-                self.lastrun=self.current_operation['when_monotonic']
+                self.lastrun_when=self.current_operation['when_monotonic']
                 self.lastrun_success=success
             self.thread_res=None
             self.thread_log=None
@@ -224,10 +238,10 @@
             callback(self, status)
 
     def __do_launch(self, queue, op, archive_or_repository, *args):
-        self.extract_passphrase()
+        passphrase=self.extract_passphrase()
 
         inst=BorgInstance(op['operation'], archive_or_repository, *args)
-        inst.launch(passphrase=self.__passphrase)
+        inst.launch(passphrase=passphrase)
 
         logger.debug('Creating listener threads')
 
@@ -258,24 +272,30 @@
                 self.timer=None
                 self.scheduled_operation=None
 
-            logger.debug("Launching '%s' on '%s'" % (op['operation'], self.name))
+            try:
+                logger.debug("Launching '%s' on '%s'" % (op['operation'], self.name))
 
-            if op['operation']=='create':
-                archive="%s::%s%s" % (self.repository,
-                                      self.archive_prefix,
-                                      self.archive_template)
+                if op['operation']=='create':
+                    archive="%s::%s%s" % (self.repository,
+                                          self.archive_prefix,
+                                          self.archive_template)
 
-                self.__do_launch(queue, op, archive,
-                                 self.common_parameters+self.create_parameters,
-                                 self.paths)
-            elif op['operation']=='prune':
-                self.__do_launch(queue, op, self.repository,
-                                 ([{'prefix': self.archive_prefix}] + 
-                                  self.common_parameters +
-                                  self.prune_parameters))
-            else:
-                logger.error("Invalid operaton '%s'" % op['operation'])
+                    self.__do_launch(queue, op, archive,
+                                     self.common_parameters+self.create_parameters,
+                                     self.paths)
+                elif op['operation']=='prune':
+                    self.__do_launch(queue, op, self.repository,
+                                     ([{'prefix': self.archive_prefix}] + 
+                                      self.common_parameters +
+                                      self.prune_parameters))
+                else:
+                    raise NotImplementedError("Invalid operation '%s'" % op['operation'])
+            except Exception as err:
+                logging.debug('Rescheduling after failure')
+                self.lastrun_when=time.monotonic()
+                self.lastrun_success=False
                 self.__schedule_unlocked()
+                raise err
 
             return True
 
@@ -338,7 +358,7 @@
     def __next_operation_unlocked(self):
         # TODO: pruning as well
         now=time.monotonic()
-        if not self.lastrun:
+        if not self.lastrun_when:
             initial_interval=self.retry_interval
             if initial_interval==0:
                 initial_interval=self.backup_interval
@@ -354,14 +374,14 @@
             else:
                 return {'operation': 'create',
                         'detail': 'retry',
-                        'when_monotonic': self.lastrun+self.retry_interval}
+                        'when_monotonic': self.lastrun_when+self.retry_interval}
         else:
             if self.backup_interval==0:
                 return None
             else:
                 return {'operation': 'create',
                         'detail': None,
-                        'when_monotonic': self.lastrun+self.backup_interval}
+                        'when_monotonic': self.lastrun_when+self.backup_interval}
 
     def __schedule_unlocked(self):
         if self.current_operation:

mercurial