Revert temporary reversion of 1.9.4.dev0.
All checks were successful
build / test (push) Successful in 4m9s
build / docs (push) Successful in 6s

revert Temporary revert of 1.9.4.dev0 changeset so we can re-build 1.9.3 (which never actually got built).

revert Fix library error when running within a PyInstaller bundle (#926).
This commit is contained in:
Dan Helfman 2024-11-26 16:20:06 +00:00
parent bf40b01077
commit a07cf9e699
4 changed files with 76 additions and 21 deletions

3
NEWS
View File

@ -1,3 +1,6 @@
1.9.4.dev0
* #926: Fix library error when running within a PyInstaller bundle.
1.9.3
* #261 (beta): Add a ZFS hook for snapshotting and backing up ZFS datasets. See the documentation
for more information: https://torsion.org/borgmatic/docs/how-to/snapshot-your-filesystems/

View File

@ -2,8 +2,9 @@ import logging
import os
import re
import shlex
import sys
from borgmatic import execute
import borgmatic.execute
logger = logging.getLogger(__name__)
@ -27,6 +28,20 @@ def interpolate_context(config_filename, hook_description, command, context):
return command
def make_environment(current_environment, sys_module=sys):
'''
Given the existing system environment as a map from environment variable name to value, return
(in the same form) any extra environment variables that should be used when running command
hooks.
'''
# Detect whether we're running within a PyInstaller bundle. If so, set or clear LD_LIBRARY_PATH
# based on the value of LD_LIBRARY_PATH_ORIG. This prevents library version information errors.
if getattr(sys_module, 'frozen', False) and hasattr(sys_module, '_MEIPASS'):
return {'LD_LIBRARY_PATH': current_environment.get('LD_LIBRARY_PATH_ORIG', '')}
return {}
def execute_hook(commands, umask, config_filename, description, dry_run, **context):
'''
Given a list of hook commands to execute, a umask to execute with (or None), a config filename,
@ -65,14 +80,15 @@ def execute_hook(commands, umask, config_filename, description, dry_run, **conte
try:
for command in commands:
if not dry_run:
execute.execute_command(
[command],
output_log_level=(
logging.ERROR if description == 'on-error' else logging.WARNING
),
shell=True,
)
if dry_run:
continue
borgmatic.execute.execute_command(
[command],
output_log_level=(logging.ERROR if description == 'on-error' else logging.WARNING),
shell=True,
extra_environment=make_environment(os.environ),
)
finally:
if original_umask:
os.umask(original_umask)

View File

@ -1,6 +1,6 @@
[project]
name = "borgmatic"
version = "1.9.3"
version = "1.9.4.dev0"
authors = [
{ name="Dan Helfman", email="witten@torsion.org" },
]

View File

@ -35,12 +35,32 @@ def test_interpolate_context_escapes_interpolated_variables():
)
def test_make_environment_without_pyinstaller_does_not_touch_environment():
assert module.make_environment({}, sys_module=flexmock()) == {}
def test_make_environment_with_pyinstaller_clears_LD_LIBRARY_PATH():
assert module.make_environment({}, sys_module=flexmock(frozen=True, _MEIPASS='yup')) == {
'LD_LIBRARY_PATH': ''
}
def test_make_environment_with_pyinstaller_and_LD_LIBRARY_PATH_ORIG_copies_it_into_LD_LIBRARY_PATH():
assert module.make_environment(
{'LD_LIBRARY_PATH_ORIG': '/lib/lib/lib'}, sys_module=flexmock(frozen=True, _MEIPASS='yup')
) == {'LD_LIBRARY_PATH': '/lib/lib/lib'}
def test_execute_hook_invokes_each_command():
flexmock(module).should_receive('interpolate_context').replace_with(
lambda config_file, hook_description, command, context: command
)
flexmock(module.execute).should_receive('execute_command').with_args(
[':'], output_log_level=logging.WARNING, shell=True
flexmock(module).should_receive('make_environment').and_return({})
flexmock(module.borgmatic.execute).should_receive('execute_command').with_args(
[':'],
output_log_level=logging.WARNING,
shell=True,
extra_environment={},
).once()
module.execute_hook([':'], None, 'config.yaml', 'pre-backup', dry_run=False)
@ -50,11 +70,18 @@ def test_execute_hook_with_multiple_commands_invokes_each_command():
flexmock(module).should_receive('interpolate_context').replace_with(
lambda config_file, hook_description, command, context: command
)
flexmock(module.execute).should_receive('execute_command').with_args(
[':'], output_log_level=logging.WARNING, shell=True
flexmock(module).should_receive('make_environment').and_return({})
flexmock(module.borgmatic.execute).should_receive('execute_command').with_args(
[':'],
output_log_level=logging.WARNING,
shell=True,
extra_environment={},
).once()
flexmock(module.execute).should_receive('execute_command').with_args(
['true'], output_log_level=logging.WARNING, shell=True
flexmock(module.borgmatic.execute).should_receive('execute_command').with_args(
['true'],
output_log_level=logging.WARNING,
shell=True,
extra_environment={},
).once()
module.execute_hook([':', 'true'], None, 'config.yaml', 'pre-backup', dry_run=False)
@ -66,8 +93,12 @@ def test_execute_hook_with_umask_sets_that_umask():
)
flexmock(module.os).should_receive('umask').with_args(0o77).and_return(0o22).once()
flexmock(module.os).should_receive('umask').with_args(0o22).once()
flexmock(module.execute).should_receive('execute_command').with_args(
[':'], output_log_level=logging.WARNING, shell=True
flexmock(module).should_receive('make_environment').and_return({})
flexmock(module.borgmatic.execute).should_receive('execute_command').with_args(
[':'],
output_log_level=logging.WARNING,
shell=True,
extra_environment={},
)
module.execute_hook([':'], 77, 'config.yaml', 'pre-backup', dry_run=False)
@ -77,7 +108,8 @@ def test_execute_hook_with_dry_run_skips_commands():
flexmock(module).should_receive('interpolate_context').replace_with(
lambda config_file, hook_description, command, context: command
)
flexmock(module.execute).should_receive('execute_command').never()
flexmock(module).should_receive('make_environment').and_return({})
flexmock(module.borgmatic.execute).should_receive('execute_command').never()
module.execute_hook([':', 'true'], None, 'config.yaml', 'pre-backup', dry_run=True)
@ -90,8 +122,12 @@ def test_execute_hook_on_error_logs_as_error():
flexmock(module).should_receive('interpolate_context').replace_with(
lambda config_file, hook_description, command, context: command
)
flexmock(module.execute).should_receive('execute_command').with_args(
[':'], output_log_level=logging.ERROR, shell=True
flexmock(module).should_receive('make_environment').and_return({})
flexmock(module.borgmatic.execute).should_receive('execute_command').with_args(
[':'],
output_log_level=logging.ERROR,
shell=True,
extra_environment={},
).once()
module.execute_hook([':'], None, 'config.yaml', 'on-error', dry_run=False)