Skip to content

Commit 1210ae5

Browse files
authored
Merge pull request #193 from elastic/main
🤖 ESQL: Merge upstream
2 parents 2821681 + a67920e commit 1210ae5

File tree

461 files changed

+7504
-1905
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

461 files changed

+7504
-1905
lines changed

BUILDING.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,38 @@ E.g. [configuration-cache support](https://github.com/elastic/elasticsearch/issu
6363
There are a few guidelines to follow that should make your life easier to make changes to the elasticsearch build.
6464
Please add a member of the `es-delivery` team as a reviewer if you're making non-trivial changes to the build.
6565

66+
#### Adding or updating a dependency
67+
68+
We rely on [Gradle dependency verification](https://docs.gradle.org/current/userguide/dependency_verification.html) to mitigate the security risks and avoid integrating compromised dependencies.
69+
70+
This requires to have third party dependencies and their checksums listed in `gradle/verification-metadata.xml`.
71+
72+
For updated or newly added dependencies you need to add an entry to this verification file or update the existing one:
73+
```
74+
<component group="asm" name="asm" version="3.1">
75+
<artifact name="asm-3.1.jar">
76+
<sha256 value="333ff5369043975b7e031b8b27206937441854738e038c1f47f98d072a20437a" origin="official site"/>
77+
</artifact>
78+
</component>
79+
```
80+
81+
You can also automate the generation of this entry by running your build using the `--write-verification-metadata` commandline option:
82+
```
83+
>./gradlew --write-verification-metadata sha256 precommit
84+
```
85+
86+
The `--write-verification-metadata` Gradle option is generally able to resolve reachable configurations,
87+
but we use detached configurations for a certain set of plugins and tasks. Therefore, please ensure you run this option with a task that
88+
uses the changed dependencies. In most cases, `precommit` or `check` are good candidates.
89+
90+
We prefer sha256 checksums as md5 and sha1 are not considered safe anymore these days. The generated entry
91+
will have the `origin` attribute been set to `Generated by Gradle`.
92+
93+
>A manual confirmation of the Gradle generated checksums is currently not mandatory.
94+
>If you want to add a level of verification you can manually confirm the checksum (e.g by looking it up on the website of the library)
95+
>Please replace the content of the `origin` attribute by `official site` in that case.
96+
>
97+
6698
#### Custom Plugin and Task implementations
6799

68100
Build logic that is used across multiple subprojects should considered to be moved into a Gradle plugin with according Gradle task implmentation.

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
# Elasticsearch Changlog
1+
# Elasticsearch Changelog
22

33
Please see the [release notes](https://www.elastic.co/guide/en/elasticsearch/reference/current/es-release-notes.html) in the reference manual.

build-tools-internal/src/main/groovy/elasticsearch.fips.gradle

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@
66
* Side Public License, v 1.
77
*/
88

9+
910
import org.elasticsearch.gradle.internal.ExportElasticsearchBuildResourcesTask
1011
import org.elasticsearch.gradle.internal.info.BuildParams
11-
import org.elasticsearch.gradle.testclusters.TestDistribution
1212
import org.elasticsearch.gradle.testclusters.TestClustersAware
13+
import org.elasticsearch.gradle.testclusters.TestDistribution
1314

1415
// Common config when running with a FIPS-140 runtime JVM
1516
if (BuildParams.inFipsJvm) {
@@ -31,7 +32,13 @@ if (BuildParams.inFipsJvm) {
3132
copy 'fips_java.policy'
3233
copy 'cacerts.bcfks'
3334
}
34-
def extraFipsJarsConfiguration = configurations.detachedConfiguration(bcFips, bcTlsFips)
35+
36+
def extraFipsJarsConfiguration = configurations.create("fipsImplementation") {
37+
withDependencies {
38+
add(bcFips)
39+
add(bcTlsFips)
40+
}
41+
}
3542

3643
project.afterEvaluate {
3744
// ensure that bouncycastle is on classpath for the all of test types, must happen in evaluateAfter since the rest tests explicitly

build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/precommit/DependencyLicensesPrecommitPlugin.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,6 @@ public TaskProvider<? extends Task> createTask(Project project) {
3434
runtimeClasspath.fileCollection(dependency -> dependency instanceof ProjectDependency == false).minus(compileOnly)
3535
);
3636
});
37-
38-
// we also create the updateShas helper task that is associated with dependencyLicenses
39-
project.getTasks().register("updateShas", UpdateShasTask.class, t -> t.setParentTask(dependencyLicenses));
4037
return dependencyLicenses;
4138
}
4239
}

build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/precommit/DependencyLicensesTask.java

Lines changed: 4 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
*/
88
package org.elasticsearch.gradle.internal.precommit;
99

10-
import org.apache.commons.codec.binary.Hex;
1110
import org.elasticsearch.gradle.internal.precommit.LicenseAnalyzer.LicenseInfo;
1211
import org.gradle.api.DefaultTask;
1312
import org.gradle.api.GradleException;
@@ -23,30 +22,21 @@
2322
import org.gradle.api.tasks.Input;
2423
import org.gradle.api.tasks.InputDirectory;
2524
import org.gradle.api.tasks.InputFiles;
26-
import org.gradle.api.tasks.Internal;
2725
import org.gradle.api.tasks.Optional;
2826
import org.gradle.api.tasks.OutputDirectory;
2927
import org.gradle.api.tasks.TaskAction;
3028

3129
import java.io.File;
32-
import java.io.IOException;
33-
import java.nio.charset.StandardCharsets;
34-
import java.nio.file.Files;
35-
import java.security.MessageDigest;
36-
import java.security.NoSuchAlgorithmException;
3730
import java.util.ArrayList;
38-
import java.util.Arrays;
3931
import java.util.HashMap;
4032
import java.util.HashSet;
4133
import java.util.LinkedHashMap;
4234
import java.util.LinkedHashSet;
4335
import java.util.List;
44-
import java.util.Locale;
4536
import java.util.Map;
4637
import java.util.Set;
4738
import java.util.regex.Matcher;
4839
import java.util.regex.Pattern;
49-
import java.util.stream.Collectors;
5040

5141
import javax.inject.Inject;
5242

@@ -193,7 +183,7 @@ public void ignoreFile(String file) {
193183
}
194184

195185
@TaskAction
196-
public void checkDependencies() throws IOException, NoSuchAlgorithmException {
186+
public void checkDependencies() {
197187
if (dependencies == null) {
198188
throw new GradleException("No dependencies variable defined.");
199189
}
@@ -214,12 +204,9 @@ public void checkDependencies() throws IOException, NoSuchAlgorithmException {
214204
Map<String, Boolean> licenses = new HashMap<>();
215205
Map<String, Boolean> notices = new HashMap<>();
216206
Map<String, Boolean> sources = new HashMap<>();
217-
Set<File> shaFiles = new HashSet<>();
218207
for (File file : licensesDirAsFile.listFiles()) {
219208
String name = file.getName();
220-
if (name.endsWith(SHA_EXTENSION)) {
221-
shaFiles.add(file);
222-
} else if (name.endsWith("-LICENSE") || name.endsWith("-LICENSE.txt")) {
209+
if (name.endsWith("-LICENSE") || name.endsWith("-LICENSE.txt")) {
223210
// TODO: why do we support suffix of LICENSE *and* LICENSE.txt??
224211
licenses.put(name, false);
225212
} else if (name.contains("-NOTICE") || name.contains("-NOTICE.txt")) {
@@ -233,18 +220,13 @@ public void checkDependencies() throws IOException, NoSuchAlgorithmException {
233220
notices.keySet().removeAll(ignoreFiles);
234221
sources.keySet().removeAll(ignoreFiles);
235222

236-
checkDependencies(licenses, notices, sources, shaFiles);
223+
checkDependencies(licenses, notices, sources);
237224

238225
licenses.forEach((item, exists) -> failIfAnyMissing(item, exists, "license"));
239226

240227
notices.forEach((item, exists) -> failIfAnyMissing(item, exists, "notice"));
241228

242229
sources.forEach((item, exists) -> failIfAnyMissing(item, exists, "sources"));
243-
244-
if (shaFiles.isEmpty() == false) {
245-
throw new GradleException("Unused sha files found: \n" + joinFilenames(shaFiles));
246-
}
247-
248230
}
249231

250232
// This is just a marker output folder to allow this task being up-to-date.
@@ -261,18 +243,10 @@ private void failIfAnyMissing(String item, Boolean exists, String type) {
261243
}
262244
}
263245

264-
private void checkDependencies(
265-
Map<String, Boolean> licenses,
266-
Map<String, Boolean> notices,
267-
Map<String, Boolean> sources,
268-
Set<File> shaFiles
269-
) throws NoSuchAlgorithmException, IOException {
246+
private void checkDependencies(Map<String, Boolean> licenses, Map<String, Boolean> notices, Map<String, Boolean> sources) {
270247
for (File dependency : dependencies) {
271248
String jarName = dependency.getName();
272249
String depName = regex.matcher(jarName).replaceFirst("");
273-
274-
validateSha(shaFiles, dependency, jarName, depName);
275-
276250
String dependencyName = getDependencyName(mappings, depName);
277251
logger.info("mapped dependency name {} to {} for license/notice check", depName, dependencyName);
278252
checkFile(dependencyName, jarName, licenses, "LICENSE");
@@ -286,24 +260,6 @@ private void checkDependencies(
286260
}
287261
}
288262

289-
private void validateSha(Set<File> shaFiles, File dependency, String jarName, String depName) throws NoSuchAlgorithmException,
290-
IOException {
291-
if (ignoreShas.contains(depName)) {
292-
// local deps should not have sha files!
293-
if (getShaFile(jarName).exists()) {
294-
throw new GradleException("SHA file " + getShaFile(jarName) + " exists for ignored dependency " + depName);
295-
}
296-
} else {
297-
logger.info("Checking sha for {}", jarName);
298-
checkSha(dependency, jarName, shaFiles);
299-
}
300-
}
301-
302-
private String joinFilenames(Set<File> shaFiles) {
303-
List<String> names = shaFiles.stream().map(File::getName).collect(Collectors.toList());
304-
return String.join("\n", names);
305-
}
306-
307263
public static String getDependencyName(Map<String, String> mappings, String dependencyName) {
308264
// order is the same for keys and values iteration since we use a linked hashmap
309265
List<String> mapped = new ArrayList<>(mappings.values());
@@ -319,30 +275,6 @@ public static String getDependencyName(Map<String, String> mappings, String depe
319275
return dependencyName;
320276
}
321277

322-
private void checkSha(File jar, String jarName, Set<File> shaFiles) throws NoSuchAlgorithmException, IOException {
323-
File shaFile = getShaFile(jarName);
324-
if (shaFile.exists() == false) {
325-
throw new GradleException("Missing SHA for " + jarName + ". Run \"gradle updateSHAs\" to create them");
326-
}
327-
328-
// TODO: shouldn't have to trim, sha files should not have trailing newline
329-
byte[] fileBytes = Files.readAllBytes(shaFile.toPath());
330-
String expectedSha = new String(fileBytes, StandardCharsets.UTF_8).trim();
331-
332-
String sha = getSha1(jar);
333-
334-
if (expectedSha.equals(sha) == false) {
335-
final String exceptionMessage = String.format(Locale.ROOT, """
336-
SHA has changed! Expected %s for %s but got %s.
337-
This usually indicates a corrupt dependency cache or artifacts changed upstream.
338-
Either wipe your cache, fix the upstream artifact, or delete %s and run updateShas
339-
""", expectedSha, jarName, sha, shaFile);
340-
341-
throw new GradleException(exceptionMessage);
342-
}
343-
shaFiles.remove(shaFile);
344-
}
345-
346278
private void checkFile(String name, String jarName, Map<String, Boolean> counters, String type) {
347279
String fileName = getFileName(name, counters, type);
348280

@@ -375,27 +307,4 @@ public LinkedHashMap<String, String> getMappings() {
375307
return new LinkedHashMap<>(mappings);
376308
}
377309

378-
File getShaFile(String jarName) {
379-
return new File(licensesDir.get().getAsFile(), jarName + SHA_EXTENSION);
380-
}
381-
382-
@Internal
383-
Set<File> getShaFiles() {
384-
File licenseDirAsFile = licensesDir.get().getAsFile();
385-
File[] array = licenseDirAsFile.listFiles();
386-
if (array == null) {
387-
throw new GradleException("\"" + licenseDirAsFile.getPath() + "\" isn't a valid directory");
388-
}
389-
390-
return Arrays.stream(array).filter(file -> file.getName().endsWith(SHA_EXTENSION)).collect(Collectors.toSet());
391-
}
392-
393-
String getSha1(File file) throws IOException, NoSuchAlgorithmException {
394-
byte[] bytes = Files.readAllBytes(file.toPath());
395-
396-
MessageDigest digest = MessageDigest.getInstance("SHA-1");
397-
char[] encoded = Hex.encodeHex(digest.digest(bytes));
398-
return String.copyValueOf(encoded);
399-
}
400-
401310
}

build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/precommit/UpdateShasTask.java

Lines changed: 0 additions & 78 deletions
This file was deleted.

0 commit comments

Comments
 (0)