Skip to content

Commit 5dc703c

Browse files
committed
Make docker-compose-polaris match the quick start
1 parent 65fa586 commit 5dc703c

File tree

4 files changed

+280
-194
lines changed

4 files changed

+280
-194
lines changed

Makefile

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -129,26 +129,10 @@ test-polaris-setup: install ## Start Docker services for Polaris integration tes
129129
docker compose -f dev/docker-compose-polaris.yml kill
130130
docker compose -f dev/docker-compose-polaris.yml rm -f
131131
docker compose -f dev/docker-compose-polaris.yml up -d --build --wait
132-
uv run $(PYTHON_ARG) python dev/provision_polaris.py > dev/polaris_creds.env
132+
docker compose -f dev/docker-compose-polaris.yml exec -T polaris-setup cat /tmp/polaris_creds.env > dev/polaris_creds.env
133133

134134
test-polaris-exec: ## Run Polaris integration tests
135-
@eval $$(cat dev/polaris_creds.env) && \
136-
PYICEBERG_TEST_CATALOG="polaris" \
137-
PYICEBERG_CATALOG__POLARIS__TYPE="rest" \
138-
PYICEBERG_CATALOG__POLARIS__URI="http://localhost:8181/api/catalog" \
139-
PYICEBERG_CATALOG__POLARIS__OAUTH2_SERVER_URI="http://localhost:8181/api/catalog/v1/oauth/tokens" \
140-
PYICEBERG_CATALOG__POLARIS__CREDENTIAL="$$CLIENT_ID:$$CLIENT_SECRET" \
141-
PYICEBERG_CATALOG__POLARIS__SCOPE="PRINCIPAL_ROLE:ALL" \
142-
PYICEBERG_CATALOG__POLARIS__WAREHOUSE="polaris" \
143-
PYICEBERG_CATALOG__POLARIS__HEADER__X_ICEBERG_ACCESS_DELEGATION="vended-credentials" \
144-
PYICEBERG_CATALOG__POLARIS__HEADER__REALM="POLARIS" \
145-
PYICEBERG_CATALOG__POLARIS__S3__ENDPOINT="http://localhost:9000" \
146-
PYICEBERG_CATALOG__POLARIS__S3__ACCESS_KEY_ID="admin" \
147-
PYICEBERG_CATALOG__POLARIS__S3__SECRET_ACCESS_KEY="password" \
148-
PYICEBERG_CATALOG__POLARIS__S3__REGION="us-east-1" \
149-
$(TEST_RUNNER) pytest tests/integration/test_catalog.py -k "rest_test_catalog and not test_update_namespace_properties" $(PYTEST_ARGS)
150-
# Skip test_update_namespace_properties: Polaris triggers a CommitConflictException when updates and removals are in the same request.
151-
# TODO: Remove test exception after https://github.com/apache/polaris/pull/4013 is merged.
135+
TEST_RUNNER="$(TEST_RUNNER)" sh dev/test-polaris.sh $(PYTEST_ARGS)
152136

153137
test-polaris-cleanup: ## Clean up Polaris integration test environment
154138
@if [ "${KEEP_COMPOSE}" != "1" ]; then \

dev/docker-compose-polaris.yml

Lines changed: 224 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -16,61 +16,246 @@
1616
# under the License.
1717

