diff --git a/NEWS b/NEWS index 0f2aba3c..2214d6db 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,6 @@ +1.9.1.dev0 + * #928: Fix the user runtime directory location on macOS (and possibly Cygwin). + 1.9.0 * #609: Fix the glob expansion of "source_directories" values to respect the "working_directory" option. diff --git a/borgmatic/commands/arguments.py b/borgmatic/commands/arguments.py index 2eba9ff7..f20984fa 100644 --- a/borgmatic/commands/arguments.py +++ b/borgmatic/commands/arguments.py @@ -876,7 +876,7 @@ def make_parsers(): ) config_bootstrap_group.add_argument( '--user-runtime-directory', - help='Path used for temporary runtime data like bootstrap metadata. Defaults to $XDG_RUNTIME_DIR or /var/run/$UID', + help='Path used for temporary runtime data like bootstrap metadata. Defaults to $XDG_RUNTIME_DIR or $TMPDIR or $TEMP or /var/run/$UID', ) config_bootstrap_group.add_argument( '--borgmatic-source-directory', diff --git a/borgmatic/config/paths.py b/borgmatic/config/paths.py index d56ccc50..ad318d6d 100644 --- a/borgmatic/config/paths.py +++ b/borgmatic/config/paths.py @@ -30,7 +30,8 @@ def get_borgmatic_runtime_directory(config): ''' Given a configuration dict, get the borgmatic runtime directory used for storing temporary runtime data like streaming database dumps and bootstrap metadata. Defaults to - $XDG_RUNTIME_DIR/./borgmatic or /run/user/$UID/./borgmatic. + $XDG_RUNTIME_DIR/./borgmatic or $TMPDIR/./borgmatic or $TEMP/./borgmatic or + /run/user/$UID/./borgmatic. The "/./" is taking advantage of a Borg feature such that the part of the path before the "/./" does not get stored in the file path within an archive. That way, the path of the runtime @@ -39,10 +40,10 @@ def get_borgmatic_runtime_directory(config): return expand_user_in_path( os.path.join( config.get('user_runtime_directory') - or os.environ.get( - 'XDG_RUNTIME_DIR', - f'/run/user/{os.getuid()}', - ), + or os.environ.get('XDG_RUNTIME_DIR') + or os.environ.get('TMPDIR') + or os.environ.get('TEMP') + or f'/run/user/{os.getuid()}', '.', 'borgmatic', ) diff --git a/borgmatic/config/schema.yaml b/borgmatic/config/schema.yaml index 66ee665d..accfbfde 100644 --- a/borgmatic/config/schema.yaml +++ b/borgmatic/config/schema.yaml @@ -218,7 +218,7 @@ properties: Path for storing temporary runtime data like streaming database dumps and bootstrap metadata. borgmatic automatically creates and uses a "borgmatic" subdirectory here. Defaults to $XDG_RUNTIME_DIR - or /run/user/$UID. + or or $TMPDIR or $TEMP or /run/user/$UID. example: /run/user/1001/borgmatic user_state_directory: type: string diff --git a/docs/how-to/backup-your-databases.md b/docs/how-to/backup-your-databases.md index fc5aa5e7..f2162754 100644 --- a/docs/how-to/backup-your-databases.md +++ b/docs/how-to/backup-your-databases.md @@ -76,6 +76,11 @@ borgmatic created temporary streaming database dumps within the `~/.borgmatic` directory by default. At that time, the path was configurable by the `borgmatic_source_directory` configuration option (now deprecated). +New in version 1.9.1In addition +to `XDG_RUNTIME_DIR`, borgmatic also uses the `TMPDIR` or `TEMP` environment +variable if set. `TMPDIR` is available on macOS, while `TEMP` is often +available on other platforms. + Also note that using a database hook implicitly enables the `read_special` configuration option (even if it's disabled in your configuration) to support this dump and restore streaming. See Limitations diff --git a/pyproject.toml b/pyproject.toml index 647fa06a..c3338c9c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "borgmatic" -version = "1.9.0" +version = "1.9.1.dev0" authors = [ { name="Dan Helfman", email="witten@torsion.org" }, ] diff --git a/tests/unit/config/test_paths.py b/tests/unit/config/test_paths.py index 0b5eddee..deeac41b 100644 --- a/tests/unit/config/test_paths.py +++ b/tests/unit/config/test_paths.py @@ -44,11 +44,28 @@ def test_get_borgmatic_runtime_directory_uses_config_option(): ) -def test_get_borgmatic_runtime_directory_falls_back_to_environment_variable(): +def test_get_borgmatic_runtime_directory_falls_back_to_linux_environment_variable(): flexmock(module).should_receive('expand_user_in_path').replace_with(lambda path: path) - flexmock(module.os.environ).should_receive('get').with_args( - 'XDG_RUNTIME_DIR', object - ).and_return('/tmp') + flexmock(module.os.environ).should_receive('get').with_args('XDG_RUNTIME_DIR').and_return( + '/tmp' + ) + + assert module.get_borgmatic_runtime_directory({}) == '/tmp/./borgmatic' + + +def test_get_borgmatic_runtime_directory_falls_back_to_macos_environment_variable(): + flexmock(module).should_receive('expand_user_in_path').replace_with(lambda path: path) + flexmock(module.os.environ).should_receive('get').with_args('XDG_RUNTIME_DIR').and_return(None) + flexmock(module.os.environ).should_receive('get').with_args('TMPDIR').and_return('/tmp') + + assert module.get_borgmatic_runtime_directory({}) == '/tmp/./borgmatic' + + +def test_get_borgmatic_runtime_directory_falls_back_to_other_environment_variable(): + flexmock(module).should_receive('expand_user_in_path').replace_with(lambda path: path) + flexmock(module.os.environ).should_receive('get').with_args('XDG_RUNTIME_DIR').and_return(None) + flexmock(module.os.environ).should_receive('get').with_args('TMPDIR').and_return(None) + flexmock(module.os.environ).should_receive('get').with_args('TEMP').and_return('/tmp') assert module.get_borgmatic_runtime_directory({}) == '/tmp/./borgmatic'