diff --git a/.github/workflows/pxf-ci.yml b/.github/workflows/pxf-ci.yml index 9ea85aad..14002921 100644 --- a/.github/workflows/pxf-ci.yml +++ b/.github/workflows/pxf-ci.yml @@ -191,6 +191,78 @@ jobs: path: workspace/cloudberry-source-rocky9.tar.gz retention-days: 7 + build-cloudberry-rpm-rocky10: + name: Build Cloudberry RPM Package (Rocky 10) + runs-on: ubuntu-latest + container: + image: apache/incubator-cloudberry:cbdb-build-rocky10-latest + options: --user root + steps: + - name: Get month number + id: get-month + run: echo "month=$(/bin/date -u '+%Y-%m')" >> "$GITHUB_OUTPUT" + + - name: Restore RPM Rocky 10 cache + id: cache-rpm-rocky10 + uses: actions/cache/restore@v4 + with: + path: | + workspace/cloudberry-rpm-rocky10 + workspace/cloudberry-source-rocky10.tar.gz + key: cloudberry-rpm-rocky10-${{ runner.os }}-${{ steps.get-month.outputs.month }} + + - name: Checkout Cloudberry source + if: steps.cache-rpm-rocky10.outputs.cache-hit != 'true' + uses: actions/checkout@v4 + with: + repository: apache/cloudberry + ref: ${{ env.CLOUDBERRY_VERSION }} + path: workspace/cloudberry + submodules: true + + - name: Checkout PXF source (for build script) + if: steps.cache-rpm-rocky10.outputs.cache-hit != 'true' + uses: actions/checkout@v4 + with: + path: cloudberry-pxf + + - name: Build Cloudberry RPM (Rocky 10) + if: steps.cache-rpm-rocky10.outputs.cache-hit != 'true' + run: | + export WORKSPACE=$PWD/workspace + export CLOUDBERRY_VERSION=99.0.0 + export CLOUDBERRY_BUILD=1 + bash cloudberry-pxf/ci/docker/pxf-cbdb-dev/rocky10/script/build_cloudberry_rpm.sh + + - name: Package Cloudberry source + if: steps.cache-rpm-rocky10.outputs.cache-hit != 'true' + run: | + cd workspace + tar czf cloudberry-source-rocky10.tar.gz cloudberry/ + + - name: Save RPM Rocky 10 cache + if: steps.cache-rpm-rocky10.outputs.cache-hit != 'true' && github.ref == 'refs/heads/main' + uses: actions/cache/save@v4 + with: + path: | + workspace/cloudberry-rpm-rocky10 + workspace/cloudberry-source-rocky10.tar.gz + key: cloudberry-rpm-rocky10-${{ runner.os }}-${{ steps.get-month.outputs.month }} + + - name: Upload RPM artifact (Rocky 10) + uses: actions/upload-artifact@v4 + with: + name: cloudberry-rpm-rocky10 + path: workspace/cloudberry-rpm-rocky10/*.rpm + retention-days: 7 + + - name: Upload Cloudberry source artifact (Rocky 10) + uses: actions/upload-artifact@v4 + with: + name: cloudberry-source-rocky10 + path: workspace/cloudberry-source-rocky10.tar.gz + retention-days: 7 + build-docker-images: name: Build Docker Images (Ubuntu) runs-on: ubuntu-latest @@ -252,6 +324,28 @@ jobs: path: /tmp/singlecluster-rocky9-image.tar retention-days: 1 + build-docker-images-rocky10: + name: Build Docker Images (Rocky 10) + runs-on: ubuntu-latest + steps: + - name: Checkout PXF source + uses: actions/checkout@v4 + with: + path: cloudberry-pxf + + - name: Build singlecluster Rocky 10 image + run: | + cd cloudberry-pxf/ci/singlecluster + docker build --build-arg BASE_IMAGE=apache/incubator-cloudberry:cbdb-build-rocky10-latest -t pxf/singlecluster-rocky10:3 . + docker save pxf/singlecluster-rocky10:3 > /tmp/singlecluster-rocky10-image.tar + + - name: Upload singlecluster Rocky 10 image + uses: actions/upload-artifact@v4 + with: + name: singlecluster-rocky10-image + path: /tmp/singlecluster-rocky10-image.tar + retention-days: 1 + build-pxf-cbdb-testcontainer-image: name: Build Testcontainer Images (${{ matrix.distro }}) runs-on: ubuntu-latest @@ -266,6 +360,9 @@ jobs: - distro: rocky9 base_image: apache/incubator-cloudberry:cbdb-build-rocky9-latest image_tag: pxf/cbdb-testcontainer-rocky9:1 + - distro: rocky10 + base_image: apache/incubator-cloudberry:cbdb-build-rocky10-latest + image_tag: pxf/cbdb-testcontainer-rocky10:1 steps: - name: Get month number id: get-month @@ -694,6 +791,198 @@ jobs: fi + # Stage 2b2: Rocky 10 parallel test jobs + pxf-test-rocky10: + name: Test PXF Rocky10 - ${{ matrix.test_group }} + needs: [build-cloudberry-rpm-rocky10, build-docker-images-rocky10] + 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 + - features + - gpdb + - gpdb_fdw + - load + 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 (Rocky 10) + uses: actions/download-artifact@v4 + with: + name: cloudberry-rpm-rocky10 + path: /tmp + + - name: Download Cloudberry source (Rocky 10) + uses: actions/download-artifact@v4 + with: + name: cloudberry-source-rocky10 + path: /tmp + + - name: Download singlecluster Rocky 10 image + uses: actions/download-artifact@v4 + with: + name: singlecluster-rocky10-image + path: /tmp + + - name: Load singlecluster Rocky 10 image + run: | + docker load < /tmp/singlecluster-rocky10-image.tar + + - name: Prepare Cloudberry source + run: | + tar xzf /tmp/cloudberry-source-rocky10.tar.gz + chmod -R u+rwX,go+rX cloudberry + + - name: Restore Maven cache + id: cache-mvn + uses: actions/cache/restore@v4 + with: + path: .m2 + key: mvn-container-${{ hashFiles('cloudberry-pxf/automation/pom.xml') }} + restore-keys: | + mvn-container- + + - name: Prepare Maven cache dir + run: | + mkdir -p .m2 + chmod -R a+rwX .m2 || true + + - name: Start Services + id: start_services + run: | + cd cloudberry-pxf + docker compose -f ci/docker/pxf-cbdb-dev/rocky10/docker-compose.yml down -v || true + docker compose -f ci/docker/pxf-cbdb-dev/rocky10/docker-compose.yml up -d + docker exec pxf-cbdb-dev sudo chown -R gpadmin:gpadmin /home/gpadmin/workspace/cloudberry + docker exec pxf-cbdb-dev sudo chown -R gpadmin:gpadmin /home/gpadmin/.m2 + 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 <> $GITHUB_OUTPUT + echo "skipped_count=$SKIPPED" >> $GITHUB_OUTPUT + echo "Test stats for $TEST_GROUP (Rocky 10): 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/rocky10/docker-compose.yml down -v || true + + - name: Save Maven cache + if: always() && steps.cache-mvn.outputs.cache-hit != 'true' + uses: actions/cache/save@v4 + with: + path: .m2 + key: mvn-container-${{ hashFiles('cloudberry-pxf/automation/pom.xml') }} + + - name: Upload test artifacts + if: always() + uses: actions/upload-artifact@v4 + with: + name: test-results-rocky10-${{ 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 10) failed (Failures: $FAILED_COUNT, Skipped: $SKIPPED_COUNT)" + exit 1 + fi + + # Stage 2c: Testcontainers-based tests pxf-testcontainer-test: name: "TC Test - ${{ matrix.tc_group }} (${{ matrix.use_fdw == 'true' && 'fdw' || 'external-table' }}, ${{ matrix.distro }})" @@ -713,6 +1002,7 @@ jobs: distro: - 'ubuntu' - 'rocky9' + - 'rocky10' exclude: - tc_group: 'pxf-extension' use_fdw: 'true' @@ -877,7 +1167,7 @@ jobs: # Stage 3: Summary job test-summary: name: Test Summary - needs: [pxf-test, pxf-test-rocky9, pxf-testcontainer-test] + needs: [pxf-test, pxf-test-rocky9, pxf-test-rocky10, pxf-testcontainer-test] if: always() runs-on: ubuntu-latest steps: @@ -970,10 +1260,13 @@ jobs: EXIT_CODE=0 - # Ubuntu results (test-results-, excluding test-results-rocky9-*) + # Ubuntu results (test-results-, excluding test-results-rocky*-*) 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 + # Rocky 10 results + generate_os_summary "Rocky 10" "test-results-rocky10-*" || EXIT_CODE=1 + exit $EXIT_CODE diff --git a/automation/src/main/java/org/apache/cloudberry/pxf/automation/testcontainers/PXFCloudberryContainer.java b/automation/src/main/java/org/apache/cloudberry/pxf/automation/testcontainers/PXFCloudberryContainer.java index 798af68a..df7858e7 100644 --- a/automation/src/main/java/org/apache/cloudberry/pxf/automation/testcontainers/PXFCloudberryContainer.java +++ b/automation/src/main/java/org/apache/cloudberry/pxf/automation/testcontainers/PXFCloudberryContainer.java @@ -59,6 +59,7 @@ public class PXFCloudberryContainer extends GenericContainer/dev/null 2>&1; then \ locales wget lsb-release openssh-server iproute2 sudo \ openjdk-11-jdk-headless; \ elif command -v dnf >/dev/null 2>&1; then \ - sudo dnf install -y --allowerasing --nobest \ - curl ca-certificates wget maven unzip openssh-server iproute sudo glibc-langpack-en glibc-locale-source \ - java-11-openjdk-devel && \ + if [ -f /etc/os-release ] && . /etc/os-release && [ "$ID" = "rocky" ] && [ "${VERSION_ID%%.*}" -ge 10 ]; then \ + echo "Rocky 10+: JDK 11 / glibc-locale-source not in distro repos, using JDK 21 / glibc-all-langpacks"; \ + sudo dnf install -y --allowerasing --nobest \ + curl ca-certificates wget maven unzip openssh-server iproute sudo \ + glibc-langpack-en glibc-all-langpacks \ + java-21-openjdk-devel; \ + else \ + sudo dnf install -y --allowerasing --nobest \ + curl ca-certificates wget maven unzip openssh-server iproute sudo \ + glibc-langpack-en glibc-locale-source \ + java-11-openjdk-devel; \ + fi && \ sudo dnf clean all; \ fi diff --git a/ci/docker/pxf-cbdb-dev/rocky10/docker-compose.yml b/ci/docker/pxf-cbdb-dev/rocky10/docker-compose.yml new file mode 100644 index 00000000..317996bc --- /dev/null +++ b/ci/docker/pxf-cbdb-dev/rocky10/docker-compose.yml @@ -0,0 +1,58 @@ +# -------------------------------------------------------------------- +# +# 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-rocky10-latest + image: pxf/singlecluster-rocky10:3 + container_name: pxf_singlecluster_rocky10 + hostname: cdw + + pxf-cbdb-dev: + image: pxf/singlecluster-rocky10:3 + container_name: pxf-cbdb-dev + hostname: mdw + depends_on: + - singlecluster + environment: + # Pin container TZ so JVM's ZoneId.systemDefault() (used by + # ParquetTypeConverter for INT96 timestamp encode/decode) is the + # same across distros. Matches the PGOPTIONS timezone='GMT-1' set + # by run_tests.sh, keeping the Parquet-vs-PG timestamp path + # internally consistent. + TZ: Etc/GMT-1 + ports: + - "2222:22" + volumes: + - ../../../../../cloudberry-pxf:/home/gpadmin/workspace/cloudberry-pxf + - ../../../../../cloudberry:/home/gpadmin/workspace/cloudberry + # Share host's Maven local repo with the container so mvn dependency + # downloads survive across runs via actions/cache. Neutralises transient + # 5xx from Maven Central and single-source repos (top-q.co.il for + # JSystem) once the cache is warm. + - ../../../../../.m2:/home/gpadmin/.m2 + command: ["tail", "-f", "/dev/null"] + +networks: + default: + name: pxf-cbdb-ci diff --git a/ci/docker/pxf-cbdb-dev/rocky10/script/build_cloudberry_rpm.sh b/ci/docker/pxf-cbdb-dev/rocky10/script/build_cloudberry_rpm.sh new file mode 100755 index 00000000..54ea59bd --- /dev/null +++ b/ci/docker/pxf-cbdb-dev/rocky10/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 10 +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 (Rocky 10) ===" +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/singlecluster/Dockerfile b/ci/singlecluster/Dockerfile index e5b6566b..0c36a12f 100644 --- a/ci/singlecluster/Dockerfile +++ b/ci/singlecluster/Dockerfile @@ -29,10 +29,27 @@ RUN if command -v apt-get >/dev/null 2>&1; then \ openjdk-8-jdk-headless \ openjdk-11-jdk-headless; \ elif command -v dnf >/dev/null 2>&1; then \ - sudo dnf install -y --allowerasing --nobest \ - curl ca-certificates \ - java-1.8.0-openjdk-devel \ - java-11-openjdk-devel && \ + sudo dnf install -y --allowerasing --nobest curl ca-certificates && \ + if [ -f /etc/os-release ] && . /etc/os-release && [ "$ID" = "rocky" ] && [ "${VERSION_ID%%.*}" -ge 10 ]; then \ + echo "Rocky 10+: JDK 8/11 not in distro repos, downloading from Adoptium"; \ + sudo dnf install -y --allowerasing --nobest java-21-openjdk-devel; \ + ADOPTIUM_BASE="https://github.com/adoptium/temurin8-binaries/releases/download/jdk8u442-b06/OpenJDK8U-jdk_x64_linux_hotspot_8u442b06"; \ + curl -fsSL "$ADOPTIUM_BASE.tar.gz" -o /tmp/jdk8.tar.gz && \ + sudo mkdir -p /usr/lib/jvm && sudo tar xzf /tmp/jdk8.tar.gz -C /usr/lib/jvm && \ + sudo ln -sf /usr/lib/jvm/jdk8u442-b06 /usr/lib/jvm/java-1.8.0-openjdk && \ + sudo alternatives --install /usr/bin/java java /usr/lib/jvm/java-1.8.0-openjdk/bin/java 1 && \ + rm /tmp/jdk8.tar.gz && \ + ADOPTIUM_BASE11="https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.26%2B4/OpenJDK11U-jdk_x64_linux_hotspot_11.0.26_4"; \ + curl -fsSL "$ADOPTIUM_BASE11.tar.gz" -o /tmp/jdk11.tar.gz && \ + sudo mkdir -p /usr/lib/jvm && sudo tar xzf /tmp/jdk11.tar.gz -C /usr/lib/jvm && \ + sudo ln -sf /usr/lib/jvm/jdk-11.0.26+4 /usr/lib/jvm/java-11-openjdk && \ + sudo alternatives --install /usr/bin/java java /usr/lib/jvm/java-11-openjdk/bin/java 2 && \ + rm /tmp/jdk11.tar.gz; \ + else \ + sudo dnf install -y --allowerasing --nobest \ + java-1.8.0-openjdk-devel \ + java-11-openjdk-devel; \ + fi && \ sudo dnf clean all; \ fi