1818
services:
19+
20+
rustfs:
21+
image: rustfs/rustfs:1.0.0-alpha.81
22+
networks:
23+
iceberg_net:
24+
ports:
25+
# API port
26+
- "9000:9000"
27+
# UI port
28+
- "9001:9001"
29+
environment:
30+
RUSTFS_ACCESS_KEY: polaris_root
31+
RUSTFS_SECRET_KEY: polaris_pass
32+
RUSTFS_VOLUMES: /data
33+
RUSTFS_ADDRESS: ":9000"
34+
RUSTFS_CONSOLE_ENABLE: "true"
35+
RUSTFS_CONSOLE_ADDRESS: ":9001"
36+
healthcheck:
37+
test: ["CMD-SHELL", "curl --fail http://127.0.0.1:9000/health && curl --fail http://127.0.0.1:9001/rustfs/console/health"]
38+
interval: 10s
39+
timeout: 10s
40+
retries: 3
41+
start_period: 40s
42+
1943
polaris:
2044
image: apache/polaris:latest
2145
container_name: pyiceberg-polaris
2246
networks:
2347
iceberg_net:
2448
ports:
25-
- 8181:8181
26-
- 8182:8182
49+
# API port
50+
- "8181:8181"
51+
# Management port (metrics and health checks)
52+
- "8182:8182"
53+
# Optional, allows attaching a debugger to the Polaris JVM
54+
- "5005:5005"
55+
depends_on:
56+
rustfs:
57+
condition: service_healthy
58+
bucket-setup:
59+
condition: service_completed_successfully
2760
environment:
28-
- POLARIS_BOOTSTRAP_CREDENTIALS=POLARIS,root,s3cr3t
29-
- polaris.features."ALLOW_INSECURE_STORAGE_TYPES"=true
30-
- polaris.features."SUPPORTED_CATALOG_STORAGE_TYPES"=["FILE","S3"]
31-
- polaris.features."ALLOW_OVERLAPPING_CATALOG_URLS"=true
32-
- polaris.readiness.ignore-severe-issues=true
33-
- AWS_ACCESS_KEY_ID=admin
34-
- AWS_SECRET_ACCESS_KEY=password
35-
- AWS_REGION=us-east-1
61+
JAVA_DEBUG: true
62+
JAVA_DEBUG_PORT: "*:5005"
63+
AWS_REGION: us-west-2
64+
AWS_ACCESS_KEY_ID: polaris_root
65+
AWS_SECRET_ACCESS_KEY: polaris_pass
66+
POLARIS_BOOTSTRAP_CREDENTIALS: POLARIS,root,s3cr3t
67+
polaris.realm-context.realms: POLARIS
68+
quarkus.otel.sdk.disabled: "true"
69+
polaris.features."ALLOW_INSECURE_STORAGE_TYPES": "true"
70+
polaris.features."SUPPORTED_CATALOG_STORAGE_TYPES": '["FILE","S3"]'
71+
polaris.features."ALLOW_OVERLAPPING_CATALOG_URLS": "true"
72+
polaris.readiness.ignore-severe-issues: "true"
3673
healthcheck:
37-
test: ["CMD", "curl", "http://localhost:8182/q/health"]
38-
interval: 10s
74+
test: ["CMD", "curl", "--fail", "http://localhost:8182/q/health"]
75+
interval: 2s
3976
timeout: 10s
40-
retries: 5
41-
minio:
42-
image: minio/minio
43-
container_name: pyiceberg-polaris-minio
77+
retries: 10
78+
start_period: 10s
79+
80+
bucket-setup:
81+
image: amazon/aws-cli:2.34.19
4482
networks:
4583
iceberg_net:
46-
aliases:
47-
- warehouse.minio
48-
ports:
49-
- 9001:9001
50-
- 9000:9000
84+
depends_on:
85+
rustfs:
86+
condition: service_healthy
5187
environment:
52-
- MINIO_ROOT_USER=admin
53-
- MINIO_ROOT_PASSWORD=password
54-
- MINIO_DOMAIN=minio
55-
command: ["server", "/data", "--console-address", ":9001"]
56-
mc:
57-
image: minio/mc
58-
container_name: pyiceberg-polaris-mc
88+
AWS_ACCESS_KEY_ID: polaris_root
89+
AWS_SECRET_ACCESS_KEY: polaris_pass
90+
AWS_ENDPOINT_URL: http://rustfs:9000
91+
entrypoint: "/bin/sh"
92+
command:
93+
- "-c"
94+
- >-
95+
echo Creating RustFS bucket... &&
96+
aws s3 mb s3://bucket123 &&
97+
aws s3 ls &&
98+
echo Bucket setup complete.
99+
100+
polaris-setup:
101+
image: alpine/curl:8.17.0
59102
networks:
60103
iceberg_net:
61104
depends_on:
62-
- minio
105+
polaris:
106+
condition: service_healthy
63107
environment:
64-
- AWS_ACCESS_KEY_ID=admin
65-
- AWS_SECRET_ACCESS_KEY=password
66-
- AWS_REGION=us-east-1
67-
entrypoint: >
68-
/bin/sh -c "
69-
until (/usr/bin/mc alias set minio http://minio:9000 admin password) do echo '...waiting...' && sleep 1; done;
70-
/usr/bin/mc mb minio/warehouse;
71-
/usr/bin/mc policy set public minio/warehouse;
72-
tail -f /dev/null
73-
"
108+
- CLIENT_ID=root
109+
- CLIENT_SECRET=s3cr3t
110+
- CATALOG_NAME=polaris
111+
- REALM=POLARIS
112+
entrypoint: /bin/sh
113+
command:
114+
- -c
115+
- |
116+
set -e
117+
apk add --no-cache jq
118+
119+
echo "Obtaining root access token..."
120+
TOKEN_RESPONSE=$$(curl --fail-with-body -s -S -X POST http://polaris:8181/api/catalog/v1/oauth/tokens \
121+
-H 'Content-Type: application/x-www-form-urlencoded' \
122+
-d "grant_type=client_credentials&client_id=$${CLIENT_ID}&client_secret=$${CLIENT_SECRET}&scope=PRINCIPAL_ROLE:ALL" 2>&1) || {
123+
echo "❌ Failed to obtain access token"
124+
echo "$$TOKEN_RESPONSE" >&2
125+
exit 1
126+
}
127+
128+
TOKEN=$$(echo $$TOKEN_RESPONSE | jq -r '.access_token')
129+
if [ -z "$$TOKEN" ] || [ "$$TOKEN" = "null" ]; then
130+
echo "❌ Failed to parse access token from response"
131+
echo "$$TOKEN_RESPONSE"
132+
exit 1
133+
fi
134+
echo "✅ Obtained access token"
135+
136+
echo "Creating catalog '$$CATALOG_NAME' in realm $$REALM..."
137+
PAYLOAD='{
138+
"catalog": {
139+
"name": "'$$CATALOG_NAME'",
140+
"type": "INTERNAL",
141+
"readOnly": false,
142+
"properties": {
143+
"default-base-location": "s3://bucket123",
144+
"polaris.config.drop-with-purge.enabled": "true"
145+
},
146+
"storageConfigInfo": {
147+
"storageType": "S3",
148+
"allowedLocations": ["s3://bucket123"],
149+
"endpoint": "http://localhost:9000",
150+
"endpointInternal": "http://rustfs:9000",
151+
"pathStyleAccess": true
152+
}
153+
}
154+
}'
155+
156+
RESPONSE=$$(curl --fail-with-body -s -S -X POST http://polaris:8181/api/management/v1/catalogs \
157+
-H "Authorization: Bearer $$TOKEN" \
158+
-H "Accept: application/json" \
159+
-H "Content-Type: application/json" \
160+
-H "Polaris-Realm: $$REALM" \
161+
-d "$$PAYLOAD" 2>&1) && echo -n "" || {
162+
echo "❌ Failed to create catalog"
163+
echo "$$RESPONSE" >&2
164+
exit 1
165+
}
166+
echo "✅ Catalog created"
167+
168+
echo ""
169+
echo "Creating principal 'quickstart_user'..."
170+
PRINCIPAL_RESPONSE=$$(curl --fail-with-body -s -X POST http://polaris:8181/api/management/v1/principals \
171+
-H "Authorization: Bearer $$TOKEN" \
172+
-H "Polaris-Realm: $$REALM" \
173+
-H "Content-Type: application/json" \
174+
-d '{"principal": {"name": "quickstart_user", "properties": {}}}' 2>&1) || {
175+
echo "❌ Failed to create principal"
176+
echo "$$PRINCIPAL_RESPONSE" >&2
177+
exit 1
178+
}
179+
180+
USER_CLIENT_ID=$$(echo $$PRINCIPAL_RESPONSE | jq -r '.credentials.clientId')
181+
USER_CLIENT_SECRET=$$(echo $$PRINCIPAL_RESPONSE | jq -r '.credentials.clientSecret')
182+
if [ -z "$$USER_CLIENT_ID" ] || [ "$$USER_CLIENT_ID" = "null" ] || [ -z "$$USER_CLIENT_SECRET" ] || [ "$$USER_CLIENT_SECRET" = "null" ]; then
183+
echo "❌ Failed to parse user credentials from response"
184+
echo "$$PRINCIPAL_RESPONSE"
185+
exit 1
186+
fi
187+
echo "✅ Principal created with clientId: $$USER_CLIENT_ID"
188+
189+
echo "Creating principal role 'quickstart_user_role'..."
190+
RESPONSE=$$(curl --fail-with-body -s -S -X POST http://polaris:8181/api/management/v1/principal-roles \
191+
-H "Authorization: Bearer $$TOKEN" \
192+
-H "Polaris-Realm: $$REALM" \
193+
-H "Content-Type: application/json" \
194+
-d '{"principalRole": {"name": "quickstart_user_role", "properties": {}}}' 2>&1) && echo -n "" || {
195+
echo "❌ Failed to create principal role"
196+
echo "$$RESPONSE" >&2
197+
exit 1
198+
}
199+
echo "✅ Principal role created"
200+
201+
echo "Creating catalog role 'quickstart_catalog_role'..."
202+
RESPONSE=$$(curl --fail-with-body -s -S -X POST http://polaris:8181/api/management/v1/catalogs/$$CATALOG_NAME/catalog-roles \
203+
-H "Authorization: Bearer $$TOKEN" \
204+
-H "Polaris-Realm: $$REALM" \
205+
-H "Content-Type: application/json" \
206+
-d '{"catalogRole": {"name": "quickstart_catalog_role", "properties": {}}}' 2>&1) && echo -n "" || {
207+
echo "❌ Failed to create catalog role"
208+
echo "$$RESPONSE" >&2
209+
exit 1
210+
}
211+
echo "✅ Catalog role created"
212+
213+
echo "Assigning principal role to principal..."
214+
RESPONSE=$$(curl --fail-with-body -s -S -X PUT http://polaris:8181/api/management/v1/principals/quickstart_user/principal-roles \
215+
-H "Authorization: Bearer $$TOKEN" \
216+
-H "Polaris-Realm: $$REALM" \
217+
-H "Content-Type: application/json" \
218+
-d '{"principalRole": {"name": "quickstart_user_role"}}' 2>&1) && echo -n "" || {
219+
echo "❌ Failed to assign principal role"
220+
echo "$$RESPONSE" >&2
221+
exit 1
222+
}
223+
echo "✅ Principal role assigned"
224+
225+
echo "Assigning catalog role to principal role..."
226+
RESPONSE=$$(curl --fail-with-body -s -S -X PUT http://polaris:8181/api/management/v1/principal-roles/quickstart_user_role/catalog-roles/$$CATALOG_NAME \
227+
-H "Authorization: Bearer $$TOKEN" \
228+
-H "Polaris-Realm: $$REALM" \
229+
-H "Content-Type: application/json" \
230+
-d '{"catalogRole": {"name": "quickstart_catalog_role"}}' 2>&1) && echo -n "" || {
231+
echo "❌ Failed to assign catalog role"
232+
echo "$$RESPONSE" >&2
233+
exit 1
234+
}
235+
echo "✅ Catalog role assigned"
236+
237+
echo "Granting CATALOG_MANAGE_CONTENT privilege..."
238+
RESPONSE=$$(curl --fail-with-body -s -S -X PUT http://polaris:8181/api/management/v1/catalogs/$$CATALOG_NAME/catalog-roles/quickstart_catalog_role/grants \
239+
-H "Authorization: Bearer $$TOKEN" \
240+
-H "Polaris-Realm: $$REALM" \
241+
-H "Content-Type: application/json" \
242+
-d '{"type": "catalog", "privilege": "CATALOG_MANAGE_CONTENT"}' 2>&1) && echo -n "" || {
243+
echo "❌ Failed to grant privileges"
244+
echo "$$RESPONSE" >&2
245+
exit 1
246+
}
247+
echo "✅ Privileges granted"
248+
249+
echo "CLIENT_ID=$$USER_CLIENT_ID" > /tmp/polaris_creds.env
250+
echo "CLIENT_SECRET=$$USER_CLIENT_SECRET" >> /tmp/polaris_creds.env
251+
252+
touch /tmp/polaris-setup-done
253+
tail -f /dev/null
254+
healthcheck:
255+
interval: 1s
256+
timeout: 10s
257+
retries: 240
258+
test: ["CMD", "test", "-f", "/tmp/polaris-setup-done"]
74259

75260
networks:
76261
iceberg_net:

0 commit comments

Comments
 (0)