# HG changeset patch # User Tuomo Valkonen # Date 1516492236 0 # Node ID fdfbe5d7b67729d97904584e287319de65ade9c2 # Parent f9ce2442f14f7a7ea2b2d8b88ee62fddd6b6e8f8 Keychain support and random fixes diff -r f9ce2442f14f -r fdfbe5d7b677 README.md --- 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 (). -# 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. + diff -r f9ce2442f14f -r fdfbe5d7b677 backup.py --- 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 diff -r f9ce2442f14f -r fdfbe5d7b677 instance.py --- 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() diff -r f9ce2442f14f -r fdfbe5d7b677 ui.py --- 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