mirror of
https://github.com/borgbackup/borg.git
synced 2024-12-26 17:57:59 +00:00
Merge pull request #4918 from mirobertod/master
Issue #4788 added consider checkpoints and relative test
This commit is contained in:
commit
da80a6a37d
3 changed files with 31 additions and 7 deletions
|
@ -1124,6 +1124,7 @@ def _delete_archives(self, args, repository):
|
|||
archives.insert(0, args.location.archive)
|
||||
archive_names = tuple(archives)
|
||||
else:
|
||||
args.consider_checkpoints = True
|
||||
archive_names = tuple(x.name for x in manifest.archives.list_considering(args))
|
||||
if not archive_names:
|
||||
return self.exit_code
|
||||
|
@ -1330,6 +1331,7 @@ def format_cmdline(cmdline):
|
|||
if args.location.archive:
|
||||
archive_names = (args.location.archive,)
|
||||
else:
|
||||
args.consider_checkpoints = True
|
||||
archive_names = tuple(x.name for x in manifest.archives.list_considering(args))
|
||||
if not archive_names:
|
||||
return self.exit_code
|
||||
|
@ -1418,6 +1420,7 @@ def do_prune(self, args, repository, manifest, key):
|
|||
args.glob_archives = args.prefix + '*'
|
||||
checkpoint_re = r'\.checkpoint(\.\d+)?'
|
||||
archives_checkpoints = manifest.archives.list(glob=args.glob_archives,
|
||||
consider_checkpoints=True,
|
||||
match_end=r'(%s)?\Z' % checkpoint_re,
|
||||
sort_by=['ts'], reverse=True)
|
||||
is_checkpoint = re.compile(r'(%s)\Z' % checkpoint_re).search
|
||||
|
@ -2637,6 +2640,8 @@ def define_borg_mount(parser):
|
|||
parser.set_defaults(func=self.do_mount)
|
||||
parser.add_argument('location', metavar='REPOSITORY_OR_ARCHIVE', type=location_validator(),
|
||||
help='repository or archive to mount')
|
||||
parser.add_argument('--consider-checkpoints', action='store_true', dest='consider_checkpoints',
|
||||
help='Show checkpoint archives in the repository contents list (default: hidden).')
|
||||
parser.add_argument('mountpoint', metavar='MOUNTPOINT', type=str,
|
||||
help='where to mount filesystem')
|
||||
parser.add_argument('-f', '--foreground', dest='foreground',
|
||||
|
@ -3848,6 +3853,8 @@ def define_borg_mount(parser):
|
|||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
help='list archive or repository contents')
|
||||
subparser.set_defaults(func=self.do_list)
|
||||
subparser.add_argument('--consider-checkpoints', action='store_true', dest='consider_checkpoints',
|
||||
help='Show checkpoint archives in the repository contents list (default: hidden).')
|
||||
subparser.add_argument('--short', dest='short', action='store_true',
|
||||
help='only print file/directory names, nothing else')
|
||||
subparser.add_argument('--format', '--list-format', metavar='FORMAT', dest='format',
|
||||
|
|
|
@ -74,7 +74,7 @@ def __delitem__(self, name):
|
|||
name = safe_encode(name)
|
||||
del self._archives[name]
|
||||
|
||||
def list(self, *, glob=None, match_end=r'\Z', sort_by=(), first=None, last=None, reverse=False):
|
||||
def list(self, *, glob=None, match_end=r'\Z', sort_by=(), consider_checkpoints=False, first=None, last=None, reverse=False):
|
||||
"""
|
||||
Return list of ArchiveInfo instances according to the parameters.
|
||||
|
||||
|
@ -87,6 +87,8 @@ def list(self, *, glob=None, match_end=r'\Z', sort_by=(), first=None, last=None,
|
|||
raise TypeError('sort_by must be a sequence of str')
|
||||
regex = re.compile(shellpattern.translate(glob or '*', match_end=match_end))
|
||||
archives = [x for x in self.values() if regex.match(x.name) is not None]
|
||||
if not consider_checkpoints:
|
||||
archives = [x for x in archives if '.checkpoint' not in x.name]
|
||||
for sortkey in reversed(sort_by):
|
||||
archives.sort(key=attrgetter(sortkey))
|
||||
if first:
|
||||
|
@ -99,13 +101,13 @@ def list(self, *, glob=None, match_end=r'\Z', sort_by=(), first=None, last=None,
|
|||
|
||||
def list_considering(self, args):
|
||||
"""
|
||||
get a list of archives, considering --first/last/prefix/glob-archives/sort cmdline args
|
||||
get a list of archives, considering --first/last/prefix/glob-archives/sort/consider-checkpoints cmdline args
|
||||
"""
|
||||
if args.location.archive:
|
||||
raise Error('The options --first, --last, --prefix and --glob-archives can only be used on repository targets.')
|
||||
raise Error('The options --first, --last, --prefix, and --glob-archives, and --consider-checkpoints can only be used on repository targets.')
|
||||
if args.prefix is not None:
|
||||
args.glob_archives = args.prefix + '*'
|
||||
return self.list(sort_by=args.sort_by.split(','), glob=args.glob_archives, first=args.first, last=args.last)
|
||||
return self.list(sort_by=args.sort_by.split(','), consider_checkpoints=args.consider_checkpoints, glob=args.glob_archives, first=args.first, last=args.last)
|
||||
|
||||
def set_raw_dict(self, d):
|
||||
"""set the dict we get from the msgpack unpacker"""
|
||||
|
|
|
@ -1858,14 +1858,14 @@ def test_prune_repository(self):
|
|||
assert re.search(r'Keeping archive \(rule: daily #1\):\s+test2', output)
|
||||
# must keep the latest checkpoint archive:
|
||||
assert re.search(r'Keeping checkpoint archive:\s+test4.checkpoint', output)
|
||||
output = self.cmd('list', self.repository_location)
|
||||
output = self.cmd('list', '--consider-checkpoints', self.repository_location)
|
||||
self.assert_in('test1', output)
|
||||
self.assert_in('test2', output)
|
||||
self.assert_in('test3.checkpoint', output)
|
||||
self.assert_in('test3.checkpoint.1', output)
|
||||
self.assert_in('test4.checkpoint', output)
|
||||
self.cmd('prune', self.repository_location, '--keep-daily=2')
|
||||
output = self.cmd('list', self.repository_location)
|
||||
output = self.cmd('list', '--consider-checkpoints', self.repository_location)
|
||||
self.assert_not_in('test1', output)
|
||||
# the latest non-checkpoint archive must be still there:
|
||||
self.assert_in('test2', output)
|
||||
|
@ -1876,7 +1876,7 @@ def test_prune_repository(self):
|
|||
# now we supercede the latest checkpoint by a successful backup:
|
||||
self.cmd('create', self.repository_location + '::test5', src_dir)
|
||||
self.cmd('prune', self.repository_location, '--keep-daily=2')
|
||||
output = self.cmd('list', self.repository_location)
|
||||
output = self.cmd('list', '--consider-checkpoints', self.repository_location)
|
||||
# all checkpoints should be gone now:
|
||||
self.assert_not_in('checkpoint', output)
|
||||
# the latest archive must be still there
|
||||
|
@ -1984,6 +1984,21 @@ def test_list_hash(self):
|
|||
assert "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0 input/amb" in output
|
||||
assert "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 input/empty_file" in output
|
||||
|
||||
def test_list_consider_checkpoints(self):
|
||||
self.cmd('init', '--encryption=repokey', self.repository_location)
|
||||
self.cmd('create', self.repository_location + '::test1', src_dir)
|
||||
# these are not really a checkpoints, but they look like some:
|
||||
self.cmd('create', self.repository_location + '::test2.checkpoint', src_dir)
|
||||
self.cmd('create', self.repository_location + '::test3.checkpoint.1', src_dir)
|
||||
output = self.cmd('list', self.repository_location)
|
||||
assert "test1" in output
|
||||
assert "test2.checkpoint" not in output
|
||||
assert "test3.checkpoint.1" not in output
|
||||
output = self.cmd('list', '--consider-checkpoints', self.repository_location)
|
||||
assert "test1" in output
|
||||
assert "test2.checkpoint" in output
|
||||
assert "test3.checkpoint.1" in output
|
||||
|
||||
def test_list_chunk_counts(self):
|
||||
self.create_regular_file('empty_file', size=0)
|
||||
self.create_regular_file('two_chunks')
|
||||
|
|
Loading…
Reference in a new issue