1
0
Fork 0
mirror of https://github.com/borgbackup/borg.git synced 2025-03-10 06:03:38 +00:00

Merge branch '1.0-maint'

This commit is contained in:
Thomas Waldmann 2016-05-20 22:48:57 +02:00
commit b8303a38bf
10 changed files with 130 additions and 61 deletions

4
Vagrantfile vendored
View file

@ -202,8 +202,8 @@ def install_borg(boxname)
rm -f borg/{chunker,crypto,compress,hashindex,platform_linux}.c
rm -rf borg/__pycache__ borg/support/__pycache__ borg/testsuite/__pycache__
pip install -r requirements.d/development.txt
pip install -r requirements.d/fuse.txt
pip install -e .
# by using [fuse], setup.py can handle different fuse requirements:
pip install -e .[fuse]
EOF
end

View file

@ -2120,6 +2120,14 @@ def sig_info_handler(signum, stack): # pragma: no cover
break
class SIGTERMReceived(BaseException):
pass
def sig_term_handler(signum, stack):
raise SIGTERMReceived
def setup_signal_handlers(): # pragma: no cover
sigs = []
if hasattr(signal, 'SIGUSR1'):
@ -2128,6 +2136,7 @@ def setup_signal_handlers(): # pragma: no cover
sigs.append(signal.SIGINFO) # kill -INFO pid (or ctrl-t)
for sig in sigs:
signal.signal(sig, sig_info_handler)
signal.signal(signal.SIGTERM, sig_term_handler)
def main(): # pragma: no cover
@ -2159,6 +2168,9 @@ def main(): # pragma: no cover
except KeyboardInterrupt:
msg = 'Keyboard interrupt.\n%s\n%s' % (traceback.format_exc(), sysinfo())
exit_code = EXIT_ERROR
except SIGTERMReceived:
msg = 'Received SIGTERM.'
exit_code = EXIT_ERROR
if msg:
logger.error(msg)
if args.show_rc:

View file

@ -1,4 +1,4 @@
from binascii import a2b_base64, b2a_base64
from binascii import a2b_base64, b2a_base64, hexlify
import configparser
import getpass
import os
@ -413,16 +413,19 @@ class KeyfileKey(KeyfileKeyBase):
FILE_ID = 'BORG_KEY'
def sanity_check(self, filename, id):
with open(filename, 'r') as fd:
line = fd.readline().strip()
if not line.startswith(self.FILE_ID):
file_id = self.FILE_ID.encode() + b' '
repo_id = hexlify(id)
with open(filename, 'rb') as fd:
# we do the magic / id check in binary mode to avoid stumbling over
# decoding errors if somebody has binary files in the keys dir for some reason.
if fd.read(len(file_id)) != file_id:
raise KeyfileInvalidError(self.repository._location.canonical_path(), filename)
if line[len(self.FILE_ID) + 1:] != id:
if fd.read(len(repo_id)) != repo_id:
raise KeyfileMismatchError(self.repository._location.canonical_path(), filename)
return filename
def find_key(self):
id = self.repository.id_str
id = self.repository.id
keyfile = os.environ.get('BORG_KEY_FILE')
if keyfile:
return self.sanity_check(keyfile, id)

View file

