summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukáš Poláček <lukas@spotify.com>2015-07-20 16:54:24 +0200
committerLars Wirzenius <liw@liw.fi>2015-07-25 14:26:08 +0300
commit0da82b27bd07b781e441793b08c661516a33489b (patch)
treeb7b782548f3efa2b81518eae800625db0a0e4cb1
parentf22994cc99017f5aeab809a406b0c5d1940fd5a8 (diff)
downloadobnam-0da82b27bd07b781e441793b08c661516a33489b.tar.gz
Add --ignore-missing-chunks option to forget
-rw-r--r--obnamlib/delegator.py4
-rw-r--r--obnamlib/fmt_6/repo_fmt_6.py15
-rw-r--r--obnamlib/fmt_ga/client.py2
-rw-r--r--obnamlib/plugins/forget_plugin.py9
-rw-r--r--obnamlib/repo_interface.py5
5 files changed, 24 insertions, 11 deletions
diff --git a/obnamlib/delegator.py b/obnamlib/delegator.py
index f0c6038a..5065a62d 100644
--- a/obnamlib/delegator.py
+++ b/obnamlib/delegator.py
@@ -198,10 +198,10 @@ class RepositoryDelegator(obnamlib.RepositoryInterface):
client = self._lookup_client_by_generation(generation_id)
return client.set_generation_key(generation_id.gen_number, key, value)
- def remove_generation(self, generation_id):
+ def remove_generation(self, generation_id, ignore_missing_chunks=False):
self._require_got_client_lock(generation_id.client_name)
client = self._lookup_client_by_generation(generation_id)
- return client.remove_generation(generation_id.gen_number)
+ return client.remove_generation(generation_id.gen_number, ignore_missing_chunks)
def get_generation_chunk_ids(self, generation_id):
client = self._lookup_client_by_generation(generation_id)
diff --git a/obnamlib/fmt_6/repo_fmt_6.py b/obnamlib/fmt_6/repo_fmt_6.py
index 31ae8779..3cc54426 100644
--- a/obnamlib/fmt_6/repo_fmt_6.py
+++ b/obnamlib/fmt_6/repo_fmt_6.py
@@ -340,7 +340,7 @@ class RepositoryFormat6(obnamlib.RepositoryInterface):
self._raw_unlock_client(client_name)
def _remove_chunks_from_removed_generations(
- self, client_name, remove_gen_nos):
+ self, client_name, remove_gen_nos, ignore_missing_chunks=False):
def find_chunkids_in_gens(gen_nos):
chunkids = set()
@@ -358,7 +358,7 @@ class RepositoryFormat6(obnamlib.RepositoryInterface):
keep.append(gen_number)
return keep
- def remove_chunks(chunk_ids): # pragma: no cover
+ def remove_chunks(chunk_ids, ignore_missing_chunks=False): # pragma: no cover
for chunk_id in chunk_ids:
try:
checksum = self._chunklist.get_checksum(chunk_id)
@@ -368,14 +368,16 @@ class RepositoryFormat6(obnamlib.RepositoryInterface):
self._remove_chunk(chunk_id)
else:
self.remove_chunk_from_indexes(chunk_id, client_name)
- if not self._chunksums.chunk_is_used(checksum, chunk_id):
+ # We can skip removal if the chunk doesn't exist
+ skip_removal = ignore_missing_chunks and not self.has_chunk(chunk_id)
+ if not skip_removal and not self._chunksums.chunk_is_used(checksum, chunk_id):
self._remove_chunk(chunk_id)
keep_gen_nos = find_gens_to_keep()
keep_chunkids = find_chunkids_in_gens(keep_gen_nos)
maybe_remove_chunkids = find_chunkids_in_gens(remove_gen_nos)
remove_chunkids = maybe_remove_chunkids.difference(keep_chunkids)
- remove_chunks(remove_chunkids)
+ remove_chunks(remove_chunkids, ignore_missing_chunks)
def get_allowed_client_keys(self):
return []
@@ -547,7 +549,7 @@ class RepositoryFormat6(obnamlib.RepositoryInterface):
client_name, gen_number = self._unpack_gen_id(gen_id)
return str(gen_number)
- def remove_generation(self, gen_id):
+ def remove_generation(self, gen_id, ignore_missing_chunks=False):
tracing.trace('gen_id=%s' % repr(gen_id))
client_name, gen_number = self._unpack_gen_id(gen_id)
self._require_client_lock(client_name)
@@ -561,7 +563,8 @@ class RepositoryFormat6(obnamlib.RepositoryInterface):
self._forget_open_client_info_cached_generation(
open_client_info, gen_id)
- self._remove_chunks_from_removed_generations(client_name, [gen_number])
+ self._remove_chunks_from_removed_generations(client_name, [gen_number],
+ ignore_missing_chunks)
open_client_info.client.start_changes(create_tree=False)
open_client_info.client.remove_generation(gen_number)
diff --git a/obnamlib/fmt_ga/client.py b/obnamlib/fmt_ga/client.py
index 65422855..ecd3b21a 100644
--- a/obnamlib/fmt_ga/client.py
+++ b/obnamlib/fmt_ga/client.py
@@ -174,7 +174,7 @@ class GAClient(object):
else:
return str(1)
- def remove_generation(self, gen_number):
+ def remove_generation(self, gen_number, ignore_missing_chunks=False):
self._load_data()
remaining = []
removed = False
diff --git a/obnamlib/plugins/forget_plugin.py b/obnamlib/plugins/forget_plugin.py
index 860cd116..c12c36a4 100644
--- a/obnamlib/plugins/forget_plugin.py
+++ b/obnamlib/plugins/forget_plugin.py
@@ -24,6 +24,8 @@ class ForgetPlugin(obnamlib.ObnamPlugin):
'''Forget generations.'''
def enable(self):
+ forget_group = obnamlib.option_group['forget'] = 'Forgetting generations (forget)'
+
self.app.add_subcommand(
'forget', self.forget, arg_synopsis='[GENERATION]...')
self.app.settings.string(
@@ -31,6 +33,11 @@ class ForgetPlugin(obnamlib.ObnamPlugin):
'policy for what generations to keep '
'when forgetting')
+ self.app.settings.boolean(
+ ['ignore-missing-chunks'],
+ 'ignore missing chunks when forgetting generations',
+ group=forget_group)
+
def forget(self, args):
'''Forget (remove) specified backup generations.'''
self.app.settings.require('repository')
@@ -130,4 +137,4 @@ class ForgetPlugin(obnamlib.ObnamPlugin):
'Pretending to remove generation %s' %
self.repo.make_generation_spec(genid))
else:
- self.repo.remove_generation(genid)
+ self.repo.remove_generation(genid, self.app.settings['ignore-missing-chunks'])
diff --git a/obnamlib/repo_interface.py b/obnamlib/repo_interface.py
index f16d6925..50832290 100644
--- a/obnamlib/repo_interface.py
+++ b/obnamlib/repo_interface.py
@@ -572,11 +572,14 @@ class RepositoryInterface(object):
'''Set a key/value pair for a given generation.'''
raise NotImplementedError()
- def remove_generation(self, generation_id):
+ def remove_generation(self, generation_id, ignore_missing_chunks=False):
'''Remove an existing generation.
The removed generation may be the currently unfinished one.
+ When removing chunks, don't try to remove those that are missing
+ if ignore_missing_chunks is set to True.
+
'''
raise NotImplementedError()