This is an automated email from the ASF dual-hosted git repository.

difin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hive.git


The following commit(s) were added to refs/heads/master by this push:
     new 51dd8d0fa00 HIVE-29285: Iceberg: Add docker-compose setups for REST 
Catalog integrations with Gravitino and Polaris (#6147)
51dd8d0fa00 is described below

commit 51dd8d0fa0007af16c3681b65b7fa35c924ce3e7
Author: Dmitriy Fingerman <[email protected]>
AuthorDate: Tue Oct 28 14:42:50 2025 -0400

    HIVE-29285: Iceberg: Add docker-compose setups for REST Catalog 
integrations with Gravitino and Polaris (#6147)
---
 .../src/docker/thirdparties/gravitino/README.md    | 242 +++++++++++++++++++++
 .../docker/thirdparties/gravitino/common/init.sh   |  30 +++
 .../thirdparties/gravitino/docker-compose.yml      | 103 +++++++++
 .../gravitino/gravitino-iceberg-rest-server.conf   |  50 +++++
 .../gravitino/gravitino/healthcheck.sh             |  47 ++++
 .../thirdparties/gravitino/gravitino/init.sh       |  30 +++
 .../gravitino/start-iceberg-rest-server.sh         |  31 +++
 .../thirdparties/gravitino/hive/hive-site.xml      | 123 +++++++++++
 .../gravitino/keycloak/realm-export.json           |  43 ++++
 .../src/docker/thirdparties/polaris/README.md      | 184 ++++++++++++++++
 .../docker/thirdparties/polaris/docker-compose.yml |  94 ++++++++
 .../docker/thirdparties/polaris/hive/hive-site.xml | 138 ++++++++++++
 .../docker/thirdparties/polaris/polaris/init.sh    | 184 ++++++++++++++++
 .../thirdparties/polaris/polaris/obtain-token.sh   |  37 ++++
 14 files changed, 1336 insertions(+)

diff --git a/packaging/src/docker/thirdparties/gravitino/README.md 
b/packaging/src/docker/thirdparties/gravitino/README.md
new file mode 100644
index 00000000000..d97c5725eeb
--- /dev/null
+++ b/packaging/src/docker/thirdparties/gravitino/README.md
@@ -0,0 +1,242 @@
+<!--
+{% comment %}
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to you under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+{% endcomment %}
+-->
+
+# Hive + Gravitino + Keycloak: Docker-Compose Setup
+
+This package contains a docker-compose-based setup integrating Apache Hive, 
Gravitino Iceberg REST server, and Keycloak for OAuth2 authentication. It 
allows Hive to use an Iceberg REST catalog secured via Keycloak.
+
+## Table of Contents
+- Architecture Overview
+- Prerequisites
+- Quickstart
+- Configuration
+  - Keycloak
+  - Gravitino
+  - Hive
+- Networking Notes
+
+## Architecture Overview
+This diagram illustrates the key docker-compose components and their 
interactions in this setup:
+
+```
+                                  oAuth2 (REST API)
+         +-------------------------------------------------------------------+
+         |                                                                   |
+         |                                                                   v
++--------+----------+               +-------------------+            
+-----------------+
+|                   |  RESTCatalog  |                   |   oauth2   |         
        |
+|     Hive          |   (REST API)  |      Gravitino    | (REST API) |    
Keycloak     |
+|  (HiveServer2)    +-------------->|    Iceberg REST   +----------->|  OAuth2 
Auth    |
+|                   |               |       Server      |            |     
Server      |
++--------+----------+               +---------+---------+            
+-----------------+
+         |                                    |                    
+  data   |          metadata files            |                    
+  files  +------------------------------------+                    
+         |                                                 
+         v                                                 
++-------------------+               +-------------------+     
+|                   |  creates dir  |                   |     
+|     /warehouse    |<--------------+       init        |
+|  (Docker volume)  |     sets      |     container     |
+|                   |  permissions  |                   |
++-------------------+               +-------------------+
+```
+
+- Hive:
+    - Runs HiveServer2, connects to Gravitino via Iceberg REST catalog.
+    - Write Iceberg data files to the shared warehouse volume.
+- Gravitino:
+    - Exposes REST API for Iceberg catalog.
+    - Writes Iceberg metadata files to shared warehouse volume 
(.metadata.json).
+    - Doesn't supports serving as oauth2 provider, so this example uses an 
external OAuth2 provider (Keyclock).
+- Keycloak: 
+  - OAuth2 server providing authentication and token issuance for 
Hive/Gravitino.
+- /warehouse:
+    - Shared Docker volume for Iceberg table data and metadata.
+- Init container:
+    - Creates shared /warehouse folder and sets filesystem permissions as a 
one time initialization step.
+
+## Prerequisites
+- Docker & Docker Compose
+- Java (for local Hive beeline client)
+- ```$HIVE_HOME``` environment variable pointing to Hive installation (for 
connecting to Beeline)
+
+## Quickstart
+
+### STEP 1: Export the Hive version
+```shell
+export HIVE_VERSION=4.2.0
+```
+
+### STEP 2: Start services
+```shell
+docker-compose up -d
+```
+
+### STEP 3: Connect to beeline
+```shell
+"${HIVE_HOME}/bin/beeline" -u "jdbc:hive2://localhost:10001/default" -n hive 
-p hive
+```
+
+### STEP 4: Stop services:
+```shell
+docker-compose down -v
+```
+
+### Configuration
+
+#### Keycloak
+
+- Realm: hive
+- Client: iceberg-client
+  - Secret: iceberg-client-secret
+  - Protocol: OpenID Connect
+  - Audience: hive-iceberg
+- Imported via `realm-export.json` in Keycloak container.
+- Port: 8080
+
+#### Gravitino
+
+- HTTP port: 9001
+- Catalog backend: JDBC H2 (/tmp/gravitino_h2_db)
+- Warehouse: /warehouse (shared with Hive)
+- Iceberg REST Catalog Backend config:
+    ```
+    # Backend type for the catalog. Here we use JDBC (H2 database) as the 
metadata store.
+    gravitino.iceberg-rest.catalog-backend = jdbc
+    
+    # JDBC connection URI for the H2 database storing catalog metadata.
+    gravitino.iceberg-rest.uri = 
jdbc:h2:file:/tmp/gravitino_h2_db;AUTO_SERVER=TRUE
+    
+    # JDBC driver class used to connect to the metadata database.
+    gravitino.iceberg-rest.jdbc-driver = org.h2.Driver
+    
+    # Database username for connecting to the metadata store.
+    gravitino.iceberg-rest.jdbc-user = sa
+    
+    # Database password for connecting to the metadata store (empty here).
+    gravitino.iceberg-rest.jdbc-password = ""
+    
+    # Whether to initialize the catalog schema on startup.
+    gravitino.iceberg-rest.jdbc-initialize = true
+    
+    # --- Warehouse Location (shared folder) ---
+    
+    # Path to the Iceberg warehouse directory shared with Hive.
+    gravitino.iceberg-rest.warehouse = file:///warehouse
+    ```
+- OAuth2 config pointing to Keycloak:
+    ```
+    # Enables OAuth2 as the authentication mechanism for Gravitino.
+    gravitino.authenticators = oauth
+    
+    # URL of the Keycloak realm to request tokens from.
+    gravitino.authenticator.oauth.serverUri = http://keycloak:8080/realms/hive
+    
+    # Path to the OAuth2 token endpoint on Keycloak.
+    gravitino.authenticator.oauth.tokenPath = /protocol/openid-connect/token
+    
+    # OAuth2 scopes requested when obtaining a token. Includes "openid" and 
the custom "catalog" scope.
+    gravitino.authenticator.oauth.scope = openid catalog
+    
+    # OAuth2 client ID registered in Keycloak.
+    gravitino.authenticator.oauth.clientId = iceberg-client
+    
+    # OAuth2 client secret associated with the client ID.
+    gravitino.authenticator.oauth.clientSecret = iceberg-client-secret
+    
+    # Java class used to validate incoming JWT tokens using the JWKS endpoint.
+    gravitino.authenticator.oauth.tokenValidatorClass = 
org.apache.gravitino.server.authentication.JwksTokenValidator
+    
+    # URL to fetch JSON Web Key Set (JWKS) for verifying token signatures.
+    gravitino.authenticator.oauth.jwksUri = 
http://keycloak:8080/realms/hive/protocol/openid-connect/certs
+    
+    # Identifier for the OAuth2 provider configuration in Gravitino.
+    gravitino.authenticator.oauth.provider = default
+    
+    # JWT claim field(s) to extract as the principal/username (here, 'sub' 
claim).
+    gravitino.authenticator.oauth.principalFields = sub
+    
+    # Acceptable clock skew (in seconds) when validating token expiration 
times.
+    gravitino.authenticator.oauth.allowSkewSecs = 60
+    
+    # Expected audience claim in the token to ensure it is intended for this 
service.
+    gravitino.authenticator.oauth.serviceAudience = hive-iceberg
+    ```
+
+#### Hive
+
+- Uses ```HiveRESTCatalogClient``` for connecting to Iceberg REST catalog 
(Gravitino).
+- Catalog configuration in ```hive-site.xml```:
+    ```
+    <property>
+      <name>metastore.catalog.default</name>
+      <value>ice01</value>
+      <description>Sets the default Iceberg catalog for Hive. Here, "ice01" is 
used.</description>
+    </property>
+    
+    <property>
+      <name>metastore.client.impl</name>
+      <value>org.apache.iceberg.hive.client.HiveRESTCatalogClient</value>
+      <description>Specifies the client implementation to use for accessing 
Iceberg via REST.</description>
+    </property>
+    
+    <property>
+      <name>iceberg.catalog.ice01.uri</name>
+      <value>http://gravitino:9001/iceberg</value>
+      <description>URI of the Iceberg REST server (Gravitino). Hive will send 
catalog requests here.</description>
+    </property>
+    
+    <property>
+      <name>iceberg.catalog.ice01.type</name>
+      <value>rest</value>
+      <description>Defines the catalog type as "rest", indicating it uses a 
REST API backend.</description>
+    </property>
+    
+    <!-- Iceberg REST Catalog: OAuth2 authentication -->
+    
+    <property>
+      <name>iceberg.catalog.ice01.rest.auth.type</name>
+      <value>oauth2</value>
+      <description>Configures Hive to use OAuth2 for authenticating requests 
to the REST catalog.</description>
+    </property>
+    
+    <property>
+      <name>iceberg.catalog.ice01.oauth2-server-uri</name>
+      
<value>http://keycloak:8080/realms/hive/protocol/openid-connect/token</value>
+      <description>URL of the Keycloak OAuth2 token endpoint used to request 
access tokens.</description>
+    </property>
+    
+    <property>
+      <name>iceberg.catalog.ice01.credential</name>
+      <value>iceberg-client:iceberg-client-secret</value>
+      <description>Client credentials (ID and secret) used to authenticate 
with Keycloak.</description>
+    </property>
+    ```
+- HiveServer2 port: 10000 (mapped to 10001 in Docker Compose)
+
+## Networking Notes
+
+- All containers share a custom bridge network ```hive-net```.
+- Services communicate via container names: hive, gravitino, keycloak.
+- Ports mapped for host access:
+  - Keycloak → 8080
+  - Gravitino → 9001
+  - HiveServer2 → 10001
+
diff --git a/packaging/src/docker/thirdparties/gravitino/common/init.sh 
b/packaging/src/docker/thirdparties/gravitino/common/init.sh
new file mode 100755
index 00000000000..0f1b24d07c8
--- /dev/null
+++ b/packaging/src/docker/thirdparties/gravitino/common/init.sh
@@ -0,0 +1,30 @@
+#!/bin/sh -x
+
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+apk add --no-cache acl
+
+mkdir -p /tmp/hive/jars
+mkdir -p $WAREHOUSE
+chmod 777 $WAREHOUSE
+
+# Give the hive user id full rwx access to all existing files and directories 
under $WAREHOUSE
+setfacl -R -m u:$HIVE_USER_ID:rwx $WAREHOUSE
+
+# Ensure all new files/directories created inside $WAREHOUSE automatically 
grant rwx access to hive user id
+setfacl -d -m u:$HIVE_USER_ID:rwx $WAREHOUSE
diff --git a/packaging/src/docker/thirdparties/gravitino/docker-compose.yml 
b/packaging/src/docker/thirdparties/gravitino/docker-compose.yml
new file mode 100644
index 00000000000..694934e7a84
--- /dev/null
+++ b/packaging/src/docker/thirdparties/gravitino/docker-compose.yml
@@ -0,0 +1,103 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+version: "3.9"
+
+name: hive-gravitino-rest-catalog-integration
+
+services:
+  keycloak:
+    image: quay.io/keycloak/keycloak:25.0.1
+    container_name: keycloak
+    environment:
+      KEYCLOAK_ADMIN: admin
+      KEYCLOAK_ADMIN_PASSWORD: admin
+    volumes:
+      - 
./keycloak/realm-export.json:/opt/keycloak/data/import/realm-export.json
+    ports:
+      - "8080:8080"
+    networks:
+      - hive-net
+    command: [
+      "start-dev",
+      "--import-realm",
+      "--health-enabled=true"
+    ]
+    healthcheck:
+      test: "exec 3<>/dev/tcp/localhost/9000 && \
+        echo -e 'GET /health/ready HTTP/1.1\\r\\nHost: 
localhost\\r\\nConnection: close\\r\\n\\r\\n' >&3 && \
+        cat <&3 | grep -q '200 OK'"
+      interval: 5s
+      timeout: 2s
+      retries: 15
+
+  gravitino:
+    image: apache/gravitino-iceberg-rest:1.0.0
+    container_name: gravitino
+    environment:
+      JAVA_OPTS: "-Dlog4j2.formatMsgNoLookups=true"
+    volumes:
+      - ./gravitino:/tmp/gravitino
+      - warehouse:/warehouse
+    ports:
+      - "9001:9001"
+    networks:
+      - hive-net
+    entrypoint: /bin/bash /tmp/gravitino/init.sh
+    healthcheck:
+      test: [ "CMD", "/tmp/gravitino/healthcheck.sh" ]
+      interval: 5s
+      timeout: 60s
+      retries: 5
+      start_period: 20s
+
+  hive:
+    image: apache/hive:${HIVE_VERSION}
+    container_name: hive
+    depends_on:
+      keycloak:
+        condition: service_healthy
+      gravitino:
+        condition: service_healthy
+    environment:
+      SERVICE_NAME: hiveserver2
+    volumes:
+      - ./hive/hive-site.xml:/opt/hive/conf/hive-site.xml 
+      - warehouse:/warehouse
+    ports:
+      - "10001:10000"
+    networks:
+      - hive-net
+    entrypoint: '/bin/sh -c "/opt/hive/bin/schematool -dbType derby 
-initOrUpgradeSchema && /entrypoint.sh"'
+    
+  init:
+    image: alpine/curl
+    container_name: init
+    user: "0:0"   # run as root
+    environment:
+      - WAREHOUSE=/warehouse
+      - HIVE_USER_ID=1000
+    volumes:
+      - ./common/:/common
+      - warehouse:/warehouse
+    entrypoint: '/bin/sh -c /common/init.sh'
+
+networks:
+  hive-net:
+    driver: bridge
+
+volumes:
+  warehouse:
diff --git 
a/packaging/src/docker/thirdparties/gravitino/gravitino/gravitino-iceberg-rest-server.conf
 
b/packaging/src/docker/thirdparties/gravitino/gravitino/gravitino-iceberg-rest-server.conf
new file mode 100644
index 00000000000..f0c4bb72f22
--- /dev/null
+++ 
b/packaging/src/docker/thirdparties/gravitino/gravitino/gravitino-iceberg-rest-server.conf
@@ -0,0 +1,50 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# --- HTTP Server ---
+gravitino.iceberg-rest.httpPort = 9001
+
+# --- Iceberg REST Catalog Backend (JDBC/H2) ---
+gravitino.iceberg-rest.catalog-backend = jdbc
+gravitino.iceberg-rest.uri = jdbc:h2:file:/tmp/gravitino_h2_db;AUTO_SERVER=TRUE
+gravitino.iceberg-rest.jdbc-driver = org.h2.Driver
+gravitino.iceberg-rest.jdbc-user = sa
+gravitino.iceberg-rest.jdbc-password = ""
+gravitino.iceberg-rest.jdbc-initialize = true
+
+# --- Warehouse Location (shared folder) ---
+gravitino.iceberg-rest.warehouse = file:///warehouse
+
+# --- OAuth2 Authentication ---
+gravitino.authenticators = oauth
+
+gravitino.authenticator.oauth.serverUri = http://keycloak:8080/realms/hive
+gravitino.authenticator.oauth.tokenPath = /protocol/openid-connect/token
+gravitino.authenticator.oauth.scope = openid catalog
+gravitino.authenticator.oauth.clientId = iceberg-client
+gravitino.authenticator.oauth.clientSecret = iceberg-client-secret
+
+gravitino.authenticator.oauth.tokenValidatorClass = 
org.apache.gravitino.server.authentication.JwksTokenValidator
+gravitino.authenticator.oauth.jwksUri = 
http://keycloak:8080/realms/hive/protocol/openid-connect/certs
+gravitino.authenticator.oauth.provider = default
+gravitino.authenticator.oauth.principalFields = sub
+gravitino.authenticator.oauth.allowSkewSecs = 60
+gravitino.authenticator.oauth.serviceAudience = hive-iceberg
+
+# --- Logging ---
+gravitino.logging.level = INFO
+
diff --git 
a/packaging/src/docker/thirdparties/gravitino/gravitino/healthcheck.sh 
b/packaging/src/docker/thirdparties/gravitino/gravitino/healthcheck.sh
new file mode 100755
index 00000000000..8f6b6cffc35
--- /dev/null
+++ b/packaging/src/docker/thirdparties/gravitino/gravitino/healthcheck.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+set -ex
+
+max_attempts=3
+attempt=0
+success=false
+
+while [ $attempt -lt $max_attempts ]; do
+  response=$(curl -X GET -H "Content-Type: application/json" 
http://gravitino:9001/iceberg/api/version)
+  
+  if echo "$response" | grep -q "HTTP ERROR 401 The provided credentials did 
not support" 
+  then
+    success=true
+    break
+  else
+    echo "Attempt $((attempt + 1)) failed..."
+    sleep 1
+  fi
+
+  ((attempt++))
+done
+
+if [ "$success" = true ]; then
+  exit 0
+else
+  exit 1
+fi
\ No newline at end of file
diff --git a/packaging/src/docker/thirdparties/gravitino/gravitino/init.sh 
b/packaging/src/docker/thirdparties/gravitino/gravitino/init.sh
new file mode 100755
index 00000000000..ecb05e0459e
--- /dev/null
+++ b/packaging/src/docker/thirdparties/gravitino/gravitino/init.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Copy Gravitino start script
+cp /tmp/gravitino/start-iceberg-rest-server.sh 
/root/gravitino-iceberg-rest-server/bin/start-iceberg-rest-server.sh
+
+# Copy Gravitino config file
+cp /tmp/gravitino/gravitino-iceberg-rest-server.conf 
/root/gravitino-iceberg-rest-server/conf/gravitino-iceberg-rest-server.conf
+
+# Download H2 Driver to Gravitino libs folder
+mkdir -p /root/gravitino-iceberg-rest-server/libs
+curl -L -o /root/gravitino-iceberg-rest-server/libs/h2-2.2.220.jar 
https://repo1.maven.org/maven2/com/h2database/h2/2.2.220/h2-2.2.220.jar
+
+/bin/bash /root/gravitino-iceberg-rest-server/bin/start-iceberg-rest-server.sh
\ No newline at end of file
diff --git 
a/packaging/src/docker/thirdparties/gravitino/gravitino/start-iceberg-rest-server.sh
 
b/packaging/src/docker/thirdparties/gravitino/gravitino/start-iceberg-rest-server.sh
new file mode 100755
index 00000000000..9b487a10293
--- /dev/null
+++ 
b/packaging/src/docker/thirdparties/gravitino/gravitino/start-iceberg-rest-server.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+set -ex
+bin_dir="$(dirname "${BASH_SOURCE-$0}")"
+iceberg_rest_server_dir="$(cd "${bin_dir}/../">/dev/null; pwd)"
+
+cd ${iceberg_rest_server_dir}
+
+JAVA_OPTS+=" -XX:-UseContainerSupport"
+export JAVA_OPTS
+
+./bin/gravitino-iceberg-rest-server.sh start
\ No newline at end of file
diff --git a/packaging/src/docker/thirdparties/gravitino/hive/hive-site.xml 
b/packaging/src/docker/thirdparties/gravitino/hive/hive-site.xml
new file mode 100644
index 00000000000..59e07cbe643
--- /dev/null
+++ b/packaging/src/docker/thirdparties/gravitino/hive/hive-site.xml
@@ -0,0 +1,123 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<configuration>
+
+  <property>
+    <name>hive.jar.directory</name>
+    <value>file:/tmp/hive/jars</value>
+  </property>
+
+  <property>
+    <name>hive.user.install.directory</name>
+    <value>file:/tmp/hive/user_install</value>
+  </property>
+
+  <property>
+    <name>tez.local.mode</name>
+    <value>true</value>
+  </property>
+
+  <property>
+    <name>tez.runtime.optimize.local.fetch</name>
+    <value>true</value>
+  </property>
+
+  <property>
+    <name>tez.am.mode.session</name>
+    <value>true</value>
+  </property>
+
+  <property>
+    <name>hive.scheduled.queries.executor.enabled</name>
+    <value>false</value>
+  </property>
+
+  <property>
+    <name>hive.materializedview.rebuild.incremental</name>
+    <value>false</value>
+  </property>
+
+  <property>
+    <name>hive.metastore.transactional.event.listeners</name>
+    <value></value>
+  </property>
+
+  <property>
+    <name>hive.notification.event.poll.interval</name>
+    <value>0</value>
+  </property>
+
+  <property>
+    <name>hive.stats.autogather</name>
+    <value>false</value>
+  </property>
+
+  <property>
+    <name>hive.stats.fetch.column.stats</name>
+    <value>false</value>
+  </property>
+
+  <property>
+    <name>hive.stats.estimate</name>
+    <value>false</value>
+  </property>
+
+
+  <!-- Iceberg REST Catalog: general -->
+
+
+  <property>
+    <name>metastore.catalog.default</name>
+    <value>ice01</value>
+  </property>
+
+  <property>
+    <name>metastore.client.impl</name>
+    <value>org.apache.iceberg.hive.client.HiveRESTCatalogClient</value>
+  </property>
+
+  <property>
+    <name>iceberg.catalog.ice01.uri</name>
+    <value>http://gravitino:9001/iceberg</value>
+  </property>
+
+  <property>
+    <name>iceberg.catalog.ice01.type</name>
+    <value>rest</value>
+  </property>
+
+  <!-- Iceberg REST Catalog: oAuth2 -->
+
+  <property>
+    <name>iceberg.catalog.ice01.rest.auth.type</name>
+    <value>oauth2</value>
+  </property>
+
+  <property>
+    <name>iceberg.catalog.ice01.oauth2-server-uri</name>
+    
<value>http://keycloak:8080/realms/hive/protocol/openid-connect/token</value>
+  </property>
+
+  <property>
+    <name>iceberg.catalog.ice01.credential</name>
+    <value>iceberg-client:iceberg-client-secret</value>
+  </property>
+
+</configuration>
diff --git 
a/packaging/src/docker/thirdparties/gravitino/keycloak/realm-export.json 
b/packaging/src/docker/thirdparties/gravitino/keycloak/realm-export.json
new file mode 100644
index 00000000000..26c34b52e21
--- /dev/null
+++ b/packaging/src/docker/thirdparties/gravitino/keycloak/realm-export.json
@@ -0,0 +1,43 @@
+{
+  "realm": "hive",
+  "enabled": true,
+  "clients": [
+    {
+      "clientId": "iceberg-client",
+      "secret": "iceberg-client-secret",
+      "enabled": true,
+      "redirectUris": ["*"],
+      "serviceAccountsEnabled": true,
+      "protocol": "openid-connect",
+      "publicClient": false,
+      "directAccessGrantsEnabled": false,
+      "standardFlowEnabled": false,
+      "defaultClientScopes": ["catalog"],
+      "optionalClientScopes": [],
+      "protocolMappers": [
+        {
+          "name": "audience",
+          "protocol": "openid-connect",
+          "protocolMapper": "oidc-audience-mapper",
+          "consentRequired": false,
+          "config": {
+            "included.client.audience": "hive-iceberg",
+            "id.token.claim": "false",
+            "access.token.claim": "true"
+          }
+        }
+      ],
+      "attributes": {
+        "access.token.lifespan": "3600"
+      }
+    }
+  ],
+  "clientScopes": [
+    {
+      "name": "catalog",
+      "protocol": "openid-connect",
+      "attributes": {},
+      "protocolMappers": []
+    }
+  ]
+}
diff --git a/packaging/src/docker/thirdparties/polaris/README.md 
b/packaging/src/docker/thirdparties/polaris/README.md
new file mode 100644
index 00000000000..f3305ac1990
--- /dev/null
+++ b/packaging/src/docker/thirdparties/polaris/README.md
@@ -0,0 +1,184 @@
+<!--
+{% comment %}
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to you under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+{% endcomment %}
+-->
+
+# Hive + Polaris: Docker-Compose Setup
+
+This package contains a docker-compose-based setup integrating Apache Hive and 
Polaris. 
+It allows Hive to use an Iceberg REST catalog secured with oauth2 provided by 
Polaris.
+
+## Table of Contents
+- Architecture Overview
+- Prerequisites
+- Quickstart
+- Configuration
+  - Polaris
+  - Hive
+- Networking Notes
+
+## Architecture Overview
+This diagram illustrates the key docker-compose components and their 
interactions in this setup:
+```
++-------------------+               +-------------------+
+|                   |  RESTCatalog  |                   |
+|     Hive          |   (REST API)  |      Polaris      |<-------+
+|  (HiveServer2)    +-------------->|      Server       |        |
+|                   |    oAuth2     |                   |        |  
++--------+----------+  (REST API)   +---------+---------+        | creates:
+         |                                    |                  |     catalog,
+  data   |           metadata files           |                  |     
principal,
+  files  +------------------------------------+                  |     roles,
+         |                                                       |     grants 
(REST API)
+         v                                                       |
++-------------------+               +-------------------+        |
+|                   |  creates dir  |                   |        |
+|     /warehouse    |<--------------+    Polaris-init   +--------+
+|  (Docker volume)  |     syncs     |      container    |
+|                   |  permissions  |                   |
++-------------------+               +-------------------+
+```
+
+- Hive: 
+  - Runs HiveServer2, connects to Polaris via Iceberg REST catalog. 
+  - Write Iceberg data files to shared warehouse volume.
+- Polaris: 
+  - Exposes REST API for Iceberg catalog and provides oauth2 for 
authentication. 
+  - Supports serving as oauth2 provider, so this example doesn't need an 
external OAuth2 component.
+  - Writes Iceberg metadata files to shared warehouse volume (.metadata.json).
+- /warehouse: 
+  - Shared Docker volume for Iceberg table data and metadata.
+- Polaris-init
+  - Bootstraps Polaris for Hive-Iceberg.
+  - Creates and configures Polaris resources via REST API.
+  - Continuously synchronizes filesystem permissions for the shared 
/warehouse/* folders.
+    - required because Polaris and Hive run as different users in their 
respective containers.
+
+## Prerequisites
+- Docker & Docker Compose
+- Java (for local Hive beeline client)
+- ```$HIVE_HOME``` environment variable pointing to Hive installation (for 
connecting to Beeline)
+
+## Quickstart
+
+### STEP 1: Export the Hive version
+```shell
+export HIVE_VERSION=4.2.0-SNAPSHOT
+```
+
+### STEP 2: Start services
+```shell
+docker-compose up -d
+```
+
+### STEP 3: Connect to beeline
+```shell
+"${HIVE_HOME}/bin/beeline" -u "jdbc:hive2://localhost:10001/default" -n hive 
-p hive
+```
+
+### STEP 4: Stop services:
+```shell
+docker-compose down -v
+```
+
+## Configuration
+
+### Polaris
+
+- HTTP port: 8181
+- Warehouse: /warehouse (shared with Hive)
+- Key Polaris configs (defined via env variables in docker-compose.yml) :
+     ```
+      # A realm provides logical isolation for different Polaris environments.
+      polaris.realm-context.realms: POLARIS
+  
+      # Initial bootstrap credentials for the Polaris server.
+      # The format is: <realm-name>,<client-id>,<client-secret>
+      POLARIS_BOOTSTRAP_CREDENTIALS: 
POLARIS,iceberg-client,iceberg-client-secret`
+    ```
+
+### Hive
+
+- Uses ```HiveRESTCatalogClient``` for connecting to Iceberg REST catalog 
(Polaris).
+- Catalog configuration in ```hive-site.xml```:
+    ```
+    <property>
+      <name>metastore.catalog.default</name>
+      <value>ice01</value>
+      <description>Sets the default Iceberg catalog for Hive. Here, "ice01" is 
used.</description>
+    </property>
+    
+    <property>
+      <name>metastore.client.impl</name>
+      <value>org.apache.iceberg.hive.client.HiveRESTCatalogClient</value>
+      <description>Specifies the client implementation to use for accessing 
Iceberg via REST.</description>
+    </property>
+    
+    <property>
+      <name>iceberg.catalog.ice01.uri</name>
+      <value>http://polaris:8181/api/catalog</value>
+      <description>URI of the Iceberg REST server (Polaris). Hive will send 
catalog requests here.</description>
+    </property>
+    
+    <property>
+      <name>iceberg.catalog.ice01.type</name>
+      <value>rest</value>
+      <description>Defines the catalog type as "rest", indicating it uses a 
REST API backend.</description>
+    </property>
+  
+    <property>
+      <name>hive.metastore.warehouse.dir</name>
+      <value>file:///warehouse</value>
+      <description>Defines the warehouse location, required for 
Polaris</description>
+    </property>
+    
+    <!-- Iceberg REST Catalog: OAuth2 authentication -->
+    
+    <property>
+      <name>iceberg.catalog.ice01.rest.auth.type</name>
+      <value>oauth2</value>
+      <description>Configures Hive to use OAuth2 for authenticating requests 
to the REST catalog.</description>
+    </property>
+    
+    <property>
+      <name>iceberg.catalog.ice01.oauth2-server-uri</name>
+      <value>http://polaris:8181/api/catalog/v1/oauth/tokens</value>
+      <description>URL of the Polaris OAuth2 token endpoint used to request 
access tokens.</description>
+    </property>
+    
+    <property>
+      <name>iceberg.catalog.ice01.credential</name>
+      <value>iceberg-client:iceberg-client-secret</value>
+      <description>Client credentials (ID and secret) used to authenticate 
with Keycloak.</description>
+    </property>
+  
+    <property>
+      <name>iceberg.catalog.ice01.scope</name>
+      <value>PRINCIPAL_ROLE:ALL</value>
+      <description>oAuth2 scope tied to the principal role defined in 
Polaris</description>
+    </property>
+    ```
+- HiveServer2 port: 10000 (mapped to 10001 in Docker Compose)
+
+## Networking Notes
+
+- All containers share a custom bridge network ```hive-net```.
+- Services communicate via container names: hive and polaris
+- Ports mapped for host access:
+  - Polaris → 8181
+  - HiveServer2 → 10001
+
diff --git a/packaging/src/docker/thirdparties/polaris/docker-compose.yml 
b/packaging/src/docker/thirdparties/polaris/docker-compose.yml
new file mode 100644
index 00000000000..f6979e57f67
--- /dev/null
+++ b/packaging/src/docker/thirdparties/polaris/docker-compose.yml
@@ -0,0 +1,94 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+version: "3.9"
+
+name: hive-polaris-rest-catalog-integration
+
+services:
+
+  polaris:
+    image: apache/polaris:latest
+    container_name: polaris
+    ports:
+      # API port
+      - "8181:8181"
+      # Management port (metrics and health checks)
+      - "8182:8182"
+    environment:
+      polaris.realm-context.realms: POLARIS
+      quarkus.otel.sdk.disabled: "true"
+      POLARIS_BOOTSTRAP_CREDENTIALS: 
POLARIS,iceberg-client,iceberg-client-secret
+      polaris.features."ALLOW_INSECURE_STORAGE_TYPES": "true"
+      polaris.features."SUPPORTED_CATALOG_STORAGE_TYPES": "[\"FILE\"]"
+      polaris.readiness.ignore-severe-issues: "true"
+    healthcheck:
+      test: ["CMD", "curl", "http://localhost:8182/q/health";]
+      interval: 2s
+      timeout: 10s
+      retries: 10
+      start_period: 10s
+    volumes:
+      - warehouse:/warehouse
+    networks:
+      - hive-net
+
+  polaris-init:
+    image: alpine/curl
+    container_name: polaris-init
+    user: "0:0"   # run as root
+    depends_on:
+      polaris:
+        condition: service_healthy
+    environment:
+      - CLIENT_ID=iceberg-client
+      - CLIENT_SECRET=iceberg-client-secret
+      - WAREHOUSE=/warehouse
+      - REALM=POLARIS
+      - POLARIS_USER_ID=10000
+      - HIVE_USER_ID=1000
+    volumes:
+      - ./polaris/:/polaris
+      - warehouse:/warehouse
+    entrypoint: '/bin/sh -c "chmod +x /polaris/init.sh && /polaris/init.sh"'
+    networks:
+      - hive-net
+
+  hive:
+    image: apache/hive:${HIVE_VERSION}
+    container_name: hive
+    depends_on:
+      polaris:
+          condition: service_healthy
+    environment:
+      SERVICE_NAME: hiveserver2
+    volumes:
+      - ./hive/hive-site.xml:/opt/hive/conf/hive-site.xml
+      - warehouse:/warehouse
+    ports:
+      - "10001:10000"
+    networks:
+      - hive-net
+    entrypoint: '/bin/sh -c "mkdir -p /tmp/hive/jars && \
+      /opt/hive/bin/schematool -dbType derby -initOrUpgradeSchema && sh 
/entrypoint.sh"'
+
+networks:
+  hive-net:
+    driver: bridge
+
+volumes:
+  warehouse:
+  realm-data:
diff --git a/packaging/src/docker/thirdparties/polaris/hive/hive-site.xml 
b/packaging/src/docker/thirdparties/polaris/hive/hive-site.xml
new file mode 100644
index 00000000000..df952937757
--- /dev/null
+++ b/packaging/src/docker/thirdparties/polaris/hive/hive-site.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<configuration>
+
+  <property>
+    <name>hive.jar.directory</name>
+    <value>file:/tmp/hive/jars</value>
+  </property>
+
+  <property>
+    <name>hive.user.install.directory</name>
+    <value>file:/tmp/hive/user_install</value>
+  </property>
+
+  <property>
+    <name>tez.local.mode</name>
+    <value>true</value>
+  </property>
+
+  <property>
+    <name>tez.runtime.optimize.local.fetch</name>
+    <value>true</value>
+  </property>
+
+  <property>
+    <name>tez.am.mode.session</name>
+    <value>true</value>
+  </property>
+
+  <property>
+    <name>hive.scheduled.queries.executor.enabled</name>
+    <value>false</value>
+  </property>
+
+  <property>
+    <name>hive.materializedview.rebuild.incremental</name>
+    <value>false</value>
+  </property>
+
+  <property>
+    <name>hive.metastore.transactional.event.listeners</name>
+    <value></value>
+  </property>
+
+  <property>
+    <name>hive.notification.event.poll.interval</name>
+    <value>0</value>
+  </property>
+
+  <property>
+    <name>hive.stats.autogather</name>
+    <value>false</value>
+  </property>
+
+  <property>
+    <name>hive.stats.fetch.column.stats</name>
+    <value>false</value>
+  </property>
+
+  <property>
+    <name>hive.stats.estimate</name>
+    <value>false</value>
+  </property>
+
+
+  <!-- Iceberg REST Catalog: general -->
+
+
+  <property>
+    <name>metastore.catalog.default</name>
+    <value>ice01</value>
+  </property>
+
+  <property>
+    <name>metastore.client.impl</name>
+    <value>org.apache.iceberg.hive.client.HiveRESTCatalogClient</value>
+  </property>
+
+  <property>
+    <name>iceberg.catalog.ice01.uri</name>
+    <value>http://polaris:8181/api/catalog</value>
+  </property>
+
+  <property>
+    <name>iceberg.catalog.ice01.type</name>
+    <value>rest</value>
+  </property>
+
+  <property>
+    <name>iceberg.catalog.ice01.warehouse</name>
+    <value>ice01</value>
+  </property>
+
+  <property>
+    <name>hive.metastore.warehouse.dir</name>
+    <value>file:///warehouse</value>
+  </property>
+
+  <!-- Iceberg REST Catalog: oAuth2 -->
+
+  <property>
+    <name>iceberg.catalog.ice01.rest.auth.type</name>
+    <value>oauth2</value>
+  </property>
+
+  <property>
+    <name>iceberg.catalog.ice01.oauth2-server-uri</name>
+    <value>http://polaris:8181/api/catalog/v1/oauth/tokens</value>
+  </property>  
+
+  <property>
+    <name>iceberg.catalog.ice01.credential</name>
+    <value>iceberg-client:iceberg-client-secret</value>
+  </property>
+
+  <property>
+    <name>iceberg.catalog.ice01.scope</name>
+    <value>PRINCIPAL_ROLE:ALL</value>
+  </property>
+
+</configuration>
diff --git a/packaging/src/docker/thirdparties/polaris/polaris/init.sh 
b/packaging/src/docker/thirdparties/polaris/polaris/init.sh
new file mode 100755
index 00000000000..72201f278c9
--- /dev/null
+++ b/packaging/src/docker/thirdparties/polaris/polaris/init.sh
@@ -0,0 +1,184 @@
+#!/bin/sh -x
+
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+set -e
+
+apk add --no-cache jq
+apk add --no-cache acl
+
+#--------------------------------------------------------------------------------
+# OBTAIN TOKEN
+#--------------------------------------------------------------------------------
+
+source /polaris/obtain-token.sh
+
+echo
+echo "Obtained access token: ${TOKEN}"
+
+#--------------------------------------------------------------------------------
+# CREATE CATALOG
+#--------------------------------------------------------------------------------
+
+echo
+echo Creating a catalog named ice01 in realm $REALM...
+
+STORAGE_TYPE="FILE"
+STORAGE_LOCATION="file://${WAREHOUSE}"
+STORAGE_CONFIG_INFO="{\"storageType\": \"$STORAGE_TYPE\", 
\"allowedLocations\": [\"$STORAGE_LOCATION\"]}"
+
+PAYLOAD='{
+   "catalog": {
+     "name": "ice01",
+     "type": "INTERNAL",
+     "readOnly": false,
+     "properties": {
+       "default-base-location": "'$STORAGE_LOCATION'"
+     },
+     "storageConfigInfo": '$STORAGE_CONFIG_INFO'
+   }
+ }'
+
+echo $PAYLOAD
+
+curl -s -H "Authorization: Bearer ${TOKEN}" \
+   -H 'Accept: application/json' \
+   -H 'Content-Type: application/json' \
+   -H "Polaris-Realm: $REALM" \
+   http://polaris:8181/api/management/v1/catalogs \
+   -d "$PAYLOAD" -v
+   
+#--------------------------------------------------------------------------------
+# CREATE PRINCIPAL
+#--------------------------------------------------------------------------------
+
+echo
+echo Creating a principal named 'ice01_principal' in realm $REALM...
+
+PAYLOAD='{
+    "principal": {
+      "name": "ice01_principal"
+    },
+    "credentialRotationRequired": false
+ }'
+
+echo $PAYLOAD
+
+curl -s -H "Authorization: Bearer ${TOKEN}" \
+   -H 'Accept: application/json' \
+   -H 'Content-Type: application/json' \
+   -H "Polaris-Realm: $REALM" \
+   http://polaris:8181/api/management/v1/principals \
+   -d "$PAYLOAD" -v
+
+#--------------------------------------------------------------------------------
+# CREATE PRINCIPAL ROLE
+#--------------------------------------------------------------------------------
+
+PAYLOAD='{
+    "principalRole": {
+      "name": "ice01_principal_role"
+    }
+ }'
+ 
+echo $PAYLOAD
+
+curl -s -H "Authorization: Bearer ${TOKEN}" \
+   -H 'Accept: application/json' \
+   -H 'Content-Type: application/json' \
+   -H "Polaris-Realm: $REALM" \
+   http://polaris:8181/api/management/v1/principal-roles \
+   -d "$PAYLOAD" -v
+   
+#--------------------------------------------------------------------------------
+# CATALOG ROLE
+#--------------------------------------------------------------------------------
+
+PAYLOAD='{
+  "catalogRole": {
+    "name": "ice01_catalog_role"
+  }
+}'
+
+echo $PAYLOAD
+
+curl -s -H "Authorization: Bearer ${TOKEN}" \
+   -H 'Accept: application/json' \
+   -H 'Content-Type: application/json' \
+   -H "Polaris-Realm: $REALM" \
+   http://polaris:8181/api/management/v1/catalogs/ice01/catalog-roles \
+   -d "$PAYLOAD" -v
+
+#--------------------------------------------------------------------------------
+# GRANT THE PRINCIPAL THE PRINCIPAL ROLE
+#--------------------------------------------------------------------------------
+   
+PAYLOAD='{
+  "principalRole": {
+    "name": "ice01_principal_role"
+  }
+}'
+
+echo $PAYLOAD
+
+curl -s -X PUT -H "Authorization: Bearer ${TOKEN}" \
+   -H 'Accept: application/json' \
+   -H 'Content-Type: application/json' \
+   -H "Polaris-Realm: $REALM" \
+   
http://polaris:8181/api/management/v1/principals/ice01_principal/principal-roles
 \
+   -d "$PAYLOAD" -v
+   
+#--------------------------------------------------------------------------------
+# GRANT THE CATALOG ROLE TO THE PRINCIPAL ROLE
+#--------------------------------------------------------------------------------
+
+PAYLOAD='{
+  "type": "catalog", 
+  "privilege": "CATALOG_MANAGE_CONTENT"
+}'
+
+echo $PAYLOAD
+
+curl -s -X PUT -H "Authorization: Bearer ${TOKEN}" \
+   -H 'Accept: application/json' \
+   -H 'Content-Type: application/json' \
+   -H "Polaris-Realm: $REALM" \
+   
http://polaris:8181/api/management/v1/catalogs/ice01/catalog-roles/ice01_catalog_role/grants
 \
+   -d "$PAYLOAD" -v
+
+#--------------------------------------------------------------------------------
+# Create warehouse directory and set permissions
+#--------------------------------------------------------------------------------
+
+mkdir -p ${WAREHOUSE}
+chmod 777 ${WAREHOUSE}
+
+#--------------------------------------------------------------------------------
+# Start ACL sync on the warehouse folder for hive and polaris users
+#--------------------------------------------------------------------------------
+
+while true
+do
+  # Existing files ACLs
+  setfacl -R -m u:$HIVE_USER_ID:rwx,u:$POLARIS_USER_ID:rwx ${WAREHOUSE}
+
+  # Default ACLs for new files
+  setfacl -R -d -m u:$HIVE_USER_ID:rwx,u:$POLARIS_USER_ID:rwx ${WAREHOUSE}
+done
diff --git a/packaging/src/docker/thirdparties/polaris/polaris/obtain-token.sh 
b/packaging/src/docker/thirdparties/polaris/polaris/obtain-token.sh
new file mode 100755
index 00000000000..aba4faf4e07
--- /dev/null
+++ b/packaging/src/docker/thirdparties/polaris/polaris/obtain-token.sh
@@ -0,0 +1,37 @@
+#!/bin/sh -x
+
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+set -e
+
+apk add --no-cache jq
+
+TOKEN=$(curl -s http://polaris:8181/api/catalog/v1/oauth/tokens \
+  --user ${CLIENT_ID}:${CLIENT_SECRET} \
+  -H "Polaris-Realm: $REALM" \
+  -d grant_type=client_credentials \
+  -d scope=PRINCIPAL_ROLE:ALL | jq -r .access_token)
+
+if [ -z "${TOKEN}" ]; then
+  echo "Failed to obtain access token."
+  exit 1
+fi
+
+export TOKEN

Reply via email to