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

liuxiaoyu pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudberry-pxf.git


The following commit(s) were added to refs/heads/main by this push:
     new 5d13cad0 ci: add Rocky 9 support for CI and Docker build environment 
(#78)
5d13cad0 is described below

commit 5d13cad04d64c4dee1efe0742e63f4989884415e
Author: liuxiaoyu <[email protected]>
AuthorDate: Thu Mar 26 20:53:27 2026 +0800

    ci: add Rocky 9 support for CI and Docker build environment (#78)
    
    - Unify CI scripts from ubuntu/ to common/, supporting both Ubuntu and 
Rocky/RHEL
    - via auto-detection of package manager (apt-get vs dnf)
    - Add Rocky 9 Docker Compose and RPM build script (rocky9/)
    - Parameterize singlecluster Dockerfile with ARG BASE_IMAGE for 
multi-distro builds
    - Add Rocky 9 singlecluster image build job to GitHub Actions workflow
    - Cross-platform JAVA_HOME auto-detection in build_pxf.sh
---
 .github/workflows/pxf-ci.yml                       | 402 +++++++++++++++++----
 .../{ubuntu => common}/script/build_cloudberrry.sh | 128 +++++--
 .../{ubuntu => common}/script/build_pxf.sh         |  25 +-
 .../{ubuntu => common}/script/entrypoint.sh        | 275 +++++++++-----
 .../{ubuntu => common}/script/pxf-env.sh           |  33 +-
 .../{ubuntu => common}/script/pxf-test.sh          |   0
 .../{ubuntu => common}/script/run_tests.sh         |   0
 .../{ubuntu => common}/script/start_minio.bash     |   0
 .../{ubuntu => common}/script/utils.sh             |  15 +-
 ci/docker/pxf-cbdb-dev/rocky9/docker-compose.yml   |  46 +++
 .../rocky9/script/build_cloudberry_rpm.sh          | 110 ++++++
 .../ubuntu/script/build_cloudberry_deb.sh          |  34 +-
 ci/singlecluster/Dockerfile                        |  67 ++--
 13 files changed, 842 insertions(+), 293 deletions(-)

diff --git a/.github/workflows/pxf-ci.yml b/.github/workflows/pxf-ci.yml
index 660c47d4..1195d060 100644
--- a/.github/workflows/pxf-ci.yml
+++ b/.github/workflows/pxf-ci.yml
@@ -91,8 +91,54 @@ jobs:
         path: workspace/cloudberry-source.tar.gz
         retention-days: 7
 
+  build-cloudberry-rpm:
+    name: Build Cloudberry RPM Package
+    runs-on: ubuntu-latest
+    container:
+      image: apache/incubator-cloudberry:cbdb-build-rocky9-latest
+      options: --user root
+    steps:
+    - name: Checkout Cloudberry source
+      uses: actions/checkout@v4
+      with:
+        repository: apache/cloudberry
+        ref: ${{ env.CLOUDBERRY_VERSION }}
+        path: workspace/cloudberry
+        submodules: true
+
+    - name: Checkout PXF source (for build script)
+      uses: actions/checkout@v4
+      with:
+        path: cloudberry-pxf
+
+    - name: Build Cloudberry RPM
+      run: |
+        export WORKSPACE=$PWD/workspace
+        export CLOUDBERRY_VERSION=99.0.0
+        export CLOUDBERRY_BUILD=1
+        bash 
cloudberry-pxf/ci/docker/pxf-cbdb-dev/rocky9/script/build_cloudberry_rpm.sh
+
+    - name: Package Cloudberry source
+      run: |
+        cd workspace
+        tar czf cloudberry-source-rocky9.tar.gz cloudberry/
+
+    - name: Upload RPM artifact
+      uses: actions/upload-artifact@v4
+      with:
+        name: cloudberry-rpm
+        path: workspace/cloudberry-rpm/*.rpm
+        retention-days: 7
+
+    - name: Upload Cloudberry source artifact (Rocky 9)
+      uses: actions/upload-artifact@v4
+      with:
+        name: cloudberry-source-rocky9
+        path: workspace/cloudberry-source-rocky9.tar.gz
+        retention-days: 7
+
   build-docker-images:
-    name: Build Docker Images
+    name: Build Docker Images (Ubuntu)
     runs-on: ubuntu-latest
     steps:
     - name: Checkout PXF source
@@ -130,6 +176,28 @@ jobs:
         working-directory: ./server
         run: make test
 
+  build-docker-images-rocky9:
+    name: Build Docker Images (Rocky 9)
+    runs-on: ubuntu-latest
+    steps:
+    - name: Checkout PXF source
+      uses: actions/checkout@v4
+      with:
+        path: cloudberry-pxf
+
+    - name: Build singlecluster Rocky 9 image
+      run: |
+        cd cloudberry-pxf/ci/singlecluster
+        docker build --build-arg 
BASE_IMAGE=apache/incubator-cloudberry:cbdb-build-rocky9-latest -t 
pxf/singlecluster-rocky9:3 .
+        docker save pxf/singlecluster-rocky9:3 > 
/tmp/singlecluster-rocky9-image.tar
+
+    - name: Upload singlecluster Rocky 9 image
+      uses: actions/upload-artifact@v4
+      with:
+        name: singlecluster-rocky9-image
+        path: /tmp/singlecluster-rocky9-image.tar
+        retention-days: 1
+
   # Stage 2: Parallel test jobs using matrix strategy
   pxf-test:
     name: Test PXF - ${{ matrix.test_group }}
@@ -214,14 +282,14 @@ jobs:
         docker exec pxf-cbdb-dev sudo chown -R gpadmin:gpadmin 
/home/gpadmin/workspace/cloudberry
         docker cp /tmp/*.deb pxf-cbdb-dev:/tmp/
         docker exec pxf-cbdb-dev sudo chown gpadmin:gpadmin /tmp/*.deb
-        docker exec pxf-cbdb-dev bash -lc "cd 
/home/gpadmin/workspace/cloudberry-pxf/ci/docker/pxf-cbdb-dev/ubuntu && 
./script/entrypoint.sh"
+        docker exec pxf-cbdb-dev bash -lc "cd 
/home/gpadmin/workspace/cloudberry-pxf && 
./ci/docker/pxf-cbdb-dev/common/script/entrypoint.sh"
 
     - name: Run Test - ${{ matrix.test_group }}
       id: run_test
       continue-on-error: true
       timeout-minutes: 120
       run: |
-        docker exec pxf-cbdb-dev bash -lc "cd 
/home/gpadmin/workspace/cloudberry-pxf/automation && source 
../ci/docker/pxf-cbdb-dev/ubuntu/script/pxf-env.sh && 
../ci/docker/pxf-cbdb-dev/ubuntu/script/run_tests.sh ${{ matrix.test_group }}"
+        docker exec pxf-cbdb-dev bash -lc "cd 
/home/gpadmin/workspace/cloudberry-pxf/automation && source 
../ci/docker/pxf-cbdb-dev/common/script/pxf-env.sh && 
../ci/docker/pxf-cbdb-dev/common/script/run_tests.sh ${{ matrix.test_group }}"
         
     - name: Collect artifacts and generate stats
       if: always()
@@ -301,10 +369,182 @@ jobs:
           exit 1
         fi
 
+  # Stage 2b: Rocky 9 parallel test jobs
+  pxf-test-rocky9:
+    name: Test PXF Rocky9 - ${{ matrix.test_group }}
+    needs: [build-cloudberry-rpm, build-docker-images-rocky9]
+    runs-on: ubuntu-latest
+    strategy:
+      fail-fast: false
+      matrix:
+        test_group:
+          - cli
+          - external-table
+          - fdw
+          - server
+          - sanity
+          - smoke
+          - hdfs
+          - hcatalog
+          - hcfs
+          - hive
+          - hbase
+          - profile
+          - jdbc
+          - proxy
+          - unused
+          - s3
+          - features
+          - gpdb
+          - gpdb_fdw
+          - load
+          - pxf_extension
+    steps:
+    - name: Free disk space
+      run: |
+        sudo rm -rf /usr/share/dotnet
+        sudo rm -rf /opt/ghc
+        sudo rm -rf /usr/local/share/boost
+        sudo rm -rf /usr/local/lib/android
+        sudo rm -rf /opt/hostedtoolcache
+        sudo docker system prune -af
+        df -h
+
+    - name: Checkout PXF source
+      uses: actions/checkout@v4
+      with:
+        fetch-depth: 1
+        path: cloudberry-pxf
+        submodules: true
+
+    - name: Download Cloudberry RPM
+      uses: actions/download-artifact@v4
+      with:
+        name: cloudberry-rpm
+        path: /tmp
+
+    - name: Download Cloudberry source (Rocky 9)
+      uses: actions/download-artifact@v4
+      with:
+        name: cloudberry-source-rocky9
+        path: /tmp
+
+    - name: Download singlecluster Rocky 9 image
+      uses: actions/download-artifact@v4
+      with:
+        name: singlecluster-rocky9-image
+        path: /tmp
+
+    - name: Load singlecluster Rocky 9 image
+      run: |
+        docker load < /tmp/singlecluster-rocky9-image.tar
+
+    - name: Prepare Cloudberry source
+      run: |
+        tar xzf /tmp/cloudberry-source-rocky9.tar.gz
+        chmod -R u+rwX,go+rX cloudberry
+
+    - name: Start Services
+      id: start_services
+      run: |
+        cd cloudberry-pxf
+        docker compose -f ci/docker/pxf-cbdb-dev/rocky9/docker-compose.yml 
down -v || true
+        docker compose -f ci/docker/pxf-cbdb-dev/rocky9/docker-compose.yml 
build
+        docker compose -f ci/docker/pxf-cbdb-dev/rocky9/docker-compose.yml up 
-d
+        docker exec pxf-cbdb-dev sudo chown -R gpadmin:gpadmin 
/home/gpadmin/workspace/cloudberry
+        docker cp /tmp/*.rpm pxf-cbdb-dev:/tmp/
+        docker exec pxf-cbdb-dev sudo chown gpadmin:gpadmin /tmp/*.rpm
+        docker exec pxf-cbdb-dev bash -lc "cd 
/home/gpadmin/workspace/cloudberry-pxf && 
./ci/docker/pxf-cbdb-dev/common/script/entrypoint.sh"
+
+    - name: Run Test - ${{ matrix.test_group }}
+      id: run_test
+      continue-on-error: true
+      timeout-minutes: 120
+      run: |
+        docker exec pxf-cbdb-dev bash -lc "cd 
/home/gpadmin/workspace/cloudberry-pxf/automation && source 
../ci/docker/pxf-cbdb-dev/common/script/pxf-env.sh && 
../ci/docker/pxf-cbdb-dev/common/script/run_tests.sh ${{ matrix.test_group }}"
+
+    - name: Collect artifacts and generate stats
+      if: always()
+      id: collect_artifacts
+      run: |
+        mkdir -p artifacts/logs
+        TEST_GROUP="${{ matrix.test_group }}"
+        TEST_RESULT="${{ steps.run_test.outcome }}"
+
+        # Initialize counters
+        TOTAL=0
+        PASSED=0
+        FAILED=0
+        SKIPPED=0
+
+        # Copy test artifacts
+        cp -r cloudberry-pxf/automation/test_artifacts/* artifacts/ 
2>/dev/null || true
+        docker exec pxf-cbdb-dev bash -c "cp -r /usr/local/pxf/logs/* 
/tmp/pxf-logs/ 2>/dev/null || true" || true
+        docker cp pxf-cbdb-dev:/tmp/pxf-logs artifacts/logs/ 2>/dev/null || 
true
+
+        # Parse surefire reports for automation tests
+        if [[ "$TEST_GROUP" != "cli" && "$TEST_GROUP" != "server" ]]; then
+          for xml in 
cloudberry-pxf/automation/target/surefire-reports/TEST-*.xml; do
+            if [ -f "$xml" ]; then
+              tests=$(grep -oP 'tests="\K\d+' "$xml" 2>/dev/null | head -1 || 
echo "0")
+              failures=$(grep -oP 'failures="\K\d+' "$xml" 2>/dev/null | head 
-1 || echo "0")
+              errors=$(grep -oP 'errors="\K\d+' "$xml" 2>/dev/null | head -1 
|| echo "0")
+              skipped=$(grep -oP 'skipped="\K\d+' "$xml" 2>/dev/null | head -1 
|| echo "0")
+
+              TOTAL=$((TOTAL + tests))
+              FAILED=$((FAILED + failures + errors))
+              SKIPPED=$((SKIPPED + skipped))
+            fi
+          done
+          PASSED=$((TOTAL - FAILED - SKIPPED))
+        fi
+
+        # Generate stats JSON
+        cat > artifacts/test_stats.json <<EOF
+        {
+          "group": "$TEST_GROUP",
+          "result": "$TEST_RESULT",
+          "total": $TOTAL,
+          "passed": $PASSED,
+          "failed": $FAILED,
+          "skipped": $SKIPPED
+        }
+        EOF
+
+        echo "failed_count=$FAILED" >> $GITHUB_OUTPUT
+        echo "skipped_count=$SKIPPED" >> $GITHUB_OUTPUT
+        echo "Test stats for $TEST_GROUP (Rocky 9): total=$TOTAL, 
passed=$PASSED, failed=$FAILED, skipped=$SKIPPED"
+
+    - name: Cleanup containers
+      if: always()
+      run: |
+        cd cloudberry-pxf
+        docker compose -f ci/docker/pxf-cbdb-dev/rocky9/docker-compose.yml 
down -v || true
+
+    - name: Upload test artifacts
+      if: always()
+      uses: actions/upload-artifact@v4
+      with:
+        name: test-results-rocky9-${{ matrix.test_group }}
+        path: artifacts/**
+        if-no-files-found: ignore
+        retention-days: 7
+
+    - name: Check test result
+      if: always()
+      run: |
+        FAILED_COUNT="${{ steps.collect_artifacts.outputs.failed_count || 0 }}"
+        SKIPPED_COUNT="${{ steps.collect_artifacts.outputs.skipped_count || 0 
}}"
+
+        if [ "${{ steps.run_test.outcome }}" == "failure" ] || [ 
"$FAILED_COUNT" -gt 0 ]; then
+          echo "Test group ${{ matrix.test_group }} (Rocky 9) failed 
(Failures: $FAILED_COUNT, Skipped: $SKIPPED_COUNT)"
+          exit 1
+        fi
+
   # Stage 3: Summary job
   test-summary:
     name: Test Summary
-    needs: [pxf-test]
+    needs: [pxf-test, pxf-test-rocky9]
     if: always()
     runs-on: ubuntu-latest
     steps:
@@ -318,79 +558,89 @@ jobs:
       run: |
         echo "## PXF Test Results Summary" >> $GITHUB_STEP_SUMMARY
         echo "" >> $GITHUB_STEP_SUMMARY
-        
-        # Overall counters
-        OVERALL_TOTAL=0
-        OVERALL_PASSED=0
-        OVERALL_FAILED=0
-        OVERALL_SKIPPED=0
-        GROUPS_PASSED=0
-        GROUPS_FAILED=0
-        FAILED_GROUP_NAMES=""
-        
-        # Collect all test stats
-        declare -A GROUP_STATS
-        
-        for dir in all-artifacts/test-results-*; do
-          if [ -d "$dir" ] && [ -f "$dir/test_stats.json" ]; then
-            group=$(cat "$dir/test_stats.json" | grep -oP 
'"group":\s*"\K[^"]+' || basename "$dir" | sed 's/test-results-//')
-            result=$(cat "$dir/test_stats.json" | grep -oP 
'"result":\s*"\K[^"]+' || echo "unknown")
-            total=$(cat "$dir/test_stats.json" | grep -oP '"total":\s*\K\d+' 
|| echo "0")
-            passed=$(cat "$dir/test_stats.json" | grep -oP '"passed":\s*\K\d+' 
|| echo "0")
-            failed=$(cat "$dir/test_stats.json" | grep -oP '"failed":\s*\K\d+' 
|| echo "0")
-            skipped=$(cat "$dir/test_stats.json" | grep -oP 
'"skipped":\s*\K\d+' || echo "0")
-            
-            GROUP_STATS[$group]="$result,$total,$passed,$failed,$skipped"
-            
-            OVERALL_TOTAL=$((OVERALL_TOTAL + total))
-            OVERALL_PASSED=$((OVERALL_PASSED + passed))
-            OVERALL_FAILED=$((OVERALL_FAILED + failed))
-            OVERALL_SKIPPED=$((OVERALL_SKIPPED + skipped))
-            
+
+        generate_os_summary() {
+          local os_label="$1"
+          local pattern="$2"
+
+          # OS-level counters
+          local OVERALL_TOTAL=0
+          local OVERALL_PASSED=0
+          local OVERALL_FAILED=0
+          local OVERALL_SKIPPED=0
+          local GROUPS_PASSED=0
+          local GROUPS_FAILED=0
+          local FAILED_GROUP_NAMES=""
+
+          declare -A GROUP_STATS
+
+          for dir in all-artifacts/${pattern}; do
+            if [ -d "$dir" ] && [ -f "$dir/test_stats.json" ]; then
+              group=$(cat "$dir/test_stats.json" | grep -oP 
'"group":\s*"\K[^"]+' || basename "$dir" | sed "s/${pattern%\*}//")
+              result=$(cat "$dir/test_stats.json" | grep -oP 
'"result":\s*"\K[^"]+' || echo "unknown")
+              total=$(cat "$dir/test_stats.json" | grep -oP '"total":\s*\K\d+' 
|| echo "0")
+              passed=$(cat "$dir/test_stats.json" | grep -oP 
'"passed":\s*\K\d+' || echo "0")
+              failed=$(cat "$dir/test_stats.json" | grep -oP 
'"failed":\s*\K\d+' || echo "0")
+              skipped=$(cat "$dir/test_stats.json" | grep -oP 
'"skipped":\s*\K\d+' || echo "0")
+
+              GROUP_STATS[$group]="$result,$total,$passed,$failed,$skipped"
+
+              OVERALL_TOTAL=$((OVERALL_TOTAL + total))
+              OVERALL_PASSED=$((OVERALL_PASSED + passed))
+              OVERALL_FAILED=$((OVERALL_FAILED + failed))
+              OVERALL_SKIPPED=$((OVERALL_SKIPPED + skipped))
+
+              if [ "$result" == "success" ] && [ "$failed" -eq 0 ]; then
+                GROUPS_PASSED=$((GROUPS_PASSED + 1))
+              else
+                GROUPS_FAILED=$((GROUPS_FAILED + 1))
+                FAILED_GROUP_NAMES="${FAILED_GROUP_NAMES}${group} "
+              fi
+            fi
+          done
+
+          echo "### ${os_label}" >> $GITHUB_STEP_SUMMARY
+          echo "" >> $GITHUB_STEP_SUMMARY
+          if [ $GROUPS_FAILED -eq 0 ]; then
+            echo "All ${GROUPS_PASSED} test groups passed" >> 
$GITHUB_STEP_SUMMARY
+          else
+            echo "${GROUPS_FAILED} of $((GROUPS_PASSED + GROUPS_FAILED)) test 
groups failed" >> $GITHUB_STEP_SUMMARY
+          fi
+          echo "" >> $GITHUB_STEP_SUMMARY
+          echo "- Total Tests: $OVERALL_TOTAL" >> $GITHUB_STEP_SUMMARY
+          echo "- Passed: $OVERALL_PASSED" >> $GITHUB_STEP_SUMMARY
+          echo "- Failed: $OVERALL_FAILED" >> $GITHUB_STEP_SUMMARY
+          echo "- Skipped: $OVERALL_SKIPPED" >> $GITHUB_STEP_SUMMARY
+          echo "" >> $GITHUB_STEP_SUMMARY
+
+          echo "| Test Group | Status | Passed | Failed | Skipped | Total |" 
>> $GITHUB_STEP_SUMMARY
+          echo "|------------|--------|-------:|-------:|--------:|------:|" 
>> $GITHUB_STEP_SUMMARY
+
+          for group in $(echo "${!GROUP_STATS[@]}" | tr ' ' '\n' | sort); do
+            IFS=',' read -r result total passed failed skipped <<< 
"${GROUP_STATS[$group]}"
             if [ "$result" == "success" ] && [ "$failed" -eq 0 ]; then
-              GROUPS_PASSED=$((GROUPS_PASSED + 1))
+              status="PASS"
             else
-              GROUPS_FAILED=$((GROUPS_FAILED + 1))
-              FAILED_GROUP_NAMES="${FAILED_GROUP_NAMES}${group} "
+              status="FAIL"
             fi
+            echo "| $group | $status | $passed | $failed | $skipped | $total 
|" >> $GITHUB_STEP_SUMMARY
+          done
+
+          echo "" >> $GITHUB_STEP_SUMMARY
+
+          if [ $GROUPS_FAILED -gt 0 ]; then
+            echo "::error::${os_label}: ${GROUPS_FAILED} test group(s) failed: 
${FAILED_GROUP_NAMES}"
+            return 1
           fi
-        done
-        
-        # Overall summary
-        echo "### Overall Summary" >> $GITHUB_STEP_SUMMARY
-        echo "" >> $GITHUB_STEP_SUMMARY
-        if [ $GROUPS_FAILED -eq 0 ]; then
-          echo "✅ **All ${GROUPS_PASSED} test groups passed**" >> 
$GITHUB_STEP_SUMMARY
-        else
-          echo "❌ **${GROUPS_FAILED} of $((GROUPS_PASSED + GROUPS_FAILED)) 
test groups failed**" >> $GITHUB_STEP_SUMMARY
-        fi
-        echo "" >> $GITHUB_STEP_SUMMARY
-        echo "- Total Tests: $OVERALL_TOTAL" >> $GITHUB_STEP_SUMMARY
-        echo "- Passed: $OVERALL_PASSED" >> $GITHUB_STEP_SUMMARY
-        echo "- Failed: $OVERALL_FAILED" >> $GITHUB_STEP_SUMMARY
-        echo "- Skipped: $OVERALL_SKIPPED" >> $GITHUB_STEP_SUMMARY
-        echo "" >> $GITHUB_STEP_SUMMARY
-        
-        # Detailed table
-        echo "### Test Results by Group" >> $GITHUB_STEP_SUMMARY
-        echo "" >> $GITHUB_STEP_SUMMARY
-        echo "| Test Group | Status | Passed | Failed | Skipped | Total |" >> 
$GITHUB_STEP_SUMMARY
-        echo "|------------|--------|-------:|-------:|--------:|------:|" >> 
$GITHUB_STEP_SUMMARY
-        
-        for group in $(echo "${!GROUP_STATS[@]}" | tr ' ' '\n' | sort); do
-          IFS=',' read -r result total passed failed skipped <<< 
"${GROUP_STATS[$group]}"
-          if [ "$result" == "success" ] && [ "$failed" -eq 0 ]; then
-            status="✅ PASS"
-          else
-            status="❌ FAIL"
-          fi
-          echo "| $group | $status | $passed | $failed | $skipped | $total |" 
>> $GITHUB_STEP_SUMMARY
-        done
-        
-        echo "" >> $GITHUB_STEP_SUMMARY
-        
-        # Check if any group failed
-        if [ $GROUPS_FAILED -gt 0 ]; then
-          echo "::error::${GROUPS_FAILED} test group(s) failed: 
${FAILED_GROUP_NAMES}"
-          exit 1
-        fi
+          return 0
+        }
+
+        EXIT_CODE=0
+
+        # Ubuntu results (test-results-<group>, excluding 
test-results-rocky9-*)
+        generate_os_summary "Ubuntu 22.04" "test-results-[!r]*" || EXIT_CODE=1
+
+        # Rocky 9 results
+        generate_os_summary "Rocky 9" "test-results-rocky9-*" || EXIT_CODE=1
+
+        exit $EXIT_CODE
diff --git a/ci/docker/pxf-cbdb-dev/ubuntu/script/build_cloudberrry.sh 
b/ci/docker/pxf-cbdb-dev/common/script/build_cloudberrry.sh
similarity index 69%
rename from ci/docker/pxf-cbdb-dev/ubuntu/script/build_cloudberrry.sh
rename to ci/docker/pxf-cbdb-dev/common/script/build_cloudberrry.sh
index e1ae6e26..cd4c4758 100755
--- a/ci/docker/pxf-cbdb-dev/ubuntu/script/build_cloudberrry.sh
+++ b/ci/docker/pxf-cbdb-dev/common/script/build_cloudberrry.sh
@@ -1,3 +1,4 @@
+#!/bin/bash
 # --------------------------------------------------------------------
 #
 # Licensed to the Apache Software Foundation (ASF) under one or more
@@ -17,8 +18,14 @@
 # permissions and limitations under the License.
 #
 # --------------------------------------------------------------------
+# Build Cloudberry from source — works on both Ubuntu and Rocky/RHEL
+
 # Install sudo & git
-sudo apt update && sudo apt install -y sudo git
+if command -v apt-get >/dev/null 2>&1; then
+  sudo apt update && sudo apt install -y sudo git
+elif command -v dnf >/dev/null 2>&1; then
+  sudo dnf install -y sudo git
+fi
 
 # Required configuration
 ## Add Cloudberry environment setup to .bashrc
@@ -57,44 +64,85 @@ EOF
 ulimit -a
 
 # Install basic system packages
-sudo apt update
-sudo apt install -y bison \
-  bzip2 \
-  cmake \
-  curl \
-  flex \
-  gcc \
-  g++ \
-  iproute2 \
-  iputils-ping \
-  language-pack-en \
-  locales \
-  libapr1-dev \
-  libbz2-dev \
-  libcurl4-gnutls-dev \
-  libevent-dev \
-  libkrb5-dev \
-  libipc-run-perl \
-  libldap2-dev \
-  libpam0g-dev \
-  libprotobuf-dev \
-  libreadline-dev \
-  libssl-dev \
-  libuv1-dev \
-  liblz4-dev \
-  libxerces-c-dev \
-  libxml2-dev \
-  libyaml-dev \
-  libzstd-dev \
-  libperl-dev \
-  make \
-  pkg-config \
-  protobuf-compiler \
-  python3-dev \
-  python3-pip \
-  python3-setuptools \
-  rsync \
-  libsnappy-dev
+if command -v apt-get >/dev/null 2>&1; then
+  sudo apt update
+  sudo apt install -y bison \
+    bzip2 \
+    cmake \
+    curl \
+    flex \
+    gcc \
+    g++ \
+    iproute2 \
+    iputils-ping \
+    language-pack-en \
+    locales \
+    libapr1-dev \
+    libbz2-dev \
+    libcurl4-gnutls-dev \
+    libevent-dev \
+    libkrb5-dev \
+    libipc-run-perl \
+    libldap2-dev \
+    libpam0g-dev \
+    libprotobuf-dev \
+    libreadline-dev \
+    libssl-dev \
+    libuv1-dev \
+    liblz4-dev \
+    libxerces-c-dev \
+    libxml2-dev \
+    libyaml-dev \
+    libzstd-dev \
+    libperl-dev \
+    make \
+    pkg-config \
+    protobuf-compiler \
+    python3-dev \
+    python3-pip \
+    python3-setuptools \
+    rsync \
+    libsnappy-dev
+elif command -v dnf >/dev/null 2>&1; then
+  sudo dnf install -y \
+    bison \
+    bzip2 \
+    cmake \
+    curl \
+    flex \
+    gcc \
+    gcc-c++ \
+    iproute \
+    iputils \
+    glibc-langpack-en \
+    glibc-locale-source \
+    apr-devel \
+    bzip2-devel \
+    libcurl-devel \
+    libevent-devel \
+    krb5-devel \
+    perl-IPC-Run \
+    openldap-devel \
+    pam-devel \
+    protobuf-devel \
+    readline-devel \
+    openssl-devel \
+    libuv-devel \
+    lz4-devel \
+    xerces-c-devel \
+    libxml2-devel \
+    libyaml-devel \
+    libzstd-devel \
+    perl-devel \
+    make \
+    pkgconfig \
+    protobuf-compiler \
+    python3-devel \
+    python3-pip \
+    python3-setuptools \
+    rsync \
+    snappy-devel
+fi
 
 # Continue as gpadmin user
 
@@ -149,4 +197,4 @@ source /usr/local/cloudberry-db/cloudberry-env.sh
 make create-demo-cluster -C ~/workspace/cloudberry
 source ~/workspace/cloudberry/gpAux/gpdemo/gpdemo-env.sh
 psql -P pager=off template1 -c 'SELECT * from gp_segment_configuration'
-psql template1 -c 'SELECT version()'
\ No newline at end of file
+psql template1 -c 'SELECT version()'
diff --git a/ci/docker/pxf-cbdb-dev/ubuntu/script/build_pxf.sh 
b/ci/docker/pxf-cbdb-dev/common/script/build_pxf.sh
similarity index 80%
rename from ci/docker/pxf-cbdb-dev/ubuntu/script/build_pxf.sh
rename to ci/docker/pxf-cbdb-dev/common/script/build_pxf.sh
index b48cbc9e..08f7c765 100755
--- a/ci/docker/pxf-cbdb-dev/ubuntu/script/build_pxf.sh
+++ b/ci/docker/pxf-cbdb-dev/common/script/build_pxf.sh
@@ -1,3 +1,4 @@
+#!/bin/bash
 # --------------------------------------------------------------------
 #
 # Licensed to the Apache Software Foundation (ASF) under one or more
@@ -17,18 +18,28 @@
 # permissions and limitations under the License.
 #
 # --------------------------------------------------------------------
-case "$(uname -m)" in
-  aarch64|arm64) JAVA_HOME=${JAVA_HOME:-/usr/lib/jvm/java-11-openjdk-arm64} ;;
-  x86_64|amd64)  JAVA_HOME=${JAVA_HOME:-/usr/lib/jvm/java-11-openjdk-amd64} ;;
-  *)             JAVA_HOME=${JAVA_HOME:-/usr/lib/jvm/java-11-openjdk-amd64} ;;
-esac
+# Build and install PXF — works on both Ubuntu and Rocky/RHEL
+
+# Auto-detect Java 11 path
+if [ -d /usr/lib/jvm/java-11-openjdk-amd64 ]; then
+  JAVA_HOME=${JAVA_HOME:-/usr/lib/jvm/java-11-openjdk-amd64}
+elif [ -d /usr/lib/jvm/java-11-openjdk-arm64 ]; then
+  JAVA_HOME=${JAVA_HOME:-/usr/lib/jvm/java-11-openjdk-arm64}
+else
+  JAVA_HOME=${JAVA_HOME:-/usr/lib/jvm/java-11-openjdk}
+fi
 export PATH=$JAVA_HOME/bin:$PATH
 export GPHOME=/usr/local/cloudberry-db
 source /usr/local/cloudberry-db/cloudberry-env.sh
 export PATH=$GPHOME/bin:$PATH
 
-sudo apt update
-sudo apt install -y openjdk-11-jdk maven
+# Install Java 11 JDK and Maven
+if command -v apt-get >/dev/null 2>&1; then
+  sudo apt update
+  sudo apt install -y openjdk-11-jdk maven
+elif command -v dnf >/dev/null 2>&1; then
+  sudo dnf install -y java-11-openjdk-devel maven
+fi
 
 cd /home/gpadmin/workspace/cloudberry-pxf
 
diff --git a/ci/docker/pxf-cbdb-dev/ubuntu/script/entrypoint.sh 
b/ci/docker/pxf-cbdb-dev/common/script/entrypoint.sh
similarity index 66%
rename from ci/docker/pxf-cbdb-dev/ubuntu/script/entrypoint.sh
rename to ci/docker/pxf-cbdb-dev/common/script/entrypoint.sh
index f3ca1bee..832e5067 100755
--- a/ci/docker/pxf-cbdb-dev/ubuntu/script/entrypoint.sh
+++ b/ci/docker/pxf-cbdb-dev/common/script/entrypoint.sh
@@ -26,41 +26,66 @@ die() { log "ERROR $*"; exit 1; }
 ROOT_DIR=/home/gpadmin/workspace
 REPO_DIR=${ROOT_DIR}/cloudberry-pxf
 GPHD_ROOT=${ROOT_DIR}/singlecluster
-PXF_SCRIPTS=${REPO_DIR}/ci/docker/pxf-cbdb-dev/ubuntu/script
-source "${PXF_SCRIPTS}/utils.sh"
+COMMON_SCRIPTS=${REPO_DIR}/ci/docker/pxf-cbdb-dev/common/script
+source "${COMMON_SCRIPTS}/utils.sh"
 
 HADOOP_ROOT=${GPHD_ROOT}/hadoop
 HIVE_ROOT=${GPHD_ROOT}/hive
 HBASE_ROOT=${GPHD_ROOT}/hbase
 ZOOKEEPER_ROOT=${GPHD_ROOT}/zookeeper
 
-JAVA_11_ARM=/usr/lib/jvm/java-11-openjdk-arm64
-JAVA_11_AMD=/usr/lib/jvm/java-11-openjdk-amd64
-JAVA_8_ARM=/usr/lib/jvm/java-8-openjdk-arm64
-JAVA_8_AMD=/usr/lib/jvm/java-8-openjdk-amd64
+# --------------------------------------------------------------------
+# OS detection: "deb" (Ubuntu/Debian) or "rpm" (Rocky/RHEL/CentOS)
+# --------------------------------------------------------------------
+if command -v apt-get >/dev/null 2>&1; then
+  OS_FAMILY="deb"
+else
+  OS_FAMILY="rpm"
+fi
 
 detect_java_paths() {
-  case "$(uname -m)" in
-    aarch64|arm64) JAVA_BUILD=${JAVA_11_ARM}; JAVA_HADOOP=${JAVA_8_ARM} ;;
-    x86_64|amd64)  JAVA_BUILD=${JAVA_11_AMD}; JAVA_HADOOP=${JAVA_8_AMD} ;;
-    *)             JAVA_BUILD=${JAVA_11_ARM}; JAVA_HADOOP=${JAVA_8_ARM} ;;
-  esac
+  if [ "$OS_FAMILY" = "deb" ]; then
+    case "$(uname -m)" in
+      aarch64|arm64) JAVA_BUILD=/usr/lib/jvm/java-11-openjdk-arm64;  
JAVA_HADOOP=/usr/lib/jvm/java-8-openjdk-arm64 ;;
+      *)             JAVA_BUILD=/usr/lib/jvm/java-11-openjdk-amd64;  
JAVA_HADOOP=/usr/lib/jvm/java-8-openjdk-amd64 ;;
+    esac
+  else
+    JAVA_BUILD=/usr/lib/jvm/java-11-openjdk
+    JAVA_HADOOP=/usr/lib/jvm/java-1.8.0-openjdk
+  fi
   export JAVA_BUILD JAVA_HADOOP
 }
 
 setup_locale_and_packages() {
   log "install base packages and locales"
-  sudo apt-get update
-  sudo apt-get install -y wget lsb-release locales maven unzip openssh-server 
iproute2 sudo \
-    openjdk-11-jre-headless openjdk-8-jre-headless
-  sudo locale-gen en_US.UTF-8 ru_RU.CP1251 ru_RU.UTF-8
-  sudo update-locale LANG=en_US.UTF-8
+  if [ "$OS_FAMILY" = "deb" ]; then
+    sudo apt-get update
+    sudo apt-get install -y wget lsb-release locales maven unzip 
openssh-server iproute2 sudo \
+      openjdk-11-jre-headless openjdk-8-jre-headless
+    sudo locale-gen en_US.UTF-8 ru_RU.CP1251 ru_RU.UTF-8
+    sudo update-locale LANG=en_US.UTF-8
+  else
+    sudo dnf install -y wget maven unzip openssh-server iproute sudo \
+      java-11-openjdk-headless java-1.8.0-openjdk-headless \
+      glibc-langpack-en glibc-locale-source
+    sudo localedef -c -i en_US -f UTF-8 en_US.UTF-8 || true
+    sudo localedef -c -i ru_RU -f UTF-8 ru_RU.UTF-8 || true
+  fi
   sudo localedef -c -i ru_RU -f CP1251 ru_RU.CP1251 || true
   export LANG=en_US.UTF-8 LANGUAGE=en_US:en LC_ALL=en_US.UTF-8
 }
 
 setup_ssh() {
   log "configure ssh"
+  # Rocky 9 / RHEL 9 enforces system-wide crypto-policies that override 
sshd_config
+  # settings for algorithm negotiation.  The automation test framework uses the
+  # Ganymed SSH-2 (ch.ethz.ssh2) library which only supports older KEX 
algorithms
+  # (diffie-hellman-group-exchange-sha1, diffie-hellman-group14-sha1, etc.).
+  # Downgrade to the LEGACY crypto policy so sshd accepts these algorithms.
+  if [ "$OS_FAMILY" = "rpm" ] && command -v update-crypto-policies >/dev/null 
2>&1; then
+    log "setting LEGACY crypto policy for SSH compatibility"
+    sudo update-crypto-policies --set LEGACY 2>/dev/null || true
+  fi
   sudo ssh-keygen -A
   sudo bash -c 'echo "PasswordAuthentication yes" >> /etc/ssh/sshd_config'
   sudo mkdir -p /etc/ssh/sshd_config.d
@@ -69,7 +94,11 @@ KexAlgorithms 
+diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,di
 HostKeyAlgorithms +ssh-rsa,ssh-dss
 PubkeyAcceptedAlgorithms +ssh-rsa,ssh-dss
 EOF'
-  sudo usermod -a -G sudo gpadmin
+  if [ "$OS_FAMILY" = "deb" ]; then
+    sudo usermod -a -G sudo gpadmin
+  else
+    sudo usermod -a -G wheel gpadmin 2>/dev/null || true
+  fi
   echo "gpadmin:cbdb@123" | sudo chpasswd
   echo "gpadmin        ALL=(ALL)       NOPASSWD: ALL" | sudo tee -a 
/etc/sudoers >/dev/null
   echo "root           ALL=(ALL)       NOPASSWD: ALL" | sudo tee -a 
/etc/sudoers >/dev/null
@@ -84,7 +113,21 @@ EOF'
   ssh-keyscan -t rsa mdw cdw localhost 2>/dev/null > 
/home/gpadmin/.ssh/known_hosts || true
   sudo rm -rf /run/nologin
   sudo mkdir -p /var/run/sshd && sudo chmod 0755 /var/run/sshd
-  sudo /usr/sbin/sshd || die "Failed to start sshd"
+  # Ensure privilege separation user exists (required by Rocky 9 sshd)
+  id sshd &>/dev/null || sudo useradd -r -d /var/empty/sshd -s /sbin/nologin 
sshd 2>/dev/null || true
+  sudo mkdir -p /var/empty/sshd && sudo chmod 0755 /var/empty/sshd
+  sudo /usr/sbin/sshd -E /tmp/sshd.log || die "Failed to start sshd, check 
/tmp/sshd.log"
+  sleep 1
+  if ! ss -tlnp | grep -q ':22 '; then
+    log "ERROR: sshd is not listening on port 22"
+    cat /tmp/sshd.log 2>/dev/null || true
+    sudo /usr/sbin/sshd -D -e &
+    sleep 1
+    if ! ss -tlnp | grep -q ':22 '; then
+      die "sshd failed to bind to port 22"
+    fi
+  fi
+  log "sshd is running on port 22"
 }
 
 relax_pg_hba() {
@@ -101,105 +144,81 @@ EOF
   fi
 }
 
-install_cloudberry_from_deb() {
-  log "installing Cloudberry from .deb package"
-  local deb_file=$(find /tmp -name "apache-cloudberry-db*.deb" 2>/dev/null | 
head -1)
-  if [ -z "$deb_file" ]; then
-    die "No .deb package found in /tmp"
+install_build_deps() {
+  if [ "$OS_FAMILY" = "deb" ]; then
+    sudo apt update && sudo apt install -y sudo git
+    sudo apt update
+    sudo apt install -y bison bzip2 cmake curl flex gcc g++ iproute2 
iputils-ping \
+      language-pack-en locales libapr1-dev libbz2-dev libcurl4-gnutls-dev 
libevent-dev \
+      libkrb5-dev libipc-run-perl libldap2-dev libpam0g-dev libprotobuf-dev 
libreadline-dev \
+      libssl-dev libuv1-dev liblz4-dev libxerces-c-dev libxml2-dev libyaml-dev 
libzstd-dev \
+      libperl-dev make pkg-config protobuf-compiler python3-dev python3-pip 
python3-setuptools \
+      rsync libsnappy-dev
+  else
+    sudo dnf install -y sudo git
+    sudo dnf install -y --allowerasing bison bzip2 cmake curl flex gcc gcc-c++ 
iproute iputils \
+      glibc-langpack-en glibc-locale-source apr-devel bzip2-devel 
libcurl-devel libevent-devel \
+      krb5-devel perl-IPC-Run openldap-devel pam-devel protobuf-devel 
readline-devel \
+      openssl-devel libuv-devel lz4-devel libxml2-devel libyaml-devel \
+      libzstd-devel perl-devel make pkgconfig protobuf-compiler python3-devel 
python3-pip \
+      python3-setuptools rsync snappy-devel
   fi
+}
 
-  # Install sudo & git
-  sudo apt update && sudo apt install -y sudo git
+install_cloudberry_from_package() {
+  log "installing Cloudberry from package"
+
+  local pkg_file=""
+  if [ "$OS_FAMILY" = "deb" ]; then
+    pkg_file=$(find /tmp -name "apache-cloudberry-db*.deb" 2>/dev/null | head 
-1)
+    [ -z "$pkg_file" ] && die "No .deb package found in /tmp"
+  else
+    pkg_file=$(find /tmp -name "apache-cloudberry-db*.rpm" 2>/dev/null | head 
-1)
+    [ -z "$pkg_file" ] && die "No .rpm package found in /tmp"
+  fi
+
+  install_build_deps
 
   # Required configuration
-  ## Add Cloudberry environment setup to .bashrc
   echo -e '\n# Add Cloudberry entries
   if [ -f /usr/local/cloudberry-db/cloudberry-env.sh ]; then
     source /usr/local/cloudberry-db/cloudberry-env.sh
   fi
-  ## US English with UTF-8 character encoding
   export LANG=en_US.UTF-8
   ' >> /home/gpadmin/.bashrc
-  ## Set up SSH for passwordless access
+
   mkdir -p /home/gpadmin/.ssh
   if [ ! -f /home/gpadmin/.ssh/id_rsa ]; then
     ssh-keygen -t rsa -b 2048 -C 'apache-cloudberry-dev' -f 
/home/gpadmin/.ssh/id_rsa -N ""
   fi
   cat /home/gpadmin/.ssh/id_rsa.pub >> /home/gpadmin/.ssh/authorized_keys
-  ## Set proper SSH directory permissions
   chmod 700 /home/gpadmin/.ssh
   chmod 600 /home/gpadmin/.ssh/authorized_keys
   chmod 644 /home/gpadmin/.ssh/id_rsa.pub
 
-# Configure system settings
 sudo tee /etc/security/limits.d/90-db-limits.conf << 'EOF'
-## Core dump file size limits for gpadmin
 gpadmin soft core unlimited
 gpadmin hard core unlimited
-## Open file limits for gpadmin
 gpadmin soft nofile 524288
 gpadmin hard nofile 524288
-## Process limits for gpadmin
 gpadmin soft nproc 131072
 gpadmin hard nproc 131072
 EOF
 
-  # Verify resource limits
   ulimit -a
 
-  # Install basic system packages
-  sudo apt update
-  sudo apt install -y bison \
-    bzip2 \
-    cmake \
-    curl \
-    flex \
-    gcc \
-    g++ \
-    iproute2 \
-    iputils-ping \
-    language-pack-en \
-    locales \
-    libapr1-dev \
-    libbz2-dev \
-    libcurl4-gnutls-dev \
-    libevent-dev \
-    libkrb5-dev \
-    libipc-run-perl \
-    libldap2-dev \
-    libpam0g-dev \
-    libprotobuf-dev \
-    libreadline-dev \
-    libssl-dev \
-    libuv1-dev \
-    liblz4-dev \
-    libxerces-c-dev \
-    libxml2-dev \
-    libyaml-dev \
-    libzstd-dev \
-    libperl-dev \
-    make \
-    pkg-config \
-    protobuf-compiler \
-    python3-dev \
-    python3-pip \
-    python3-setuptools \
-    rsync \
-    libsnappy-dev
-
-
-  # Continue as gpadmin user
-
-
-  # Prepare the build environment for Apache Cloudberry
   sudo rm -rf /usr/local/cloudberry-db
   sudo chmod a+w /usr/local
   mkdir -p /usr/local/cloudberry-db
   sudo chown -R gpadmin:gpadmin /usr/local/cloudberry-db
 
-  sudo dpkg -i "$deb_file" || sudo apt-get install -f -y
-  log "Cloudberry installed from $deb_file"
-  
+  if [ "$OS_FAMILY" = "deb" ]; then
+    sudo dpkg -i "$pkg_file" || sudo apt-get install -f -y
+  else
+    sudo rpm -Uvh --force "$pkg_file" || sudo dnf install -y "$pkg_file"
+  fi
+  log "Cloudberry installed from $pkg_file"
+
   # Initialize and start Cloudberry cluster
   source /usr/local/cloudberry-db/cloudberry-env.sh
   make create-demo-cluster -C ~/workspace/cloudberry || {
@@ -219,30 +238,30 @@ build_cloudberry() {
   rm -rf /home/gpadmin/workspace/cloudberry/gpAux/gpdemo/datadirs
   rm -f /tmp/.s.PGSQL.700*
   find "${ROOT_DIR}" -not -path '*/.git/*' -exec sudo chown gpadmin:gpadmin {} 
+ 2>/dev/null || true
-  "${PXF_SCRIPTS}/build_cloudberrry.sh"
+  "${COMMON_SCRIPTS}/build_cloudberrry.sh"
 }
 
 setup_cloudberry() {
-  # Auto-detect: if deb exists, install it; otherwise build from source
-  if [ -f /tmp/apache-cloudberry-db*.deb ]; then
-    log "detected .deb package, using fast install"
-    install_cloudberry_from_deb
-  elif [ "${CLOUDBERRY_USE_DEB:-}" = "true" ]; then
-    die "CLOUDBERRY_USE_DEB=true but no .deb found in /tmp"
+  # Auto-detect: if package exists, install it; otherwise build from source
+  if ls /tmp/apache-cloudberry-db*.deb 1>/dev/null 2>&1 || ls 
/tmp/apache-cloudberry-db*.rpm 1>/dev/null 2>&1; then
+    log "detected package, using fast install"
+    install_cloudberry_from_package
+  elif [ "${CLOUDBERRY_USE_PKG:-}" = "true" ]; then
+    die "CLOUDBERRY_USE_PKG=true but no .deb/.rpm found in /tmp"
   else
-    log "no .deb found, building from source (local dev mode)"
+    log "no package found, building from source (local dev mode)"
     build_cloudberry
   fi
 }
 
 build_pxf() {
   log "build PXF"
-  "${PXF_SCRIPTS}/build_pxf.sh"
+  "${COMMON_SCRIPTS}/build_pxf.sh"
 }
 
 configure_pxf() {
   log "configure PXF"
-  source "${PXF_SCRIPTS}/pxf-env.sh"
+  source "${COMMON_SCRIPTS}/pxf-env.sh"
   export PATH="$PXF_HOME/bin:$PATH"
   export PXF_JVM_OPTS="-Xmx512m -Xms256m"
   export PXF_HOST=localhost
@@ -318,7 +337,7 @@ EOF
 
   # Configure S3 settings
   mkdir -p "$PXF_BASE/servers/s3" "$PXF_HOME/servers/s3"
-  
+
   for s3_site in "$PXF_BASE/servers/s3/s3-site.xml" 
"$PXF_BASE/servers/default/s3-site.xml" "$PXF_HOME/servers/s3/s3-site.xml"; do
     mkdir -p "$(dirname "$s3_site")"
     cat > "$s3_site" <<'EOF'
@@ -364,6 +383,63 @@ EOF
 
 }
 
+wait_for_datanode() {
+  log "waiting for HDFS DataNode to become available..."
+  local max_attempts=2
+  for _attempt in $(seq 1 ${max_attempts}); do
+    local dn_ready=false
+    # Wait up to 90s (45 tries * 2s) for DataNode to register
+    for _dn_try in $(seq 1 45); do
+      if hdfs dfsadmin -report 2>/dev/null | grep -q "Live datanodes.*[1-9]"; 
then
+        dn_ready=true
+        break
+      fi
+      sleep 2
+    done
+
+    if [ "${dn_ready}" = "true" ]; then
+      log "HDFS DataNode is available"
+      return 0
+    fi
+
+    # DataNode didn't come up; diagnose and attempt restart
+    log "DataNode not available after 90s (attempt 
${_attempt}/${max_attempts})"
+    log "--- DataNode diagnostic info ---"
+    # Check if DataNode process is alive
+    if command -v jps >/dev/null 2>&1; then
+      log "JPS output: $(jps 2>&1)"
+    fi
+    if pgrep -f "proc_datanode" >/dev/null 2>&1 || pgrep -f "datanode" 
>/dev/null 2>&1; then
+      log "DataNode process exists but not yet registered with NameNode"
+    else
+      log "DataNode process is NOT running"
+    fi
+    # Show DataNode logs if available
+    local dn_log
+    dn_log=$(ls -t "${GPHD_ROOT}"/storage/logs/*datanode*.log 2>/dev/null | 
head -1)
+    if [ -n "${dn_log}" ]; then
+      log "Last 30 lines of DataNode log (${dn_log}):"
+      tail -30 "${dn_log}" 2>/dev/null || true
+    fi
+    log "HDFS report:"
+    hdfs dfsadmin -report 2>&1 | head -20 || true
+    log "--- end diagnostic ---"
+
+    if [ "${_attempt}" -lt "${max_attempts}" ]; then
+      log "Attempting to restart DataNode..."
+      # Stop any zombie DataNode processes
+      pkill -f "proc_datanode" 2>/dev/null || true
+      sleep 2
+      # Restart DataNode via the singlecluster script
+      "${GPHD_ROOT}/bin/hadoop-datanode.sh" start 0 2>&1 || true
+      "${HADOOP_ROOT}/sbin/hadoop-daemon.sh" --config 
"${GPHD_ROOT}/storage/hadoop/datanode0/etc/hadoop" start datanode 2>&1 || true
+      log "DataNode restart issued, waiting again..."
+    fi
+  done
+
+  die "HDFS DataNode failed to start after ${max_attempts} attempts. Tez 
upload will fail without a running DataNode."
+}
+
 prepare_hadoop_stack() {
   log "prepare Hadoop/Hive/HBase stack"
   export JAVA_HOME="${JAVA_HADOOP}"
@@ -386,12 +462,19 @@ prepare_hadoop_stack() {
   if pgrep -f HiveServer2 >/dev/null 2>&1; then
     "${GPHD_ROOT}/bin/hive-service.sh" hiveserver2 stop || true
   fi
+  log "JAVA_HOME=${JAVA_HOME} JAVA_HADOOP=${JAVA_HADOOP}"
+  log "java check: $(ls -la ${JAVA_HOME}/bin/java 2>&1)"
   if [ ! -d "${GPHD_ROOT}/storage/hadoop/dfs/name/current" ]; then
-    ${GPHD_ROOT}/bin/init-gphd.sh
+    log "initializing HDFS namenode..."
+    ${GPHD_ROOT}/bin/init-gphd.sh 2>&1 || log "init-gphd.sh failed with exit 
code $?"
   fi
-  if ! ${GPHD_ROOT}/bin/start-gphd.sh; then
+  log "starting HDFS/YARN/HBase via start-gphd.sh..."
+  if ! ${GPHD_ROOT}/bin/start-gphd.sh 2>&1; then
     log "start-gphd.sh returned non-zero (services may already be running), 
continue"
   fi
+  # Wait for HDFS DataNode to be ready before proceeding; Tez upload in
+  # start_hive_services will fail if no DataNode is accepting writes.
+  wait_for_datanode
   if ! ${GPHD_ROOT}/bin/start-zookeeper.sh; then
     log "start-zookeeper.sh returned non-zero (may already be running)"
   fi
@@ -487,7 +570,7 @@ start_hive_services() {
 
 deploy_minio() {
   log "deploying MinIO"
-  bash "${PXF_SCRIPTS}/start_minio.bash"
+  bash "${COMMON_SCRIPTS}/start_minio.bash"
 }
 
 main() {
diff --git a/ci/docker/pxf-cbdb-dev/ubuntu/script/pxf-env.sh 
b/ci/docker/pxf-cbdb-dev/common/script/pxf-env.sh
similarity index 81%
rename from ci/docker/pxf-cbdb-dev/ubuntu/script/pxf-env.sh
rename to ci/docker/pxf-cbdb-dev/common/script/pxf-env.sh
index bd785ea1..81b23556 100755
--- a/ci/docker/pxf-cbdb-dev/ubuntu/script/pxf-env.sh
+++ b/ci/docker/pxf-cbdb-dev/common/script/pxf-env.sh
@@ -21,22 +21,25 @@
 # Centralized environment for Cloudberry + PXF + Hadoop stack
 
 # --------------------------------------------------------------------
-# Architecture-aware Java selections
+# Architecture-aware Java selections (auto-detect OS)
 # --------------------------------------------------------------------
-case "$(uname -m)" in
-  aarch64|arm64)
-    JAVA_BUILD=${JAVA_BUILD:-/usr/lib/jvm/java-11-openjdk-arm64}
-    JAVA_HADOOP=${JAVA_HADOOP:-/usr/lib/jvm/java-8-openjdk-arm64}
-    ;;
-  x86_64|amd64)
-    JAVA_BUILD=${JAVA_BUILD:-/usr/lib/jvm/java-11-openjdk-amd64}
-    JAVA_HADOOP=${JAVA_HADOOP:-/usr/lib/jvm/java-8-openjdk-amd64}
-    ;;
-  *)
-    JAVA_BUILD=${JAVA_BUILD:-/usr/lib/jvm/java-11-openjdk}
-    JAVA_HADOOP=${JAVA_HADOOP:-/usr/lib/jvm/java-8-openjdk}
-    ;;
-esac
+if [ -d /usr/lib/jvm/java-11-openjdk-amd64 ] || [ -d 
/usr/lib/jvm/java-11-openjdk-arm64 ]; then
+  # Debian/Ubuntu: paths include architecture suffix
+  case "$(uname -m)" in
+    aarch64|arm64)
+      JAVA_BUILD=${JAVA_BUILD:-/usr/lib/jvm/java-11-openjdk-arm64}
+      JAVA_HADOOP=${JAVA_HADOOP:-/usr/lib/jvm/java-8-openjdk-arm64}
+      ;;
+    *)
+      JAVA_BUILD=${JAVA_BUILD:-/usr/lib/jvm/java-11-openjdk-amd64}
+      JAVA_HADOOP=${JAVA_HADOOP:-/usr/lib/jvm/java-8-openjdk-amd64}
+      ;;
+  esac
+else
+  # RHEL/Rocky: architecture-independent symlinks
+  JAVA_BUILD=${JAVA_BUILD:-/usr/lib/jvm/java-11-openjdk}
+  JAVA_HADOOP=${JAVA_HADOOP:-/usr/lib/jvm/java-1.8.0-openjdk}
+fi
 
 # --------------------------------------------------------------------
 # Core paths
diff --git a/ci/docker/pxf-cbdb-dev/ubuntu/script/pxf-test.sh 
b/ci/docker/pxf-cbdb-dev/common/script/pxf-test.sh
similarity index 100%
rename from ci/docker/pxf-cbdb-dev/ubuntu/script/pxf-test.sh
rename to ci/docker/pxf-cbdb-dev/common/script/pxf-test.sh
diff --git a/ci/docker/pxf-cbdb-dev/ubuntu/script/run_tests.sh 
b/ci/docker/pxf-cbdb-dev/common/script/run_tests.sh
similarity index 100%
rename from ci/docker/pxf-cbdb-dev/ubuntu/script/run_tests.sh
rename to ci/docker/pxf-cbdb-dev/common/script/run_tests.sh
diff --git a/ci/docker/pxf-cbdb-dev/ubuntu/script/start_minio.bash 
b/ci/docker/pxf-cbdb-dev/common/script/start_minio.bash
similarity index 100%
rename from ci/docker/pxf-cbdb-dev/ubuntu/script/start_minio.bash
rename to ci/docker/pxf-cbdb-dev/common/script/start_minio.bash
diff --git a/ci/docker/pxf-cbdb-dev/ubuntu/script/utils.sh 
b/ci/docker/pxf-cbdb-dev/common/script/utils.sh
old mode 100644
new mode 100755
similarity index 89%
rename from ci/docker/pxf-cbdb-dev/ubuntu/script/utils.sh
rename to ci/docker/pxf-cbdb-dev/common/script/utils.sh
index 786017fc..c055dd25
--- a/ci/docker/pxf-cbdb-dev/ubuntu/script/utils.sh
+++ b/ci/docker/pxf-cbdb-dev/common/script/utils.sh
@@ -107,13 +107,26 @@ check_pxf() {
   fi
 }
 
+# Auto-detect default Java 8 path based on OS
+_detect_java8_default() {
+  if [ -d /usr/lib/jvm/java-8-openjdk-amd64 ]; then
+    echo "/usr/lib/jvm/java-8-openjdk-amd64"
+  elif [ -d /usr/lib/jvm/java-8-openjdk-arm64 ]; then
+    echo "/usr/lib/jvm/java-8-openjdk-arm64"
+  elif [ -d /usr/lib/jvm/java-1.8.0-openjdk ]; then
+    echo "/usr/lib/jvm/java-1.8.0-openjdk"
+  else
+    echo "/usr/lib/jvm/java-8-openjdk"
+  fi
+}
+
 health_check() {
   log "sanity check Hadoop/Hive/HBase/PXF"
   GPHD_ROOT=${GPHD_ROOT:-/home/gpadmin/workspace/singlecluster}
   HADOOP_ROOT=${HADOOP_ROOT:-${GPHD_ROOT}/hadoop}
   HBASE_ROOT=${HBASE_ROOT:-${GPHD_ROOT}/hbase}
   HIVE_ROOT=${HIVE_ROOT:-${GPHD_ROOT}/hive}
-  JAVA_HADOOP=${JAVA_HADOOP:-/usr/lib/jvm/java-8-openjdk-amd64}
+  JAVA_HADOOP=${JAVA_HADOOP:-$(_detect_java8_default)}
 
   export JAVA_HOME="${JAVA_HADOOP}"
   export 
PATH="$JAVA_HOME/bin:$HADOOP_ROOT/bin:$HIVE_ROOT/bin:$HBASE_ROOT/bin:$PATH"
diff --git a/ci/docker/pxf-cbdb-dev/rocky9/docker-compose.yml 
b/ci/docker/pxf-cbdb-dev/rocky9/docker-compose.yml
new file mode 100644
index 00000000..37738078
--- /dev/null
+++ b/ci/docker/pxf-cbdb-dev/rocky9/docker-compose.yml
@@ -0,0 +1,46 @@
+# --------------------------------------------------------------------
+#
+# 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.
+#
+# --------------------------------------------------------------------
+services:
+# hadoop
+  singlecluster:
+    build:
+      context: ../../../singlecluster
+      args:
+        BASE_IMAGE: apache/incubator-cloudberry:cbdb-build-rocky9-latest
+    image: pxf/singlecluster-rocky9:3
+    container_name: pxf_singlecluster_rocky9
+    hostname: cdw
+
+  pxf-cbdb-dev:
+    image: pxf/singlecluster-rocky9:3
+    container_name: pxf-cbdb-dev
+    hostname: mdw
+    depends_on:
+      - singlecluster
+    ports:
+      - "2222:22"
+    volumes:
+      - ../../../../../cloudberry-pxf:/home/gpadmin/workspace/cloudberry-pxf
+      - ../../../../../cloudberry:/home/gpadmin/workspace/cloudberry
+    command: ["tail", "-f", "/dev/null"]
+
+networks:
+  default:
+    name: pxf-cbdb-ci
diff --git a/ci/docker/pxf-cbdb-dev/rocky9/script/build_cloudberry_rpm.sh 
b/ci/docker/pxf-cbdb-dev/rocky9/script/build_cloudberry_rpm.sh
new file mode 100755
index 00000000..1d3e6888
--- /dev/null
+++ b/ci/docker/pxf-cbdb-dev/rocky9/script/build_cloudberry_rpm.sh
@@ -0,0 +1,110 @@
+#!/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 -euo pipefail
+
+# Cloudberry RPM Package Build Script for Rocky 9
+CLOUDBERRY_VERSION="${CLOUDBERRY_VERSION:-99.0.0}"
+CLOUDBERRY_BUILD="${CLOUDBERRY_BUILD:-1}"
+INSTALL_PREFIX="${INSTALL_PREFIX:-/usr/local/cloudberry-db}"
+WORKSPACE="${WORKSPACE:-$HOME/workspace}"
+CLOUDBERRY_SRC="${WORKSPACE}/cloudberry"
+
+echo "=== Cloudberry RPM Package Build ==="
+echo "Version: ${CLOUDBERRY_VERSION}"
+echo "Build: ${CLOUDBERRY_BUILD}"
+echo "Install Prefix: ${INSTALL_PREFIX}"
+echo "Source: ${CLOUDBERRY_SRC}"
+
+# Clean previous installation
+rm -rf "${INSTALL_PREFIX}"
+mkdir -p "${INSTALL_PREFIX}"
+
+# Copy xerces-c shared libraries required by ORCA
+mkdir -p "${INSTALL_PREFIX}/lib"
+cp -v /usr/local/xerces-c/lib/libxerces-c.so \
+      /usr/local/xerces-c/lib/libxerces-c-3.*.so \
+      "${INSTALL_PREFIX}/lib/"
+
+# Build Cloudberry using official build scripts
+export SRC_DIR="${CLOUDBERRY_SRC}"
+export CPPFLAGS="${CPPFLAGS:-} -I/usr/local/xerces-c/include"
+export LDFLAGS="${LDFLAGS:-} -L${INSTALL_PREFIX}/lib"
+mkdir -p "${SRC_DIR}/build-logs"
+cd "${CLOUDBERRY_SRC}"
+./devops/build/automation/cloudberry/scripts/configure-cloudberry.sh
+./devops/build/automation/cloudberry/scripts/build-cloudberry.sh
+
+# Copy LICENSE
+cp LICENSE "${INSTALL_PREFIX}/"
+
+# Create RPM build structure
+RPM_BUILD_DIR="${WORKSPACE}/cloudberry-rpm"
+mkdir -p "${RPM_BUILD_DIR}"/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
+RPM_INSTALL_ROOT="${RPM_BUILD_DIR}/BUILDROOT/apache-cloudberry-db-${CLOUDBERRY_VERSION}-${CLOUDBERRY_BUILD}.x86_64"
+mkdir -p "${RPM_INSTALL_ROOT}${INSTALL_PREFIX}"
+
+# Copy installed files
+cp -a "${INSTALL_PREFIX}"/* "${RPM_INSTALL_ROOT}${INSTALL_PREFIX}/"
+
+# Create spec file
+cat > "${RPM_BUILD_DIR}/SPECS/cloudberry-db.spec" << EOF
+Name: apache-cloudberry-db
+Version: ${CLOUDBERRY_VERSION}
+Release: ${CLOUDBERRY_BUILD}%{?dist}
+Summary: Apache Cloudberry Database
+License: Apache-2.0
+Group: Applications/Databases
+AutoReqProv: no
+
+%description
+Apache Cloudberry is a massively parallel processing (MPP) database
+built on PostgreSQL for analytics and data warehousing.
+
+%install
+mkdir -p %{buildroot}${INSTALL_PREFIX}
+cp -a ${RPM_INSTALL_ROOT}${INSTALL_PREFIX}/* %{buildroot}${INSTALL_PREFIX}/
+
+%files
+${INSTALL_PREFIX}
+
+%post
+if ! id -u gpadmin >/dev/null 2>&1; then
+    useradd -m -s /bin/bash gpadmin
+fi
+chown -R gpadmin:gpadmin ${INSTALL_PREFIX}
+echo "Apache Cloudberry Database installed successfully"
+
+%clean
+rm -rf %{buildroot}
+EOF
+
+# Build RPM package
+rpmbuild --define "_topdir ${RPM_BUILD_DIR}" -bb 
"${RPM_BUILD_DIR}/SPECS/cloudberry-db.spec"
+
+RPM_FILE=$(find "${RPM_BUILD_DIR}/RPMS" -name "*.rpm" | head -1)
+echo "=== RPM Package Created ==="
+ls -lh "${RPM_FILE}"
+rpm -qpi "${RPM_FILE}"
+
+# Copy RPM to output directory
+cp "${RPM_FILE}" "${RPM_BUILD_DIR}/"
+
+echo "=== Build Complete ==="
diff --git a/ci/docker/pxf-cbdb-dev/ubuntu/script/build_cloudberry_deb.sh 
b/ci/docker/pxf-cbdb-dev/ubuntu/script/build_cloudberry_deb.sh
index fc117e88..991cb648 100755
--- a/ci/docker/pxf-cbdb-dev/ubuntu/script/build_cloudberry_deb.sh
+++ b/ci/docker/pxf-cbdb-dev/ubuntu/script/build_cloudberry_deb.sh
@@ -37,36 +37,12 @@ echo "Source: ${CLOUDBERRY_SRC}"
 rm -rf "${INSTALL_PREFIX}"
 mkdir -p "${INSTALL_PREFIX}"
 
-# Configure Cloudberry
+# Build Cloudberry using official build scripts
+export SRC_DIR="${CLOUDBERRY_SRC}"
+mkdir -p "${SRC_DIR}/build-logs"
 cd "${CLOUDBERRY_SRC}"
-./configure --prefix="${INSTALL_PREFIX}" \
-            --disable-external-fts \
-            --enable-gpcloud \
-            --enable-ic-proxy \
-            --enable-mapreduce \
-            --enable-orafce \
-            --enable-orca \
-            --disable-pax \
-            --disable-pxf \
-            --enable-tap-tests \
-            --with-gssapi \
-            --with-ldap \
-            --with-libxml \
-            --with-lz4 \
-            --with-pam \
-            --with-perl \
-            --with-pgport=5432 \
-            --with-python \
-            --with-pythonsrc-ext \
-            --with-ssl=openssl \
-            --with-uuid=e2fs \
-            --with-includes=/usr/include/xercesc
-
-# Build and install
-make -j$(nproc)
-make -j$(nproc) -C contrib
-make install
-make install -C contrib
+./devops/build/automation/cloudberry/scripts/configure-cloudberry.sh
+./devops/build/automation/cloudberry/scripts/build-cloudberry.sh
 
 # Copy LICENSE
 cp LICENSE "${INSTALL_PREFIX}/"
diff --git a/ci/singlecluster/Dockerfile b/ci/singlecluster/Dockerfile
index accf1d51..4d6bb655 100644
--- a/ci/singlecluster/Dockerfile
+++ b/ci/singlecluster/Dockerfile
@@ -17,15 +17,24 @@
 # permissions and limitations under the License.
 #
 # --------------------------------------------------------------------
-FROM apache/incubator-cloudberry:cbdb-build-ubuntu22.04-latest
-
-ENV DEBIAN_FRONTEND noninteractive
-
-RUN sudo apt-get update &&  \
-    sudo apt-get install -y --no-install-recommends \
-      curl ca-certificates \
-      openjdk-8-jdk-headless \
-      openjdk-11-jdk-headless
+ARG BASE_IMAGE=apache/incubator-cloudberry:cbdb-build-ubuntu22.04-latest
+FROM ${BASE_IMAGE}
+
+# Install Java 8 & 11: auto-detect OS package manager
+RUN if command -v apt-get >/dev/null 2>&1; then \
+      export DEBIAN_FRONTEND=noninteractive && \
+      sudo apt-get update && \
+      sudo apt-get install -y --no-install-recommends \
+        curl ca-certificates \
+        openjdk-8-jdk-headless \
+        openjdk-11-jdk-headless; \
+    elif command -v dnf >/dev/null 2>&1; then \
+      sudo dnf install -y --allowerasing \
+        curl ca-certificates \
+        java-1.8.0-openjdk-devel \
+        java-11-openjdk-devel && \
+      sudo dnf clean all; \
+    fi
 
 # TODO: update hive to support java 11+
 ENV    HADOOP_VERSION=3.1.2
@@ -60,36 +69,36 @@ ENV ZOOKEEPER_ROOT=$GPHD_ROOT/zookeeper
 ENV TEZ_ROOT=$GPHD_ROOT/tez
 
 RUN mkdir -p $HADOOP_ROOT && \
-    curl -fSL "$HADOOP_URL" -o hadoop.tar.gz && \
-    echo "$HADOOP_SHA512 hadoop.tar.gz" | sha512sum -c && \
-    tar xvf hadoop.tar.gz -C $HADOOP_ROOT --strip-components 1  
--exclude="share/doc/*" --exclude="*-sources.jar" && \
-    rm hadoop.tar.gz && \
+    curl -fSL "$HADOOP_URL" -o /tmp/hadoop.tar.gz && \
+    echo "$HADOOP_SHA512 /tmp/hadoop.tar.gz" | sha512sum -c && \
+    tar xvf /tmp/hadoop.tar.gz -C $HADOOP_ROOT --strip-components 1  
--exclude="share/doc/*" --exclude="*-sources.jar" && \
+    rm /tmp/hadoop.tar.gz && \
     curl -fSL 
"https://repo1.maven.org/maven2/javax/activation/javax.activation-api/1.2.0/javax.activation-api-1.2.0.jar";
 \
       -o $HADOOP_ROOT/share/hadoop/common/lib/javax.activation-api-1.2.0.jar
 
 RUN mkdir -p $HIVE_ROOT && \
-    curl -fSL $HIVE_URL -o hive.tar.gz && \
-    echo "$HIVE_SHA256 hive.tar.gz" | sha256sum -c && \
-    tar xvf hive.tar.gz -C $HIVE_ROOT --strip-components 1 && \
-    rm hive.tar.gz
+    curl -fSL $HIVE_URL -o /tmp/hive.tar.gz && \
+    echo "$HIVE_SHA256 /tmp/hive.tar.gz" | sha256sum -c && \
+    tar xvf /tmp/hive.tar.gz -C $HIVE_ROOT --strip-components 1 && \
+    rm /tmp/hive.tar.gz
 
 RUN mkdir -p $ZOOKEEPER_ROOT && \
-    curl -fSL $ZOOKEEPER_URL -o zookeeper.tar.gz && \
-    echo "$ZOOKEEPER_SHA512 zookeeper.tar.gz" | sha512sum -c && \
-    tar xvf zookeeper.tar.gz -C $ZOOKEEPER_ROOT --strip-components 1 
--exclude="docs/*" && \
-    rm zookeeper.tar.gz
+    curl -fSL $ZOOKEEPER_URL -o /tmp/zookeeper.tar.gz && \
+    echo "$ZOOKEEPER_SHA512 /tmp/zookeeper.tar.gz" | sha512sum -c && \
+    tar xvf /tmp/zookeeper.tar.gz -C $ZOOKEEPER_ROOT --strip-components 1 
--exclude="docs/*" && \
+    rm /tmp/zookeeper.tar.gz
 
 RUN mkdir -p $HBASE_ROOT && \
-    curl -fSL "$HBASE_URL" -o hbase.tar.gz && \
-    echo "$HBASE_SHA512 hbase.tar.gz" | sha512sum -c && \
-    tar xvf hbase.tar.gz -C $HBASE_ROOT --strip-components 1 
--exclude="docs/*" --exclude="lib/*-tests.jar" --exclude="lib/shaded-clients" 
&& \
-    rm hbase.tar.gz
+    curl -fSL "$HBASE_URL" -o /tmp/hbase.tar.gz && \
+    echo "$HBASE_SHA512 /tmp/hbase.tar.gz" | sha512sum -c && \
+    tar xvf /tmp/hbase.tar.gz -C $HBASE_ROOT --strip-components 1 
--exclude="docs/*" --exclude="lib/*-tests.jar" --exclude="lib/shaded-clients" 
&& \
+    rm /tmp/hbase.tar.gz
 
 RUN mkdir -p $TEZ_ROOT && \
-    curl -fSL "$TEZ_URL" -o tez.tar.gz && \
-    echo "$TEZ_SHA512 tez.tar.gz" | sha512sum -c && \
-    tar xvf tez.tar.gz -C $TEZ_ROOT --strip-components 1 && \
-    rm tez.tar.gz
+    curl -fSL "$TEZ_URL" -o /tmp/tez.tar.gz && \
+    echo "$TEZ_SHA512 /tmp/tez.tar.gz" | sha512sum -c && \
+    tar xvf /tmp/tez.tar.gz -C $TEZ_ROOT --strip-components 1 && \
+    rm /tmp/tez.tar.gz
 
 # Install Go (required by PXF). Pick archive based on architecture 
(amd64/arm64).
 ARG TARGETARCH


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to