From 030c24f64e0504f6050245879fec7ad13d5282d8 Mon Sep 17 00:00:00 2001 From: Sai Asish Y Date: Thu, 23 Apr 2026 08:47:51 -0700 Subject: [PATCH] ui: honor AWS_ENDPOINT in read_basebackups S3 list/get (#3079) read_stored_clusters and read_versions build their S3 clients with endpoint_url=AWS_ENDPOINT, but read_basebackups used a bare client('s3') for both the list_objects_v2 paginator and the per-key get_object call. On MinIO / S3-compatible backends the list+get requests go to the default AWS endpoint, so the Backups tab renders cluster/version prefixes (picked up by the correctly-configured read_stored_clusters) but then returns empty base backup details (silently no hits against the real backend) (#3078). Build s3_client once per call with endpoint_url=AWS_ENDPOINT and reuse it for both the paginator and get_object. No behaviour change when AWS_ENDPOINT is unset; boto3 defaults to the AWS endpoint either way. Fixes #3078 Signed-off-by: SAY-5 Co-authored-by: SAY-5 Co-authored-by: Ida Novindasari --- ui/operator_ui/spiloutils.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/ui/operator_ui/spiloutils.py b/ui/operator_ui/spiloutils.py index 6a2f03bb2..8d2b73967 100644 --- a/ui/operator_ui/spiloutils.py +++ b/ui/operator_ui/spiloutils.py @@ -321,11 +321,18 @@ def read_basebackups( suffix = '' if uid == 'base' else '/' + uid backups = [] + # Reuse a single S3 client configured with AWS_ENDPOINT so MinIO / + # other S3-compatible backends are hit for list+get calls too. The + # previous plain client('s3') fell back to the default AWS endpoint + # and returned empty data against a custom endpoint; read_stored_clusters + # and read_versions already pass endpoint_url=AWS_ENDPOINT (#3078). + s3_client = client('s3', endpoint_url=AWS_ENDPOINT) + for vp in postgresql_versions: backup_prefix = f'{prefix}{pg_cluster}{suffix}/wal/{vp}/basebackups_005/' logger.info(f"{bucket}/{backup_prefix}") - paginator = client('s3').get_paginator('list_objects_v2') + paginator = s3_client.get_paginator('list_objects_v2') pages = paginator.paginate(Bucket=bucket, Prefix=backup_prefix) for page in pages: @@ -334,7 +341,7 @@ def read_basebackups( if not key.endswith("backup_stop_sentinel.json"): continue - response = client('s3').get_object(Bucket=bucket, Key=key) + response = s3_client.get_object(Bucket=bucket, Key=key) backup_info = loads(response["Body"].read().decode("utf-8")) last_modified = response["LastModified"].astimezone(timezone.utc).isoformat()