@ -424,6 +424,9 @@ class RepositoryCache(RepositoryNoCache):
Caches Repository GET operations using a local temporary Repository.
"""
# maximum object size that will be cached, 64 kiB.
THRESHOLD = 2**16
def __init__(self, repository):
super().__init__(repository)
tmppath = tempfile.mkdtemp(prefix='borg-tmp')
@ -444,7 +447,8 @@ class RepositoryCache(RepositoryNoCache):
except Repository.ObjectNotFound:
for key_, data in repository_iterator:
if key_ == key:
self.caching_repo.put(key, data)
if len(data) <= self.THRESHOLD:
self.caching_repo.put(key, data)
yield data
break
# Consume any pending requests

View file

@ -544,7 +544,7 @@ class LoggedIO:
"""Return the last committed segment.
"""
for segment, filename in self.segment_iterator(reverse=True):
if self.is_committed_segment(filename):
if self.is_committed_segment(segment):
return segment
return None
@ -558,10 +558,14 @@ class LoggedIO:
else:
break
def is_committed_segment(self, filename):
def is_committed_segment(self, segment):
"""Check if segment ends with a COMMIT_TAG tag
"""
with open(filename, 'rb') as fd:
try:
iterator = self.iter_objects(segment)
except IntegrityError:
return False
with open(self.segment_filename(segment), 'rb') as fd:
try:
fd.seek(-self.header_fmt.size, os.SEEK_END)
except OSError as e:
@ -569,7 +573,22 @@ class LoggedIO:
if e.errno == errno.EINVAL:
return False
raise e
return fd.read(self.header_fmt.size) == self.COMMIT
if fd.read(self.header_fmt.size) != self.COMMIT:
return False
seen_commit = False
while True:
try:
tag, key, offset = next(iterator)
except IntegrityError:
return False
except StopIteration:
break
if tag == TAG_COMMIT:
seen_commit = True
continue
if seen_commit:
return False
return seen_commit
def segment_filename(self, segment):
return os.path.join(self.path, 'data', str(segment // self.segments_per_dir), str(segment))

View file

@ -10,7 +10,7 @@ from ..hashindex import NSIndex
from ..helpers import Location, IntegrityError
from ..locking import UpgradableLock, LockFailed
from ..remote import RemoteRepository, InvalidRPCMethod, ConnectionClosedWithHint
from ..repository import Repository
from ..repository import Repository, LoggedIO
from . import BaseTestCase
@ -194,6 +194,13 @@ class RepositoryCommitTestCase(RepositoryTestCaseBase):
self.assert_equal(self.repository.check(), True)
self.assert_equal(len(self.repository), 3)
def test_ignores_commit_tag_in_data(self):
self.repository.put(b'0' * 32, LoggedIO.COMMIT)
self.reopen()
with self.repository:
io = self.repository.io
assert not io.is_committed_segment(io.get_latest_segment())
class RepositoryAppendOnlyTestCase(RepositoryTestCaseBase):
def test_destroy_append_only(self):
@ -270,7 +277,7 @@ class RepositoryCheckTestCase(RepositoryTestCaseBase):
return set(int(key) for key in self.repository.list())
def test_repair_corrupted_segment(self):
self.add_objects([[1, 2, 3], [4, 5, 6]])
self.add_objects([[1, 2, 3], [4, 5], [6]])
self.assert_equal(set([1, 2, 3, 4, 5, 6]), self.list_objects())
self.check(status=True)
self.corrupt_object(5)

View file

@ -2,31 +2,11 @@
API Documentation
=================
.. automodule:: borg.platform
.. automodule:: borg.archiver
:members:
:undoc-members:
.. automodule:: borg.shellpattern
:members:
:undoc-members:
.. automodule:: borg.locking
:members:
:undoc-members:
.. automodule:: borg.hash_sizes
:members:
:undoc-members:
.. automodule:: borg.logger
:members:
:undoc-members:
.. automodule:: borg.remote
:members:
:undoc-members:
.. automodule:: borg.fuse
.. automodule:: borg.upgrader
:members:
:undoc-members:
@ -34,7 +14,23 @@ API Documentation
:members:
:undoc-members:
.. automodule:: borg.helpers
.. automodule:: borg.fuse
:members:
:undoc-members:
.. automodule:: borg.platform
:members:
:undoc-members:
.. automodule:: borg.locking
:members:
:undoc-members:
.. automodule:: borg.shellpattern
:members:
:undoc-members:
.. automodule:: borg.repository
:members:
:undoc-members:
@ -42,15 +38,19 @@ API Documentation
:members:
:undoc-members:
.. automodule:: borg.remote
:members:
:undoc-members:
.. automodule:: borg.hash_sizes
:members:
:undoc-members:
.. automodule:: borg.xattr
:members:
:undoc-members:
.. automodule:: borg.archiver
:members:
:undoc-members:
.. automodule:: borg.repository
.. automodule:: borg.helpers
:members:
:undoc-members:
@ -62,7 +62,7 @@ API Documentation
:members:
:undoc-members:
.. automodule:: borg.upgrader
.. automodule:: borg.logger
:members:
:undoc-members:
@ -70,15 +70,15 @@ API Documentation
:members:
:undoc-members:
.. automodule:: borg.compress
:members:
:undoc-members:
.. automodule:: borg.platform_linux
:members:
:undoc-members:
.. automodule:: borg.crypto
.. automodule:: borg.hashindex
:members:
:undoc-members:
.. automodule:: borg.compress
:members:
:undoc-members:
@ -86,10 +86,10 @@ API Documentation
:members:
:undoc-members:
.. automodule:: borg.platform_freebsd
.. automodule:: borg.crypto
:members:
:undoc-members:
.. automodule:: borg.hashindex
.. automodule:: borg.platform_freebsd
:members:
:undoc-members:

View file

@ -74,22 +74,34 @@ Other changes:
- ChunkBuffer: add test for leaving partial chunk in buffer, fixes #945
Version 1.0.3 (not released yet)
--------------------------------
Version 1.0.3
-------------
Bug fixes:
- prune: ignore checkpoints, #997
- prune: fix bad validator, #942
- fix capabilities extraction on Linux (set xattrs last, after chown())
- prune: avoid that checkpoints are kept and completed archives are deleted in
a prune run), #997
- prune: fix commandline argument validation - some valid command lines were
considered invalid (annoying, but harmless), #942
- fix capabilities extraction on Linux (set xattrs last, after chown()), #1069
- repository: fix commit tags being seen in data
- when probing key files, do binary reads. avoids crash when non-borg binary
files are located in borg's key files directory.
- handle SIGTERM and make a clean exit - avoids orphan lock files.
- repository cache: don't cache large objects (avoid using lots of temp. disk
space), #1063
Other changes:
- update readthedocs URLs, #991
- add missing docs for "borg break-lock", #992
- borg create help: add some words to about the archive name
- borg create help: document format tags, #894
- Vagrantfile: OS X: update osxfuse / install lzma package, #933
- setup.py: add check for platform_darwin.c
- setup.py: on freebsd, use a llfuse release that builds ok
- docs / help:
- update readthedocs URLs, #991
- add missing docs for "borg break-lock", #992
- borg create help: add some words to about the archive name
- borg create help: document format tags, #894
Version 1.0.2

View file

@ -74,6 +74,12 @@ This command creates a backup archive containing all files found while recursive
traversing all paths specified. The archive will consume almost no disk space for
files or parts of files that have already been stored in other archives.
The archive name needs to be unique. It must not end in '.checkpoint' or
'.checkpoint.N' (with N being a number), because these names are used for
checkpoints and treated in special ways.
In the archive name, you may use the following format tags:
{now}, {utcnow}, {fqdn}, {hostname}, {user}, {pid}
To speed up pulling backups over sshfs and similar network file systems which do
not provide correct inode information the --ignore-inode flag can be used. This

View file

@ -26,12 +26,18 @@ install_requires = ['msgpack-python>=0.4.6', ]
extras_require = {
# llfuse 0.40 (tested, proven, ok), needs FUSE version >= 2.8.0
# llfuse 0.41 (tested shortly, looks ok), needs FUSE version >= 2.8.0
# llfuse 0.41.1 (tested shortly, looks ok), needs FUSE version >= 2.8.0
# llfuse 0.42 (tested shortly, looks ok), needs FUSE version >= 2.8.0
# llfuse 1.0 (tested shortly, looks ok), needs FUSE version >= 2.8.0
# llfuse 2.0 will break API
'fuse': ['llfuse<2.0', ],
}
if sys.platform.startswith('freebsd'):
# while llfuse 1.0 is the latest llfuse release right now,
# llfuse 0.41.1 is the latest release that actually builds on freebsd:
extras_require['fuse'] = ['llfuse==0.41.1', ]
from setuptools import setup, Extension
from setuptools.command.sdist import sdist
@ -84,7 +90,7 @@ except ImportError:
from distutils.command.build_ext import build_ext
if not on_rtd and not all(os.path.exists(path) for path in [
compress_source, crypto_source, chunker_source, hashindex_source,
platform_posix_source, platform_linux_source, platform_freebsd_source]):
platform_posix_source, platform_linux_source, platform_freebsd_source, platform_darwin_source]):
raise ImportError('The GIT version of Borg needs Cython. Install Cython or use a released version.')