From dc2718be8606f74c62a8bf3236712231d6d8451b Mon Sep 17 00:00:00 2001 From: Kevin Liu Date: Mon, 8 Jun 2026 14:20:58 -0700 Subject: [PATCH 1/8] Open-API: Drop bundled runtime jar; build REST fixture Docker image from staged classpath Replaces the iceberg-open-api shadowJar with a Sync task that lays out the REST catalog test-fixtures runtime as a directory of jars plus LICENSE/NOTICE under build/iceberg-rest-server/. The iceberg-rest-fixture Docker image copies that directory and launches the server via java -cp ".../libs/*" org.apache.iceberg.rest.RESTCatalogServer. The publish-iceberg-rest-fixture-docker and cve-scan workflows are updated to run the new installRESTServer task; the open-api CVE scan entry now scans every dependency jar individually. --- .github/workflows/cve-scan.yml | 7 +++++-- .../publish-iceberg-rest-fixture-docker.yml | 4 ++-- build.gradle | 21 +++++++------------ docker/iceberg-rest-fixture/Dockerfile | 4 ++-- docker/iceberg-rest-fixture/README.md | 2 +- docker/iceberg-rest-fixture/entrypoint.sh | 2 +- 6 files changed, 18 insertions(+), 22 deletions(-) diff --git a/.github/workflows/cve-scan.yml b/.github/workflows/cve-scan.yml index 043d2378bd43..18b7b1cee666 100644 --- a/.github/workflows/cve-scan.yml +++ b/.github/workflows/cve-scan.yml @@ -166,9 +166,10 @@ jobs: scan-path: flink/v2.1/flink-runtime/build/libs unpack: false - distribution: open-api-test-fixtures-runtime - build-task: :iceberg-open-api:shadowJar - scan-path: open-api/build/libs + build-task: :iceberg-open-api:installRESTServer + scan-path: open-api/build/iceberg-rest-server/libs unpack: false + copy-all: true name: ${{ matrix.distribution }} steps: - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 @@ -192,6 +193,8 @@ jobs: mkdir -p /tmp/cve-scan if [ "${{ matrix.unpack }}" = "true" ]; then unzip ${{ matrix.scan-path }}/*.zip -d /tmp/cve-scan + elif [ "${{ matrix.copy-all }}" = "true" ]; then + cp ${{ matrix.scan-path }}/*.jar /tmp/cve-scan/ else cp ${{ matrix.scan-path }}/iceberg-${{ matrix.distribution }}-*.jar /tmp/cve-scan/ fi diff --git a/.github/workflows/publish-iceberg-rest-fixture-docker.yml b/.github/workflows/publish-iceberg-rest-fixture-docker.yml index 71e6c68b07e5..ed2aa8a1624b 100644 --- a/.github/workflows/publish-iceberg-rest-fixture-docker.yml +++ b/.github/workflows/publish-iceberg-rest-fixture-docker.yml @@ -52,8 +52,8 @@ jobs: with: # Read-only: small job; restore opportunistically from other jobs' caches but never write. cache-read-only: true - - name: Build Iceberg Open API project - run: ./gradlew :iceberg-open-api:shadowJar + - name: Stage REST fixture image classpath + run: ./gradlew :iceberg-open-api:installRESTServer - name: Login to Docker Hub env: DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }} diff --git a/build.gradle b/build.gradle index 01e282ecf9dd..5fa7bd2f40e6 100644 --- a/build.gradle +++ b/build.gradle @@ -1077,9 +1077,6 @@ project(':iceberg-snowflake') { project(':iceberg-open-api') { apply plugin: 'java-test-fixtures' - apply plugin: 'com.gradleup.shadow' - - build.dependsOn shadowJar dependencies { testImplementation project(':iceberg-api') @@ -1164,23 +1161,19 @@ project(':iceberg-open-api') { } check.dependsOn('validateRESTCatalogSpec') - shadowJar { - archiveBaseName.set("iceberg-open-api-test-fixtures-runtime") - archiveClassifier.set(null) - configurations = [project.configurations.testFixturesRuntimeClasspath] - from sourceSets.testFixtures.output - zip64 true - - // include the LICENSE and NOTICE files for the runtime Jar + // REST server runtime as a dir of jars; consumed by docker/iceberg-rest-fixture. + tasks.register('installRESTServer', Sync) { + into layout.buildDirectory.dir('iceberg-rest-server') from(projectDir) { include 'LICENSE' include 'NOTICE' } - - manifest { - attributes 'Main-Class': 'org.apache.iceberg.rest.RESTCatalogServer' + into('libs') { + from configurations.testFixturesRuntimeClasspath + from tasks.testFixturesJar } } + build.dependsOn 'installRESTServer' jar { enabled = false diff --git a/docker/iceberg-rest-fixture/Dockerfile b/docker/iceberg-rest-fixture/Dockerfile index 1f3fc881a1b2..ecbe349f0555 100644 --- a/docker/iceberg-rest-fixture/Dockerfile +++ b/docker/iceberg-rest-fixture/Dockerfile @@ -30,8 +30,8 @@ RUN set -xeu && \ # Working directory for the application WORKDIR /usr/lib/iceberg-rest -# Copy runtime files directly to the target location -COPY --chown=iceberg:iceberg open-api/build/libs/iceberg-open-api-test-fixtures-runtime-*.jar /usr/lib/iceberg-rest/iceberg-rest-adapter.jar +# Copy REST server libs and LICENSE/NOTICE +COPY --chown=iceberg:iceberg open-api/build/iceberg-rest-server/ /usr/lib/iceberg-rest/ COPY --chown=iceberg:iceberg docker/iceberg-rest-fixture/entrypoint.sh /usr/lib/iceberg-rest/entrypoint.sh ENV CATALOG_CATALOG__IMPL=org.apache.iceberg.jdbc.JdbcCatalog diff --git a/docker/iceberg-rest-fixture/README.md b/docker/iceberg-rest-fixture/README.md index 928c37fe38dd..bb6ece4aa683 100644 --- a/docker/iceberg-rest-fixture/README.md +++ b/docker/iceberg-rest-fixture/README.md @@ -86,7 +86,7 @@ When making changes to the local files and test them out, you can build the imag ```bash # Build the project from iceberg root directory -./gradlew :iceberg-open-api:shadowJar +./gradlew :iceberg-open-api:installRESTServer # Rebuild the docker image docker image rm -f apache/iceberg-rest-fixture && docker build -t apache/iceberg-rest-fixture -f docker/iceberg-rest-fixture/Dockerfile . diff --git a/docker/iceberg-rest-fixture/entrypoint.sh b/docker/iceberg-rest-fixture/entrypoint.sh index 052bd7b7229b..fb53f60cbd21 100644 --- a/docker/iceberg-rest-fixture/entrypoint.sh +++ b/docker/iceberg-rest-fixture/entrypoint.sh @@ -20,7 +20,7 @@ set -eu -CLASSPATH="iceberg-rest-adapter.jar" +CLASSPATH="libs/*" if [ -n "${LOG_CONFIG_DIR:-}" ]; then CLASSPATH="${LOG_CONFIG_DIR}:${CLASSPATH}" From f26270dd381033fa898f50e92e251330deb08945 Mon Sep 17 00:00:00 2001 From: Kevin Liu Date: Wed, 17 Jun 2026 12:18:12 -0700 Subject: [PATCH 2/8] Open-API: Keep REST fixture staging explicit --- build.gradle | 1 - deploy.gradle | 6 +++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 5fa7bd2f40e6..5689196f2f53 100644 --- a/build.gradle +++ b/build.gradle @@ -1173,7 +1173,6 @@ project(':iceberg-open-api') { from tasks.testFixturesJar } } - build.dependsOn 'installRESTServer' jar { enabled = false diff --git a/deploy.gradle b/deploy.gradle index 65836bf1b3f1..d78688dfb438 100644 --- a/deploy.gradle +++ b/deploy.gradle @@ -55,7 +55,11 @@ subprojects { } // add LICENSE and NOTICE - [jar, sourceJar, javadocJar, testJar].each { task -> + def archiveTasks = [jar, sourceJar, javadocJar, testJar] + if (isOpenApi) { + archiveTasks.add(testFixturesJar) + } + archiveTasks.each { task -> task.dependsOn rootProject.tasks.buildInfo task.from("${rootDir}/build") { include 'iceberg-build.properties' From e154da426ecf850dd62904740c62faee2307b539 Mon Sep 17 00:00:00 2001 From: Kevin Liu Date: Wed, 17 Jun 2026 12:24:31 -0700 Subject: [PATCH 3/8] Open-API: Rename REST fixture runtime staging task --- .github/workflows/cve-scan.yml | 2 +- .github/workflows/publish-iceberg-rest-fixture-docker.yml | 2 +- build.gradle | 2 +- docker/iceberg-rest-fixture/README.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/cve-scan.yml b/.github/workflows/cve-scan.yml index 18b7b1cee666..ee0c41308df6 100644 --- a/.github/workflows/cve-scan.yml +++ b/.github/workflows/cve-scan.yml @@ -166,7 +166,7 @@ jobs: scan-path: flink/v2.1/flink-runtime/build/libs unpack: false - distribution: open-api-test-fixtures-runtime - build-task: :iceberg-open-api:installRESTServer + build-task: :iceberg-open-api:stageRESTFixtureRuntime scan-path: open-api/build/iceberg-rest-server/libs unpack: false copy-all: true diff --git a/.github/workflows/publish-iceberg-rest-fixture-docker.yml b/.github/workflows/publish-iceberg-rest-fixture-docker.yml index ed2aa8a1624b..3622f14870b5 100644 --- a/.github/workflows/publish-iceberg-rest-fixture-docker.yml +++ b/.github/workflows/publish-iceberg-rest-fixture-docker.yml @@ -53,7 +53,7 @@ jobs: # Read-only: small job; restore opportunistically from other jobs' caches but never write. cache-read-only: true - name: Stage REST fixture image classpath - run: ./gradlew :iceberg-open-api:installRESTServer + run: ./gradlew :iceberg-open-api:stageRESTFixtureRuntime - name: Login to Docker Hub env: DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }} diff --git a/build.gradle b/build.gradle index 5689196f2f53..ec038929f4f1 100644 --- a/build.gradle +++ b/build.gradle @@ -1162,7 +1162,7 @@ project(':iceberg-open-api') { check.dependsOn('validateRESTCatalogSpec') // REST server runtime as a dir of jars; consumed by docker/iceberg-rest-fixture. - tasks.register('installRESTServer', Sync) { + tasks.register('stageRESTFixtureRuntime', Sync) { into layout.buildDirectory.dir('iceberg-rest-server') from(projectDir) { include 'LICENSE' diff --git a/docker/iceberg-rest-fixture/README.md b/docker/iceberg-rest-fixture/README.md index bb6ece4aa683..5e8734facfe3 100644 --- a/docker/iceberg-rest-fixture/README.md +++ b/docker/iceberg-rest-fixture/README.md @@ -86,7 +86,7 @@ When making changes to the local files and test them out, you can build the imag ```bash # Build the project from iceberg root directory -./gradlew :iceberg-open-api:installRESTServer +./gradlew :iceberg-open-api:stageRESTFixtureRuntime # Rebuild the docker image docker image rm -f apache/iceberg-rest-fixture && docker build -t apache/iceberg-rest-fixture -f docker/iceberg-rest-fixture/Dockerfile . From 1cd4a96ce3d2df4913ed918a89eca687d0ea1d04 Mon Sep 17 00:00:00 2001 From: Kevin Liu Date: Wed, 17 Jun 2026 15:01:06 -0700 Subject: [PATCH 4/8] Open-API: Clarify test fixtures archive metadata --- deploy.gradle | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/deploy.gradle b/deploy.gradle index d78688dfb438..2a72a7f601e1 100644 --- a/deploy.gradle +++ b/deploy.gradle @@ -54,12 +54,8 @@ subprojects { testArtifacts testJar } - // add LICENSE and NOTICE - def archiveTasks = [jar, sourceJar, javadocJar, testJar] - if (isOpenApi) { - archiveTasks.add(testFixturesJar) - } - archiveTasks.each { task -> + // add build info, LICENSE, and NOTICE + def addBuildInfoAndLicense = { task -> task.dependsOn rootProject.tasks.buildInfo task.from("${rootDir}/build") { include 'iceberg-build.properties' @@ -69,6 +65,11 @@ subprojects { include 'NOTICE' } } + [jar, sourceJar, javadocJar, testJar].each(addBuildInfoAndLicense) + if (isOpenApi) { + // OpenAPI also publishes testFixturesJar for REST fixture consumers. + addBuildInfoAndLicense(testFixturesJar) + } } publishing { From afbb84a5e5c6e2aa8f62eb0f7528bc7d478e2da5 Mon Sep 17 00:00:00 2001 From: Kevin Liu Date: Sat, 27 Jun 2026 13:40:17 -0700 Subject: [PATCH 5/8] Docker: Clarify REST fixture runtime paths --- docker/iceberg-rest-fixture/Dockerfile | 7 ++++--- docker/iceberg-rest-fixture/entrypoint.sh | 5 +++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/docker/iceberg-rest-fixture/Dockerfile b/docker/iceberg-rest-fixture/Dockerfile index ecbe349f0555..eb83ec670fc6 100644 --- a/docker/iceberg-rest-fixture/Dockerfile +++ b/docker/iceberg-rest-fixture/Dockerfile @@ -28,11 +28,12 @@ RUN set -xeu && \ rm -rf /var/lib/apt/lists/* # Working directory for the application -WORKDIR /usr/lib/iceberg-rest +ENV REST_SERVER_HOME=/usr/lib/iceberg-rest +WORKDIR $REST_SERVER_HOME # Copy REST server libs and LICENSE/NOTICE -COPY --chown=iceberg:iceberg open-api/build/iceberg-rest-server/ /usr/lib/iceberg-rest/ -COPY --chown=iceberg:iceberg docker/iceberg-rest-fixture/entrypoint.sh /usr/lib/iceberg-rest/entrypoint.sh +COPY --chown=iceberg:iceberg open-api/build/iceberg-rest-server/ ./ +COPY --chown=iceberg:iceberg docker/iceberg-rest-fixture/entrypoint.sh ./entrypoint.sh ENV CATALOG_CATALOG__IMPL=org.apache.iceberg.jdbc.JdbcCatalog ENV CATALOG_URI=jdbc:sqlite:/tmp/iceberg_catalog.db diff --git a/docker/iceberg-rest-fixture/entrypoint.sh b/docker/iceberg-rest-fixture/entrypoint.sh index fb53f60cbd21..dc4298d9b429 100644 --- a/docker/iceberg-rest-fixture/entrypoint.sh +++ b/docker/iceberg-rest-fixture/entrypoint.sh @@ -20,7 +20,8 @@ set -eu -CLASSPATH="libs/*" +REST_SERVER_MAIN="org.apache.iceberg.rest.RESTCatalogServer" +CLASSPATH="${REST_SERVER_HOME}/libs/*" if [ -n "${LOG_CONFIG_DIR:-}" ]; then CLASSPATH="${LOG_CONFIG_DIR}:${CLASSPATH}" @@ -32,4 +33,4 @@ if [ -n "${LOG_LEVEL:-}" ]; then set -- "$@" "-Dorg.slf4j.simpleLogger.defaultLogLevel=${LOG_LEVEL}" fi -exec "$@" -cp "$CLASSPATH" org.apache.iceberg.rest.RESTCatalogServer +exec "$@" -cp "$CLASSPATH" "$REST_SERVER_MAIN" From e2438972fb03aeeb498d76dff109fdb50bdb83f2 Mon Sep 17 00:00:00 2001 From: Kevin Liu Date: Sat, 27 Jun 2026 13:42:39 -0700 Subject: [PATCH 6/8] Docker: Minimize REST fixture runtime path changes --- docker/iceberg-rest-fixture/Dockerfile | 7 +++---- docker/iceberg-rest-fixture/entrypoint.sh | 5 ++--- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/docker/iceberg-rest-fixture/Dockerfile b/docker/iceberg-rest-fixture/Dockerfile index eb83ec670fc6..ecbe349f0555 100644 --- a/docker/iceberg-rest-fixture/Dockerfile +++ b/docker/iceberg-rest-fixture/Dockerfile @@ -28,12 +28,11 @@ RUN set -xeu && \ rm -rf /var/lib/apt/lists/* # Working directory for the application -ENV REST_SERVER_HOME=/usr/lib/iceberg-rest -WORKDIR $REST_SERVER_HOME +WORKDIR /usr/lib/iceberg-rest # Copy REST server libs and LICENSE/NOTICE -COPY --chown=iceberg:iceberg open-api/build/iceberg-rest-server/ ./ -COPY --chown=iceberg:iceberg docker/iceberg-rest-fixture/entrypoint.sh ./entrypoint.sh +COPY --chown=iceberg:iceberg open-api/build/iceberg-rest-server/ /usr/lib/iceberg-rest/ +COPY --chown=iceberg:iceberg docker/iceberg-rest-fixture/entrypoint.sh /usr/lib/iceberg-rest/entrypoint.sh ENV CATALOG_CATALOG__IMPL=org.apache.iceberg.jdbc.JdbcCatalog ENV CATALOG_URI=jdbc:sqlite:/tmp/iceberg_catalog.db diff --git a/docker/iceberg-rest-fixture/entrypoint.sh b/docker/iceberg-rest-fixture/entrypoint.sh index dc4298d9b429..fb53f60cbd21 100644 --- a/docker/iceberg-rest-fixture/entrypoint.sh +++ b/docker/iceberg-rest-fixture/entrypoint.sh @@ -20,8 +20,7 @@ set -eu -REST_SERVER_MAIN="org.apache.iceberg.rest.RESTCatalogServer" -CLASSPATH="${REST_SERVER_HOME}/libs/*" +CLASSPATH="libs/*" if [ -n "${LOG_CONFIG_DIR:-}" ]; then CLASSPATH="${LOG_CONFIG_DIR}:${CLASSPATH}" @@ -33,4 +32,4 @@ if [ -n "${LOG_LEVEL:-}" ]; then set -- "$@" "-Dorg.slf4j.simpleLogger.defaultLogLevel=${LOG_LEVEL}" fi -exec "$@" -cp "$CLASSPATH" "$REST_SERVER_MAIN" +exec "$@" -cp "$CLASSPATH" org.apache.iceberg.rest.RESTCatalogServer From ad06f9eb23f48bc8b7fe31109fe0b76114d234ed Mon Sep 17 00:00:00 2001 From: Kevin Liu Date: Sat, 27 Jun 2026 13:46:04 -0700 Subject: [PATCH 7/8] Docker: Clarify REST fixture staged runtime comment --- docker/iceberg-rest-fixture/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/iceberg-rest-fixture/Dockerfile b/docker/iceberg-rest-fixture/Dockerfile index ecbe349f0555..a36f26d3e917 100644 --- a/docker/iceberg-rest-fixture/Dockerfile +++ b/docker/iceberg-rest-fixture/Dockerfile @@ -30,7 +30,7 @@ RUN set -xeu && \ # Working directory for the application WORKDIR /usr/lib/iceberg-rest -# Copy REST server libs and LICENSE/NOTICE +# Copy staged REST fixture runtime, including libs/ and LICENSE/NOTICE COPY --chown=iceberg:iceberg open-api/build/iceberg-rest-server/ /usr/lib/iceberg-rest/ COPY --chown=iceberg:iceberg docker/iceberg-rest-fixture/entrypoint.sh /usr/lib/iceberg-rest/entrypoint.sh From d54d7856d2db336416aa63d11076b1d2f6d5ef27 Mon Sep 17 00:00:00 2001 From: Kevin Liu Date: Sat, 27 Jun 2026 13:47:50 -0700 Subject: [PATCH 8/8] Docker: Explain REST fixture runtime classpath --- docker/iceberg-rest-fixture/entrypoint.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/docker/iceberg-rest-fixture/entrypoint.sh b/docker/iceberg-rest-fixture/entrypoint.sh index fb53f60cbd21..29d9cdc895b8 100644 --- a/docker/iceberg-rest-fixture/entrypoint.sh +++ b/docker/iceberg-rest-fixture/entrypoint.sh @@ -20,6 +20,7 @@ set -eu +# The staged runtime puts all REST server jars under libs/; Java expands this wildcard. CLASSPATH="libs/*" if [ -n "${LOG_CONFIG_DIR:-}" ]; then