Skip to content

Commit d6f7eb3

Browse files
committed
Merge branch 'master' into 2019-06-14-elect-nodes-outside-voting-configuration
2 parents 2e6fb3c + 42e19b7 commit d6f7eb3

File tree

125 files changed

+3041
-869
lines changed

Some content is hidden

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

125 files changed

+3041
-869
lines changed

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,16 +109,19 @@ public BwcVersions(List<String> versionLines) {
109109
}
110110

111111
protected BwcVersions(List<String> versionLines, Version currentVersionProperty) {
112-
SortedSet<Version> allVersions = versionLines.stream()
112+
this(versionLines.stream()
113113
.map(LINE_PATTERN::matcher)
114114
.filter(Matcher::matches)
115115
.map(match -> new Version(
116116
Integer.parseInt(match.group(1)),
117117
Integer.parseInt(match.group(2)),
118118
Integer.parseInt(match.group(3))
119119
))
120-
.collect(Collectors.toCollection(TreeSet::new));
120+
.collect(Collectors.toCollection(TreeSet::new)), currentVersionProperty);
121+
}
121122

123+
// for testkit tests, until BwcVersions is extracted into an extension
124+
public BwcVersions(SortedSet<Version> allVersions, Version currentVersionProperty) {
122125
if (allVersions.isEmpty()) {
123126
throw new IllegalArgumentException("Could not parse any versions");
124127
}
Lines changed: 273 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,273 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.gradle;
21+
22+
import org.elasticsearch.gradle.ElasticsearchDistribution.Flavor;
23+
import org.elasticsearch.gradle.ElasticsearchDistribution.Platform;
24+
import org.elasticsearch.gradle.ElasticsearchDistribution.Type;
25+
import org.gradle.api.GradleException;
26+
import org.gradle.api.NamedDomainObjectContainer;
27+
import org.gradle.api.Plugin;
28+
import org.gradle.api.Project;
29+
import org.gradle.api.UnknownTaskException;
30+
import org.gradle.api.artifacts.Configuration;
31+
import org.gradle.api.artifacts.ConfigurationContainer;
32+
import org.gradle.api.artifacts.Dependency;
33+
import org.gradle.api.artifacts.dsl.DependencyHandler;
34+
import org.gradle.api.artifacts.repositories.IvyArtifactRepository;
35+
import org.gradle.api.credentials.HttpHeaderCredentials;
36+
import org.gradle.api.file.FileTree;
37+
import org.gradle.api.plugins.ExtraPropertiesExtension;
38+
import org.gradle.api.tasks.Copy;
39+
import org.gradle.api.tasks.TaskProvider;
40+
import org.gradle.authentication.http.HttpHeaderAuthentication;
41+
42+
import java.io.File;
43+
import java.util.HashMap;
44+
import java.util.Locale;
45+
import java.util.Map;
46+
import java.util.concurrent.Callable;
47+
import java.util.function.Supplier;
48+
49+
/**
50+
* A plugin to manage getting and extracting distributions of Elasticsearch.
51+
*
52+
* The source of the distribution could be from a local snapshot, a locally built
53+
* bwc snapshot, or the Elastic downloads service.
54+
*/
55+
public class DistributionDownloadPlugin implements Plugin<Project> {
56+
57+
private static final String FAKE_GROUP = "elasticsearch-distribution";
58+
private static final String DOWNLOAD_REPO_NAME = "elasticsearch-downloads";
59+
60+
private BwcVersions bwcVersions;
61+
private NamedDomainObjectContainer<ElasticsearchDistribution> distributionsContainer;
62+
63+
@Override
64+
public void apply(Project project) {
65+
distributionsContainer = project.container(ElasticsearchDistribution.class, name -> new ElasticsearchDistribution(name, project));
66+
project.getExtensions().add("elasticsearch_distributions", distributionsContainer);
67+
68+
setupDownloadServiceRepo(project);
69+
70+
ExtraPropertiesExtension extraProperties = project.getExtensions().getExtraProperties();
71+
this.bwcVersions = (BwcVersions) extraProperties.get("bwcVersions");
72+
// TODO: setup snapshot dependency instead of pointing to bwc distribution projects for external projects
73+
74+
project.afterEvaluate(this::setupDistributions);
75+
}
76+
77+
// pkg private for tests
78+
void setupDistributions(Project project) {
79+
for (ElasticsearchDistribution distribution : distributionsContainer) {
80+
distribution.finalizeValues();
81+
82+
DependencyHandler dependencies = project.getDependencies();
83+
// for the distribution as a file, just depend on the artifact directly
84+
dependencies.add(distribution.configuration.getName(), dependencyNotation(project, distribution));
85+
86+
// no extraction allowed for rpm or deb
87+
if (distribution.getType() != Type.RPM && distribution.getType() != Type.DEB) {
88+
// for the distribution extracted, add a root level task that does the extraction, and depend on that
89+
// extracted configuration as an artifact consisting of the extracted distribution directory
90+
dependencies.add(distribution.getExtracted().configuration.getName(),
91+
projectDependency(project, ":", configName("extracted_elasticsearch", distribution)));
92+
// ensure a root level download task exists
93+
setupRootDownload(project.getRootProject(), distribution);
94+
}
95+
}
96+
}
97+
98+
private void setupRootDownload(Project rootProject, ElasticsearchDistribution distribution) {
99+
String extractTaskName = extractTaskName(distribution);
100+
// NOTE: this is *horrendous*, but seems to be the only way to check for the existence of a registered task
101+
try {
102+
rootProject.getTasks().named(extractTaskName);
103+
// already setup this version
104+
return;
105+
} catch (UnknownTaskException e) {
106+
// fall through: register the task
107+
}
108+
setupDownloadServiceRepo(rootProject);
109+
110+
final ConfigurationContainer configurations = rootProject.getConfigurations();
111+
String downloadConfigName = configName("elasticsearch", distribution);
112+
String extractedConfigName = "extracted_" + downloadConfigName;
113+
final Configuration downloadConfig = configurations.create(downloadConfigName);
114+
configurations.create(extractedConfigName);
115+
Object distroDep = dependencyNotation(rootProject, distribution);
116+
rootProject.getDependencies().add(downloadConfigName, distroDep);
117+
118+
// add task for extraction, delaying resolving config until runtime
119+
if (distribution.getType() == Type.ARCHIVE || distribution.getType() == Type.INTEG_TEST_ZIP) {
120+
Supplier<File> archiveGetter = downloadConfig::getSingleFile;
121+
String extractDir = rootProject.getBuildDir().toPath().resolve("elasticsearch-distros").resolve(extractedConfigName).toString();
122+
TaskProvider<Copy> extractTask = rootProject.getTasks().register(extractTaskName, Copy.class, copyTask -> {
123+
copyTask.dependsOn(downloadConfig);
124+
copyTask.doFirst(t -> rootProject.delete(extractDir));
125+
copyTask.into(extractDir);
126+
copyTask.from((Callable<FileTree>)() -> {
127+
File archiveFile = archiveGetter.get();
128+
String archivePath = archiveFile.toString();
129+
if (archivePath.endsWith(".zip")) {
130+
return rootProject.zipTree(archiveFile);
131+
} else if (archivePath.endsWith(".tar.gz")) {
132+
return rootProject.tarTree(rootProject.getResources().gzip(archiveFile));
133+
}
134+
throw new IllegalStateException("unexpected file extension on [" + archivePath + "]");
135+
});
136+
});
137+
rootProject.getArtifacts().add(extractedConfigName,
138+
rootProject.getLayout().getProjectDirectory().dir(extractDir),
139+
artifact -> artifact.builtBy(extractTask));
140+
}
141+
}
142+
143+
private static void setupDownloadServiceRepo(Project project) {
144+
if (project.getRepositories().findByName(DOWNLOAD_REPO_NAME) != null) {
145+
return;
146+
}
147+
project.getRepositories().ivy(ivyRepo -> {
148+
ivyRepo.setName(DOWNLOAD_REPO_NAME);
149+
ivyRepo.setUrl("https://artifacts.elastic.co");
150+
ivyRepo.metadataSources(IvyArtifactRepository.MetadataSources::artifact);
151+
// this header is not a credential but we hack the capability to send this header to avoid polluting our download stats
152+
ivyRepo.credentials(HttpHeaderCredentials.class, creds -> {
153+
creds.setName("X-Elastic-No-KPI");
154+
creds.setValue("1");
155+
});
156+
ivyRepo.getAuthentication().create("header", HttpHeaderAuthentication.class);
157+
ivyRepo.patternLayout(layout -> layout.artifact("/downloads/elasticsearch/[module]-[revision](-[classifier]).[ext]"));
158+
ivyRepo.content(content -> content.includeGroup(FAKE_GROUP));
159+
});
160+
project.getRepositories().all(repo -> {
161+
if (repo.getName().equals(DOWNLOAD_REPO_NAME) == false) {
162+
// all other repos should ignore the special group name
163+
repo.content(content -> content.excludeGroup(FAKE_GROUP));
164+
}
165+
});
166+
// TODO: need maven repo just for integ-test-zip, but only in external cases
167+
}
168+
169+
/**
170+
* Returns a dependency object representing the given distribution.
171+
*
172+
* The returned object is suitable to be passed to {@link DependencyHandler}.
173+
* The concrete type of the object will either be a project {@link Dependency} or
174+
* a set of maven coordinates as a {@link String}. Project dependencies point to
175+
* a project in the Elasticsearch repo either under `:distribution:bwc`,
176+
* `:distribution:archives` or :distribution:packages`. Maven coordinates point to
177+
* either the integ-test-zip coordinates on maven central, or a set of artificial
178+
* coordinates that resolve to the Elastic download service through an ivy repository.
179+
*/
180+
private Object dependencyNotation(Project project, ElasticsearchDistribution distribution) {
181+
182+
if (Version.fromString(VersionProperties.getElasticsearch()).equals(distribution.getVersion())) {
183+
return projectDependency(project, distributionProjectPath(distribution), "default");
184+
// TODO: snapshot dep when not in ES repo
185+
}
186+
BwcVersions.UnreleasedVersionInfo unreleasedInfo = bwcVersions.unreleasedInfo(distribution.getVersion());
187+
if (unreleasedInfo != null) {
188+
assert distribution.getBundledJdk();
189+
return projectDependency(project, unreleasedInfo.gradleProjectPath, distributionProjectName(distribution));
190+
}
191+
192+
if (distribution.getType() == Type.INTEG_TEST_ZIP) {
193+
return "org.elasticsearch.distribution.integ-test-zip:elasticsearch:" + distribution.getVersion();
194+
}
195+
196+
String extension = distribution.getType().toString();
197+
String classifier = "x86_64";
198+
if (distribution.getType() == Type.ARCHIVE) {
199+
extension = distribution.getPlatform() == Platform.WINDOWS ? "zip" : "tar.gz";
200+
classifier = distribution.getPlatform() + "-" + classifier;
201+
}
202+
return FAKE_GROUP + ":elasticsearch" + (distribution.getFlavor() == Flavor.OSS ? "-oss:" : ":")
203+
+ distribution.getVersion() + ":" + classifier + "@" + extension;
204+
}
205+
206+
private static Dependency projectDependency(Project project, String projectPath, String projectConfig) {
207+
208+
if (project.findProject(projectPath) == null) {
209+
throw new GradleException("no project [" + projectPath + "], project names: " + project.getRootProject().getAllprojects());
210+
}
211+
Map<String, Object> depConfig = new HashMap<>();
212+
depConfig.put("path", projectPath);
213+
depConfig.put("configuration", projectConfig);
214+
return project.getDependencies().project(depConfig);
215+
}
216+
217+
private static String distributionProjectPath(ElasticsearchDistribution distribution) {
218+
String projectPath = ":distribution";
219+
if (distribution.getType() == Type.INTEG_TEST_ZIP) {
220+
projectPath += ":archives:integ-test-zip";
221+
} else {
222+
projectPath += distribution.getType() == Type.ARCHIVE ? ":archives:" : ":packages:";
223+
projectPath += distributionProjectName(distribution);
224+
}
225+
return projectPath;
226+
}
227+
228+
private static String distributionProjectName(ElasticsearchDistribution distribution) {
229+
String projectName = "";
230+
if (distribution.getFlavor() == Flavor.OSS) {
231+
projectName += "oss-";
232+
}
233+
if (distribution.getBundledJdk() == false) {
234+
projectName += "no-jdk-";
235+
}
236+
if (distribution.getType() == Type.ARCHIVE) {
237+
Platform platform = distribution.getPlatform();
238+
projectName += platform.toString() + (platform == Platform.WINDOWS ? "-zip" : "-tar");
239+
} else {
240+
projectName += distribution.getType();
241+
}
242+
return projectName;
243+
}
244+
245+
private static String configName(String prefix, ElasticsearchDistribution distribution) {
246+
return prefix + "_" + distribution.getVersion() + "_" + distribution.getType() + "_" +
247+
(distribution.getPlatform() == null ? "" : distribution.getPlatform() + "_")
248+
+ distribution.getFlavor() + (distribution.getBundledJdk() ? "" : "_nojdk");
249+
}
250+
251+
private static String capitalize(String s) {
252+
return s.substring(0, 1).toUpperCase(Locale.ROOT) + s.substring(1);
253+
}
254+
255+
private static String extractTaskName(ElasticsearchDistribution distribution) {
256+
String taskName = "extractElasticsearch";
257+
if (distribution.getType() != Type.INTEG_TEST_ZIP) {
258+
if (distribution.getFlavor() == Flavor.OSS) {
259+
taskName += "Oss";
260+
}
261+
if (distribution.getBundledJdk() == false) {
262+
taskName += "NoJdk";
263+
}
264+
}
265+
if (distribution.getType() == Type.ARCHIVE) {
266+
taskName += capitalize(distribution.getPlatform().toString());
267+
} else if (distribution.getType() != Type.INTEG_TEST_ZIP) {
268+
taskName += capitalize(distribution.getType().toString());
269+
}
270+
taskName += distribution.getVersion();
271+
return taskName;
272+
}
273+
}

0 commit comments

Comments
 (0)