Skip to content

Commit

Permalink
Fix pg-backup-api so it can handle Barman <= 3.9
Browse files Browse the repository at this point in the history
pg-backup-api 2.1.0 doesn't work with Barman <= 3.9 because it attempts to
fetch models independently of the Barman version it operates on. As Barman
models were introduced through version 3.10, pg-backup-api fails with an
ugly stack trace:

```
Traceback (most recent call last):
  File "/usr/lib/python3.9/site-packages/flask/app.py", line 2073, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/lib/python3.9/site-packages/flask/app.py", line 1518, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/lib/python3.9/site-packages/flask/app.py", line 1516, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/lib/python3.9/site-packages/flask/app.py", line 1502, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
  File "/usr/lib/python3.9/site-packages/pg_backup_api/logic/utility_controller.py", line 76, in diagnose
    available_models = barman.__config__.model_names()
AttributeError: 'Config' object has no attribute 'model_names'
```

Through this commit we fix pg-backup-api in that sense:

* It attempts to use models and the new signature of the `exec_diagnose`,
  which were introduced by Barman 3.10;
* It falls back to the old signature of `exec_diagnose` if models are not
  available (Barman <= 3.9).

References: BAR-171.

Signed-off-by: Israel Barth Rubio <[email protected]>
  • Loading branch information
barthisrael committed May 21, 2024
1 parent ae608b6 commit 85af364
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 9 deletions.
24 changes: 15 additions & 9 deletions pg_backup_api/pg_backup_api/logic/utility_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,18 +73,24 @@ def diagnose() -> 'Response':
else:
server_dict[server] = Server(conf)

available_models = barman.__config__.model_names()
model_dict = {}
for model in available_models: # pyright: ignore
model_dict[model] = barman.__config__.get_model(model)

# errors list with duplicate paths between servers
errors_list = barman.__config__.servers_msg_list

barman_diagnose.exec_diagnose(server_dict,
model_dict,
errors_list,
show_config_source=False)
try:
available_models = barman.__config__.model_names()
model_dict = {}
for model in available_models: # pyright: ignore
model_dict[model] = barman.__config__.get_model(model)

barman_diagnose.exec_diagnose(server_dict,
model_dict,
errors_list,
show_config_source=False)
# An attribute error is thown when calling `model_names()` if using Barman
# older than 3.10, in which case models are not yet implemented, so we fall
# back to the old signature of diagnose command.
except AttributeError:
barman_diagnose.exec_diagnose(server_dict, errors_list)

# new outputs are appended, so grab the last one
stored_output = json.loads(output._writer.json_output["_INFO"][-1])
Expand Down
23 changes: 23 additions & 0 deletions pg_backup_api/pg_backup_api/tests/test_utility_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,29 @@ def test_diagnose_ok(self, client):
assert response.status_code == 200
assert response.data == b'{"global":{"config":{}}}\n'

@patch("pg_backup_api.logic.utility_controller.barman_diagnose", Mock())
@patch.dict(
"pg_backup_api.logic.utility_controller.output._writer.json_output",
{
'_INFO': ['SOME', 'JSON', 'ENTRIES', '{"global":{"config":{}}}'],
},
)
def test_diagnose_ok_old_barman(self, client):
"""Test ``/diagnose`` endpoint.
Ensure a ``GET`` request returns ``200`` and the expected JSON output,
even if using Barman 3.9 or older, in which case models implementation
is not available.
"""
path = "/diagnose"

with patch("barman.__config__") as mock_config:
mock_config.model_names.side_effect = AttributeError("Old Barman")
response = client.get(path)

assert response.status_code == 200
assert response.data == b'{"global":{"config":{}}}\n'

def test_diagnose_not_allowed(self, client):
"""Test ``/diagnose`` endpoint.
Expand Down

0 comments on commit 85af364

Please sign in to comment.