# (C) Copyright IBM Corporation 2021, 2024 # # Licensed 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 # # https://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. # FROM registry.access.redhat.com/ubi9/ubi:latest ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' LC_ALL='en_US.UTF-8' RUN dnf install -y \ # CRIU dependencies iptables-libs iptables jansson libibverbs libmnl libnet libnftnl libpcap nftables protobuf-c \ # Semeru dependencies tzdata openssl ca-certificates fontconfig glibc-langpack-en gzip tar \ && dnf update -y && dnf clean all; LABEL name="IBM Semeru Runtime Open Edition" \ vendor="International Business Machines Corporation" \ version="jdk-17.0.12+7_openj9-0.46.1" \ release="17" \ run="docker run --rm -ti /bin/bash" \ summary="IBM Semeru Runtime Docker Image for OpenJDK with openj9 and ubi" \ description="For more information on this image please see https://github.com/ibmruntimes/semeru-containers/blob/master/README.md" # Install CRIU RUN --mount=type=secret,id=criu_secrets source /run/secrets/criu_secrets; \ ARCH="$(uname -m)"; \ case "${ARCH}" in \ amd64|x86_64|ppc64el|ppc64le|s390x|aarch64|arm64) \ case "${ARCH}" in \ amd64|x86_64) \ CRIU_URL='https://na-public.artifactory.swg-devops.com/artifactory/sys-rt-generic-local/hyc-runtimes-jenkins.swg-devops.com/criu_build_sandbox/73/x64_linux/ubi9/criu.tar.gz'; \ CRIU_SHA_URL='https://na-public.artifactory.swg-devops.com/artifactory/sys-rt-generic-local/hyc-runtimes-jenkins.swg-devops.com/criu_build_sandbox/73/x64_linux/ubi9/criu.tar.gz.sha256.txt'; \ ;; \ ppc64el|ppc64le) \ CRIU_URL='https://na-public.artifactory.swg-devops.com/artifactory/sys-rt-generic-local/hyc-runtimes-jenkins.swg-devops.com/criu_build_sandbox/73/ppc64le_linux/ubi9/criu.tar.gz'; \ CRIU_SHA_URL='https://na-public.artifactory.swg-devops.com/artifactory/sys-rt-generic-local/hyc-runtimes-jenkins.swg-devops.com/criu_build_sandbox/73/ppc64le_linux/ubi9/criu.tar.gz.sha256.txt'; \ ;; \ s390x) \ CRIU_URL='https://na-public.artifactory.swg-devops.com/artifactory/sys-rt-generic-local/hyc-runtimes-jenkins.swg-devops.com/criu_build_sandbox/73/s390x_linux/ubi9/criu.tar.gz'; \ CRIU_SHA_URL='https://na-public.artifactory.swg-devops.com/artifactory/sys-rt-generic-local/hyc-runtimes-jenkins.swg-devops.com/criu_build_sandbox/73/s390x_linux/ubi9/criu.tar.gz.sha256.txt'; \ ;; \ aarch64) \ CRIU_URL='https://na-public.artifactory.swg-devops.com/artifactory/sys-rt-generic-local/hyc-runtimes-jenkins.swg-devops.com/build-scripts/criu_build/36/aarch64_linux/criu.tar.gz'; \ CRIU_SHA_URL='https://na-public.artifactory.swg-devops.com/artifactory/sys-rt-generic-local/hyc-runtimes-jenkins.swg-devops.com/build-scripts/criu_build/36/aarch64_linux/criu.tar.gz.sha256.txt'; \ ;; \ *) \ echo "CRIU is not supported on: ${ARCH}"; \ ;; \ esac; \ cd /tmp; \ curl -H "${CRIU_AUTH_HEADER}" -LfsSo criu.tar.gz ${CRIU_URL}; \ curl -H "${CRIU_AUTH_HEADER}" -LfsSo criu.tar.gz.sha256.txt ${CRIU_SHA_URL}; \ sha256sum -c criu.tar.gz.sha256.txt; \ tar -xzf criu.tar.gz --strip-components=1; \ cp -R usr/local /usr; \ echo /usr/local/lib64 > /etc/ld.so.conf.d/criu.conf; \ ldconfig; \ setcap cap_checkpoint_restore,cap_sys_ptrace,cap_setpcap=eip /usr/local/sbin/criu; \ mkdir -p /opt/criu; \ cp /usr/local/sbin/criu /opt/criu/criu; \ setcap cap_checkpoint_restore,cap_setpcap=eip /opt/criu/criu; \ rm -fr criu criu.tar.gz; \ ;; \ *) \ echo "CRIU is not supported on: ${ARCH}"; \ ;; \ esac; ENV PATH="/usr/local/sbin:$PATH" ENV JAVA_VERSION jdk-17.0.12+7_openj9-0.46.1 RUN set -eux; \ ARCH="$(uname -m)"; \ case "${ARCH}" in \ aarch64|arm64) \ ESUM='7484887b92ea21fecfc506146545eb68a7bdd2b9a373022ae27fb30832002ad0'; \ BINARY_URL='https://github.com/ibmruntimes/semeru17-binaries/releases/download/jdk-17.0.12%2B7_openj9-0.46.1/ibm-semeru-open-jdk_aarch64_linux_17.0.12_7_openj9-0.46.1.tar.gz'; \ ;; \ amd64|x86_64) \ ESUM='67890f8b705cc1cab1024a4cd86da7eb34adfc76b3917d8f708776e5b0c9f8b3'; \ BINARY_URL='https://github.com/ibmruntimes/semeru17-binaries/releases/download/jdk-17.0.12%2B7_openj9-0.46.1/ibm-semeru-open-jdk_x64_linux_17.0.12_7_openj9-0.46.1.tar.gz'; \ ;; \ ppc64el|ppc64le) \ ESUM='19b2ab1471ad29b01d0af4b66dce1f3c64fb736e727dc977cacaa38ed22dfd99'; \ BINARY_URL='https://github.com/ibmruntimes/semeru17-binaries/releases/download/jdk-17.0.12%2B7_openj9-0.46.1/ibm-semeru-open-jdk_ppc64le_linux_17.0.12_7_openj9-0.46.1.tar.gz'; \ ;; \ s390x) \ ESUM='facf9c788668d6de1fb2aea3ceb6a613fb547fde70189f9ada8c60e82f201583'; \ BINARY_URL='https://github.com/ibmruntimes/semeru17-binaries/releases/download/jdk-17.0.12%2B7_openj9-0.46.1/ibm-semeru-open-jdk_s390x_linux_17.0.12_7_openj9-0.46.1.tar.gz'; \ ;;\ *) \ echo "Unsupported arch: ${ARCH}"; \ exit 1; \ ;; \ esac; \ curl -LfsSo /tmp/openjdk.tar.gz ${BINARY_URL}; \ echo "${ESUM} */tmp/openjdk.tar.gz" | sha256sum -c -; \ mkdir -p /opt/java/openjdk; \ cd /opt/java/openjdk; \ tar -xf /tmp/openjdk.tar.gz --strip-components=1; \ mkdir -p /licenses; \ cp /opt/java/openjdk/legal/java.base/LICENSE /licenses; \ rm -rf /tmp/openjdk.tar.gz; ENV JAVA_HOME=/opt/java/openjdk \ PATH="/opt/java/openjdk/bin:$PATH" ENV JAVA_TOOL_OPTIONS="-XX:+IgnoreUnrecognizedVMOptions -XX:+PortableSharedCache -XX:+IdleTuningGcOnIdle -Xshareclasses:name=openj9_system_scc,cacheDir=/opt/java/.scc,readonly,nonFatal" # Create OpenJ9 SharedClassCache (SCC) for bootclasses to improve the java startup. # Downloads and runs tomcat to generate SCC for bootclasses at /opt/java/.scc/openj9_system_scc # Does a dry-run and calculates the optimal cache size and recreates the cache with the appropriate size. # With SCC, OpenJ9 startup is improved ~50% with an increase in image size of ~14MB # Application classes can be create a separate cache layer with this as the base for further startup improvement RUN set -eux; \ unset OPENJ9_JAVA_OPTIONS; \ SCC_SIZE="50m"; \ DOWNLOAD_PATH_TOMCAT=/tmp/tomcat; \ INSTALL_PATH_TOMCAT=/opt/tomcat-home; \ TOMCAT_CHECKSUM="b18103153169c7bf98da055f8ba0ac3e141d121c78869881d3be480e90fcbc3a178a8e71fa70a11aee7f2584727df72be15d30331faec65f4e57c7e67c85c1cf"; \ TOMCAT_DWNLD_URL="https://dlcdn.apache.org/tomcat/tomcat-9/v9.0.95/bin/apache-tomcat-9.0.95.tar.gz"; \ \ mkdir -p "${DOWNLOAD_PATH_TOMCAT}" "${INSTALL_PATH_TOMCAT}"; \ curl -LfsSo "${DOWNLOAD_PATH_TOMCAT}"/tomcat.tar.gz "${TOMCAT_DWNLD_URL}"; \ echo "${TOMCAT_CHECKSUM} *${DOWNLOAD_PATH_TOMCAT}/tomcat.tar.gz" | sha512sum -c -; \ tar -xf "${DOWNLOAD_PATH_TOMCAT}"/tomcat.tar.gz -C "${INSTALL_PATH_TOMCAT}" --strip-components=1; \ rm -rf "${DOWNLOAD_PATH_TOMCAT}"; \ \ java -Xshareclasses:name=dry_run_scc,cacheDir=/opt/java/.scc,bootClassesOnly,nonFatal,createLayer -Xscmx$SCC_SIZE -version; \ export OPENJ9_JAVA_OPTIONS="-XX:+IProfileDuringStartupPhase -Xshareclasses:name=dry_run_scc,cacheDir=/opt/java/.scc,bootClassesOnly,nonFatal"; \ "${INSTALL_PATH_TOMCAT}"/bin/startup.sh; \ sleep 5; \ "${INSTALL_PATH_TOMCAT}"/bin/shutdown.sh -force; \ sleep 15; \ FULL=$( (java -Xshareclasses:name=dry_run_scc,cacheDir=/opt/java/.scc,printallStats 2>&1 || true) | awk '/^Cache is [0-9.]*% .*full/ {print substr($3, 1, length($3)-1)}'); \ DST_CACHE=$(java -Xshareclasses:name=dry_run_scc,cacheDir=/opt/java/.scc,destroy 2>&1 || true); \ SCC_SIZE=$(echo $SCC_SIZE | sed 's/.$//'); \ SCC_SIZE=$(awk "BEGIN {print int($SCC_SIZE * $FULL / 100.0)}"); \ [ "${SCC_SIZE}" -eq 0 ] && SCC_SIZE=1; \ SCC_SIZE="${SCC_SIZE}m"; \ java -Xshareclasses:name=openj9_system_scc,cacheDir=/opt/java/.scc,bootClassesOnly,nonFatal,createLayer -Xscmx$SCC_SIZE -version; \ unset OPENJ9_JAVA_OPTIONS; \ \ export OPENJ9_JAVA_OPTIONS="-XX:+IProfileDuringStartupPhase -Xshareclasses:name=openj9_system_scc,cacheDir=/opt/java/.scc,bootClassesOnly,nonFatal"; \ "${INSTALL_PATH_TOMCAT}"/bin/startup.sh; \ sleep 5; \ "${INSTALL_PATH_TOMCAT}"/bin/shutdown.sh -force; \ sleep 5; \ FULL=$( (java -Xshareclasses:name=openj9_system_scc,cacheDir=/opt/java/.scc,printallStats 2>&1 || true) | awk '/^Cache is [0-9.]*% .*full/ {print substr($3, 1, length($3)-1)}'); \ echo "SCC layer is $FULL% full."; \ rm -rf "${INSTALL_PATH_TOMCAT}"; \ if [ -d "/opt/java/.scc" ]; then \ chmod -R 0777 /opt/java/.scc; \ fi; \ \ echo "SCC generation phase completed"; # For InstantOn, generate instanton.ld.so.cache which excludes glibc-hwcaps directories. # ldconfig output example lines: # libcap-ng.so.0 (libc6,64bit) => /lib64/libcap-ng.so.0 # libc_malloc_debug.so.0 (libc6,64bit, OS ABI: Linux 3.10.0) => /lib64/libc_malloc_debug.so.0 # libc.so.6 (libc6,64bit, hwcap: "power10", OS ABI: Linux 3.10.0) => /lib64/glibc-hwcaps/power10/libc.so.6 # sed regexp filter should pass any line that looks as follows: ... => /.../glibc-hwcaps/... RUN glibc_hwcaps_dirs=$(ldconfig --print-cache | sed --regexp-extended --silent 's,^.+[[:space:]]+=>[[:space:]]+(/.+/glibc-hwcaps)/.+$,\1,p' | sort | uniq) \ && mv -v /etc/ld.so.cache /etc/ld.so.cache.orig \ && for d in $glibc_hwcaps_dirs; do mv -v $d $d-hidden; done \ && ldconfig \ && mv -v /etc/ld.so.cache /etc/instanton.ld.so.cache \ && for d in $glibc_hwcaps_dirs; do mv -v $d-hidden $d; done \ && mv -v /etc/ld.so.cache.orig /etc/ld.so.cache USER 1001