Browse Source

Improve build configuration time (#41392)

This commit moves the expensive configuration-time calculation of Java runtime version information
to runtime instead and also makes that work cacheable. This roughly equates to about a 50% 
reduction in project configuration time.
Mark Vieira 6 years ago
parent
commit
eda3da31da
31 changed files with 1003 additions and 646 deletions
  1. 3 6
      build.gradle
  2. 3 31
      buildSrc/build.gradle
  3. 251 464
      buildSrc/src/main/groovy/org/elasticsearch/gradle/BuildPlugin.groovy
  4. 3 2
      buildSrc/src/main/groovy/org/elasticsearch/gradle/plugin/PluginBuildPlugin.groovy
  5. 16 15
      buildSrc/src/main/groovy/org/elasticsearch/gradle/precommit/PrecommitTasks.groovy
  6. 14 13
      buildSrc/src/main/groovy/org/elasticsearch/gradle/test/ClusterFormationTasks.groovy
  7. 7 34
      buildSrc/src/main/groovy/org/elasticsearch/gradle/test/RestIntegTestTask.groovy
  8. 7 1
      buildSrc/src/main/groovy/org/elasticsearch/gradle/test/StandaloneRestTestPlugin.groovy
  9. 0 0
      buildSrc/src/main/java/org/elasticsearch/gradle/JdkJarHellCheck.java
  10. 0 0
      buildSrc/src/main/java/org/elasticsearch/gradle/LazyFileOutputStream.java
  11. 0 0
      buildSrc/src/main/java/org/elasticsearch/gradle/LoggedExec.java
  12. 0 0
      buildSrc/src/main/java/org/elasticsearch/gradle/Version.java
  13. 0 0
      buildSrc/src/main/java/org/elasticsearch/gradle/VersionProperties.java
  14. 276 0
      buildSrc/src/main/java/org/elasticsearch/gradle/info/GenerateGlobalBuildInfoTask.java
  15. 198 0
      buildSrc/src/main/java/org/elasticsearch/gradle/info/GlobalBuildInfoPlugin.java
  16. 12 0
      buildSrc/src/main/java/org/elasticsearch/gradle/info/GlobalInfoExtension.java
  17. 35 0
      buildSrc/src/main/java/org/elasticsearch/gradle/info/JavaHome.java
  18. 84 0
      buildSrc/src/main/java/org/elasticsearch/gradle/info/PrintGlobalBuildInfoTask.java
  19. 4 7
      buildSrc/src/main/java/org/elasticsearch/gradle/precommit/ThirdPartyAuditTask.java
  20. 1 0
      buildSrc/src/main/resources/META-INF/gradle-plugins/elasticsearch.global-build-info.properties
  21. 3 3
      distribution/tools/plugin-cli/build.gradle
  22. 8 6
      modules/transport-netty4/build.gradle
  23. 5 5
      plugins/ingest-attachment/build.gradle
  24. 8 6
      plugins/transport-nio/build.gradle
  25. 4 2
      server/build.gradle
  26. 1 1
      x-pack/plugin/ccr/qa/restart/build.gradle
  27. 14 12
      x-pack/plugin/security/cli/build.gradle
  28. 6 8
      x-pack/plugin/sql/qa/security/with-ssl/build.gradle
  29. 18 14
      x-pack/qa/full-cluster-restart/build.gradle
  30. 4 2
      x-pack/qa/reindex-tests-with-security/build.gradle
  31. 18 14
      x-pack/qa/rolling-upgrade/build.gradle

+ 3 - 6
build.gradle

@@ -31,6 +31,7 @@ import org.gradle.plugins.ide.eclipse.model.SourceFolder
 plugins {
     id 'com.gradle.build-scan' version '2.2.1'
     id 'base'
+    id 'elasticsearch.global-build-info'
 }
 if (Boolean.valueOf(project.findProperty('org.elasticsearch.acceptScanTOS') ?: "false")) {
     buildScan {
@@ -262,7 +263,7 @@ allprojects {
   }
 
   project.afterEvaluate {
-    configurations.all {
+    configurations.matching { it.canBeResolved }.all {
       resolutionStrategy.dependencySubstitution { DependencySubstitutions subs ->
         projectSubstitutions.each { k,v ->
           subs.substitute(subs.module(k)).with(subs.project(v))
@@ -336,7 +337,7 @@ gradle.projectsEvaluated {
     if (tasks.findByPath('test') != null && tasks.findByPath('integTest') != null) {
       integTest.mustRunAfter test
     }
-    configurations.all { Configuration configuration ->
+    configurations.matching { it.canBeResolved }.all { Configuration configuration ->
       dependencies.all { Dependency dep ->
         Project upstreamProject = dependencyToProject(dep)
         if (upstreamProject != null) {
@@ -617,7 +618,3 @@ allprojects {
     }
   } 
 }
-
-
-
-

+ 3 - 31
buildSrc/build.gradle

@@ -69,37 +69,10 @@ processResources {
 if (JavaVersion.current() < JavaVersion.VERSION_11) {
   throw new GradleException('At least Java 11 is required to build elasticsearch gradle tools')
 }
-// Gradle 4.10 does not support setting this to 11 yet
-targetCompatibility = "10"
-sourceCompatibility = "10"
-
-// We have a few classes that need to be compiled for older java versions because these are used to run checks against
-// those
-sourceSets {
-  minimumRuntime {
-    // We only want Java here, but the Groovy doesn't configure javadoc correctly if we don't define this as groovy
-    groovy {
-      srcDirs = ['src/main/minimumRuntime']
-    }
-  }
-}
-compileMinimumRuntimeGroovy {
-  targetCompatibility = 8
-  sourceCompatibility = 8
-}
-dependencies {
-  if (project.ext.has("isEclipse") == false || project.ext.isEclipse == false) {
-      // eclipse is confused if this is set explicitly
-    compile sourceSets.minimumRuntime.output
-  }
-  minimumRuntimeCompile "junit:junit:${props.getProperty('junit')}"
-  minimumRuntimeCompile localGroovy()
-  minimumRuntimeCompile gradleApi()
-}
-jar {
-  from sourceSets.minimumRuntime.output
-}
 
+// Keep compatibility with Java 8 for external users of build-tools that haven't migrated to Java 11
+targetCompatibility = '8'
+sourceCompatibility = '8'
 
 /*****************************************************************************
  *                    Dependencies used by the entire build                  *
@@ -164,7 +137,6 @@ if (project != rootProject) {
   dependenciesInfo.enabled = false
   forbiddenApisMain.enabled = false
   forbiddenApisTest.enabled = false
-  forbiddenApisMinimumRuntime.enabled = false
   jarHell.enabled = false
   thirdPartyAudit.enabled = false
 

File diff suppressed because it is too large
+ 251 - 464
buildSrc/src/main/groovy/org/elasticsearch/gradle/BuildPlugin.groovy


+ 3 - 2
buildSrc/src/main/groovy/org/elasticsearch/gradle/plugin/PluginBuildPlugin.groovy

@@ -28,6 +28,7 @@ import org.elasticsearch.gradle.test.RestIntegTestTask
 import org.elasticsearch.gradle.test.RunTask
 import org.elasticsearch.gradle.testclusters.TestClustersPlugin
 import org.gradle.api.InvalidUserDataException
+import org.gradle.api.Plugin
 import org.gradle.api.Project
 import org.gradle.api.Task
 import org.gradle.api.publish.maven.MavenPublication
@@ -43,13 +44,13 @@ import java.util.regex.Pattern
 /**
  * Encapsulates build configuration for an Elasticsearch plugin.
  */
-class PluginBuildPlugin extends BuildPlugin {
+class PluginBuildPlugin implements Plugin<Project> {
 
     public static final String PLUGIN_EXTENSION_NAME = 'esplugin'
 
     @Override
     void apply(Project project) {
-        super.apply(project)
+        project.pluginManager.apply(BuildPlugin)
 
         PluginPropertiesExtension extension = project.extensions.create(PLUGIN_EXTENSION_NAME, PluginPropertiesExtension, project)
         configureDependencies(project)

+ 16 - 15
buildSrc/src/main/groovy/org/elasticsearch/gradle/precommit/PrecommitTasks.groovy

@@ -118,15 +118,13 @@ class PrecommitTasks {
     }
 
     private static Task configureThirdPartyAudit(Project project) {
-        ThirdPartyAuditTask thirdPartyAuditTask = project.tasks.create('thirdPartyAudit', ThirdPartyAuditTask.class)
         ExportElasticsearchBuildResourcesTask buildResources = project.tasks.getByName('buildResources')
-        thirdPartyAuditTask.configure {
-            dependsOn(buildResources)
-            signatureFile = buildResources.copy("forbidden/third-party-audit.txt")
-            javaHome = project.runtimeJavaHome
-            targetCompatibility = project.runtimeJavaVersion
+        return project.tasks.create('thirdPartyAudit', ThirdPartyAuditTask.class) { task ->
+            task.dependsOn(buildResources)
+            task.signatureFile = buildResources.copy("forbidden/third-party-audit.txt")
+            task.javaHome = project.runtimeJavaHome
+            task.targetCompatibility.set(project.provider({ project.runtimeJavaVersion }))
         }
-        return thirdPartyAuditTask
     }
 
     private static Task configureForbiddenApisCli(Project project) {
@@ -134,15 +132,18 @@ class PrecommitTasks {
         ExportElasticsearchBuildResourcesTask buildResources = project.tasks.getByName('buildResources')
         project.tasks.withType(CheckForbiddenApis) {
             dependsOn(buildResources)
-            targetCompatibility = project.runtimeJavaVersion.getMajorVersion()
-            if (project.runtimeJavaVersion > JavaVersion.VERSION_11) {
-                doLast {
-                    project.logger.info(
-                            "Forbidden APIs does not support java version past 11. Will use the signatures from 11 for ",
-                            project.runtimeJavaVersion
-                    )
+            doFirst {
+                // we need to defer this configuration since we don't know the runtime java version until execution time
+                targetCompatibility = project.runtimeJavaVersion.getMajorVersion()
+                if (project.runtimeJavaVersion > JavaVersion.VERSION_11) {
+                    doLast {
+                        project.logger.info(
+                                "Forbidden APIs does not support java version past 11. Will use the signatures from 11 for ",
+                                project.runtimeJavaVersion
+                        )
+                    }
+                    targetCompatibility = JavaVersion.VERSION_11.getMajorVersion()
                 }
-                targetCompatibility = JavaVersion.VERSION_11.getMajorVersion()
             }
             bundledSignatures = [
                     "jdk-unsafe", "jdk-deprecated", "jdk-non-portable", "jdk-system-out"

+ 14 - 13
buildSrc/src/main/groovy/org/elasticsearch/gradle/test/ClusterFormationTasks.groovy

@@ -300,12 +300,6 @@ class ClusterFormationTasks {
         // its run after plugins have been installed, as the extra config files may belong to plugins
         setup = configureExtraConfigFilesTask(taskName(prefix, node, 'extraConfig'), project, setup, node)
 
-        // If the node runs in a FIPS 140-2 JVM, the BCFKS default keystore will be password protected
-        if (project.inFipsJvm){
-            node.config.systemProperties.put('javax.net.ssl.trustStorePassword', 'password')
-            node.config.systemProperties.put('javax.net.ssl.keyStorePassword', 'password')
-        }
-
         // extra setup commands
         for (Map.Entry<String, Object[]> command : node.config.setupCommands.entrySet()) {
             // the first argument is the actual script name, relative to home
@@ -402,16 +396,17 @@ class ClusterFormationTasks {
         if (node.nodeVersion.major >= 7) {
             esConfig['indices.breaker.total.use_real_memory'] = false
         }
-        for (Map.Entry<String, Object> setting : node.config.settings) {
-            if (setting.value == null) {
-                esConfig.remove(setting.key)
-            } else {
-                esConfig.put(setting.key, setting.value)
-            }
-        }
 
         Task writeConfig = project.tasks.create(name: name, type: DefaultTask, dependsOn: setup)
         writeConfig.doFirst {
+            for (Map.Entry<String, Object> setting : node.config.settings) {
+                if (setting.value == null) {
+                    esConfig.remove(setting.key)
+                } else {
+                    esConfig.put(setting.key, setting.value)
+                }
+            }
+
             esConfig = configFilter.call(esConfig)
             File configFile = new File(node.pathConf, 'elasticsearch.yml')
             logger.info("Configuring ${configFile}")
@@ -732,6 +727,12 @@ class ClusterFormationTasks {
         }
         start.doLast(elasticsearchRunner)
         start.doFirst {
+            // If the node runs in a FIPS 140-2 JVM, the BCFKS default keystore will be password protected
+            if (project.inFipsJvm){
+                node.config.systemProperties.put('javax.net.ssl.trustStorePassword', 'password')
+                node.config.systemProperties.put('javax.net.ssl.keyStorePassword', 'password')
+            }
+
             // Configure ES JAVA OPTS - adds system properties, assertion flags, remote debug etc
             List<String> esJavaOpts = [node.env.get('ES_JAVA_OPTS', '')]
             String collectedSystemProperties = node.config.systemProperties.collect { key, value -> "-D${key}=${value}" }.join(" ")

+ 7 - 34
buildSrc/src/main/groovy/org/elasticsearch/gradle/test/RestIntegTestTask.groovy

@@ -86,52 +86,25 @@ class RestIntegTestTask extends DefaultTask {
         runner.include('**/*IT.class')
         runner.systemProperty('tests.rest.load_packaged', 'false')
 
-        /*
-         * We use lazy-evaluated strings in order to configure system properties whose value will not be known until
-         * execution time (e.g. cluster port numbers). Adding these via the normal DSL doesn't work as these get treated
-         * as task inputs and therefore Gradle attempts to snapshot them before/after task execution. This fails due
-         * to the GStrings containing references to non-serializable objects.
-         *
-         * We bypass this by instead passing this system properties vi a CommandLineArgumentProvider. This has the added
-         * side-effect that these properties are NOT treated as inputs, therefore they don't influence things like the
-         * build cache key or up to date checking.
-         */
-        def nonInputProperties = new CommandLineArgumentProvider() {
-            private final Map<String, Object> systemProperties = [:]
-
-            void systemProperty(String key, Object value) {
-                systemProperties.put(key, value)
-            }
-
-            @Override
-            Iterable<String> asArguments() {
-                return systemProperties.collect { key, value ->
-                    "-D${key}=${value.toString()}".toString()
-                }
-            }
-        }
-        runner.jvmArgumentProviders.add(nonInputProperties)
-        runner.ext.nonInputProperties = nonInputProperties
-
         if (System.getProperty("tests.rest.cluster") == null) {
             if (System.getProperty("tests.cluster") != null || System.getProperty("tests.clustername") != null) {
                 throw new IllegalArgumentException("tests.rest.cluster, tests.cluster, and tests.clustername must all be null or non-null")
             }
             if (usesTestclusters == true) {
                 ElasticsearchCluster cluster = project.testClusters."${name}"
-                nonInputProperties.systemProperty('tests.rest.cluster', "${-> cluster.allHttpSocketURI.join(",") }")
-                nonInputProperties.systemProperty('tests.cluster', "${-> cluster.transportPortURI }")
-                nonInputProperties.systemProperty('tests.clustername', "${-> cluster.getName() }")
+                runner.nonInputProperties.systemProperty('tests.rest.cluster', "${-> cluster.allHttpSocketURI.join(",") }")
+                runner.nonInputProperties.systemProperty('tests.cluster', "${-> cluster.transportPortURI }")
+                runner.nonInputProperties.systemProperty('tests.clustername', "${-> cluster.getName() }")
             } else {
                 // we pass all nodes to the rest cluster to allow the clients to round-robin between them
                 // this is more realistic than just talking to a single node
-                nonInputProperties.systemProperty('tests.rest.cluster', "${-> nodes.collect { it.httpUri() }.join(",")}")
-                nonInputProperties.systemProperty('tests.config.dir', "${-> nodes[0].pathConf}")
+                runner.nonInputProperties.systemProperty('tests.rest.cluster', "${-> nodes.collect { it.httpUri() }.join(",")}")
+                runner.nonInputProperties.systemProperty('tests.config.dir', "${-> nodes[0].pathConf}")
                 // TODO: our "client" qa tests currently use the rest-test plugin. instead they should have their own plugin
                 // that sets up the test cluster and passes this transport uri instead of http uri. Until then, we pass
                 // both as separate sysprops
-                nonInputProperties.systemProperty('tests.cluster', "${-> nodes[0].transportUri()}")
-                nonInputProperties.systemProperty('tests.clustername', "${-> nodes[0].clusterName}")
+                runner.nonInputProperties.systemProperty('tests.cluster', "${-> nodes[0].transportUri()}")
+                runner.nonInputProperties.systemProperty('tests.clustername', "${-> nodes[0].clusterName}")
 
                 // dump errors and warnings from cluster log on failure
                 TaskExecutionAdapter logDumpListener = new TaskExecutionAdapter() {

+ 7 - 1
buildSrc/src/main/groovy/org/elasticsearch/gradle/test/StandaloneRestTestPlugin.groovy

@@ -27,11 +27,14 @@ import org.elasticsearch.gradle.ExportElasticsearchBuildResourcesTask
 import org.elasticsearch.gradle.VersionProperties
 import org.elasticsearch.gradle.precommit.PrecommitTasks
 import org.gradle.api.InvalidUserDataException
+import org.gradle.api.JavaVersion
 import org.gradle.api.Plugin
 import org.gradle.api.Project
 import org.gradle.api.artifacts.Configuration
+import org.gradle.api.plugins.ExtraPropertiesExtension
 import org.gradle.api.plugins.JavaBasePlugin
 import org.gradle.api.plugins.JavaPlugin
+import org.gradle.api.plugins.JavaPluginExtension
 import org.gradle.api.tasks.SourceSet
 import org.gradle.api.tasks.SourceSetContainer
 import org.gradle.api.tasks.compile.JavaCompile
@@ -57,10 +60,13 @@ class StandaloneRestTestPlugin implements Plugin<Project> {
         project.pluginManager.apply(JavaBasePlugin)
 
         project.getTasks().create("buildResources", ExportElasticsearchBuildResourcesTask)
-        BuildPlugin.globalBuildInfo(project)
         BuildPlugin.configureRepositories(project)
         BuildPlugin.configureTestTasks(project)
 
+        ExtraPropertiesExtension ext = project.extensions.getByType(ExtraPropertiesExtension)
+        project.extensions.getByType(JavaPluginExtension).sourceCompatibility = ext.get('minimumRuntimeVersion') as JavaVersion
+        project.extensions.getByType(JavaPluginExtension).targetCompatibility = ext.get('minimumRuntimeVersion') as JavaVersion
+
         // only setup tests to build
         SourceSetContainer sourceSets = project.extensions.getByType(SourceSetContainer)
         SourceSet testSourceSet = sourceSets.create('test')

+ 0 - 0
buildSrc/src/main/minimumRuntime/org/elasticsearch/gradle/JdkJarHellCheck.java → buildSrc/src/main/java/org/elasticsearch/gradle/JdkJarHellCheck.java


+ 0 - 0
buildSrc/src/main/minimumRuntime/org/elasticsearch/gradle/LazyFileOutputStream.java → buildSrc/src/main/java/org/elasticsearch/gradle/LazyFileOutputStream.java


+ 0 - 0
buildSrc/src/main/minimumRuntime/org/elasticsearch/gradle/LoggedExec.java → buildSrc/src/main/java/org/elasticsearch/gradle/LoggedExec.java


+ 0 - 0
buildSrc/src/main/minimumRuntime/org/elasticsearch/gradle/Version.java → buildSrc/src/main/java/org/elasticsearch/gradle/Version.java


+ 0 - 0
buildSrc/src/main/minimumRuntime/org/elasticsearch/gradle/VersionProperties.java → buildSrc/src/main/java/org/elasticsearch/gradle/VersionProperties.java


+ 276 - 0
buildSrc/src/main/java/org/elasticsearch/gradle/info/GenerateGlobalBuildInfoTask.java

@@ -0,0 +1,276 @@
+package org.elasticsearch.gradle.info;
+
+import org.elasticsearch.gradle.OS;
+import org.gradle.api.DefaultTask;
+import org.gradle.api.GradleException;
+import org.gradle.api.JavaVersion;
+import org.gradle.api.file.RegularFileProperty;
+import org.gradle.api.model.ObjectFactory;
+import org.gradle.api.tasks.CacheableTask;
+import org.gradle.api.tasks.Input;
+import org.gradle.api.tasks.InputDirectory;
+import org.gradle.api.tasks.Nested;
+import org.gradle.api.tasks.OutputFile;
+import org.gradle.api.tasks.PathSensitive;
+import org.gradle.api.tasks.PathSensitivity;
+import org.gradle.api.tasks.TaskAction;
+import org.gradle.internal.jvm.Jvm;
+import org.gradle.process.ExecResult;
+
+import javax.inject.Inject;
+import java.io.BufferedWriter;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.io.Writer;
+import java.nio.file.Files;
+import java.util.Arrays;
+import java.util.List;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+@CacheableTask
+public class GenerateGlobalBuildInfoTask extends DefaultTask {
+    private JavaVersion minimumCompilerVersion;
+    private JavaVersion minimumRuntimeVersion;
+    private File compilerJavaHome;
+    private File runtimeJavaHome;
+    private List<JavaHome> javaVersions;
+    private final RegularFileProperty outputFile;
+    private final RegularFileProperty compilerVersionFile;
+    private final RegularFileProperty runtimeVersionFile;
+    private final RegularFileProperty fipsJvmFile;
+
+    @Inject
+    public GenerateGlobalBuildInfoTask(ObjectFactory objectFactory) {
+        this.outputFile = objectFactory.fileProperty();
+        this.compilerVersionFile = objectFactory.fileProperty();
+        this.runtimeVersionFile = objectFactory.fileProperty();
+        this.fipsJvmFile = objectFactory.fileProperty();
+    }
+
+    @Input
+    public JavaVersion getMinimumCompilerVersion() {
+        return minimumCompilerVersion;
+    }
+
+    public void setMinimumCompilerVersion(JavaVersion minimumCompilerVersion) {
+        this.minimumCompilerVersion = minimumCompilerVersion;
+    }
+
+    @Input
+    public JavaVersion getMinimumRuntimeVersion() {
+        return minimumRuntimeVersion;
+    }
+
+    public void setMinimumRuntimeVersion(JavaVersion minimumRuntimeVersion) {
+        this.minimumRuntimeVersion = minimumRuntimeVersion;
+    }
+
+    @InputDirectory
+    @PathSensitive(PathSensitivity.RELATIVE)
+    public File getCompilerJavaHome() {
+        return compilerJavaHome;
+    }
+
+    public void setCompilerJavaHome(File compilerJavaHome) {
+        this.compilerJavaHome = compilerJavaHome;
+    }
+
+    @InputDirectory
+    @PathSensitive(PathSensitivity.RELATIVE)
+    public File getRuntimeJavaHome() {
+        return runtimeJavaHome;
+    }
+
+    public void setRuntimeJavaHome(File runtimeJavaHome) {
+        this.runtimeJavaHome = runtimeJavaHome;
+    }
+
+    @Nested
+    public List<JavaHome> getJavaVersions() {
+        return javaVersions;
+    }
+
+    public void setJavaVersions(List<JavaHome> javaVersions) {
+        this.javaVersions = javaVersions;
+    }
+
+    @OutputFile
+    public RegularFileProperty getOutputFile() {
+        return outputFile;
+    }
+
+    @OutputFile
+    public RegularFileProperty getCompilerVersionFile() {
+        return compilerVersionFile;
+    }
+
+    @OutputFile
+    public RegularFileProperty getRuntimeVersionFile() {
+        return runtimeVersionFile;
+    }
+
+    @OutputFile
+    public RegularFileProperty getFipsJvmFile() {
+        return fipsJvmFile;
+    }
+
+    @TaskAction
+    public void generate() {
+        String javaVendor = System.getProperty("java.vendor");
+        String gradleJavaVersion = System.getProperty("java.version");
+        String gradleJavaVersionDetails = javaVendor + " " + gradleJavaVersion + " [" + System.getProperty("java.vm.name")
+            + " " + System.getProperty("java.vm.version") + "]";
+
+        String compilerJavaVersionDetails = gradleJavaVersionDetails;
+        JavaVersion compilerJavaVersionEnum = JavaVersion.current();
+        String runtimeJavaVersionDetails = gradleJavaVersionDetails;
+        JavaVersion runtimeJavaVersionEnum = JavaVersion.current();
+        File gradleJavaHome = Jvm.current().getJavaHome();
+        boolean inFipsJvm = false;
+
+        try {
+            if (Files.isSameFile(compilerJavaHome.toPath(), gradleJavaHome.toPath()) == false) {
+                if (compilerJavaHome.exists()) {
+                    compilerJavaVersionDetails = findJavaVersionDetails(compilerJavaHome);
+                    compilerJavaVersionEnum = JavaVersion.toVersion(findJavaSpecificationVersion(compilerJavaHome));
+                } else {
+                    throw new RuntimeException("Compiler Java home path of '" + compilerJavaHome + "' does not exist");
+                }
+            }
+
+            if (Files.isSameFile(runtimeJavaHome.toPath(), gradleJavaHome.toPath()) == false) {
+                if (runtimeJavaHome.exists()) {
+                    runtimeJavaVersionDetails = findJavaVersionDetails(runtimeJavaHome);
+                    runtimeJavaVersionEnum = JavaVersion.toVersion(findJavaSpecificationVersion(runtimeJavaHome));
+
+                    // We don't expect Gradle to be running in a FIPS JVM
+                    String inFipsJvmScript = "print(java.security.Security.getProviders()[0].name.toLowerCase().contains(\"fips\"));";
+                    inFipsJvm = Boolean.parseBoolean(runJavaAsScript(runtimeJavaHome, inFipsJvmScript));
+                } else {
+                    throw new RuntimeException("Runtime Java home path of '" + compilerJavaHome + "' does not exist");
+                }
+            }
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+
+        try (BufferedWriter writer = new BufferedWriter(new FileWriter(outputFile.getAsFile().get()))) {
+            writer.write("  Gradle Version        : " + getProject().getGradle().getGradleVersion() + "\n");
+            writer.write("  OS Info               : " + System.getProperty("os.name") + " " + System.getProperty("os.version")
+                + " (" + System.getProperty("os.arch") + ")\n");
+            if (gradleJavaVersionDetails.equals(compilerJavaVersionDetails) == false
+                || gradleJavaVersionDetails.equals(runtimeJavaVersionDetails) == false) {
+                writer.write("  Compiler JDK Version  : " + compilerJavaVersionEnum + " (" + compilerJavaVersionDetails + ")\n");
+                writer.write("  Compiler java.home    : " + compilerJavaHome + "\n");
+                writer.write("  Runtime JDK Version   : " + runtimeJavaVersionEnum + " (" + runtimeJavaVersionDetails + ")\n");
+                writer.write("  Runtime java.home     : " + runtimeJavaHome + "\n");
+                writer.write("  Gradle JDK Version    : " + JavaVersion.toVersion(gradleJavaVersion)
+                    + " (" + gradleJavaVersionDetails + ")\n");
+                writer.write("  Gradle java.home      : " + gradleJavaHome);
+            } else {
+                writer.write("  JDK Version           : " + JavaVersion.toVersion(gradleJavaVersion)
+                    + " (" + gradleJavaVersionDetails + ")\n");
+                writer.write("  JAVA_HOME             : " + gradleJavaHome);
+            }
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+
+        // enforce Java version
+        if (compilerJavaVersionEnum.compareTo(minimumCompilerVersion) < 0) {
+            String message = "The compiler java.home must be set to a JDK installation directory for Java " + minimumCompilerVersion +
+                " but is [" + compilerJavaHome + "] corresponding to [" + compilerJavaVersionEnum + "]";
+            throw new GradleException(message);
+        }
+
+        if (runtimeJavaVersionEnum.compareTo(minimumRuntimeVersion) < 0) {
+            String message = "The runtime java.home must be set to a JDK installation directory for Java " + minimumRuntimeVersion +
+                " but is [" + runtimeJavaHome + "] corresponding to [" + runtimeJavaVersionEnum + "]";
+            throw new GradleException(message);
+        }
+
+        for (JavaHome javaVersion : javaVersions) {
+            File javaHome = javaVersion.getJavaHome();
+            if (javaHome == null) {
+                continue;
+            }
+            JavaVersion javaVersionEnum = JavaVersion.toVersion(findJavaSpecificationVersion(javaHome));
+            JavaVersion expectedJavaVersionEnum;
+            int version = javaVersion.getVersion();
+            if (version < 9) {
+                expectedJavaVersionEnum = JavaVersion.toVersion("1." + version);
+            } else {
+                expectedJavaVersionEnum = JavaVersion.toVersion(Integer.toString(version));
+            }
+            if (javaVersionEnum != expectedJavaVersionEnum) {
+                String message = "The environment variable JAVA" + version + "_HOME must be set to a JDK installation directory for Java " +
+                    expectedJavaVersionEnum + " but is [" + javaHome + "] corresponding to [" + javaVersionEnum + "]";
+                throw new GradleException(message);
+            }
+        }
+
+        writeToFile(compilerVersionFile.getAsFile().get(), compilerJavaVersionEnum.name());
+        writeToFile(runtimeVersionFile.getAsFile().get(), runtimeJavaVersionEnum.name());
+        writeToFile(fipsJvmFile.getAsFile().get(), Boolean.toString(inFipsJvm));
+    }
+
+    private void writeToFile(File file, String content) {
+        try (Writer writer = new FileWriter(file)) {
+            writer.write(content);
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+    }
+
+    /**
+     * Finds printable java version of the given JAVA_HOME
+     */
+    private String findJavaVersionDetails(File javaHome) {
+        String versionInfoScript = "print(" +
+            "java.lang.System.getProperty(\"java.vendor\") + \" \" + java.lang.System.getProperty(\"java.version\") + " +
+            "\" [\" + java.lang.System.getProperty(\"java.vm.name\") + \" \" + java.lang.System.getProperty(\"java.vm.version\") + \"]\");";
+        return runJavaAsScript(javaHome, versionInfoScript).trim();
+    }
+
+    /**
+     * Finds the parsable java specification version
+     */
+    private String findJavaSpecificationVersion(File javaHome) {
+        String versionScript = "print(java.lang.System.getProperty(\"java.specification.version\"));";
+        return runJavaAsScript(javaHome, versionScript);
+    }
+
+    /**
+     * Runs the given javascript using jjs from the jdk, and returns the output
+     */
+    private String runJavaAsScript(File javaHome, String script) {
+        ByteArrayOutputStream stdout = new ByteArrayOutputStream();
+        ByteArrayOutputStream stderr = new ByteArrayOutputStream();
+        if (OS.current() == OS.WINDOWS) {
+            // gradle/groovy does not properly escape the double quote for windows
+            script = script.replace("\"", "\\\"");
+        }
+        File jrunscriptPath = new File(javaHome, "bin/jrunscript");
+        String finalScript = script;
+        ExecResult result = getProject().exec(spec -> {
+            spec.setExecutable(jrunscriptPath);
+            spec.args("-e", finalScript);
+            spec.setStandardOutput(stdout);
+            spec.setErrorOutput(stderr);
+            spec.setIgnoreExitValue(true);
+        });
+
+        if (result.getExitValue() != 0) {
+            getLogger().error("STDOUT:");
+            Arrays.stream(stdout.toString(UTF_8).split(System.getProperty("line.separator"))).forEach(getLogger()::error);
+            getLogger().error("STDERR:");
+            Arrays.stream(stderr.toString(UTF_8).split(System.getProperty("line.separator"))).forEach(getLogger()::error);
+            result.rethrowFailure();
+        }
+        return stdout.toString(UTF_8).trim();
+    }
+}

+ 198 - 0
buildSrc/src/main/java/org/elasticsearch/gradle/info/GlobalBuildInfoPlugin.java

@@ -0,0 +1,198 @@
+package org.elasticsearch.gradle.info;
+
+import org.elasticsearch.gradle.OS;
+import org.gradle.api.GradleException;
+import org.gradle.api.JavaVersion;
+import org.gradle.api.Plugin;
+import org.gradle.api.Project;
+import org.gradle.api.plugins.ExtraPropertiesExtension;
+import org.gradle.internal.jvm.Jvm;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.UncheckedIOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+public class GlobalBuildInfoPlugin implements Plugin<Project> {
+    private static final String GLOBAL_INFO_EXTENSION_NAME = "globalInfo";
+    private static Integer _defaultParallel = null;
+
+    @Override
+    public void apply(Project project) {
+        if (project != project.getRootProject()) {
+            throw new IllegalStateException(this.getClass().getName() + " can only be applied to the root project.");
+        }
+
+        GlobalInfoExtension extension = project.getExtensions().create(GLOBAL_INFO_EXTENSION_NAME, GlobalInfoExtension.class);
+
+        JavaVersion minimumCompilerVersion = JavaVersion.toVersion(getResourceContents("/minimumCompilerVersion"));
+        JavaVersion minimumRuntimeVersion = JavaVersion.toVersion(getResourceContents("/minimumRuntimeVersion"));
+
+        File compilerJavaHome = findCompilerJavaHome();
+        File runtimeJavaHome = findRuntimeJavaHome(compilerJavaHome);
+
+        final List<JavaHome> javaVersions = new ArrayList<>();
+        for (int version = 8; version <= Integer.parseInt(minimumCompilerVersion.getMajorVersion()); version++) {
+            if (System.getenv(getJavaHomeEnvVarName(Integer.toString(version))) != null) {
+                javaVersions.add(JavaHome.of(version, new File(findJavaHome(Integer.toString(version)))));
+            }
+        }
+
+        GenerateGlobalBuildInfoTask generateTask = project.getTasks().create("generateGlobalBuildInfo",
+            GenerateGlobalBuildInfoTask.class, task -> {
+                task.setJavaVersions(javaVersions);
+                task.setMinimumCompilerVersion(minimumCompilerVersion);
+                task.setMinimumRuntimeVersion(minimumRuntimeVersion);
+                task.setCompilerJavaHome(compilerJavaHome);
+                task.setRuntimeJavaHome(runtimeJavaHome);
+                task.getOutputFile().set(new File(project.getBuildDir(), "global-build-info"));
+                task.getCompilerVersionFile().set(new File(project.getBuildDir(), "java-compiler-version"));
+                task.getRuntimeVersionFile().set(new File(project.getBuildDir(), "java-runtime-version"));
+                task.getFipsJvmFile().set(new File(project.getBuildDir(), "in-fips-jvm"));
+            });
+
+        PrintGlobalBuildInfoTask printTask = project.getTasks().create("printGlobalBuildInfo", PrintGlobalBuildInfoTask.class, task -> {
+            task.getBuildInfoFile().set(generateTask.getOutputFile());
+            task.getCompilerVersionFile().set(generateTask.getCompilerVersionFile());
+            task.getRuntimeVersionFile().set(generateTask.getRuntimeVersionFile());
+            task.getFipsJvmFile().set(generateTask.getFipsJvmFile());
+            task.setGlobalInfoListeners(extension.listeners);
+        });
+
+        project.getExtensions().getByType(ExtraPropertiesExtension.class).set("defaultParallel", findDefaultParallel(project));
+
+        project.allprojects(p -> {
+            // Make sure than any task execution generates and prints build info
+            p.getTasks().all(task -> {
+                if (task != generateTask && task != printTask) {
+                    task.dependsOn(printTask);
+                }
+            });
+
+            ExtraPropertiesExtension ext = p.getExtensions().getByType(ExtraPropertiesExtension.class);
+
+            ext.set("compilerJavaHome", compilerJavaHome);
+            ext.set("runtimeJavaHome", runtimeJavaHome);
+            ext.set("isRuntimeJavaHomeSet", compilerJavaHome.equals(runtimeJavaHome) == false);
+            ext.set("javaVersions", javaVersions);
+            ext.set("minimumCompilerVersion", minimumCompilerVersion);
+            ext.set("minimumRuntimeVersion", minimumRuntimeVersion);
+            ext.set("gradleJavaVersion", Jvm.current().getJavaVersion());
+        });
+    }
+
+    private static File findCompilerJavaHome() {
+        String compilerJavaHome = System.getenv("JAVA_HOME");
+        String compilerJavaProperty = System.getProperty("compiler.java");
+
+        if (compilerJavaProperty != null) {
+            compilerJavaHome = findJavaHome(compilerJavaProperty);
+        }
+
+        // if JAVA_HOME is not set,so we use the JDK that Gradle was run with.
+        return compilerJavaHome == null ? Jvm.current().getJavaHome() : new File(compilerJavaHome);
+    }
+
+    private static File findRuntimeJavaHome(final File compilerJavaHome) {
+        String runtimeJavaProperty = System.getProperty("runtime.java");
+
+        if (runtimeJavaProperty != null) {
+            return new File(findJavaHome(runtimeJavaProperty));
+        }
+
+        return System.getenv("RUNTIME_JAVA_HOME") == null ? compilerJavaHome : new File(System.getenv("RUNTIME_JAVA_HOME"));
+    }
+
+    private static String findJavaHome(String version) {
+        String versionedJavaHome = System.getenv(getJavaHomeEnvVarName(version));
+        if (versionedJavaHome == null) {
+            throw new GradleException(
+                "$versionedVarName must be set to build Elasticsearch. " +
+                    "Note that if the variable was just set you might have to run `./gradlew --stop` for " +
+                    "it to be picked up. See https://github.com/elastic/elasticsearch/issues/31399 details."
+            );
+        }
+        return versionedJavaHome;
+    }
+
+    private static String getJavaHomeEnvVarName(String version) {
+        return "JAVA" + version + "_HOME";
+    }
+
+    private static String getResourceContents(String resourcePath) {
+        try (BufferedReader reader = new BufferedReader(
+            new InputStreamReader(GlobalBuildInfoPlugin.class.getResourceAsStream(resourcePath))
+        )) {
+            StringBuilder b = new StringBuilder();
+            for (String line = reader.readLine(); line != null; line = reader.readLine()) {
+                if (b.length() != 0) {
+                    b.append('\n');
+                }
+                b.append(line);
+            }
+
+            return b.toString();
+        } catch (IOException e) {
+            throw new UncheckedIOException("Error trying to read classpath resource: " + resourcePath, e);
+        }
+    }
+
+    private static int findDefaultParallel(Project project) {
+        // Since it costs IO to compute this, and is done at configuration time we want to cache this if possible
+        // It's safe to store this in a static variable since it's just a primitive so leaking memory isn't an issue
+        if (_defaultParallel == null) {
+            File cpuInfoFile = new File("/proc/cpuinfo");
+            if (cpuInfoFile.exists()) {
+                // Count physical cores on any Linux distro ( don't count hyper-threading )
+                Map<String, Integer> socketToCore = new HashMap<>();
+                String currentID = "";
+
+                try (BufferedReader reader = new BufferedReader(new FileReader(cpuInfoFile))) {
+                    for (String line = reader.readLine(); line != null; line = reader.readLine()) {
+                        if (line.contains(":")) {
+                            List<String> parts = Arrays.stream(line.split(":", 2)).map(String::trim).collect(Collectors.toList());
+                            String name = parts.get(0);
+                            String value = parts.get(1);
+                            // the ID of the CPU socket
+                            if (name.equals("physical id")) {
+                                currentID = value;
+                            }
+                            // Number  of cores not including hyper-threading
+                            if (name.equals("cpu cores")) {
+                                assert currentID.isEmpty() == false;
+                                socketToCore.put("currentID", Integer.valueOf(value));
+                                currentID = "";
+                            }
+                        }
+                    }
+                } catch (IOException e) {
+                    throw new UncheckedIOException(e);
+                }
+                _defaultParallel = socketToCore.values().stream().mapToInt(i -> i).sum();
+            } else if (OS.current() == OS.MAC) {
+                // Ask macOS to count physical CPUs for us
+                ByteArrayOutputStream stdout = new ByteArrayOutputStream();
+                project.exec(spec -> {
+                    spec.setExecutable("sysctl");
+                    spec.args("-n", "hw.physicalcpu");
+                    spec.setStandardOutput(stdout);
+                });
+
+                _defaultParallel = Integer.parseInt(stdout.toString().trim());
+            }
+
+            _defaultParallel = Runtime.getRuntime().availableProcessors() / 2;
+        }
+
+        return _defaultParallel;
+    }
+}

+ 12 - 0
buildSrc/src/main/java/org/elasticsearch/gradle/info/GlobalInfoExtension.java

@@ -0,0 +1,12 @@
+package org.elasticsearch.gradle.info;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class GlobalInfoExtension {
+    final List<Runnable> listeners = new ArrayList<>();
+
+    public void ready(Runnable block) {
+        listeners.add(block);
+    }
+}

+ 35 - 0
buildSrc/src/main/java/org/elasticsearch/gradle/info/JavaHome.java

@@ -0,0 +1,35 @@
+package org.elasticsearch.gradle.info;
+
+import org.gradle.api.tasks.Input;
+import org.gradle.api.tasks.InputDirectory;
+import org.gradle.api.tasks.Optional;
+import org.gradle.api.tasks.PathSensitive;
+import org.gradle.api.tasks.PathSensitivity;
+
+import java.io.File;
+
+public class JavaHome {
+    private Integer version;
+    private File javaHome;
+
+    private JavaHome(int version, File javaHome) {
+        this.version = version;
+        this.javaHome = javaHome;
+    }
+
+    public static JavaHome of(int version, File javaHome) {
+        return new JavaHome(version, javaHome);
+    }
+
+    @Input
+    public Integer getVersion() {
+        return version;
+    }
+
+    @InputDirectory
+    @Optional
+    @PathSensitive(PathSensitivity.RELATIVE)
+    public File getJavaHome() {
+        return javaHome;
+    }
+}

+ 84 - 0
buildSrc/src/main/java/org/elasticsearch/gradle/info/PrintGlobalBuildInfoTask.java

@@ -0,0 +1,84 @@
+package org.elasticsearch.gradle.info;
+
+import org.gradle.api.DefaultTask;
+import org.gradle.api.JavaVersion;
+import org.gradle.api.file.RegularFileProperty;
+import org.gradle.api.model.ObjectFactory;
+import org.gradle.api.plugins.ExtraPropertiesExtension;
+import org.gradle.api.resources.TextResource;
+import org.gradle.api.tasks.InputFile;
+import org.gradle.api.tasks.TaskAction;
+
+import javax.inject.Inject;
+import java.util.ArrayList;
+import java.util.List;
+
+public class PrintGlobalBuildInfoTask extends DefaultTask {
+    private final RegularFileProperty buildInfoFile;
+    private final RegularFileProperty compilerVersionFile;
+    private final RegularFileProperty runtimeVersionFile;
+    private final RegularFileProperty fipsJvmFile;
+    private List<Runnable> globalInfoListeners = new ArrayList<>();
+
+    @Inject
+    public PrintGlobalBuildInfoTask(ObjectFactory objectFactory) {
+        this.buildInfoFile = objectFactory.fileProperty();
+        this.compilerVersionFile = objectFactory.fileProperty();
+        this.runtimeVersionFile = objectFactory.fileProperty();
+        this.fipsJvmFile = objectFactory.fileProperty();
+    }
+
+    @InputFile
+    public RegularFileProperty getBuildInfoFile() {
+        return buildInfoFile;
+    }
+
+    @InputFile
+    public RegularFileProperty getCompilerVersionFile() {
+        return compilerVersionFile;
+    }
+
+    @InputFile
+    public RegularFileProperty getRuntimeVersionFile() {
+        return runtimeVersionFile;
+    }
+
+    @InputFile
+    public RegularFileProperty getFipsJvmFile() {
+        return fipsJvmFile;
+    }
+
+    public void setGlobalInfoListeners(List<Runnable> globalInfoListeners) {
+        this.globalInfoListeners = globalInfoListeners;
+    }
+
+    @TaskAction
+    public void print() {
+        getLogger().quiet("=======================================");
+        getLogger().quiet("Elasticsearch Build Hamster says Hello!");
+        getLogger().quiet(getFileText(getBuildInfoFile()).asString());
+        getLogger().quiet("  Random Testing Seed   : " + getProject().property("testSeed"));
+        getLogger().quiet("=======================================");
+
+        setGlobalProperties();
+        globalInfoListeners.forEach(Runnable::run);
+
+        // Since all tasks depend on this task, and it always runs for every build, this makes sure that lifecycle tasks will still
+        // correctly report as UP-TO-DATE, since the convention is a lifecycle task (i.e. assemble, build, etc) will only be marked as
+        // UP-TO-DATE if all upstream tasks were also UP-TO-DATE.
+        setDidWork(false);
+    }
+
+    private TextResource getFileText(RegularFileProperty regularFileProperty) {
+        return getProject().getResources().getText().fromFile(regularFileProperty.getAsFile().get());
+    }
+
+    private void setGlobalProperties() {
+        getProject().getRootProject().allprojects(p -> {
+            ExtraPropertiesExtension ext = p.getExtensions().getByType(ExtraPropertiesExtension.class);
+            ext.set("compilerJavaVersion", JavaVersion.valueOf(getFileText(getCompilerVersionFile()).asString()));
+            ext.set("runtimeJavaVersion", JavaVersion.valueOf(getFileText(getRuntimeVersionFile()).asString()));
+            ext.set("inFipsJvm", Boolean.valueOf(getFileText(getFipsJvmFile()).asString()));
+        });
+    }
+}

+ 4 - 7
buildSrc/src/main/java/org/elasticsearch/gradle/precommit/ThirdPartyAuditTask.java

@@ -26,6 +26,7 @@ import org.gradle.api.JavaVersion;
 import org.gradle.api.artifacts.Configuration;
 import org.gradle.api.artifacts.Dependency;
 import org.gradle.api.file.FileTree;
+import org.gradle.api.provider.Property;
 import org.gradle.api.specs.Spec;
 import org.gradle.api.tasks.CacheableTask;
 import org.gradle.api.tasks.Classpath;
@@ -79,17 +80,13 @@ public class ThirdPartyAuditTask extends DefaultTask {
 
     private String javaHome;
 
-    private JavaVersion targetCompatibility;
+    private final Property<JavaVersion> targetCompatibility = getProject().getObjects().property(JavaVersion.class);
 
     @Input
-    public JavaVersion getTargetCompatibility() {
+    public Property<JavaVersion> getTargetCompatibility() {
         return targetCompatibility;
     }
 
-    public void setTargetCompatibility(JavaVersion targetCompatibility) {
-        this.targetCompatibility = targetCompatibility;
-    }
-
     @InputFiles
     @PathSensitive(PathSensitivity.NAME_ONLY)
     public Configuration getForbiddenAPIsConfiguration() {
@@ -287,7 +284,7 @@ public class ThirdPartyAuditTask extends DefaultTask {
             // pther version specific implementation of said classes.
             IntStream.rangeClosed(
                 Integer.parseInt(JavaVersion.VERSION_1_9.getMajorVersion()),
-                Integer.parseInt(targetCompatibility.getMajorVersion())
+                Integer.parseInt(targetCompatibility.get().getMajorVersion())
             ).forEach(majorVersion -> getProject().copy(spec -> {
                 spec.from(getProject().zipTree(jar));
                 spec.into(jarExpandDir);

+ 1 - 0
buildSrc/src/main/resources/META-INF/gradle-plugins/elasticsearch.global-build-info.properties

@@ -0,0 +1 @@
+implementation-class=org.elasticsearch.gradle.info.GlobalBuildInfoPlugin

+ 3 - 3
distribution/tools/plugin-cli/build.gradle

@@ -40,8 +40,8 @@ test {
   systemProperty 'tests.security.manager', 'false'
 }
 
-if (project.inFipsJvm) {
+thirdPartyAudit.onlyIf {
   // FIPS JVM includes manny classes from bouncycastle which count as jar hell for the third party audit,
   // rather than provide a long list of exclusions, disable the check on FIPS.
-  thirdPartyAudit.enabled = false
-}
+  project.inFipsJvm == false
+}

+ 8 - 6
modules/transport-netty4/build.gradle

@@ -172,10 +172,12 @@ thirdPartyAudit {
     )
 }
 
-if (project.inFipsJvm == false) {
-    // BouncyCastleFIPS provides this class, so the exclusion is invalid when running CI in
-    // a FIPS JVM with BouncyCastleFIPS Provider
-    thirdPartyAudit.ignoreMissingClasses (
-            'org.bouncycastle.asn1.x500.X500Name'
-    )
+rootProject.globalInfo.ready {
+    if (project.inFipsJvm == false) {
+        // BouncyCastleFIPS provides this class, so the exclusion is invalid when running CI in
+        // a FIPS JVM with BouncyCastleFIPS Provider
+        thirdPartyAudit.ignoreMissingClasses(
+                'org.bouncycastle.asn1.x500.X500Name'
+        )
+    }
 }

+ 5 - 5
plugins/ingest-attachment/build.gradle

@@ -84,8 +84,8 @@ thirdPartyAudit{
     ignoreMissingClasses()
 }
 
-if (project.inFipsJvm) {
-    // FIPS JVM includes manny classes from bouncycastle which count as jar hell for the third party audit,
-    // rather than provide a long list of exclusions, disable the check on FIPS.
-    thirdPartyAudit.enabled = false
-}
+thirdPartyAudit.onlyIf {
+  // FIPS JVM includes manny classes from bouncycastle which count as jar hell for the third party audit,
+  // rather than provide a long list of exclusions, disable the check on FIPS.
+  project.inFipsJvm == false
+}

+ 8 - 6
plugins/transport-nio/build.gradle

@@ -149,10 +149,12 @@ thirdPartyAudit {
         'io.netty.handler.ssl.util.OpenJdkSelfSignedCertGenerator'
     )
 }
-if (project.inFipsJvm == false) {
-    // BouncyCastleFIPS provides this class, so the exclusion is invalid when running CI in
-    // a FIPS JVM with BouncyCastleFIPS Provider
-    thirdPartyAudit.ignoreMissingClasses (
-            'org.bouncycastle.asn1.x500.X500Name'
-    )
+rootProject.globalInfo.ready {
+    if (project.inFipsJvm == false) {
+        // BouncyCastleFIPS provides this class, so the exclusion is invalid when running CI in
+        // a FIPS JVM with BouncyCastleFIPS Provider
+        thirdPartyAudit.ignoreMissingClasses(
+                'org.bouncycastle.asn1.x500.X500Name'
+        )
+    }
 }

+ 4 - 2
server/build.gradle

@@ -56,8 +56,10 @@ if (!isEclipse && !isIdea) {
   }
 
   forbiddenApisJava12 {
-    if (project.runtimeJavaVersion < JavaVersion.VERSION_12) {
-      targetCompatibility = JavaVersion.VERSION_12.getMajorVersion()
+    doFirst {
+      if (project.runtimeJavaVersion < JavaVersion.VERSION_12) {
+        targetCompatibility = JavaVersion.VERSION_12.getMajorVersion()
+      }
     }
   }
 

+ 1 - 1
x-pack/plugin/ccr/qa/restart/build.gradle

@@ -41,7 +41,7 @@ followClusterTestRunner {
 task followClusterRestartTest(type: RestIntegTestTask) {}
 
 followClusterRestartTestCluster {
-    dependsOn followClusterTestRunner
+    dependsOn followClusterTestRunner, 'followClusterTestCluster#stop'
     numNodes = 1
     clusterName = 'follow-cluster'
     dataDir = { nodeNumber -> followClusterTest.nodes[0].dataDir }

+ 14 - 12
x-pack/plugin/security/cli/build.gradle

@@ -22,16 +22,18 @@ dependencyLicenses {
     mapping from: /bc.*/, to: 'bouncycastle'
 }
 
-if (project.inFipsJvm) {
-    test.enabled = false
-    testingConventions.enabled = false
-    // Forbiden APIs non-portable checks fail because bouncy castle classes being used from the FIPS JDK since those are
-    // not part of the Java specification - all of this is as designed, so we have to relax this check for FIPS.
-    tasks.withType(CheckForbiddenApis) {
-        bundledSignatures -= "jdk-non-portable"
-    }
-    // FIPS JVM includes many classes from bouncycastle which count as jar hell for the third party audit,
-    // rather than provide a long list of exclusions, disable the check on FIPS.
-    thirdPartyAudit.enabled = false
+rootProject.globalInfo.ready {
+    if (project.inFipsJvm) {
+        test.enabled = false
+        testingConventions.enabled = false
+        // Forbiden APIs non-portable checks fail because bouncy castle classes being used from the FIPS JDK since those are
+        // not part of the Java specification - all of this is as designed, so we have to relax this check for FIPS.
+        tasks.withType(CheckForbiddenApis) {
+            bundledSignatures -= "jdk-non-portable"
+        }
+        // FIPS JVM includes many classes from bouncycastle which count as jar hell for the third party audit,
+        // rather than provide a long list of exclusions, disable the check on FIPS.
+        thirdPartyAudit.enabled = false
 
-}
+    }
+}

+ 6 - 8
x-pack/plugin/sql/qa/security/with-ssl/build.gradle

@@ -207,18 +207,16 @@ integTestCluster {
     return tmpFile.exists()
   }
 }
-Closure notRunningFips = {
-  Boolean.parseBoolean(BuildPlugin.runJavaAsScript(project, project.runtimeJavaHome,
-          'print(java.security.Security.getProviders()[0].name.toLowerCase().contains("fips"));')) == false
-}
 
 // Do not attempt to form a cluster in a FIPS JVM, as doing so with a JKS keystore will fail.
 // TODO Revisit this when SQL CLI client can handle key/certificate instead of only Keystores.
 // https://github.com/elastic/elasticsearch/issues/32306
-tasks.matching({ it.name == "integTestCluster#init" }).all { onlyIf notRunningFips }
-tasks.matching({ it.name == "integTestCluster#start" }).all { onlyIf notRunningFips }
-tasks.matching({ it.name == "integTestCluster#wait" }).all { onlyIf notRunningFips }
-tasks.matching({ it.name == "integTestRunner" }).all { onlyIf notRunningFips }
+tasks.matching { it.name in ["integTestCluster#init", "integTestCluster#start", "integTestCluster#wait", "integTestRunner"] }.all { 
+  onlyIf { 
+    project.inFipsJvm == false 
+  } 
+}
+
 
 /** A lazy evaluator to find the san to use for certificate generation. */
 class SanEvaluator {

+ 18 - 14
x-pack/qa/full-cluster-restart/build.gradle

@@ -116,13 +116,15 @@ for (Version version : bwcVersions.indexCompatible) {
 
         setting 'xpack.security.enabled', 'true'
         setting 'xpack.security.transport.ssl.enabled', 'true'
-        if (project.inFipsJvm) {
-            setting 'xpack.security.transport.ssl.key', 'testnode.pem'
-            setting 'xpack.security.transport.ssl.certificate', 'testnode.crt'
-            keystoreSetting 'xpack.security.transport.ssl.secure_key_passphrase', 'testnode'
-        } else {
-            setting 'xpack.security.transport.ssl.keystore.path', 'testnode.jks'
-            setting 'xpack.security.transport.ssl.keystore.password', 'testnode'
+        rootProject.globalInfo.ready {
+            if (project.inFipsJvm) {
+                setting 'xpack.security.transport.ssl.key', 'testnode.pem'
+                setting 'xpack.security.transport.ssl.certificate', 'testnode.crt'
+                keystoreSetting 'xpack.security.transport.ssl.secure_key_passphrase', 'testnode'
+            } else {
+                setting 'xpack.security.transport.ssl.keystore.path', 'testnode.jks'
+                setting 'xpack.security.transport.ssl.keystore.password', 'testnode'
+            }
         }
         setting 'xpack.license.self_generated.type', 'trial'
         dependsOn copyTestNodeKeyMaterial
@@ -160,13 +162,15 @@ for (Version version : bwcVersions.indexCompatible) {
         // some tests rely on the translog not being flushed
         setting 'indices.memory.shard_inactive_time', '20m'
         setting 'xpack.security.enabled', 'true'
-        if (project.inFipsJvm) {
-            setting 'xpack.security.transport.ssl.key', 'testnode.pem'
-            setting 'xpack.security.transport.ssl.certificate', 'testnode.crt'
-            keystoreSetting 'xpack.security.transport.ssl.secure_key_passphrase', 'testnode'
-        } else {
-            setting 'xpack.security.transport.ssl.keystore.path', 'testnode.jks'
-            setting 'xpack.security.transport.ssl.keystore.password', 'testnode'
+        rootProject.globalInfo.ready {
+            if (project.inFipsJvm) {
+                setting 'xpack.security.transport.ssl.key', 'testnode.pem'
+                setting 'xpack.security.transport.ssl.certificate', 'testnode.crt'
+                keystoreSetting 'xpack.security.transport.ssl.secure_key_passphrase', 'testnode'
+            } else {
+                setting 'xpack.security.transport.ssl.keystore.path', 'testnode.jks'
+                setting 'xpack.security.transport.ssl.keystore.password', 'testnode'
+            }
         }
         setting 'xpack.license.self_generated.type', 'trial'
         dependsOn copyTestNodeKeyMaterial

+ 4 - 2
x-pack/qa/reindex-tests-with-security/build.gradle

@@ -41,8 +41,10 @@ integTestCluster {
   setting 'reindex.ssl.truststore.password', 'password'
 
   // Workaround for JDK-8212885
-  if (project.ext.runtimeJavaVersion.isJava12Compatible() == false) {
-    setting 'reindex.ssl.supported_protocols', 'TLSv1.2'
+  rootProject.globalInfo.ready {
+    if (project.ext.runtimeJavaVersion.isJava12Compatible() == false) {
+      setting 'reindex.ssl.supported_protocols', 'TLSv1.2'
+    }
   }
 
   extraConfigFile 'roles.yml', 'roles.yml'

+ 18 - 14
x-pack/qa/rolling-upgrade/build.gradle

@@ -123,13 +123,15 @@ for (Version version : bwcVersions.wireCompatible) {
         setting 'xpack.security.authc.token.timeout', '60m'
         setting 'logger.org.elasticsearch.xpack.security.authc.TokenService', 'trace'
         setting 'xpack.security.audit.enabled', 'true'
-        if (project.inFipsJvm) {
-            setting 'xpack.security.transport.ssl.key', 'testnode.pem'
-            setting 'xpack.security.transport.ssl.certificate', 'testnode.crt'
-            keystoreSetting 'xpack.security.transport.ssl.secure_key_passphrase', 'testnode'
-        } else {
-            setting 'xpack.security.transport.ssl.keystore.path', 'testnode.jks'
-            setting 'xpack.security.transport.ssl.keystore.password', 'testnode'
+        rootProject.globalInfo.ready {
+            if (project.inFipsJvm) {
+                setting 'xpack.security.transport.ssl.key', 'testnode.pem'
+                setting 'xpack.security.transport.ssl.certificate', 'testnode.crt'
+                keystoreSetting 'xpack.security.transport.ssl.secure_key_passphrase', 'testnode'
+            } else {
+                setting 'xpack.security.transport.ssl.keystore.path', 'testnode.jks'
+                setting 'xpack.security.transport.ssl.keystore.password', 'testnode'
+            }
         }
         dependsOn copyTestNodeKeyMaterial
         extraConfigFile 'testnode.jks', new File(outputDir + '/testnode.jks')
@@ -188,13 +190,15 @@ for (Version version : bwcVersions.wireCompatible) {
             setting 'xpack.security.transport.ssl.enabled', 'true'
             setting 'xpack.security.authc.token.timeout', '60m'
             setting 'logger.org.elasticsearch.xpack.security.authc.TokenService', 'trace'
-            if (project.inFipsJvm) {
-                setting 'xpack.security.transport.ssl.key', 'testnode.pem'
-                setting 'xpack.security.transport.ssl.certificate', 'testnode.crt'
-                keystoreSetting 'xpack.security.transport.ssl.secure_key_passphrase', 'testnode'
-            } else {
-                setting 'xpack.security.transport.ssl.keystore.path', 'testnode.jks'
-                setting 'xpack.security.transport.ssl.keystore.password', 'testnode'
+            rootProject.globalInfo.ready {
+                if (project.inFipsJvm) {
+                    setting 'xpack.security.transport.ssl.key', 'testnode.pem'
+                    setting 'xpack.security.transport.ssl.certificate', 'testnode.crt'
+                    keystoreSetting 'xpack.security.transport.ssl.secure_key_passphrase', 'testnode'
+                } else {
+                    setting 'xpack.security.transport.ssl.keystore.path', 'testnode.jks'
+                    setting 'xpack.security.transport.ssl.keystore.password', 'testnode'
+                }
             }
             setting 'node.attr.upgraded', 'true'
             setting 'xpack.security.authc.token.enabled', 'true'

Some files were not shown because too many files changed in this diff