浏览代码

Merge pull request #9050 from ThomasWaldmann/keyfile-same-repo-path-master

docs: What happens when a new keyfile repo is created at the same path?
TW 1 周之前
父节点
当前提交
b988f9c3a2
共有 2 个文件被更改,包括 68 次插入0 次删除
  1. 20 0
      docs/faq.rst
  2. 48 0
      src/borg/testsuite/archiver/repo_create_cmd_test.py

+ 20 - 0
docs/faq.rst

@@ -391,6 +391,26 @@ The Borg config directory has content that you should take care of:
 
 Make sure that only you have access to the Borg config directory.
 
+
+Note about creating multiple keyfile repositories at the same path
+------------------------------------------------------------------
+
+If you create a new keyfile-encrypted repository at the same filesystem
+path multiple times (for example, when a previous repository at that path
+was moved away or unmounted), Borg will not overwrite or reuse the existing
+key file in your keys directory. Instead, it creates a new key file by
+appending a numeric suffix to the base name (e.g., .2, .3, ...).
+
+This means you may see multiple key files like:
+
+- ~/.config/borg/keys/home_user_backup
+- ~/.config/borg/keys/home_user_backup.2
+- ~/.config/borg/keys/home_user_backup.3
+
+Each of these corresponds to a distinct repository created at the same
+path at different times. This behavior avoids accidental key reuse or
+overwrite.
+
 .. _home_data_borg:
 
 How important is the $HOME/.local/share/borg directory?

+ 48 - 0
src/borg/testsuite/archiver/repo_create_cmd_test.py

@@ -55,3 +55,51 @@ def test_repo_create_refuse_to_overwrite_keyfile(archivers, request, monkeypatch
     with open(keyfile) as file:
         after = file.read()
     assert before == after
+
+
+def test_repo_create_keyfile_same_path_creates_new_keys(archivers, request):
+    """Regression test for GH issue #6230.
+
+    When creating a new keyfile-encrypted repository at the same filesystem path
+    multiple times (e.g., after moving/unmounting the previous one), Borg must not
+    overwrite or reuse the existing key file. Instead, it should create a new key
+    file in the keys directory, appending a numeric suffix like .2, .3, ...
+    """
+    archiver = request.getfixturevalue(archivers)
+
+    # First creation at path A
+    cmd(archiver, "repo-create", KF_ENCRYPTION)
+    keys = sorted(os.listdir(archiver.keys_path))
+    assert len(keys) == 1
+    base_key = keys[0]
+    base_path = os.path.join(archiver.keys_path, base_key)
+    with open(base_path, "rb") as f:
+        base_contents = f.read()
+
+    # Simulate moving/unmounting the repo by removing the path to allow re-create at the same path
+    import shutil
+
+    shutil.rmtree(archiver.repository_path)
+    cmd(archiver, "repo-create", KF_ENCRYPTION)
+    keys = sorted(os.listdir(archiver.keys_path))
+    assert len(keys) == 2
+    assert base_key in keys
+    # The new file should be base_key suffixed with .2
+    assert any(k == base_key + ".2" for k in keys)
+    second_path = os.path.join(archiver.keys_path, base_key + ".2")
+    with open(second_path, "rb") as f:
+        second_contents = f.read()
+    assert second_contents != base_contents
+
+    # Remove repo again and create a third time at same path
+    shutil.rmtree(archiver.repository_path)
+    cmd(archiver, "repo-create", KF_ENCRYPTION)
+    keys = sorted(os.listdir(archiver.keys_path))
+    assert len(keys) == 3
+    assert any(k == base_key + ".3" for k in keys)
+    third_path = os.path.join(archiver.keys_path, base_key + ".3")
+    with open(third_path, "rb") as f:
+        third_contents = f.read()
+    # Ensure all keys are distinct
+    assert third_contents != base_contents
+    assert third_contents != second_contents