mirror of
https://github.com/borgbackup/borg.git
synced 2025-01-01 12:45:34 +00:00
keep previous repo location only in security dir
removed some code borg had for backwards compatibility with old borg versions (that had previous_location only in the cache). now the repo location is only checked against the location file in the security dir, simplifying the code and also fixing a related test failure with NewCache. also improved test_repository_move to test for aborting in case the repo location changed unexpectedly.
This commit is contained in:
parent
fbfa7cf7bf
commit
cf8c3a3ae7
3 changed files with 15 additions and 58 deletions
|
@ -5,7 +5,6 @@
|
|||
from ..cache import Cache, assert_secure
|
||||
from ..constants import * # NOQA
|
||||
from ..helpers import Error, CommandError
|
||||
from ..helpers import Location
|
||||
from ..helpers import parse_file_size, hex_to_bin
|
||||
from ..manifest import Manifest
|
||||
|
||||
|
@ -52,11 +51,8 @@ def repo_validate(section, name, value=None, check_value=True):
|
|||
def cache_validate(section, name, value=None, check_value=True):
|
||||
if section not in ["cache"]:
|
||||
raise ValueError("Invalid section")
|
||||
if name in ["previous_location"]:
|
||||
if check_value:
|
||||
Location(value)
|
||||
else:
|
||||
raise ValueError("Invalid name")
|
||||
# currently, we do not support setting anything in the cache via borg config.
|
||||
raise ValueError("Invalid name")
|
||||
|
||||
def list_config(config):
|
||||
default_values = {
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
|
||||
from .constants import CACHE_README, FILES_CACHE_MODE_DISABLED, ROBJ_FILE_STREAM
|
||||
from .hashindex import ChunkIndex, ChunkIndexEntry, CacheSynchronizer
|
||||
from .helpers import Location
|
||||
from .helpers import Error
|
||||
from .helpers import get_cache_dir, get_security_dir
|
||||
from .helpers import bin_to_hex, hex_to_bin, parse_stringified_list
|
||||
|
@ -100,7 +99,7 @@ def save(self, manifest, key):
|
|||
with SaveFile(self.manifest_ts_file) as fd:
|
||||
fd.write(manifest.timestamp)
|
||||
|
||||
def assert_location_matches(self, cache_config=None):
|
||||
def assert_location_matches(self):
|
||||
# Warn user before sending data to a relocated repository
|
||||
try:
|
||||
with open(self.location_file) as fd:
|
||||
|
@ -112,10 +111,6 @@ def assert_location_matches(self, cache_config=None):
|
|||
except OSError as exc:
|
||||
logger.warning("Could not read previous location file: %s", exc)
|
||||
previous_location = None
|
||||
if cache_config and cache_config.previous_location and previous_location != cache_config.previous_location:
|
||||
# Reconcile cache and security dir; we take the cache location.
|
||||
previous_location = cache_config.previous_location
|
||||
logger.debug("security: using previous_location of cache: %r", previous_location)
|
||||
|
||||
repository_location = self.repository._location.canonical_path()
|
||||
if previous_location and previous_location != repository_location:
|
||||
|
@ -134,11 +129,9 @@ def assert_location_matches(self, cache_config=None):
|
|||
):
|
||||
raise Cache.RepositoryAccessAborted()
|
||||
# adapt on-disk config immediately if the new location was accepted
|
||||
logger.debug("security: updating location stored in cache and security dir")
|
||||
logger.debug("security: updating location stored in security dir")
|
||||
with SaveFile(self.location_file) as fd:
|
||||
fd.write(repository_location)
|
||||
if cache_config:
|
||||
cache_config.save()
|
||||
|
||||
def assert_no_manifest_replay(self, manifest, key, cache_config=None):
|
||||
try:
|
||||
|
@ -184,7 +177,7 @@ def assert_secure(self, manifest, key, *, cache_config=None, warn_if_unencrypted
|
|||
logger.debug("security: repository checks ok, allowing access")
|
||||
|
||||
def _assert_secure(self, manifest, key, cache_config=None):
|
||||
self.assert_location_matches(cache_config)
|
||||
self.assert_location_matches()
|
||||
self.assert_key_type(key, cache_config)
|
||||
self.assert_no_manifest_replay(manifest, key, cache_config)
|
||||
if not self.known():
|
||||
|
@ -221,29 +214,6 @@ def assert_secure(repository, manifest, lock_wait):
|
|||
sm.assert_secure(manifest, manifest.key, lock_wait=lock_wait)
|
||||
|
||||
|
||||
def recanonicalize_relative_location(cache_location, repository):
|
||||
# borg < 1.0.8rc1 had different canonicalization for the repo location (see #1655 and #1741).
|
||||
repo_location = repository._location.canonical_path()
|
||||
rl = Location(repo_location)
|
||||
cl = Location(cache_location)
|
||||
if (
|
||||
cl.proto == rl.proto
|
||||
and cl.user == rl.user
|
||||
and cl.host == rl.host
|
||||
and cl.port == rl.port
|
||||
and cl.path
|
||||
and rl.path
|
||||
and cl.path.startswith("/~/")
|
||||
and rl.path.startswith("/./")
|
||||
and cl.path[3:] == rl.path[3:]
|
||||
):
|
||||
# everything is same except the expected change in relative path canonicalization,
|
||||
# update previous_location to avoid warning / user query about changed location:
|
||||
return repo_location
|
||||
else:
|
||||
return cache_location
|
||||
|
||||
|
||||
def cache_dir(repository, path=None):
|
||||
return path or os.path.join(get_cache_dir(), repository.id_str)
|
||||
|
||||
|
@ -310,12 +280,6 @@ def load(self):
|
|||
except configparser.NoSectionError:
|
||||
logger.debug("Cache integrity: No integrity data found (files, chunks). Cache is from old version.")
|
||||
self.integrity = {}
|
||||
previous_location = self._config.get("cache", "previous_location", fallback=None)
|
||||
if previous_location:
|
||||
self.previous_location = recanonicalize_relative_location(previous_location, self.repository)
|
||||
else:
|
||||
self.previous_location = None
|
||||
self._config.set("cache", "previous_location", self.repository._location.canonical_path())
|
||||
|
||||
def save(self, manifest=None, key=None):
|
||||
if manifest:
|
||||
|
|
|
@ -153,32 +153,29 @@ def test_repository_move(archivers, request, monkeypatch):
|
|||
security_dir = get_security_directory(archiver.repository_path)
|
||||
os.replace(archiver.repository_path, archiver.repository_path + "_new")
|
||||
archiver.repository_location += "_new"
|
||||
# borg should notice that the repository location changed and abort.
|
||||
if archiver.FORK_DEFAULT:
|
||||
cmd(archiver, "rinfo", exit_code=EXIT_ERROR)
|
||||
else:
|
||||
with pytest.raises(Cache.RepositoryAccessAborted):
|
||||
cmd(archiver, "rinfo")
|
||||
# if we explicitly allow relocated repos, it should work fine.
|
||||
monkeypatch.setenv("BORG_RELOCATED_REPO_ACCESS_IS_OK", "yes")
|
||||
cmd(archiver, "rinfo")
|
||||
monkeypatch.delenv("BORG_RELOCATED_REPO_ACCESS_IS_OK")
|
||||
with open(os.path.join(security_dir, "location")) as fd:
|
||||
location = fd.read()
|
||||
assert location == Location(archiver.repository_location).canonical_path()
|
||||
# Needs no confirmation anymore
|
||||
cmd(archiver, "rinfo")
|
||||
shutil.rmtree(archiver.cache_path)
|
||||
# after new repo location was confirmed once, it needs no further confirmation anymore.
|
||||
cmd(archiver, "rinfo")
|
||||
shutil.rmtree(security_dir)
|
||||
# it also needs no confirmation if we have no knowledge about the previous location.
|
||||
cmd(archiver, "rinfo")
|
||||
# it will re-create security-related infos in the security dir:
|
||||
for file in ("location", "key-type", "manifest-timestamp"):
|
||||
assert os.path.exists(os.path.join(security_dir, file))
|
||||
|
||||
|
||||
def test_security_dir_compat(archivers, request):
|
||||
archiver = request.getfixturevalue(archivers)
|
||||
cmd(archiver, "rcreate", RK_ENCRYPTION)
|
||||
with open(os.path.join(get_security_directory(archiver.repository_path), "location"), "w") as fd:
|
||||
fd.write("something outdated")
|
||||
# This is fine, because the cache still has the correct information. security_dir and cache can disagree
|
||||
# if older versions are used to confirm a renamed repository.
|
||||
cmd(archiver, "rinfo")
|
||||
|
||||
|
||||
def test_unknown_unencrypted(archivers, request, monkeypatch):
|
||||
archiver = request.getfixturevalue(archivers)
|
||||
cmd(archiver, "rcreate", "--encryption=none")
|
||||
|
|
Loading…
Reference in a new issue