Skip to content

Commit 4a9aa95

Browse files
committed
[Backport] Consolidate docker availability logic (elastic#52656)
1 parent 21eea3b commit 4a9aa95

File tree

9 files changed

+578
-507
lines changed

9 files changed

+578
-507
lines changed

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

Lines changed: 0 additions & 47 deletions
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
Lines changed: 61 additions & 0 deletions
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)