2
0
Эх сурвалжийг харах

When databases are configured, don't auto-enable the "one_file_system" option (#918).

Dan Helfman 8 сар өмнө
parent
commit
b7efa0d3f0

+ 5 - 1
NEWS

@@ -1,7 +1,11 @@
 1.8.15.dev0
 1.8.15.dev0
+ * #918: BREAKING: When databases are configured, don't auto-enable the "one_file_system" option,
+   as existing auto-excludes of special files should be sufficient to prevent Borg from hanging on
+   them. But if this change causes problems for you, you can always enable "one_file_system"
+   explicitly.
  * #911: Add a "key change-passphrase" action to change the passphrase protecting a repository key.
  * #911: Add a "key change-passphrase" action to change the passphrase protecting a repository key.
  * #915: Rename repository actions like "rcreate" to more explicit names like "repo-create" for
  * #915: Rename repository actions like "rcreate" to more explicit names like "repo-create" for
-   compatibility with recent Borg 2 changes.
+   compatibility with recent changes in Borg 2.0.0b10.
 
 
 1.8.14
 1.8.14
  * #896: Fix an error in borgmatic rcreate/init on an empty repository directory with Borg 1.4.
  * #896: Fix an error in borgmatic rcreate/init on an empty repository directory with Borg 1.4.

+ 11 - 2
borgmatic/borg/create.py

@@ -5,6 +5,7 @@ import os
 import pathlib
 import pathlib
 import stat
 import stat
 import tempfile
 import tempfile
+import textwrap
 
 
 import borgmatic.logger
 import borgmatic.logger
 from borgmatic.borg import environment, feature, flags, state
 from borgmatic.borg import environment, feature, flags, state
@@ -330,6 +331,9 @@ def check_all_source_directories_exist(source_directories, working_directory=Non
         raise ValueError(f"Source directories do not exist: {', '.join(missing_directories)}")
         raise ValueError(f"Source directories do not exist: {', '.join(missing_directories)}")
 
 
 
 
+MAX_SPECIAL_FILE_PATHS_LENGTH = 1000
+
+
 def make_base_create_command(
 def make_base_create_command(
     dry_run,
     dry_run,
     repository_path,
     repository_path,
@@ -431,7 +435,7 @@ def make_base_create_command(
         + (('--compression', compression) if compression else ())
         + (('--compression', compression) if compression else ())
         + upload_ratelimit_flags
         + upload_ratelimit_flags
         + (('--upload-buffer', str(upload_buffer_size)) if upload_buffer_size else ())
         + (('--upload-buffer', str(upload_buffer_size)) if upload_buffer_size else ())
-        + (('--one-file-system',) if config.get('one_file_system') or stream_processes else ())
+        + (('--one-file-system',) if config.get('one_file_system') else ())
         + numeric_ids_flags
         + numeric_ids_flags
         + atime_flags
         + atime_flags
         + (('--noctime',) if config.get('ctime') is False else ())
         + (('--noctime',) if config.get('ctime') is False else ())
@@ -475,8 +479,13 @@ def make_base_create_command(
         )
         )
 
 
         if special_file_paths:
         if special_file_paths:
+            truncated_special_file_paths = textwrap.shorten(
+                ', '.join(special_file_paths),
+                width=MAX_SPECIAL_FILE_PATHS_LENGTH,
+                placeholder=' ...',
+            )
             logger.warning(
             logger.warning(
-                f'{repository_path}: Excluding special files to prevent Borg from hanging: {", ".join(special_file_paths)}'
+                f'{repository_path}: Excluding special files to prevent Borg from hanging: {truncated_special_file_paths}'
             )
             )
             exclude_file = write_pattern_file(
             exclude_file = write_pattern_file(
                 expand_home_directories(
                 expand_home_directories(

+ 7 - 6
docs/how-to/backup-your-databases.md

@@ -466,13 +466,14 @@ exclude them. <span class="minilink minilink-addedin">Prior to version
 1.7.3</span>Special files were not auto-excluded, and you were responsible for
 1.7.3</span>Special files were not auto-excluded, and you were responsible for
 excluding them yourself. Common directories to exclude are `/dev` and `/run`,
 excluding them yourself. Common directories to exclude are `/dev` and `/run`,
 but that may not be exhaustive.
 but that may not be exhaustive.
-5. Database hooks also implicitly enable the `one_file_system` option, which
-means Borg won't cross filesystem boundaries when looking for files to backup.
-This is especially important when running borgmatic in a container, as
-container volumes are mounted as separate filesystems. One work-around is to
-explicitly add each mounted volume you'd like to backup to
+5. <span class="minilink minilink-addedin">Prior to version 1.8.15</span>
+Database hooks also implicitly enabled the `one_file_system` option, which
+meant Borg wouldn't cross filesystem boundaries when looking for files to
+backup. When borgmatic was running in a container, this often required a
+work-around to explicitly add each mounted backup volume to
 `source_directories` instead of relying on Borg to include them implicitly via
 `source_directories` instead of relying on Borg to include them implicitly via
-a parent directory.
+a parent directory. However, as of borgmatic 1.8.15, `one_file_system` is no
+longer auto-enabled and such work-arounds aren't necessary.
 
 
 
 
 ### Manual restoration
 ### Manual restoration

+ 3 - 4
tests/unit/borg/test_create.py

@@ -989,7 +989,7 @@ def test_make_base_create_command_with_stream_processes_ignores_read_special_fal
         )
         )
     )
     )
 
 
-    assert create_flags == ('borg', 'create', '--one-file-system', '--read-special')
+    assert create_flags == ('borg', 'create', '--read-special')
     assert create_positional_arguments == REPO_ARCHIVE_WITH_PATHS
     assert create_positional_arguments == REPO_ARCHIVE_WITH_PATHS
     assert not pattern_file
     assert not pattern_file
     assert exclude_file
     assert exclude_file
@@ -1031,7 +1031,7 @@ def test_make_base_create_command_with_stream_processes_and_read_special_true_sk
         )
         )
     )
     )
 
 
-    assert create_flags == ('borg', 'create', '--one-file-system', '--read-special')
+    assert create_flags == ('borg', 'create', '--read-special')
     assert create_positional_arguments == REPO_ARCHIVE_WITH_PATHS
     assert create_positional_arguments == REPO_ARCHIVE_WITH_PATHS
     assert not pattern_file
     assert not pattern_file
     assert not exclude_file
     assert not exclude_file
@@ -1750,7 +1750,7 @@ def test_create_archive_with_progress_and_stream_processes_calls_borg_with_progr
     flexmock(module).should_receive('collect_borgmatic_source_directories').and_return([])
     flexmock(module).should_receive('collect_borgmatic_source_directories').and_return([])
     flexmock(module).should_receive('make_base_create_command').and_return(
     flexmock(module).should_receive('make_base_create_command').and_return(
         (
         (
-            ('borg', 'create', '--one-file-system', '--read-special'),
+            ('borg', 'create', '--read-special'),
             REPO_ARCHIVE_WITH_PATHS,
             REPO_ARCHIVE_WITH_PATHS,
             flexmock(),
             flexmock(),
             flexmock(),
             flexmock(),
@@ -1760,7 +1760,6 @@ def test_create_archive_with_progress_and_stream_processes_calls_borg_with_progr
     create_command = (
     create_command = (
         'borg',
         'borg',
         'create',
         'create',
-        '--one-file-system',
         '--read-special',
         '--read-special',
         '--progress',
         '--progress',
     ) + REPO_ARCHIVE_WITH_PATHS
     ) + REPO_ARCHIVE_WITH_PATHS