Keychain support and random fixes

Sat, 20 Jan 2018 23:50:36 +0000

author
Tuomo Valkonen <tuomov@iki.fi>
date
Sat, 20 Jan 2018 23:50:36 +0000
changeset 20
fdfbe5d7b677
parent 19
f9ce2442f14f
child 21
c36e549a7f12

Keychain support and random fixes

README.md file | annotate | diff | comparison | revisions
backup.py file | annotate | diff | comparison | revisions
instance.py file | annotate | diff | comparison | revisions
ui.py file | annotate | diff | comparison | revisions
--- a/README.md	Sat Jan 20 23:19:16 2018 +0000
+++ b/README.md	Sat Jan 20 23:50:36 2018 +0000
@@ -1,8 +1,26 @@
+# Borgend
+
 This is a retrying and queuing scheduler as well as a MacOS tray icon for [BorgBackup](https://borgbackup.readthedocs.io/en/stable/).
 
 The lead author is Tuomo Valkonen (<tuomov@iki.fi>).
 
-# LICENSE
+## Installation
+
+You will need to install the following non-standard Python packages:
+
+ - [rumps](https://github.com/jaredks/rumps) (Ridiculously Uncomplicated macOS Python Statusbar apps)
+ - [keyring](https://pypi.python.org/pypi/keyring)
+
+## Usage
+
+### Passphrases
+
+Passphrases are stored in the OS X Keychain (or whatever the keyring package support on other systems). In the Borgend configuration file, you only configure the ‘account’ of the of the password using `keychain_account` keyword of each backup set. The ‘service’ of the password has to be `borg-backup`. To add a password into the keychain for the ‘my-borg-backup’, you may use:
+
+    security add-generic-password -a my-borg-backup -s borg-backup -w [PASSWORD]
+
+
+## License
 
 This software is distributed under an ANTI-ABUSE LICENSE (aka. *fuck copyright and fuck distributions license*), and without any warranty whatsoever. If you redistribute this software as part of a larger collection/distribution/suite of software, you must do either of the following:
 
@@ -13,3 +31,4 @@
 (b) Rename the software, and make it obvious that your modified or obsolete software is in no way connected to the lead author of the original software. The users of your version should under no circumstances be under the illusion that they can contact the lead author or any of the authors of the original software if they have any complaints or queries.
 
 Otherwise, do whatever you want with this software.
+
--- a/backup.py	Sat Jan 20 23:19:16 2018 +0000
+++ b/backup.py	Sat Jan 20 23:50:36 2018 +0000
@@ -5,6 +5,7 @@
 import config
 import logging
 import time
+import keyring
 from instance import BorgInstance
 from queue import Queue
 from threading import Thread, Lock, Timer
@@ -71,6 +72,15 @@
                                                          'Prune parameters', self.loc,
                                                          default=[])
 
+        keychain_account=config.check_string(cfg, 'keychain_account',
+                                             'Keychain account', self.loc,
+                                              default='')
+
+        if keychain_account and keychain_account!='':
+            pw=keyring.get_password("borg-backup", keychain_account)
+            self.__password=pw
+        else:
+            self.__password=None
 
     def __init__(self, identifier, cfg):
         self.identifier=identifier
@@ -212,7 +222,7 @@
 
     def __do_launch(self, queue, op, archive_or_repository, *args):
         inst=BorgInstance(op['operation'], archive_or_repository, *args)
-        inst.launch()
+        inst.launch(password=self.__password)
 
         t_log=Thread(target=self.__log_listener)
         t_log.daemon=True
--- a/instance.py	Sat Jan 20 23:19:16 2018 +0000
+++ b/instance.py	Sat Jan 20 23:50:36 2018 +0000
@@ -4,6 +4,7 @@
 
 import json
 import logging
+import os
 from subprocess import Popen, PIPE
 from config import settings, arglistify
 
@@ -35,12 +36,17 @@
 
         return cmd+arglistify(self.args)+[self.archive_or_repository]+self.argsl
 
-    def launch(self):
+    def launch(self, password=None):
         cmd=self.construct_cmdline()
 
         logging.info('Launching ' + str(cmd))
 
-        self.proc=Popen(cmd, stdout=PIPE, stderr=PIPE, stdin=PIPE)
+        env=None
+        if password:
+            env=os.environ.copy()
+            env['BORG_PASSPHRASE']=password
+
+        self.proc=Popen(cmd, env=env, stdout=PIPE, stderr=PIPE, stdin=PIPE)
 
         # We don't do password input etc.
         self.proc.stdin.close()
--- a/ui.py	Sat Jan 20 23:19:16 2018 +0000
+++ b/ui.py	Sat Jan 20 23:50:36 2018 +0000
@@ -34,7 +34,7 @@
    TB = float(KB ** 4) # 1,099,511,627,776
 
    if B < KB:
-      return '{0} {1}B'.format(B)
+      return '{0}B'.format(B)
    elif KB <= B < MB:
       return '{0:.2f}KB'.format(B/KB)
    elif MB <= B < GB:
@@ -76,8 +76,8 @@
         if 'progress_current' in status and 'progress_total' in status:
             progress=' %d%%' % (status.progress_current/status.progress_total)
         elif 'original_size' in status and 'deduplicated_size' in status:
-            progress=' %s O %s D' % (humanbytes(status.original_size),
-                                     humanbytes(status.deduplicated_size))
+            progress=' %s→%s' % (humanbytes(status['original_size']),
+                                 humanbytes(status['deduplicated_size']))
         title="%s (running: %s%s)" % (status['name'], status['operation'], progress)
         state=ACTIVE
     else: # status['type']=='nothing':
@@ -122,7 +122,6 @@
         for index in range(len(self.backups)):
             b=self.backups[index]
             title, this_state=make_title(self.statuses[index])
-            logging.info('TITLE: %s' % title)
             # Python closures suck dog's balls...
             # first and the last program I write in Python until somebody
             # fixes this brain damage

mercurial