mirror of
https://github.com/borgbackup/borg.git
synced 2026-06-09 08:51:54 -04:00
Detect and abort if repository is older than the cache
This commit is contained in:
parent
b2346b7c9b
commit
5fa5380f0f
4 changed files with 27 additions and 1 deletions
8
CHANGES
8
CHANGES
|
|
@ -4,6 +4,14 @@ Attic Changelog
|
|||
Here you can see the full list of changes between each Attic release.
|
||||
|
||||
|
||||
Version 0.8
|
||||
-----------
|
||||
|
||||
(feature release, released on X)
|
||||
|
||||
- Detect and abort if repository is older than the cache
|
||||
|
||||
|
||||
Version 0.7
|
||||
-----------
|
||||
|
||||
|
|
|
|||
|
|
@ -492,6 +492,9 @@ def main():
|
|||
except Archive.DoesNotExist as e:
|
||||
archiver.print_error('Error: Archive "%s" does not exist', e)
|
||||
exit_code = 1
|
||||
except Cache.RepositoryReplay:
|
||||
archiver.print_error('Cache is newer than repository, refusing to continue')
|
||||
exit_code = 1
|
||||
except ConnectionClosed:
|
||||
archiver.print_error('Connection closed by remote host')
|
||||
exit_code = 1
|
||||
|
|
|
|||
|
|
@ -14,7 +14,12 @@ class Cache(object):
|
|||
"""Client Side cache
|
||||
"""
|
||||
|
||||
class RepositoryReplay(Exception):
|
||||
"""
|
||||
"""
|
||||
|
||||
def __init__(self, repository, key, manifest):
|
||||
self.timestamp = None
|
||||
self.txn_active = False
|
||||
self.repository = repository
|
||||
self.key = key
|
||||
|
|
@ -24,6 +29,9 @@ class Cache(object):
|
|||
self.create()
|
||||
self.open()
|
||||
if self.manifest.id != self.manifest_id:
|
||||
# If repository is older than the cache something fishy is going on
|
||||
if self.timestamp and self.timestamp > manifest.timestamp:
|
||||
raise self.RepositoryReplay()
|
||||
self.sync()
|
||||
self.commit()
|
||||
|
||||
|
|
@ -31,7 +39,7 @@ class Cache(object):
|
|||
self.close()
|
||||
|
||||
def create(self):
|
||||
"""Create a new empty repository at `path`
|
||||
"""Create a new empty cache at `path`
|
||||
"""
|
||||
os.makedirs(self.path)
|
||||
with open(os.path.join(self.path, 'README'), 'w') as fd:
|
||||
|
|
@ -59,6 +67,7 @@ class Cache(object):
|
|||
raise Exception('%s Does not look like an Attic cache')
|
||||
self.id = self.config.get('cache', 'repository')
|
||||
self.manifest_id = unhexlify(self.config.get('cache', 'manifest'))
|
||||
self.timestamp = self.config.get('cache', 'timestamp', fallback=None)
|
||||
self.chunks = ChunkIndex(os.path.join(self.path, 'chunks').encode('utf-8'))
|
||||
self.files = None
|
||||
|
||||
|
|
@ -103,6 +112,7 @@ class Cache(object):
|
|||
if item[1][0] < 10 and item[1][3] < self._newest_mtime:
|
||||
msgpack.pack(item, fd)
|
||||
self.config.set('cache', 'manifest', hexlify(self.manifest.id).decode('ascii'))
|
||||
self.config.set('cache', 'timestamp', self.manifest.timestamp)
|
||||
with open(os.path.join(self.path, 'config'), 'w') as fd:
|
||||
self.config.write(fd)
|
||||
self.chunks.flush()
|
||||
|
|
|
|||
|
|
@ -34,13 +34,18 @@ class Manifest:
|
|||
if not m.get(b'version') == 1:
|
||||
raise ValueError('Invalid manifest version')
|
||||
manifest.archives = dict((k.decode('utf-8'), v) for k,v in m[b'archives'].items())
|
||||
manifest.timestamp = m.get(b'timestamp')
|
||||
if manifest.timestamp:
|
||||
manifest.timestamp = manifest.timestamp.decode('ascii')
|
||||
manifest.config = m[b'config']
|
||||
return manifest, key
|
||||
|
||||
def write(self):
|
||||
self.timestamp = datetime.utcnow().isoformat()
|
||||
data = msgpack.packb({
|
||||
'version': 1,
|
||||
'archives': self.archives,
|
||||
'timestamp': self.timestamp,
|
||||
'config': self.config,
|
||||
})
|
||||
self.id = self.key.id_hash(data)
|
||||
|
|
|
|||
Loading…
Reference in a new issue