summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2011-04-05 17:14:29 +0100
committerLars Wirzenius <liw@liw.fi>2011-04-05 17:14:29 +0100
commitd6d768a6fd7bc1ef432d86bdf29bc241bcec83b1 (patch)
tree047aff7bc395122661caf249911ee1ae93bb144d
parent89ba6edad09d4ae42f104b2eb2ac80801dd79816 (diff)
downloadobnam-d6d768a6fd7bc1ef432d86bdf29bc241bcec83b1.tar.gz
Enable encryption plugin.
This required changed the repo trees to get the repo, not hooks, as their final argument. Meh.
-rw-r--r--obnamlib/app.py9
-rw-r--r--obnamlib/checksumtree_tests.py6
-rw-r--r--obnamlib/chunklist_tests.py6
-rw-r--r--obnamlib/clientlist_tests.py6
-rw-r--r--obnamlib/clientmetadatatree_tests.py13
-rw-r--r--obnamlib/plugins/encryption_plugin.py32
-rw-r--r--obnamlib/repo.py28
-rw-r--r--obnamlib/repo_tree.py7
8 files changed, 67 insertions, 40 deletions
diff --git a/obnamlib/app.py b/obnamlib/app.py
index 7cb97bab..247661ee 100644
--- a/obnamlib/app.py
+++ b/obnamlib/app.py
@@ -96,7 +96,14 @@ class App(object):
self.hooks.new('plugins-loaded')
self.hooks.new('config-loaded')
self.hooks.new('shutdown')
-
+
+ # The Repository class defines some hooks, but the class
+ # won't be instantiated until much after plugins are enabled,
+ # and since all hooks must be defined when plugins are enabled,
+ # we create one instance here, which will immediately be destroyed.
+ # FIXME: This is fugly.
+ obnamlib.Repository(None, 1000, 1000, 100, self.hooks)
+
def plugins_dir(self):
return os.path.join(os.path.dirname(obnamlib.__file__), 'plugins')
diff --git a/obnamlib/checksumtree_tests.py b/obnamlib/checksumtree_tests.py
index fe533a8d..9fe8d3d9 100644
--- a/obnamlib/checksumtree_tests.py
+++ b/obnamlib/checksumtree_tests.py
@@ -27,13 +27,13 @@ class ChecksumTreeTests(unittest.TestCase):
def setUp(self):
self.tempdir = tempfile.mkdtemp()
fs = obnamlib.LocalFS(self.tempdir)
- hooks = obnamlib.HookManager()
- hooks.new('repository-toplevel-init')
+ self.hooks = obnamlib.HookManager()
+ self.hooks.new('repository-toplevel-init')
self.checksum = hashlib.md5('foo').digest()
self.tree = obnamlib.ChecksumTree(fs, 'x', len(self.checksum),
obnamlib.DEFAULT_NODE_SIZE,
obnamlib.DEFAULT_UPLOAD_QUEUE_SIZE,
- obnamlib.DEFAULT_LRU_SIZE, hooks)
+ obnamlib.DEFAULT_LRU_SIZE, self)
def tearDown(self):
self.tree.commit()
diff --git a/obnamlib/chunklist_tests.py b/obnamlib/chunklist_tests.py
index df358488..642732a0 100644
--- a/obnamlib/chunklist_tests.py
+++ b/obnamlib/chunklist_tests.py
@@ -26,12 +26,12 @@ class ChunkListTests(unittest.TestCase):
def setUp(self):
self.tempdir = tempfile.mkdtemp()
fs = obnamlib.LocalFS(self.tempdir)
- hooks = obnamlib.HookManager()
- hooks.new('repository-toplevel-init')
+ self.hooks = obnamlib.HookManager()
+ self.hooks.new('repository-toplevel-init')
self.list = obnamlib.ChunkList(fs,
obnamlib.DEFAULT_NODE_SIZE,
obnamlib.DEFAULT_UPLOAD_QUEUE_SIZE,
- obnamlib.DEFAULT_LRU_SIZE, hooks)
+ obnamlib.DEFAULT_LRU_SIZE, self)
def tearDown(self):
shutil.rmtree(self.tempdir)
diff --git a/obnamlib/clientlist_tests.py b/obnamlib/clientlist_tests.py
index 6ff9df97..d54f46ed 100644
--- a/obnamlib/clientlist_tests.py
+++ b/obnamlib/clientlist_tests.py
@@ -26,12 +26,12 @@ class ClientListTests(unittest.TestCase):
def setUp(self):
self.tempdir = tempfile.mkdtemp()
fs = obnamlib.LocalFS(self.tempdir)
- hooks = obnamlib.HookManager()
- hooks.new('repository-toplevel-init')
+ self.hooks = obnamlib.HookManager()
+ self.hooks.new('repository-toplevel-init')
self.list = obnamlib.ClientList(fs,
obnamlib.DEFAULT_NODE_SIZE,
obnamlib.DEFAULT_UPLOAD_QUEUE_SIZE,
- obnamlib.DEFAULT_LRU_SIZE, hooks)
+ obnamlib.DEFAULT_LRU_SIZE, self)
def tearDown(self):
shutil.rmtree(self.tempdir)
diff --git a/obnamlib/clientmetadatatree_tests.py b/obnamlib/clientmetadatatree_tests.py
index 77ede295..35f1f79e 100644
--- a/obnamlib/clientmetadatatree_tests.py
+++ b/obnamlib/clientmetadatatree_tests.py
@@ -27,12 +27,12 @@ class ClientMetadataTreeTests(unittest.TestCase):
def setUp(self):
self.tempdir = tempfile.mkdtemp()
fs = obnamlib.LocalFS(self.tempdir)
- hooks = obnamlib.HookManager()
- hooks.new('repository-toplevel-init')
+ self.hooks = obnamlib.HookManager()
+ self.hooks.new('repository-toplevel-init')
self.client = obnamlib.ClientMetadataTree(fs, 'clientid',
obnamlib.DEFAULT_NODE_SIZE,
obnamlib.DEFAULT_UPLOAD_QUEUE_SIZE,
- obnamlib.DEFAULT_LRU_SIZE, hooks)
+ obnamlib.DEFAULT_LRU_SIZE, self)
def tearDown(self):
shutil.rmtree(self.tempdir)
@@ -140,12 +140,13 @@ class ClientMetadataTreeFileOpsTests(unittest.TestCase):
def setUp(self):
self.tempdir = tempfile.mkdtemp()
fs = obnamlib.LocalFS(self.tempdir)
- hooks = obnamlib.HookManager()
- hooks.new('repository-toplevel-init')
+ self.hooks = obnamlib.HookManager()
+ self.hooks.new('repository-toplevel-init')
self.client = obnamlib.ClientMetadataTree(fs, 'clientid',
obnamlib.DEFAULT_NODE_SIZE,
obnamlib.DEFAULT_UPLOAD_QUEUE_SIZE,
- obnamlib.DEFAULT_LRU_SIZE, hooks)
+ obnamlib.DEFAULT_LRU_SIZE,
+ self)
self.client.start_generation()
self.clientid = self.client.get_generation_id(self.client.tree)
self.file_metadata = obnamlib.Metadata(st_mode=stat.S_IFREG | 0666)
diff --git a/obnamlib/plugins/encryption_plugin.py b/obnamlib/plugins/encryption_plugin.py
index bb4d6790..7c9631c3 100644
--- a/obnamlib/plugins/encryption_plugin.py
+++ b/obnamlib/plugins/encryption_plugin.py
@@ -20,7 +20,9 @@ import obnamlib
class EncryptionPlugin(obnamlib.ObnamPlugin):
def enable(self):
- return
+ self.app.config.new_string(['encrypt-with'],
+ 'PGP key with which to encrypt data '
+ 'in the backup repository')
hooks = [
('repository-toplevel-init', self.toplevel_init),
@@ -30,28 +32,44 @@ class EncryptionPlugin(obnamlib.ObnamPlugin):
for name, callback in hooks:
self.app.hooks.add_callback(name, callback)
- self.client_keyid = self.app.config['client-keyid']
- self.client_pubkey = obnamlib.get_public_key(self.client_keyid)
+ self._pubkey = None
- def toplevel_init(self, repo, name):
+ @property
+ def keyid(self):
+ return self.app.config['encrypt-with']
+
+ @property
+ def pubkey(self):
+ if self._pubkey is None:
+ self._pubkey = obnamlib.get_public_key(self.keyid)
+ return self._pubkey
+
+ def toplevel_init(self, repo, toplevel):
'''Initialize a new toplevel for encryption.'''
+ if not self.keyid:
+ return
+
pubkeys = obnamlib.Keyring()
- pubkeys.add(self.client_pubkey)
+ pubkeys.add(self.pubkey)
symmetric_key = obnamlib.generate_symmetric_key()
encrypted = obnamlib.encrypt_with_keyring(symmetric_key, pubkeys)
- repo.fs.write_file(os.path.join(name, 'key'), encrypted)
+ repo.fs.write_file(os.path.join(toplevel, 'key'), encrypted)
encoded = str(pubkeys)
encrypted = obnamlib.encrypt_symmetric(encoded, symmetric_key)
- repo.fs.write_file(os.path.join(name, 'userkeys'), encrypted)
+ repo.fs.write_file(os.path.join(toplevel, 'userkeys'), encrypted)
def toplevel_read_data(self, encrypted, repo, toplevel):
+ if not self.keyid:
+ return encrypted
symmetric_key = self.get_symmetric_key(repo, toplevel)
return obnamlib.decrypt_with_symmetric_key(encrypted, symmetric_key)
def toplevel_write_data(self, cleartext, repo, toplevel):
+ if not self.keyid:
+ return cleartext
symmetric_key = self.get_symmetric_key(repo, toplevel)
return obnamlib.encrypt_with_symmetric_key(cleartext, symmetric_key)
diff --git a/obnamlib/repo.py b/obnamlib/repo.py
index cad485f2..9e60d1e5 100644
--- a/obnamlib/repo.py
+++ b/obnamlib/repo.py
@@ -203,16 +203,15 @@ class Repository(object):
format_version = 1
def __init__(self, fs, node_size, upload_queue_size, lru_size, hooks):
- hooks = hooks or obnamlib.HookManager()
- fs = HookedFS(self, fs, hooks)
- self.fs = fs
- self.setup_hooks(hooks)
+ self.setup_hooks(hooks or obnamlib.HookManager())
+ self.fs = HookedFS(self, fs, self.hooks)
self.node_size = node_size
self.upload_queue_size = upload_queue_size
self.lru_size = lru_size
self.got_root_lock = False
- self.clientlist = obnamlib.ClientList(fs, node_size, upload_queue_size,
- lru_size, hooks)
+ self.clientlist = obnamlib.ClientList(self.fs, node_size,
+ upload_queue_size,
+ lru_size, self)
self.got_client_lock = False
self.client_lockfile = None
self.current_client = None
@@ -222,21 +221,22 @@ class Repository(object):
self.removed_clients = []
self.removed_generations = []
self.client = None
- self.chunklist = obnamlib.ChunkList(fs, node_size, upload_queue_size,
- lru_size, hooks)
- self.chunksums = obnamlib.ChecksumTree(fs, 'chunksums',
+ self.chunklist = obnamlib.ChunkList(self.fs, node_size,
+ upload_queue_size,
+ lru_size, self)
+ self.chunksums = obnamlib.ChecksumTree(self.fs, 'chunksums',
len(self.checksum('')),
node_size, upload_queue_size,
- lru_size, hooks)
+ lru_size, self)
self.prev_chunkid = None
-
+
def setup_hooks(self, hooks):
self.hooks = hooks
self.hooks.new('repository-toplevel-init')
self.hooks.new_filter('repository-read-data')
self.hooks.new_filter('repository-write-data')
-
+
def checksum(self, data):
'''Return checksum of data.
@@ -401,7 +401,7 @@ class Repository(object):
self.client = obnamlib.ClientMetadataTree(self.fs, client_dir,
self.node_size,
self.upload_queue_size,
- self.lru_size, self.hooks)
+ self.lru_size, self)
self.client.init_forest()
@require_client_lock
@@ -444,7 +444,7 @@ class Repository(object):
self.client = obnamlib.ClientMetadataTree(self.fs, client_dir,
self.node_size,
self.upload_queue_size,
- self.lru_size, self.hooks)
+ self.lru_size, self)
self.client.init_forest()
@require_open_client
diff --git a/obnamlib/repo_tree.py b/obnamlib/repo_tree.py
index 9cbf7276..d24d92c2 100644
--- a/obnamlib/repo_tree.py
+++ b/obnamlib/repo_tree.py
@@ -35,14 +35,14 @@ class RepositoryTree(object):
'''
def __init__(self, fs, dirname, key_bytes, node_size, upload_queue_size,
- lru_size, hooks):
+ lru_size, repo):
self.fs = fs
self.dirname = dirname
self.key_bytes = key_bytes
self.node_size = node_size
self.upload_queue_size = upload_queue_size
self.lru_size = lru_size
- self.hooks = hooks
+ self.repo = repo
self.forest = None
self.tree = None
self.keep_just_one_tree = False
@@ -63,7 +63,8 @@ class RepositoryTree(object):
def start_changes(self):
if not self.fs.exists(self.dirname):
self.fs.mkdir(self.dirname)
- self.hooks.call('repository-toplevel-init', self.dirname)
+ self.repo.hooks.call('repository-toplevel-init', self.repo,
+ self.dirname)
self.init_forest()
assert self.forest is not None
if self.tree is None: