Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ request adding CHANGELOG notes for breaking (!) changes and possibly other secti

### Fixes

- Python CLI `setup` now preserves the catalog `storageName` field during export and apply, so named storage credential selection survives backup and migration round trips.
- The NoSQL persistence commit log (`Commits.commitLog`) no longer stops early when a commit's recent-ancestor tail is shorter than the internal fetch page size. With a `polaris.persistence.reference-previous-head-count` smaller than the page size, the natural-order commit log previously truncated at the first short tail because trailing null entries in the fetch page were treated as end-of-history, which could also drop still-referenced objects during maintenance.
- Python CLI REPL now shows a clear "Syntax error" message for malformed input instead of a generic "unexpected error" message.
- Python CLI `setup apply` now exits with an error after any setup operation fails, while still attempting the remaining operations. Previously, individual failures were logged but the command reported success and exited with status 0.
Expand Down
5 changes: 5 additions & 0 deletions client/python/apache_polaris/cli/command/catalogs.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ class CatalogsCommand(Command):
catalog_type: Optional[str] = None
default_base_location: Optional[str] = None
storage_type: Optional[str] = None
storage_name: Optional[str] = None
allowed_locations: Optional[List[str]] = None
role_arn: Optional[str] = None
external_id: Optional[str] = None
Expand Down Expand Up @@ -296,6 +297,7 @@ def _build_storage_config_info(self) -> Optional[StorageConfigInfo]:
if self.storage_type == StorageType.S3.value:
config = AwsStorageConfigInfo(
storage_type=self.storage_type.upper(),
storage_name=self.storage_name,
allowed_locations=self.allowed_locations,
role_arn=self.role_arn,
external_id=self.external_id,
Expand All @@ -313,6 +315,7 @@ def _build_storage_config_info(self) -> Optional[StorageConfigInfo]:
elif self.storage_type == StorageType.AZURE.value:
config = AzureStorageConfigInfo(
storage_type=self.storage_type.upper(),
storage_name=self.storage_name,
allowed_locations=self.allowed_locations,
tenant_id=self.tenant_id,
multi_tenant_app_name=self.multi_tenant_app_name,
Expand All @@ -322,12 +325,14 @@ def _build_storage_config_info(self) -> Optional[StorageConfigInfo]:
elif self.storage_type == StorageType.GCS.value:
config = GcpStorageConfigInfo(
storage_type=self.storage_type.upper(),
storage_name=self.storage_name,
allowed_locations=self.allowed_locations,
gcs_service_account=self.service_account,
)
elif self.storage_type == StorageType.FILE.value:
config = StorageConfigInfo(
storage_type=self.storage_type.upper(),
storage_name=self.storage_name,
allowed_locations=self.allowed_locations,
)
return config
Expand Down
3 changes: 3 additions & 0 deletions client/python/apache_polaris/cli/command/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,7 @@ def _export_catalogs(self, api: PolarisDefaultApi) -> List[Dict[str, Any]]:
"name": c.name,
"type": c.type.lower() if c.type else "internal",
"storage_type": storage_type.lower(),
"storage_name": c.storage_config_info.storage_name,
"default_base_location": c.properties.default_base_location,
"allowed_locations": sorted(
c.storage_config_info.allowed_locations
Expand Down Expand Up @@ -808,6 +809,7 @@ def _map_storage_properties(self, catalog_data: Dict[str, Any]) -> Dict[str, Any
"""Maps storage-related properties from YAML data to command arguments."""
storage_keys = [
"storage_type",
"storage_name",
"default_base_location",
"allowed_locations",
"properties",
Expand Down Expand Up @@ -979,6 +981,7 @@ def _create_catalogs(
catalog_type=command_args.get("catalog_type"),
default_base_location=command_args.get("default_base_location"),
storage_type=command_args.get("storage_type"),
storage_name=command_args.get("storage_name"),
allowed_locations=command_args.get("allowed_locations"),
properties=command_args.get("properties"),
set_properties=command_args.get("set_properties"),
Expand Down
8 changes: 6 additions & 2 deletions client/python/tests/test_setup_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -746,7 +746,7 @@ def test_setup_export_reports_nested_read_failures(
self.assertEqual(mock_stdout.getvalue(), "")

@patch("apache_polaris.cli.command.setup.IcebergCatalogAPI")
def test_setup_export_s3_catalog_round_trips_sts_and_internal_endpoints(
def test_setup_export_s3_catalog_round_trips_storage_details(
self, mock_catalog_api: MagicMock
) -> None:
mock_catalog_api.return_value.list_namespaces.return_value = []
Expand All @@ -764,6 +764,7 @@ def test_setup_export_s3_catalog_round_trips_sts_and_internal_endpoints(
),
storage_config_info=AwsStorageConfigInfo(
storage_type="S3",
storage_name="analytics-prod",
allowed_locations=["s3://bucket/path"],
role_arn="arn:aws:iam::123456789012:user/QuickstartUser",
endpoint="https://s3.us-west-2.amazonaws.com",
Expand All @@ -780,8 +781,10 @@ def test_setup_export_s3_catalog_round_trips_sts_and_internal_endpoints(
exported = export_command._export_catalogs(mock_client)

self.assertEqual(len(exported), 1)
self.assertEqual(exported[0]["storage_name"], "analytics-prod")
self.assertEqual(
exported[0]["endpoint_internal"], "https://bucket.vpce-1a2b3c4d-5e6f.s3.us-west-2.vpce.amazonaws.com"
exported[0]["endpoint_internal"],
"https://bucket.vpce-1a2b3c4d-5e6f.s3.us-west-2.vpce.amazonaws.com",
)
self.assertEqual(exported[0]["sts_endpoint"], "https://sts.amazonaws.com")

Expand All @@ -794,6 +797,7 @@ def test_setup_export_s3_catalog_round_trips_sts_and_internal_endpoints(

apply_client.create_catalog.assert_called_once()
created = apply_client.create_catalog.call_args[0][0].catalog
self.assertEqual(created.storage_config_info.storage_name, "analytics-prod")
self.assertEqual(
created.storage_config_info.endpoint_internal,
"https://bucket.vpce-1a2b3c4d-5e6f.s3.us-west-2.vpce.amazonaws.com",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,8 @@ catalogs:
- name: "quickstart_catalog_s3"
type: internal
storage_type: "s3"
# Optional name referencing a server-side storage configuration.
# storage_name: "analytics-prod"
default_base_location: "s3://quickstart-bucket/quickstart_catalog/"
allowed_locations:
- "s3://quickstart-bucket/quickstart_catalog/"
Expand Down