diff --git a/Elasticsearch/8.9.2/build_elasticsearch.sh b/Elasticsearch/8.9.2/build_elasticsearch.sh new file mode 100644 index 00000000..9b8cc175 --- /dev/null +++ b/Elasticsearch/8.9.2/build_elasticsearch.sh @@ -0,0 +1,366 @@ +#!/bin/bash +# © Copyright IBM Corporation 2023. +# LICENSE: Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) +# +# Instructions: +# Download build script: wget https://raw.githubusercontent.com/linux-on-ibm-z/scripts/master/Elasticsearch/8.9.2/build_elasticsearch.sh +# Execute build script: bash build_elasticsearch.sh (provide -h for help) +# +set -e -o pipefail + +PACKAGE_NAME="elasticsearch" +PACKAGE_VERSION="8.9.2" +CURDIR="$(pwd)" +PATCH_URL="https://raw.githubusercontent.com/linux-on-ibm-z/scripts/master/Elasticsearch/8.9.2/patch/elasticsearch.patch" +TEMURIN_URL="https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.7%2B7/OpenJDK17U-jdk_s390x_linux_hotspot_17.0.7_7.tar.gz" +ES_REPO_URL="https://github.com/elastic/elasticsearch" +LOG_FILE="$CURDIR/logs/${PACKAGE_NAME}-${PACKAGE_VERSION}-$(date +"%F-%T").log" +JAVA_PROVIDED="Temurin17" +NON_ROOT_USER="$(whoami)" +FORCE="false" +BUILD_ENV="$HOME/setenv.sh" +CPU_NUM="$(grep -c ^processor /proc/cpuinfo)" + +trap cleanup 0 1 2 ERR + +# Check if directory exists +if [ ! -d "$CURDIR/logs/" ]; then + mkdir -p "$CURDIR/logs/" +fi + +if [ -f "/etc/os-release" ]; then + source "/etc/os-release" +fi + +DISTRO="$ID-$VERSION_ID" +LOG_FILE="$CURDIR/logs/${PACKAGE_NAME}-${PACKAGE_VERSION}-${DISTRO}-$(date +"%F-%T").log" + +function prepare() { + + if command -v "sudo" >/dev/null; then + printf -- 'Sudo : Yes\n' >>"$LOG_FILE" + else + printf -- 'Sudo : No \n' >>"$LOG_FILE" + printf -- 'Install sudo from repository using apt, yum or zypper based on your distro. \n' + exit 1 + fi + + if [[ "$JAVA_PROVIDED" != "Temurin17" && "$JAVA_PROVIDED" != "OpenJDK17" ]]; then + printf "$JAVA_PROVIDED is not supported. Please use valid variant from {Temurin17, OpenJDK17} only.\n" + exit 1 + fi + + if [[ "$FORCE" == "true" ]]; then + printf -- 'Force attribute provided hence continuing with install without confirmation message\n' |& tee -a "$LOG_FILE" + else + printf -- 'As part of the installation, dependencies would be installed/upgraded.\n' + + while true; do + read -r -p "Do you want to continue (y/n) ? : " yn + case $yn in + [Yy]*) + + break + ;; + [Nn]*) exit ;; + *) echo "Please provide Correct input to proceed." ;; + esac + done + fi + + # zero out + true > "$BUILD_ENV" +} + +function cleanup() { + rm -rf "${CURDIR}/temurin.tar.gz" + printf -- '\nCleaned up the artifacts.\n' >>"$LOG_FILE" +} + +function configureAndInstall() { + printf -- '\nConfiguration and Installation started \n' + # Install Java + if [[ "$JAVA_PROVIDED" == "Temurin17" ]]; then + printf -- "\nInstalling Temurin 17 . . . \n" + cd "$CURDIR" + sudo mkdir -p /opt/temurin/java + curl -SL -o temurin.tar.gz $TEMURIN_URL + # Everytime new jdk is downloaded, Ensure that --strip valueis correct + sudo tar -zxf temurin.tar.gz -C /opt/temurin/java --strip-components 1 + export ES_JAVA_HOME=/opt/temurin/java + printf -- "Installation of Temurin 17 is successful\n" >> "$LOG_FILE" + elif [[ "$JAVA_PROVIDED" == "OpenJDK17" ]]; then + printf -- "\nInstalling OpenJDK 17 . . . \n" + if [[ "${ID}" == "ubuntu" ]]; then + sudo DEBIAN_FRONTEND=noninteractive apt-get install -y openjdk-17-jre openjdk-17-jdk ca-certificates-java + export ES_JAVA_HOME=/usr/lib/jvm/java-17-openjdk-s390x + elif [[ "${ID}" == "rhel" ]]; then + if [[ "${DISTRO}" == "rhel-7."* ]]; then + printf "$JAVA_PROVIDED is not available on RHEL 7. Please use valid variant Temurin17.\n" + exit 1 + else + sudo yum install -y java-17-openjdk-devel + export ES_JAVA_HOME=/usr/lib/jvm/java-17-openjdk + fi + elif [[ "${ID}" == "sles" ]]; then + if [[ "${DISTRO}" == "sles-12.5" ]]; then + printf "$JAVA_PROVIDED is not available on SLES 12 SP5. Please use valid variant Temurin17.\n" + exit 1 + else + sudo zypper install -y java-17-openjdk java-17-openjdk-devel + export ES_JAVA_HOME=/usr/lib64/jvm/java-17-openjdk + fi + fi + printf -- "Installation of OpenJDK 17 is successful\n" >> "$LOG_FILE" + else + printf "$JAVA_PROVIDED is not supported. Please use valid variant from {Temurin17, OpenJDK17} only.\n" + exit 1 + fi + + export LANG="en_US.UTF-8" + export JAVA_HOME=$ES_JAVA_HOME + export JAVA17_HOME=$ES_JAVA_HOME + printf -- "export LANG="en_US.UTF-8"\n" >> "$BUILD_ENV" + printf -- "export ES_JAVA_HOME=$ES_JAVA_HOME\n" >> "$BUILD_ENV" + printf -- "export JAVA_HOME=$JAVA_HOME\n" >> "$BUILD_ENV" + + export PATH=$ES_JAVA_HOME/bin:$PATH + printf -- "export PATH=$PATH\n" >> "$BUILD_ENV" + java -version |& tee -a "$LOG_FILE" + + #Build JANSI v2.4.0 + cd $CURDIR + git clone https://github.com/fusesource/jansi.git + cd jansi + git checkout jansi-2.4.0 + make clean-native native OS_NAME=Linux OS_ARCH=s390x + + mkdir -p $CURDIR/jansi-jar + cd $CURDIR/jansi-jar + wget https://repo1.maven.org/maven2/org/fusesource/jansi/jansi/2.4.0/jansi-2.4.0.jar + jar xvf jansi-2.4.0.jar + cd org/fusesource/jansi/internal/native/Linux + mkdir s390x + cp $CURDIR/jansi/target/native-Linux-s390x/libjansi.so s390x/ + cd $CURDIR/jansi-jar + jar cvf jansi-2.4.0.jar . + + mkdir -p $CURDIR/.gradle/caches/modules-2/files-2.1/org.fusesource.jansi/jansi/2.4.0/321c614f85f1dea6bb08c1817c60d53b7f3552fd/ + cp jansi-2.4.0.jar $CURDIR/.gradle/caches/modules-2/files-2.1/org.fusesource.jansi/jansi/2.4.0/321c614f85f1dea6bb08c1817c60d53b7f3552fd/ + export sha256=$(sha256sum jansi-2.4.0.jar | awk '{print $1}') + + cd $CURDIR + # Download and configure ElasticSearch + printf -- 'Downloading Elasticsearch. Please wait.\n' + git clone $ES_REPO_URL + cd $CURDIR/elasticsearch + git checkout v$PACKAGE_VERSION + + # Apply patch + curl -o elasticsearch.patch $PATCH_URL + git apply --ignore-whitespace elasticsearch.patch + mkdir -p $CURDIR/elasticsearch/distribution/docker/ubi-docker-s390x-export/ + echo ' + // This file is intentionally blank. All configuration of the + // export is done in the parent project. + ' | tee $CURDIR/elasticsearch/distribution/docker/ubi-docker-s390x-export/build.gradle + mkdir -p $CURDIR/elasticsearch/distribution/docker/cloud-docker-s390x-export/ + echo ' + // This file is intentionally blank. All configuration of the + // export is done in the parent project. + ' | tee $CURDIR/elasticsearch/distribution/docker/cloud-docker-s390x-export/build.gradle + mkdir -p $CURDIR/elasticsearch/distribution/docker/cloud-ess-docker-s390x-export/ + echo ' + // This file is intentionally blank. All configuration of the + // export is done in the parent project. + ' | tee $CURDIR/elasticsearch/distribution/docker/cloud-ess-docker-s390x-export/build.gradle + mkdir -p $CURDIR/elasticsearch/distribution/docker/docker-s390x-export/ + echo ' + // This file is intentionally blank. All configuration of the + // export is done in the parent project. + ' | tee $CURDIR/elasticsearch/distribution/docker/docker-s390x-export/build.gradle + mkdir -p $CURDIR/elasticsearch/distribution/docker/ironbank-docker-s390x-export/ + echo ' + // This file is intentionally blank. All configuration of the + // export is done in the parent project. + ' | tee $CURDIR/elasticsearch/distribution/docker/ironbank-docker-s390x-export/build.gradle + sed -i 's|6cd91991323dd7b2fb28ca93d7ac12af5a86a2f53279e2b35827b30313fd0b9f|'"${sha256}"'|g' ${CURDIR}/elasticsearch/gradle/verification-metadata.xml + + # Building Elasticsearch + printf -- 'Building Elasticsearch \n' + printf -- 'Build might take some time. Sit back and relax\n' + export GRADLE_USER_HOME=$CURDIR/.gradle + ./gradlew :distribution:archives:linux-s390x-tar:assemble --max-workers="$CPU_NUM" --parallel + + # Verifying Elasticsearch installation + if [[ $(grep -q "BUILD FAILED" "$LOG_FILE") ]]; then + printf -- '\nBuild failed due to some unknown issues.\n' + exit 1 + fi + printf -- 'Built Elasticsearch successfully. \n\n' + + printf -- 'Creating distributions as deb, rpm and docker: \n\n' + ./gradlew :distribution:packages:s390x-deb:assemble + printf -- 'Created deb distribution. \n\n' + ./gradlew :distribution:packages:s390x-rpm:assemble + printf -- 'Created rpm distribution. \n\n' + ./gradlew :distribution:docker:docker-s390x-export:assemble + printf -- 'Created docker distribution. \n\n' + + printf -- "\n\nInstalling Elasticsearch\n" + + cd "${CURDIR}/elasticsearch" + sudo mkdir /usr/share/elasticsearch + sudo tar -xzf distribution/archives/linux-s390x-tar/build/distributions/elasticsearch-"${PACKAGE_VERSION}"-SNAPSHOT-linux-s390x.tar.gz -C /usr/share/elasticsearch --strip-components 1 + sudo ln -sf /usr/share/elasticsearch/bin/* /usr/bin/ + + if ([[ -z "$(cut -d: -f1 /etc/group | grep elastic)" ]]); then + printf -- '\nCreating group elastic.\n' + sudo /usr/sbin/groupadd elastic # If group is not already created + fi + sudo chown "$NON_ROOT_USER:elastic" -R /usr/share/elasticsearch + + #update config to disable xpack.ml + sudo echo 'xpack.ml.enabled: false' >> /usr/share/elasticsearch/config/elasticsearch.yml + + # Verifying Elasticsearch installation + if command -v "$PACKAGE_NAME" >/dev/null; then + printf -- "%s installation completed.\n" "$PACKAGE_NAME" + else + printf -- "Error while installing %s, exiting with 127 \n" "$PACKAGE_NAME" + exit 127 + fi +} + +function runTest() { + # Setting environment variable needed for testing --max-workers=2 + export JAVA_TOOL_OPTIONS="-Dfile.encoding=UTF8" + source $HOME/setenv.sh + export RUNTIME_JAVA_HOME=$ES_JAVA_HOME + + cd "${CURDIR}/elasticsearch" + set +e + # Run Elasticsearch test suite + printf -- '\n Running Elasticsearch test suite.\n' + ./gradlew --continue test -Dtests.haltonfailure=false -Dtests.jvm.argline="-Xss2m" |& tee -a ${CURDIR}/logs/test_results.log + printf -- '***********************************************************************************************************************************' + printf -- '\n Some X-Pack test cases will fail as X-Pack plugins are not supported on s390x, such as Machine Learning features.\n' + printf -- '\n Certain test cases may require an individual rerun to pass.\n' + printf -- '***********************************************************************************************************************************\n' + set -e +} + +function logDetails() { + printf -- 'SYSTEM DETAILS\n' >"$LOG_FILE" + if [ -f "/etc/os-release" ]; then + cat "/etc/os-release" >>"$LOG_FILE" + fi + + cat /proc/version >>"$LOG_FILE" + printf -- "\nDetected %s \n" "$PRETTY_NAME" + printf -- "Request details : PACKAGE NAME= %s , VERSION= %s \n" "$PACKAGE_NAME" "$PACKAGE_VERSION" |& tee -a "$LOG_FILE" +} + +# Print the usage message +function printHelp() { + echo + echo "Usage: " + echo " bash build_elasticsearch.sh [-d debug] [-y install-without-confirmation] [-t install-with-tests] [-j Java to use from {Temurin17, OpenJDK17}]" + echo " default: If no -j specified, Temurin 17 will be installed" + echo +} + +while getopts "h?dytj:" opt; do + case "$opt" in + h | \?) + printHelp + exit 0 + ;; + d) + set -x + ;; + y) + FORCE="true" + ;; + t) + if command -v "$PACKAGE_NAME" >/dev/null; then + TESTS="true" + printf -- "%s is detected with version %s .\n" "$PACKAGE_NAME" "$PACKAGE_VERSION" |& tee -a "$LOG_FILE" + runTest |& tee -a "$LOG_FILE" + exit 0 + + else + TESTS="true" + fi + ;; + j) + JAVA_PROVIDED="$OPTARG" + ;; + esac +done + +function printSummary() { + printf -- '\n***********************************************************************************************************************************\n' + printf -- "\n* Getting Started * \n" + printf -- "Note: Environment Variables needed have been added to $HOME/setenv.sh\n" + printf -- "Note: To set the Environment Variables needed for Elasticsearch, please run: source $HOME/setenv.sh \n" + printf -- '\n\nStart Elasticsearch using the following command: elasticsearch ' + printf -- '***********************************************************************************************************************************\n' +} + +logDetails +prepare + +DISTRO="$ID-$VERSION_ID" +case "$DISTRO" in +"ubuntu-20.04" | "ubuntu-22.04") + printf -- "Installing %s %s for %s \n" "$PACKAGE_NAME" "$PACKAGE_VERSION" "$DISTRO" | tee -a "$LOG_FILE" + printf -- "Installing dependencies... it may take some time.\n" + sudo apt-get update + sudo DEBIAN_FRONTEND=noninteractive apt-get install -y curl git gzip tar wget patch locales make gcc g++ |& tee -a "$LOG_FILE" + sudo locale-gen en_US.UTF-8 + configureAndInstall |& tee -a "$LOG_FILE" + ;; + +"rhel-7.8" | "rhel-7.9") + printf -- "Installing %s %s for %s \n" "$PACKAGE_NAME" "$PACKAGE_VERSION" "$DISTRO" |& tee -a "$LOG_FILE" + printf -- "Installing dependencies... it may take some time.\n" + sudo yum install -y curl git gzip tar wget patch make gcc gcc-c++ rh-git227-git.s390x |& tee -a "$LOG_FILE" + source /opt/rh/rh-git227/enable + configureAndInstall |& tee -a "$LOG_FILE" + ;; + +"rhel-8.6" | "rhel-8.8" | "rhel-9.0" | "rhel-9.2") + printf -- "Installing %s %s for %s \n" "$PACKAGE_NAME" "$PACKAGE_VERSION" "$DISTRO" |& tee -a "$LOG_FILE" + printf -- "Installing dependencies... it may take some time.\n" + sudo yum install -y curl git gzip tar wget patch make gcc gcc-c++ |& tee -a "$LOG_FILE" + configureAndInstall |& tee -a "$LOG_FILE" + ;; + +"sles-12.5") + printf -- "Installing %s %s for %s \n" "$PACKAGE_NAME" "$PACKAGE_VERSION" "$DISTRO" |& tee -a "$LOG_FILE" + printf -- "Installing dependencies... it may take some time.\n" + sudo zypper install -y curl libnghttp2-devel git gzip tar wget patch make gcc gcc-c++ | tee -a "$LOG_FILE" + configureAndInstall |& tee -a "$LOG_FILE" + ;; + +"sles-15.4" | "sles-15.5") + printf -- "Installing %s %s for %s \n" "$PACKAGE_NAME" "$PACKAGE_VERSION" "$DISTRO" |& tee -a "$LOG_FILE" + printf -- "Installing dependencies... it may take some time.\n" + sudo zypper install -y curl git gzip tar wget patch make gcc gcc-c++ | tee -a "$LOG_FILE" + configureAndInstall |& tee -a "$LOG_FILE" + ;; + +*) + printf -- "%s not supported \n" "$DISTRO" |& tee -a "$LOG_FILE" + exit 1 + ;; +esac + +# Run tests +if [[ "$TESTS" == "true" ]]; then + runTest |& tee -a "$LOG_FILE" +fi + +cleanup +printSummary |& tee -a "$LOG_FILE" diff --git a/Elasticsearch/8.9.2/patch/elasticsearch.patch b/Elasticsearch/8.9.2/patch/elasticsearch.patch new file mode 100644 index 00000000..55e0cea9 --- /dev/null +++ b/Elasticsearch/8.9.2/patch/elasticsearch.patch @@ -0,0 +1,418 @@ +diff --git a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/Jdk.java b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/Jdk.java +index f66bcb51ea5..dbf4883a33f 100644 +--- a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/Jdk.java ++++ b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/Jdk.java +@@ -23,7 +23,7 @@ import java.util.regex.Pattern; + + public class Jdk implements Buildable, Iterable { + +- private static final List ALLOWED_ARCHITECTURES = List.of("aarch64", "x64"); ++ private static final List ALLOWED_ARCHITECTURES = List.of("aarch64", "s390x", "x64"); + private static final List ALLOWED_VENDORS = List.of("adoptium", "openjdk", "zulu"); + private static final List ALLOWED_PLATFORMS = List.of("darwin", "linux", "windows", "mac"); + private static final Pattern VERSION_PATTERN = Pattern.compile( +diff --git a/build-tools-internal/version.properties b/build-tools-internal/version.properties +index 9923a7cdbbc..5b28c4db55f 100644 +--- a/build-tools-internal/version.properties ++++ b/build-tools-internal/version.properties +@@ -1,8 +1,8 @@ + elasticsearch = 8.9.2 + lucene = 9.7.0 + +-bundled_jdk_vendor = openjdk +-bundled_jdk = 20.0.2+9@6e380f22cbe7469fa75fb448bd903d8e ++bundled_jdk_vendor = adoptium ++bundled_jdk = 17.0.7+7 + + # optional dependencies + spatial4j = 0.7 +diff --git a/build-tools/src/main/java/org/elasticsearch/gradle/Architecture.java b/build-tools/src/main/java/org/elasticsearch/gradle/Architecture.java +index 34874b62d94..90d91235829 100644 +--- a/build-tools/src/main/java/org/elasticsearch/gradle/Architecture.java ++++ b/build-tools/src/main/java/org/elasticsearch/gradle/Architecture.java +@@ -11,7 +11,8 @@ package org.elasticsearch.gradle; + public enum Architecture { + + X64("x86_64", "linux/amd64"), +- AARCH64("aarch64", "linux/arm64"); ++ AARCH64("aarch64", "linux/arm64"), ++ S390X("s390x", "linux/s390x"); + + public final String classifier; + public final String dockerPlatform; +@@ -26,6 +27,7 @@ public enum Architecture { + return switch (architecture) { + case "amd64", "x86_64" -> X64; + case "aarch64" -> AARCH64; ++ case "s390x" -> S390X; + default -> throw new IllegalArgumentException("can not determine architecture from [" + architecture + "]"); + }; + } +diff --git a/distribution/archives/build.gradle b/distribution/archives/build.gradle +index dcd9fbf7330..e02cad4f9e1 100644 +--- a/distribution/archives/build.gradle ++++ b/distribution/archives/build.gradle +@@ -97,6 +97,13 @@ distribution_archives { + } + } + ++ linuxS390xTar { ++ archiveClassifier = 'linux-s390x' ++ content { ++ archiveFiles(modulesFiles('linux-s390x'), 'tar', 'linux', 's390x', false) ++ } ++ } ++ + linuxTar { + archiveClassifier = 'linux-x86_64' + content { +diff --git a/distribution/build.gradle b/distribution/build.gradle +index 2a7ad283a81..448617d3f04 100644 +--- a/distribution/build.gradle ++++ b/distribution/build.gradle +@@ -233,7 +233,7 @@ configure(subprojects.findAll { ['archives', 'packages'].contains(it.name) }) { + // Setup all required JDKs + project.jdks { + ['darwin', 'windows', 'linux'].each { platform -> +- (platform == 'linux' || platform == 'darwin' ? ['x64', 'aarch64'] : ['x64']).each { architecture -> ++ (platform == 'linux' || platform == 'darwin' ? ['x64', 'aarch64', 's390x'] : ['x64']).each { architecture -> + "bundled_${platform}_${architecture}" { + it.platform = platform + it.version = VersionProperties.bundledJdkVersion +@@ -331,7 +331,7 @@ configure(subprojects.findAll { ['archives', 'packages'].contains(it.name) }) { + it.mode = 0644 + } + } +- List excludePlatforms = ['linux-x86_64', 'linux-aarch64', 'windows-x86_64', 'darwin-x86_64', 'darwin-aarch64'] ++ List excludePlatforms = ['linux-x86_64', 'linux-aarch64', 'linux-s390x', 'windows-x86_64', 'darwin-x86_64', 'darwin-aarch64'] + if (platform != null) { + excludePlatforms.remove(excludePlatforms.indexOf(platform)) + } else { +@@ -586,10 +586,12 @@ subprojects { + 'archives:darwin-tar', + 'archives:darwin-aarch64-tar', + 'archives:linux-aarch64-tar', ++ 'archives:linux-s390x-tar', + 'archives:linux-tar', + 'archives:integ-test-zip', + 'packages:rpm', 'packages:deb', + 'packages:aarch64-rpm', 'packages:aarch64-deb', ++ 'packages:s390x-rpm', 'packages:s390x-deb', + ].forEach { subName -> + Project subproject = project("${project.path}:${subName}") + Configuration configuration = configurations.create(subproject.name) +diff --git a/distribution/docker/build.gradle b/distribution/docker/build.gradle +index c9d8531db9e..c7784eb90df 100644 +--- a/distribution/docker/build.gradle ++++ b/distribution/docker/build.gradle +@@ -77,12 +77,19 @@ configurations { + dockerSource { + attributes { + attribute(ArtifactTypeDefinition.ARTIFACT_TYPE_ATTRIBUTE, ArtifactTypeDefinition.DIRECTORY_TYPE) +- } +- } ++ } ++ } ++ ++ s390xDockerSource { ++ attributes { ++ attribute(ArtifactTypeDefinition.ARTIFACT_TYPE_ATTRIBUTE, ArtifactTypeDefinition.DIRECTORY_TYPE) ++ } ++ } ++ + // Iron bank images require a tarball + aarch64DockerSourceTar + dockerSourceTar +- ++ s390xDockerSourceTar + log4jConfig + tini + allPlugins +@@ -99,6 +106,7 @@ dependencies { + aarch64DockerSourceTar project(path: ":distribution:archives:linux-aarch64-tar", configuration:"default") + dockerSource project(":distribution:archives:linux-tar") + dockerSourceTar project(path: ":distribution:archives:linux-tar", configuration:"default") ++ s390xDockerSource project(path: ":distribution:archives:linux-s390x-tar", configuration: 'default') + log4jConfig project(path: ":distribution", configuration: 'log4jConfig') + tini "krallin:tini:0.19.0:${tiniArch}" + allPlugins project(path: ':plugins', configuration: 'allPlugins') +@@ -150,7 +158,7 @@ private static String toCamel(String input) { + + private static String taskName(String prefix, Architecture architecture, DockerBase base, String suffix) { + return prefix + +- (architecture == Architecture.AARCH64 ? 'Aarch64' : '') + ++ (architecture == Architecture.AARCH64 ? 'Aarch64' : architecture == Architecture.S390X ? 's390x' : '') + + (base == DockerBase.DEFAULT ? "" : toCamel(base.name())) + + suffix + } +@@ -209,7 +217,7 @@ tasks.register("copyNodeKeyMaterial", Sync) { + + elasticsearch_distributions { + Architecture.values().each { eachArchitecture -> +- "docker_${eachArchitecture == Architecture.AARCH64 ? '_aarch64' : ''}" { ++ "docker_${eachArchitecture == Architecture.AARCH64 ? '_aarch64' : eachArchitecture == Architecture.S390X ? '_s390x' : ''}" { + architecture = eachArchitecture + type = InternalElasticsearchDistributionTypes.DOCKER + version = VersionProperties.getElasticsearch() +@@ -265,7 +273,7 @@ tasks.named("composeUp").configure { + + void addBuildDockerContextTask(Architecture architecture, DockerBase base) { + String configDirectory = base == DockerBase.IRON_BANK ? 'scripts' : 'config' +- String arch = architecture == Architecture.AARCH64 ? '-aarch64' : '' ++ String arch = architecture == Architecture.AARCH64 ? '-aarch64' : architecture == Architecture.S390X ? '-s390x' : '' + + final TaskProvider buildDockerContextTask = + tasks.register(taskName('build', architecture, base, 'DockerContext'), Tar) { +@@ -311,7 +319,7 @@ void addTransformDockerContextTask(Architecture architecture, DockerBase base) { + TaskProvider buildContextTask = tasks.named(taskName("build", architecture, base, "DockerContext")) + dependsOn(buildContextTask) + +- String arch = architecture == Architecture.AARCH64 ? '-aarch64' : '' ++ String arch = architecture == Architecture.AARCH64 ? '-aarch64' : architecture == Architecture.S390X ? '-s390x' : '' + String archiveName = "elasticsearch${base.suffix}-${VersionProperties.elasticsearch}-docker-build-context${arch}" + String distributionFolderName = "elasticsearch-${VersionProperties.elasticsearch}" + +@@ -338,7 +346,13 @@ void addTransformDockerContextTask(Architecture architecture, DockerBase base) { + rename { _ -> 'tini' } + } + } else { +- from(architecture == Architecture.AARCH64 ? configurations.aarch64DockerSource : configurations.dockerSource) ++ if (architecture == Architecture.AARCH64) { ++ configurations.aarch64DockerSource ++ } else if (architecture == Architecture.S390X) { ++ from configurations.s390xDockerSource ++ } else { ++ configurations.dockerSource ++ } + } + + expansions(architecture, base).findAll { it.key != 'build_date' }.each { k, v -> +@@ -429,7 +443,7 @@ void addBuildDockerImageTask(Architecture architecture, DockerBase base) { + + void addBuildEssDockerImageTask(Architecture architecture) { + DockerBase base = DockerBase.CLOUD_ESS +- String arch = architecture == Architecture.AARCH64 ? '-aarch64' : '' ++ String arch = architecture == Architecture.AARCH64 ? '-aarch64' : architecture == Architecture.S390X ? '-s390x' : '' + String contextDir = "${project.buildDir}/docker-context/elasticsearch${base.suffix}-${VersionProperties.elasticsearch}-docker-build-context${arch}" + + final TaskProvider buildContextTask = +@@ -501,7 +515,7 @@ subprojects { Project subProject -> + if (subProject.name.endsWith('-export')) { + apply plugin: 'distribution' + +- final Architecture architecture = subProject.name.contains('aarch64-') ? Architecture.AARCH64 : Architecture.X64 ++ final Architecture architecture = subProject.name.contains('aarch64-') ? Architecture.AARCH64 : subProject.name.contains('s390x-') ? Architecture.S390X : Architecture.X64 + DockerBase base = DockerBase.DEFAULT + if (subProject.name.contains('ubi-')) { + base = DockerBase.UBI +@@ -513,7 +527,7 @@ subprojects { Project subProject -> + base = DockerBase.CLOUD + } + +- final String arch = architecture == Architecture.AARCH64 ? '-aarch64' : '' ++ final String arch = architecture == Architecture.AARCH64 ? '-aarch64' : architecture == Architecture.S390X ? '-s390x' : '' + final String extension = base == DockerBase.UBI ? 'ubi.tar' : + (base == DockerBase.IRON_BANK ? 'ironbank.tar' : + (base == DockerBase.CLOUD ? 'cloud.tar' : +@@ -569,3 +583,4 @@ tasks.named('resolveAllDependencies') { + // Also skip building Elasticsearch distributions + configs = configurations.matching { it.name.contains('beat') == false && it.name.toLowerCase().contains('dockersource') == false } + } ++ +diff --git a/distribution/docker/docker-s390x-export/build.gradle b/distribution/docker/docker-s390x-export/build.gradle +new file mode 100644 +index 00000000000..4f7400c7eaa +--- /dev/null ++++ b/distribution/docker/docker-s390x-export/build.gradle +@@ -0,0 +1,2 @@ ++// This file is intentionally blank. All configuration of the ++// distribution is done in the parent project. +\ No newline at end of file +diff --git a/distribution/docker/src/docker/Dockerfile b/distribution/docker/src/docker/Dockerfile +index a6ecfdaf417..a4cca9e073b 100644 +--- a/distribution/docker/src/docker/Dockerfile ++++ b/distribution/docker/src/docker/Dockerfile +@@ -58,6 +58,7 @@ RUN set -eux ; \\ + case "\$(arch)" in \\ + aarch64) tini_bin='tini-arm64' ;; \\ + x86_64) tini_bin='tini-amd64' ;; \\ ++ s390x) tini_bin='tini-s390x' ;; \\ + *) echo >&2 ; echo >&2 "Unsupported architecture \$(arch)" ; echo >&2 ; exit 1 ;; \\ + esac ; \\ + curl --retry 10 -S -L -O https://github.com/krallin/tini/releases/download/v0.19.0/\${tini_bin} ; \\ +@@ -76,7 +77,7 @@ WORKDIR /usr/share/elasticsearch + // Iron Bank always copies the local artifact. It uses `arch` from the + // template context variables. + %> +-COPY elasticsearch-${version}-linux-${arch}.tar.gz /tmp/elasticsearch.tar.gz +++COPY ../../../archives/linux-s390x-tar/build/distributions/elasticsearch-8.9.2-SNAPSHOT-linux-s390x.tar.gz /tmp/elasticsearch.tar.gz + <% } else { + // Fetch the appropriate Elasticsearch distribution for this architecture. + // Keep this command on one line - it is replaced with a `COPY` during local builds. +@@ -108,7 +109,7 @@ RUN sed -i -e 's/ES_DISTRIBUTION_TYPE=tar/ES_DISTRIBUTION_TYPE=docker/' bin/elas + mv config/log4j2.docker.properties config/log4j2.properties && \\ + find . -type d -exec chmod 0555 {} + && \\ + find . -type f -exec chmod 0444 {} + && \\ +- chmod 0555 bin/* jdk/bin/* jdk/lib/jspawnhelper modules/x-pack-ml/platform/linux-*/bin/* && \\ ++ chmod 0555 bin/* jdk/bin/* jdk/lib/jspawnhelper && \\ + chmod 0775 bin config config/jvm.options.d data logs plugins && \\ + find config -type f -exec chmod 0664 {} + + +@@ -184,7 +185,7 @@ RUN <%= retry.loop( + RUN groupadd -g 1000 elasticsearch && \\ + adduser --uid 1000 --gid 1000 --home /usr/share/elasticsearch elasticsearch && \\ + adduser elasticsearch root && \\ +- chown -R 0:0 /usr/share/elasticsearch ++ chown -R 1000:0 /usr/share/elasticsearch + <% } else { %> + RUN groupadd -g 1000 elasticsearch && \\ + adduser -u 1000 -g 1000 -G 0 -d /usr/share/elasticsearch elasticsearch && \\ +@@ -195,7 +196,7 @@ ENV ELASTIC_CONTAINER true + + WORKDIR /usr/share/elasticsearch + +-COPY --from=builder --chown=0:0 /usr/share/elasticsearch /usr/share/elasticsearch ++COPY --from=builder --chown=1000:0 /usr/share/elasticsearch /usr/share/elasticsearch + COPY --from=builder --chown=0:0 /bin/tini /bin/tini + + <% if (docker_base == 'cloud') { %> +@@ -221,6 +222,7 @@ RUN chmod g=u /etc/passwd && \\ + chmod 0555 /usr/local/bin/docker-entrypoint.sh && \\ + find / -xdev -perm -4000 -exec chmod ug-s {} + && \\ + chmod 0775 /usr/share/elasticsearch && \\ ++ chown -R 1000:0 /usr/share/elasticsearch && \\ + chown elasticsearch bin config config/jvm.options.d data logs plugins + + <% if (docker_base == 'default' || docker_base == 'cloud') { %> +diff --git a/distribution/docker/src/docker/config/elasticsearch.yml b/distribution/docker/src/docker/config/elasticsearch.yml +index 50b154702b9..599e19cbf4b 100644 +--- a/distribution/docker/src/docker/config/elasticsearch.yml ++++ b/distribution/docker/src/docker/config/elasticsearch.yml +@@ -1,2 +1,3 @@ + cluster.name: "docker-cluster" + network.host: 0.0.0.0 ++xpack.ml.enabled: false +\ No newline at end of file +diff --git a/distribution/packages/build.gradle b/distribution/packages/build.gradle +index c99a9af302c..780e53fbb81 100644 +--- a/distribution/packages/build.gradle ++++ b/distribution/packages/build.gradle +@@ -91,6 +91,8 @@ def commonPackageConfig(String type, String architecture) { + if (type == 'deb') { + if (architecture == 'x64') { + arch('amd64') ++ } else if (architecture == 's390x') { ++ arch('s390x') + } else { + assert architecture == 'aarch64' : architecture + arch('arm64') +@@ -99,13 +101,15 @@ def commonPackageConfig(String type, String architecture) { + assert type == 'rpm' : type + if (architecture == 'x64') { + arch('X86_64') ++ } else if (architecture == 's390x') { ++ arch('s390x') + } else { + assert architecture == 'aarch64' : architecture + arch('aarch64') + } + } + // Follow elasticsearch's file naming convention +- String prefix = "${architecture == 'aarch64' ? 'aarch64-' : ''}${type}" ++ String prefix = "${architecture == 'aarch64' ? 'aarch64-' : 's390x' ? 's390x-' : ''}${type}" + destinationDirectory = file("${prefix}/build/distributions") + archiveFileName.value(project.provider({ "${packageName}-${project.version}-${archString}.${type}" } )) + String packagingFiles = "build/packaging/${type}" +@@ -133,7 +137,7 @@ def commonPackageConfig(String type, String architecture) { + with libFiles + } + into('modules') { +- with modulesFiles('linux-' + ((architecture == 'x64') ? 'x86_64' : architecture)) ++ with modulesFiles('linux-' + ((architecture == 'x64') ? 'x86_64' : (architecture == 's390x') ? 's390x' : architecture)) + } + into('jdk') { + with jdkFiles(project, 'linux', architecture) +@@ -317,6 +321,10 @@ tasks.register('buildAarch64Deb', Deb) { + configure(commonDebConfig('aarch64')) + } + ++tasks.register('buildS390xDeb', Deb) { ++ configure(commonDebConfig('s390x')) ++} ++ + tasks.register('buildDeb', Deb) { + configure(commonDebConfig('x64')) + } +@@ -350,6 +358,10 @@ tasks.register('buildAarch64Rpm', Rpm) { + configure(commonRpmConfig('aarch64')) + } + ++tasks.register('buildS390xRpm', Rpm) { ++ configure(commonRpmConfig('s390x')) ++} ++ + tasks.register('buildRpm', Rpm) { + configure(commonRpmConfig('x64')) + } +diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml +index d9090042894..455cbc00540 100644 +--- a/gradle/verification-metadata.xml ++++ b/gradle/verification-metadata.xml +@@ -36,6 +36,11 @@ + + + ++ ++ ++ ++ ++ + + + +diff --git a/server/src/main/java/org/elasticsearch/bootstrap/SystemCallFilter.java b/server/src/main/java/org/elasticsearch/bootstrap/SystemCallFilter.java +index 0ab855d1d5f..efb2efb49f6 100644 +--- a/server/src/main/java/org/elasticsearch/bootstrap/SystemCallFilter.java ++++ b/server/src/main/java/org/elasticsearch/bootstrap/SystemCallFilter.java +@@ -216,7 +216,9 @@ final class SystemCallFilter { + "amd64", + new Arch(0xC000003E, 0x3FFFFFFF, 57, 58, 59, 322, 317), + "aarch64", +- new Arch(0xC00000B7, 0xFFFFFFFF, 1079, 1071, 221, 281, 277) ++ new Arch(0xC00000B7, 0xFFFFFFFF, 1079, 1071, 221, 281, 277), ++ "s390x", ++ new Arch(0x80000016, 0x3FFFFFFF, 2, 190, 11, 354, 348) + ); + } + +diff --git a/settings.gradle b/settings.gradle +index 271b6ef34f6..6f923474d76 100644 +--- a/settings.gradle ++++ b/settings.gradle +@@ -61,6 +61,7 @@ List projects = [ + 'distribution:archives:darwin-tar', + 'distribution:archives:darwin-aarch64-tar', + 'distribution:archives:linux-aarch64-tar', ++ 'distribution:archives:linux-s390x-tar', + 'distribution:archives:linux-tar', + 'distribution:docker', + 'distribution:docker:cloud-docker-export', +@@ -68,14 +69,18 @@ List projects = [ + 'distribution:docker:cloud-ess-docker-export', + 'distribution:docker:cloud-ess-docker-aarch64-export', + 'distribution:docker:docker-aarch64-export', ++ 'distribution:docker:docker-s390x-export', + 'distribution:docker:docker-export', + 'distribution:docker:ironbank-docker-aarch64-export', + 'distribution:docker:ironbank-docker-export', + 'distribution:docker:ubi-docker-aarch64-export', ++ 'distribution:docker:ubi-docker-s390x-export', + 'distribution:docker:ubi-docker-export', + 'distribution:packages:aarch64-deb', ++ 'distribution:packages:s390x-deb', + 'distribution:packages:deb', + 'distribution:packages:aarch64-rpm', ++ 'distribution:packages:s390x-rpm', + 'distribution:packages:rpm', + 'distribution:bwc:bugfix', + 'distribution:bwc:maintenance',