Skip to content

Commit 52ad35a

Browse files
committed
Merge remote-tracking branch 'elastic/7.x' into 7x-geoshape-doc-values
2 parents b33be9e + de3d674 commit 52ad35a

File tree

394 files changed

+7488
-2842
lines changed

Some content is hidden

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

394 files changed

+7488
-2842
lines changed

build.gradle

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import static org.elasticsearch.gradle.tool.Boilerplate.maybeConfigure
3434

3535
plugins {
3636
id 'lifecycle-base'
37+
id 'elasticsearch.docker-support'
3738
id 'elasticsearch.global-build-info'
3839
id "com.diffplug.gradle.spotless" version "3.24.2" apply false
3940
}

buildSrc/src/main/groovy/org/elasticsearch/gradle/BuildPlugin.groovy

-47
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,6 @@ import java.nio.charset.StandardCharsets
8484
import java.nio.file.Files
8585

8686
import static org.elasticsearch.gradle.tool.Boilerplate.maybeConfigure
87-
import static org.elasticsearch.gradle.tool.DockerUtils.assertDockerIsAvailable
88-
import static org.elasticsearch.gradle.tool.DockerUtils.getDockerPath
8987

9088
/**
9189
* Encapsulates build configuration for elasticsearch projects.
@@ -208,51 +206,6 @@ class BuildPlugin implements Plugin<Project> {
208206
}
209207
}
210208

211-
static void requireDocker(final Task task) {
212-
final Project rootProject = task.project.rootProject
213-
ExtraPropertiesExtension ext = rootProject.extensions.getByType(ExtraPropertiesExtension)
214-
215-
if (rootProject.hasProperty('requiresDocker') == false) {
216-
/*
217-
* This is our first time encountering a task that requires Docker. We will add an extension that will let us track the tasks
218-
* that register as requiring Docker. We will add a delayed execution that when the task graph is ready if any such tasks are
219-
* in the task graph, then we check two things:
220-
* - the Docker binary is available
221-
* - we can execute a Docker command that requires privileges
222-
*
223-
* If either of these fail, we fail the build.
224-
*/
225-
226-
// check if the Docker binary exists and record its path
227-
final String dockerBinary = getDockerPath().orElse(null)
228-
229-
final boolean buildDocker
230-
final String buildDockerProperty = System.getProperty("build.docker")
231-
if (buildDockerProperty == null) {
232-
buildDocker = dockerBinary != null
233-
} else if (buildDockerProperty == "true") {
234-
buildDocker = true
235-
} else if (buildDockerProperty == "false") {
236-
buildDocker = false
237-
} else {
238-
throw new IllegalArgumentException(
239-
"expected build.docker to be unset or one of \"true\" or \"false\" but was [" + buildDockerProperty + "]")
240-
}
241-
242-
ext.set('buildDocker', buildDocker)
243-
ext.set('requiresDocker', [])
244-
rootProject.gradle.taskGraph.whenReady { TaskExecutionGraph taskGraph ->
245-
final List<String> tasks = taskGraph.allTasks.intersect(ext.get('requiresDocker') as List<Task>).collect { " ${it.path}".toString()}
246-
247-
if (tasks.isEmpty() == false) {
248-
assertDockerIsAvailable(task.project, tasks)
249-
}
250-
}
251-
}
252-
253-
(ext.get('requiresDocker') as List<Task>).add(task)
254-
}
255-
256209
/** Add a check before gradle execution phase which ensures java home for the given java version is set. */
257210
static void requireJavaHome(Task task, int version) {
258211
// use root project for global accounting

buildSrc/src/main/java/org/elasticsearch/gradle/DistributionDownloadPlugin.java

+11-1
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,11 @@
2222
import org.elasticsearch.gradle.ElasticsearchDistribution.Flavor;
2323
import org.elasticsearch.gradle.ElasticsearchDistribution.Platform;
2424
import org.elasticsearch.gradle.ElasticsearchDistribution.Type;
25+
import org.elasticsearch.gradle.docker.DockerSupportPlugin;
26+
import org.elasticsearch.gradle.docker.DockerSupportService;
2527
import org.elasticsearch.gradle.info.BuildParams;
2628
import org.elasticsearch.gradle.info.GlobalBuildInfoPlugin;
29+
import org.elasticsearch.gradle.tool.Boilerplate;
2730
import org.gradle.api.GradleException;
2831
import org.gradle.api.NamedDomainObjectContainer;
2932
import org.gradle.api.Plugin;
@@ -38,6 +41,7 @@
3841
import org.gradle.api.file.FileTree;
3942
import org.gradle.api.file.RelativePath;
4043
import org.gradle.api.plugins.ExtraPropertiesExtension;
44+
import org.gradle.api.provider.Provider;
4145
import org.gradle.api.tasks.Sync;
4246
import org.gradle.api.tasks.TaskProvider;
4347
import org.gradle.authentication.http.HttpHeaderAuthentication;
@@ -72,11 +76,17 @@ public class DistributionDownloadPlugin implements Plugin<Project> {
7276
public void apply(Project project) {
7377
// this is needed for isInternal
7478
project.getRootProject().getPluginManager().apply(GlobalBuildInfoPlugin.class);
79+
project.getRootProject().getPluginManager().apply(DockerSupportPlugin.class);
80+
81+
Provider<DockerSupportService> dockerSupport = Boilerplate.getBuildService(
82+
project.getGradle().getSharedServices(),
83+
DockerSupportPlugin.DOCKER_SUPPORT_SERVICE_NAME
84+
);
7585

7686
distributionsContainer = project.container(ElasticsearchDistribution.class, name -> {
7787
Configuration fileConfiguration = project.getConfigurations().create("es_distro_file_" + name);
7888
Configuration extractedConfiguration = project.getConfigurations().create("es_distro_extracted_" + name);
79-
return new ElasticsearchDistribution(name, project.getObjects(), fileConfiguration, extractedConfiguration);
89+
return new ElasticsearchDistribution(name, project.getObjects(), dockerSupport, fileConfiguration, extractedConfiguration);
8090
});
8191
project.getExtensions().add(CONTAINER_NAME, distributionsContainer);
8292

buildSrc/src/main/java/org/elasticsearch/gradle/ElasticsearchDistribution.java

+37-3
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,16 @@
1919

2020
package org.elasticsearch.gradle;
2121

22+
import org.elasticsearch.gradle.docker.DockerSupportService;
2223
import org.gradle.api.Buildable;
2324
import org.gradle.api.artifacts.Configuration;
2425
import org.gradle.api.model.ObjectFactory;
2526
import org.gradle.api.provider.Property;
27+
import org.gradle.api.provider.Provider;
2628
import org.gradle.api.tasks.TaskDependency;
2729

2830
import java.io.File;
31+
import java.util.Collections;
2932
import java.util.Iterator;
3033
import java.util.Locale;
3134

@@ -110,6 +113,7 @@ public String toString() {
110113
}
111114

112115
private final String name;
116+
private final Provider<DockerSupportService> dockerSupport;
113117
// pkg private so plugin can configure
114118
final Configuration configuration;
115119
private final Extracted extracted;
@@ -119,21 +123,25 @@ public String toString() {
119123
private final Property<Platform> platform;
120124
private final Property<Flavor> flavor;
121125
private final Property<Boolean> bundledJdk;
126+
private final Property<Boolean> failIfUnavailable;
122127

123128
ElasticsearchDistribution(
124129
String name,
125130
ObjectFactory objectFactory,
131+
Provider<DockerSupportService> dockerSupport,
126132
Configuration fileConfiguration,
127133
Configuration extractedConfiguration
128134
) {
129135
this.name = name;
136+
this.dockerSupport = dockerSupport;
130137
this.configuration = fileConfiguration;
131138
this.version = objectFactory.property(String.class).convention(VersionProperties.getElasticsearch());
132139
this.type = objectFactory.property(Type.class);
133140
this.type.convention(Type.ARCHIVE);
134141
this.platform = objectFactory.property(Platform.class);
135142
this.flavor = objectFactory.property(Flavor.class);
136143
this.bundledJdk = objectFactory.property(Boolean.class);
144+
this.failIfUnavailable = objectFactory.property(Boolean.class).convention(true);
137145
this.extracted = new Extracted(extractedConfiguration);
138146
}
139147

@@ -182,6 +190,14 @@ public void setBundledJdk(Boolean bundledJdk) {
182190
this.bundledJdk.set(bundledJdk);
183191
}
184192

193+
public boolean getFailIfUnavailable() {
194+
return this.failIfUnavailable.get();
195+
}
196+
197+
public void setFailIfUnavailable(boolean failIfUnavailable) {
198+
this.failIfUnavailable.set(failIfUnavailable);
199+
}
200+
185201
@Override
186202
public String toString() {
187203
return configuration.getSingleFile().toString();
@@ -203,6 +219,13 @@ public Extracted getExtracted() {
203219

204220
@Override
205221
public TaskDependency getBuildDependencies() {
222+
// For non-required Docker distributions, skip building the distribution is Docker is unavailable
223+
if (getType() == Type.DOCKER
224+
&& getFailIfUnavailable() == false
225+
&& dockerSupport.get().getDockerAvailability().isAvailable == false) {
226+
return task -> Collections.emptySet();
227+
}
228+
206229
return configuration.getBuildDependencies();
207230
}
208231

@@ -222,7 +245,7 @@ void finalizeValues() {
222245
if (getType() == Type.INTEG_TEST_ZIP) {
223246
if (platform.getOrNull() != null) {
224247
throw new IllegalArgumentException(
225-
"platform not allowed for elasticsearch distribution [" + name + "] of type [integ_test_zip]"
248+
"platform cannot be set on elasticsearch distribution [" + name + "] of type [integ_test_zip]"
226249
);
227250
}
228251
if (flavor.getOrNull() != null) {
@@ -232,12 +255,18 @@ void finalizeValues() {
232255
}
233256
if (bundledJdk.getOrNull() != null) {
234257
throw new IllegalArgumentException(
235-
"bundledJdk not allowed for elasticsearch distribution [" + name + "] of type [integ_test_zip]"
258+
"bundledJdk cannot be set on elasticsearch distribution [" + name + "] of type [integ_test_zip]"
236259
);
237260
}
238261
return;
239262
}
240263

264+
if (getType() != Type.DOCKER && failIfUnavailable.get() == false) {
265+
throw new IllegalArgumentException(
266+
"failIfUnavailable cannot be 'false' on elasticsearch distribution [" + name + "] of type [" + getType() + "]"
267+
);
268+
}
269+
241270
if (getType() == Type.ARCHIVE) {
242271
// defaults for archive, set here instead of via convention so integ-test-zip can verify they are not set
243272
if (platform.isPresent() == false) {
@@ -246,7 +275,12 @@ void finalizeValues() {
246275
} else { // rpm, deb or docker
247276
if (platform.isPresent()) {
248277
throw new IllegalArgumentException(
249-
"platform not allowed for elasticsearch distribution [" + name + "] of type [" + getType() + "]"
278+
"platform cannot be set on elasticsearch distribution [" + name + "] of type [" + getType() + "]"
279+
);
280+
}
281+
if (getType() == Type.DOCKER && bundledJdk.isPresent()) {
282+
throw new IllegalArgumentException(
283+
"bundledJdk cannot be set on elasticsearch distribution [" + name + "] of type [docker]"
250284
);
251285
}
252286
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package org.elasticsearch.gradle.docker;
2+
3+
import org.gradle.api.Plugin;
4+
import org.gradle.api.Project;
5+
import org.gradle.api.Task;
6+
import org.gradle.api.plugins.ExtraPropertiesExtension;
7+
import org.gradle.api.provider.Provider;
8+
9+
import java.io.File;
10+
import java.util.List;
11+
import java.util.stream.Collectors;
12+
13+
/**
14+
* Plugin providing {@link DockerSupportService} for detecting Docker installations and determining requirements for Docker-based
15+
* Elasticsearch build tasks.
16+
* <p>
17+
* Additionally registers a task graph listener used to assert a compatible Docker installation exists when task requiring Docker are
18+
* scheduled for execution. Tasks may declare a Docker requirement via an extra property. If a compatible Docker installation is not
19+
* available on the build system an exception will be thrown prior to task execution.
20+
*
21+
* <pre>
22+
* task myDockerTask {
23+
* ext.requiresDocker = true
24+
* }
25+
* </pre>
26+
*/
27+
public class DockerSupportPlugin implements Plugin<Project> {
28+
public static final String DOCKER_SUPPORT_SERVICE_NAME = "dockerSupportService";
29+
public static final String DOCKER_ON_LINUX_EXCLUSIONS_FILE = ".ci/dockerOnLinuxExclusions";
30+
public static final String REQUIRES_DOCKER_ATTRIBUTE = "requiresDocker";
31+
32+
@Override
33+
public void apply(Project project) {
34+
if (project != project.getRootProject()) {
35+
throw new IllegalStateException(this.getClass().getName() + " can only be applied to the root project.");
36+
}
37+
38+
Provider<DockerSupportService> dockerSupportServiceProvider = project.getGradle()
39+
.getSharedServices()
40+
.registerIfAbsent(
41+
DOCKER_SUPPORT_SERVICE_NAME,
42+
DockerSupportService.class,
43+
spec -> spec.parameters(
44+
params -> { params.setExclusionsFile(new File(project.getRootDir(), DOCKER_ON_LINUX_EXCLUSIONS_FILE)); }
45+
)
46+
);
47+
48+
// Ensure that if any tasks declare they require docker, we assert an available Docker installation exists
49+
project.getGradle().getTaskGraph().whenReady(graph -> {
50+
List<String> dockerTasks = graph.getAllTasks().stream().filter(task -> {
51+
ExtraPropertiesExtension ext = task.getExtensions().getExtraProperties();
52+
return ext.has(REQUIRES_DOCKER_ATTRIBUTE) && (boolean) ext.get(REQUIRES_DOCKER_ATTRIBUTE);
53+
}).map(Task::getPath).collect(Collectors.toList());
54+
55+
if (dockerTasks.isEmpty() == false) {
56+
dockerSupportServiceProvider.get().failIfDockerUnavailable(dockerTasks);
57+
}
58+
});
59+
}
60+
61+
}

0 commit comments

Comments
 (0)