diff options
author | Lars Wirzenius <liw@liw.fi> | 2011-04-05 17:14:29 +0100 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2011-04-05 17:14:29 +0100 |
commit | d6d768a6fd7bc1ef432d86bdf29bc241bcec83b1 (patch) | |
tree | 047aff7bc395122661caf249911ee1ae93bb144d | |
parent | 89ba6edad09d4ae42f104b2eb2ac80801dd79816 (diff) | |
download | obnam-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.py | 9 | ||||
-rw-r--r-- | obnamlib/checksumtree_tests.py | 6 | ||||
-rw-r--r-- | obnamlib/chunklist_tests.py | 6 | ||||
-rw-r--r-- | obnamlib/clientlist_tests.py | 6 | ||||
-rw-r--r-- | obnamlib/clientmetadatatree_tests.py | 13 | ||||
-rw-r--r-- | obnamlib/plugins/encryption_plugin.py | 32 | ||||
-rw-r--r-- | obnamlib/repo.py | 28 | ||||
-rw-r--r-- | obnamlib/repo_tree.py | 7 |
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: |