mirror of
https://github.com/borgmatic-collective/borgmatic.git
synced 2026-07-22 02:03:01 +02:00
Fix the PostgreSQL database hook to properly parse "*options" values containing quoted spaces.
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
* For the MariaDB and MySQL database hooks, escape quotes in passwords when the
|
||||
"password_transport" option is "pipe".
|
||||
* Add a development script for upgrading pinned dependencies.
|
||||
* Fix the PostgreSQL database hook to properly parse "*options" values containing quoted spaces.
|
||||
|
||||
2.1.5
|
||||
* #1229: Document the permissions needed for the PostgreSQL database hook:
|
||||
|
||||
@@ -100,7 +100,11 @@ def database_names_to_dump(database, config, environment, dry_run):
|
||||
if 'username' in database
|
||||
else ()
|
||||
)
|
||||
+ (tuple(database['list_options'].split(' ')) if 'list_options' in database else ())
|
||||
+ (
|
||||
tuple(shlex.quote(part) for part in shlex.split(database['list_options']))
|
||||
if 'list_options' in database
|
||||
else ()
|
||||
)
|
||||
)
|
||||
logger.debug('Querying for "all" PostgreSQL databases to dump')
|
||||
list_lines = execute_command_and_capture_output(
|
||||
@@ -226,7 +230,7 @@ def dump_data_sources(
|
||||
+ (('--compress', shlex.quote(str(compression))) if compression is not None else ())
|
||||
+ (('--file', shlex.quote(dump_filename)) if dump_format == 'directory' else ())
|
||||
+ (
|
||||
tuple(shlex.quote(option) for option in database['options'].split(' '))
|
||||
tuple(shlex.quote(part) for part in shlex.split(database['options']))
|
||||
if 'options' in database
|
||||
else ()
|
||||
)
|
||||
@@ -393,7 +397,7 @@ def restore_data_source_dump(
|
||||
+ (('--username', username) if username else ())
|
||||
+ (('--dbname', data_source['name']) if not all_databases else ())
|
||||
+ (
|
||||
tuple(data_source['analyze_options'].split(' '))
|
||||
tuple(shlex.quote(part) for part in shlex.split(data_source['analyze_options']))
|
||||
if 'analyze_options' in data_source
|
||||
else ()
|
||||
)
|
||||
@@ -414,7 +418,7 @@ def restore_data_source_dump(
|
||||
+ (('--username', username) if username else ())
|
||||
+ (('--no-owner',) if data_source.get('no_owner', False) else ())
|
||||
+ (
|
||||
tuple(data_source['restore_options'].split(' '))
|
||||
tuple(shlex.quote(part) for part in shlex.split(data_source['restore_options']))
|
||||
if 'restore_options' in data_source
|
||||
else ()
|
||||
)
|
||||
|
||||
@@ -172,13 +172,22 @@ def test_database_names_to_dump_with_all_and_format_lists_databases_with_usernam
|
||||
|
||||
|
||||
def test_database_names_to_dump_with_all_and_format_lists_databases_with_options():
|
||||
database = {'name': 'all', 'format': 'custom', 'list_options': '--harder'}
|
||||
database = {'name': 'all', 'format': 'custom', 'list_options': '--harder "foo bar"'}
|
||||
flexmock(module.borgmatic.hooks.credential.parse).should_receive(
|
||||
'resolve_credential',
|
||||
).replace_with(lambda value, config: value)
|
||||
flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
|
||||
flexmock(module).should_receive('execute_command_and_capture_output').with_args(
|
||||
('psql', '--list', '--no-password', '--no-psqlrc', '--csv', '--tuples-only', '--harder'),
|
||||
(
|
||||
'psql',
|
||||
'--list',
|
||||
'--no-password',
|
||||
'--no-psqlrc',
|
||||
'--csv',
|
||||
'--tuples-only',
|
||||
'--harder',
|
||||
"'foo bar'",
|
||||
),
|
||||
environment=object,
|
||||
working_directory=None,
|
||||
).and_yield('foo,test,', 'bar,test,"stuff and such"')
|
||||
@@ -803,7 +812,7 @@ def test_dump_data_sources_runs_pg_dump_with_integer_compression():
|
||||
|
||||
|
||||
def test_dump_data_sources_runs_pg_dump_with_options():
|
||||
databases = [{'name': 'foo', 'options': '--stuff=such'}]
|
||||
databases = [{'name': 'foo', 'options': '--stuff "foo bar"'}]
|
||||
process = flexmock()
|
||||
flexmock(module).should_receive('make_environment').and_return({'PGSSLMODE': 'disable'})
|
||||
flexmock(module).should_receive('make_dump_path').and_return('')
|
||||
@@ -826,7 +835,8 @@ def test_dump_data_sources_runs_pg_dump_with_options():
|
||||
'--if-exists',
|
||||
'--format',
|
||||
'custom',
|
||||
'--stuff=such',
|
||||
'--stuff',
|
||||
"'foo bar'",
|
||||
'foo',
|
||||
'>',
|
||||
'databases/localhost/foo',
|
||||
@@ -1340,8 +1350,8 @@ def test_restore_data_source_dump_runs_pg_restore_with_options():
|
||||
hook_config = [
|
||||
{
|
||||
'name': 'foo',
|
||||
'restore_options': '--harder',
|
||||
'analyze_options': '--smarter',
|
||||
'restore_options': '--harder "foo bar"',
|
||||
'analyze_options': '--smarter "baz quux"',
|
||||
'schemas': None,
|
||||
},
|
||||
]
|
||||
@@ -1364,6 +1374,7 @@ def test_restore_data_source_dump_runs_pg_restore_with_options():
|
||||
'--dbname',
|
||||
'foo',
|
||||
'--harder',
|
||||
"'foo bar'",
|
||||
),
|
||||
processes=[extract_process],
|
||||
output_log_level=logging.DEBUG,
|
||||
@@ -1381,6 +1392,7 @@ def test_restore_data_source_dump_runs_pg_restore_with_options():
|
||||
'--dbname',
|
||||
'foo',
|
||||
'--smarter',
|
||||
"'baz quux'",
|
||||
'--command',
|
||||
'ANALYZE',
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user