Sat, 20 Jan 2018 23:50:36 +0000
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