Can launch borg now; output not yet processed

Fri, 19 Jan 2018 14:42:27 +0000

author
Tuomo Valkonen <tuomov@iki.fi>
date
Fri, 19 Jan 2018 14:42:27 +0000
changeset 3
4cad934aa9ce
parent 2
e343594c0014
child 4
d72c4844e791

Can launch borg now; output not yet processed

backup.py file | annotate | diff | comparison | revisions
borgend.py file | annotate | diff | comparison | revisions
config.py file | annotate | diff | comparison | revisions
instance.py file | annotate | diff | comparison | revisions
--- a/backup.py	Fri Jan 19 10:41:01 2018 +0000
+++ b/backup.py	Fri Jan 19 14:42:27 2018 +0000
@@ -4,6 +4,8 @@
 
 import config
 from instance import BorgInstance
+from queue import Queue
+from threading import Thread
 
 class Backup:
 
@@ -17,6 +19,9 @@
         self.repository=config.check_string(cfg, 'repository',
                                             'Target repository', self.loc)
 
+        self.archive_prefix=config.check_string(cfg, 'archive_prefix',
+                                                'Archive prefix', self.loc)
+
         self.archive_template=config.check_string(cfg, 'archive_template',
                                                   'Archive template', self.loc)
 
@@ -30,9 +35,13 @@
 
         self.paths=config.check_nonempty_list_of_strings(cfg, 'paths', 'Paths', self.loc)
 
-        self.borg_parameters=config.check_list_of_dicts(cfg, 'borg_parameters',
-                                                        'Borg parameters', self.loc,
-                                                        default=[])
+        self.create_parameters=config.check_list_of_dicts(cfg, 'create_parameters',
+                                                         'Borg parameters', self.loc,
+                                                         default=[])
+
+        self.prune_parameters=config.check_list_of_dicts(cfg, 'prune_parameters',
+                                                         'Borg parameters', self.loc,
+                                                         default=[])
 
 
     def __init__(self, identifier, cfg):
@@ -40,20 +49,55 @@
 
         self.__decode_config(cfg)
 
-
         self.config=config
         self.lastrun=None
-        self.current_instance=None
+        self.borg_instance=None
+        self.thread=None
+
+    def __block_when_running(self):
+        assert(self.borg_instance is None and self.thread is None)
 
-    def create(self):
-        if self.current_instance is not None:
-            raise AssertionError('%s running: cannot launch' % self.loc)
+    def __listener(self):
+        for status in iter(self.borg_instance.read, None):
+            # What to do?
+            print(status)
+        # What to do on error
+            #     queue.put({'identifier': instance.identifier,
+            #                'operation': instance.operation,
+            #                'status': status})
+
+    def __launch(self, queue, operation, archive_or_repository, *args):
+
+        inst=BorgInstance(operation, archive_or_repository, *args)
+        inst.launch()
+
+        t=Thread(target=self.__listener)
+        t.daemon=True
 
-        archive="%s::%s" % (self.repository, self.archive_template)
+        self.thread=t
+        self.borg_instance=inst
+        self.queue=queue
+
+        t.start()
+
+    def create(self, queue):
+        self.__block_when_running()
 
-        inst=BorgInstance(self.identifier, 'create', self.borg_parameters, 
-                          archive, self.paths)
-        print(inst.construct_cmdline())
+        archive="%s::%s%s" % (self.repository,
+                              self.archive_prefix,
+                              self.archive_template)
+
+        self.__launch(queue, 'create', archive,
+                      self.create_parameters, self.paths)
+
+    def prune(self, queue):
+        self.__block_when_running()
+        self.__launch(queue, 'prune', self.repository,
+                      [{'prefix': self.archive_prefix}] + self.prune_parameters)
+
+    def join(self):
+        if self.thread:
+            self.thread.join()
 
 
 
--- a/borgend.py	Fri Jan 19 10:41:01 2018 +0000
+++ b/borgend.py	Fri Jan 19 14:42:27 2018 +0000
@@ -2,8 +2,8 @@
 
 from backup import Backup
 from config import settings
+from queue import Queue
 import ui
-import queue
 #import scheduler
 
 if __name__ == "__main__":
@@ -17,4 +17,7 @@
 for i in range(len(backupconfigs)):
     backups[i]=Backup(i, backupconfigs[i])
 
-backups[0].create()
+queue=Queue()
+backups[0].create(queue)
+
+backups[0].join()
--- a/config.py	Fri Jan 19 10:41:01 2018 +0000
+++ b/config.py	Fri Jan 19 14:42:27 2018 +0000
@@ -23,6 +23,7 @@
        'executable': 'borg',
        'common_parameters': [],
        'create_parameters': [],
+       'prune_parameters': [],
     }
 }
 
@@ -128,12 +129,16 @@
         cfg[field]=fn(cfg, field, field, loc, defa[field])
         return cfg
 
+    def check_parameters(cmd):
+        settings['borg']=check_and_set(settings['borg'], cmd+'_parameters',
+                                       'borg', defaults['borg'],
+                                       check_list_of_dicts)
+
     settings['borg']=check_and_set(settings['borg'], 'executable', 'borg',
                                    defaults['borg'], check_string)
 
-    settings['borg']=check_and_set(settings['borg'], 'common_parameters', 'borg',
-                                   defaults['borg'], check_list_of_dicts)
+    check_parameters('common')
+    check_parameters('create')
+    check_parameters('prune')
 
-    settings['borg']=check_and_set(settings['borg'], 'create_parameters', 'borg',
-                                   defaults['borg'], check_list_of_dicts)
 
--- a/instance.py	Fri Jan 19 10:41:01 2018 +0000
+++ b/instance.py	Fri Jan 19 14:42:27 2018 +0000
@@ -5,25 +5,13 @@
 import json
 from subprocess import Popen, PIPE
 from config import settings, arglistify
-from queue import Queue
-from threading import Thread
-
-def linereader(stream, instance, queue):
-    # What to do on error?
-    for line in iter(stream.readline, b''):
-        status=json.loads(line)
-        queue.put({'identifier': instance.identifier,
-                   'operation': instance.operation,
-                   'status': status})
-    out.close()
 
 class BorgInstance:
 
-    def __init__(self, identifier, operation, args, archive, argsl):
-        self.identifier=identifier;
+    def __init__(self, operation, archive_or_repository, args, argsl):
         self.operation=operation;
         self.args=args;
-        self.archive=archive;
+        self.archive_or_repository=archive_or_repository;
         self.argsl=argsl;
 
     def construct_cmdline(self):
@@ -33,22 +21,41 @@
         tmp1=self.operation+'_parameters'
         if tmp1 in settings['borg']:
             cmd=cmd+arglistify(settings['borg'][tmp1])
-        return cmd+arglistify(self.args)+[self.archive]+self.argsl
+        cmd=cmd+arglistify(self.args)+[self.archive_or_repository]+self.argsl
+        print(cmd)
+        return cmd
 
-    def launch(self, queue):
+    def launch(self):
         # What to do with stderr? Is it needed?
         self.proc=Popen(self.construct_cmdline(), stdout=PIPE, stderr=PIPE)
-        linereaderargs=(self.proc.stdout, self, queue)
-        self.t=Thread(target=linereader, args=linereaderargs)
-        t.daemon=True
-        t.start()
 
-    def read_output():
-        try:
-            obj=self.queue.get_nowait()
-        except Empty:
-            obj=Empty
-        return obj
+    def read(self):
+        line=self.proc.stdout.readline()
+        if line==b'':
+            line=self.proc.stderr.readline()
+            if line==b'':
+                return None
+            print('EEE'+str(line))
+            return 'error'
+        else:
+            print('###' + str(line))
+            # # What to do on error? stderr?
+            status=json.loads(line)
+            return status
+
+    # for line in iter(stream.readline, b''):
+    #     status=json.loads(line)
+    #     queue.put({'identifier': instance.identifier,
+    #                'operation': instance.operation,
+    #                'status': status})
+    # out.close()
+
+    # def read_output():
+    #     try:
+    #         obj=self.queue.get_nowait()
+    #     except Empty:
+    #         obj=Empty
+    #     return obj
 
 
 

mercurial