mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-02-08 22:14:59 +00:00
Format projects under :distribution:tools (#51292)
Backport of #51226. Opt-in the sub-projects of :distribution:tools for automatic formatting.
This commit is contained in:
parent
421aa14972
commit
1009f92b03
@ -107,6 +107,9 @@ subprojects {
|
|||||||
// switched to an exclude list, and eventualy removed completely.
|
// switched to an exclude list, and eventualy removed completely.
|
||||||
def projectPathsToFormat = [
|
def projectPathsToFormat = [
|
||||||
':build-tools',
|
':build-tools',
|
||||||
|
':distribution:tools:java-version-checker',
|
||||||
|
':distribution:tools:launchers',
|
||||||
|
':distribution:tools:plugin-cli',
|
||||||
':x-pack:plugin:autoscaling',
|
':x-pack:plugin:autoscaling',
|
||||||
':x-pack:plugin:enrich'
|
':x-pack:plugin:enrich'
|
||||||
]
|
]
|
||||||
|
@ -27,8 +27,7 @@ import java.util.Locale;
|
|||||||
*/
|
*/
|
||||||
final class JavaVersionChecker {
|
final class JavaVersionChecker {
|
||||||
|
|
||||||
private JavaVersionChecker() {
|
private JavaVersionChecker() {}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The main entry point. The exit code is 0 if the Java version is at least 1.8, otherwise the exit code is 1.
|
* The main entry point. The exit code is 0 if the Java version is at least 1.8, otherwise the exit code is 1.
|
||||||
@ -42,17 +41,19 @@ final class JavaVersionChecker {
|
|||||||
}
|
}
|
||||||
if (JavaVersion.compare(JavaVersion.CURRENT, JavaVersion.JAVA_8) < 0) {
|
if (JavaVersion.compare(JavaVersion.CURRENT, JavaVersion.JAVA_8) < 0) {
|
||||||
final String message = String.format(
|
final String message = String.format(
|
||||||
Locale.ROOT,
|
Locale.ROOT,
|
||||||
"the minimum required Java version is 8; your Java version from [%s] does not meet this requirement",
|
"the minimum required Java version is 8; your Java version from [%s] does not meet this requirement",
|
||||||
System.getProperty("java.home"));
|
System.getProperty("java.home")
|
||||||
|
);
|
||||||
errPrintln(message);
|
errPrintln(message);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
if (JavaVersion.compare(JavaVersion.CURRENT, JavaVersion.JAVA_11) < 0) {
|
if (JavaVersion.compare(JavaVersion.CURRENT, JavaVersion.JAVA_11) < 0) {
|
||||||
final String message = String.format(
|
final String message = String.format(
|
||||||
Locale.ROOT,
|
Locale.ROOT,
|
||||||
"future versions of Elasticsearch will require Java 11; your Java version from [%s] does not meet this requirement",
|
"future versions of Elasticsearch will require Java 11; your Java version from [%s] does not meet this requirement",
|
||||||
System.getProperty("java.home"));
|
System.getProperty("java.home")
|
||||||
|
);
|
||||||
errPrintln(message);
|
errPrintln(message);
|
||||||
}
|
}
|
||||||
exit(0);
|
exit(0);
|
||||||
|
@ -78,14 +78,18 @@ final class JvmErgonomics {
|
|||||||
return ergonomicChoices;
|
return ergonomicChoices;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Pattern OPTION =
|
private static final Pattern OPTION = Pattern.compile(
|
||||||
Pattern.compile("^\\s*\\S+\\s+(?<flag>\\S+)\\s+:?=\\s+(?<value>\\S+)?\\s+\\{[^}]+?\\}(\\s+\\{[^}]+})?");
|
"^\\s*\\S+\\s+(?<flag>\\S+)\\s+:?=\\s+(?<value>\\S+)?\\s+\\{[^}]+?\\}(\\s+\\{[^}]+})?"
|
||||||
|
);
|
||||||
|
|
||||||
static Map<String, Optional<String>> finalJvmOptions(
|
static Map<String, Optional<String>> finalJvmOptions(final List<String> userDefinedJvmOptions) throws InterruptedException,
|
||||||
final List<String> userDefinedJvmOptions) throws InterruptedException, IOException {
|
IOException {
|
||||||
return Collections.unmodifiableMap(flagsFinal(userDefinedJvmOptions).stream()
|
return Collections.unmodifiableMap(
|
||||||
.map(OPTION::matcher).filter(Matcher::matches)
|
flagsFinal(userDefinedJvmOptions).stream()
|
||||||
.collect(Collectors.toMap(m -> m.group("flag"), m -> Optional.ofNullable(m.group("value")))));
|
.map(OPTION::matcher)
|
||||||
|
.filter(Matcher::matches)
|
||||||
|
.collect(Collectors.toMap(m -> m.group("flag"), m -> Optional.ofNullable(m.group("value"))))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<String> flagsFinal(final List<String> userDefinedJvmOptions) throws InterruptedException, IOException {
|
private static List<String> flagsFinal(final List<String> userDefinedJvmOptions) throws InterruptedException, IOException {
|
||||||
@ -98,23 +102,24 @@ final class JvmErgonomics {
|
|||||||
* without having to implement our own JVM option parsing logic.
|
* without having to implement our own JVM option parsing logic.
|
||||||
*/
|
*/
|
||||||
final String java = Paths.get(System.getProperty("java.home"), "bin", "java").toString();
|
final String java = Paths.get(System.getProperty("java.home"), "bin", "java").toString();
|
||||||
final List<String> command =
|
final List<String> command = Collections.unmodifiableList(
|
||||||
Collections.unmodifiableList(
|
Stream.of(Stream.of(java), userDefinedJvmOptions.stream(), Stream.of("-XX:+PrintFlagsFinal"), Stream.of("-version"))
|
||||||
Stream.of(Stream.of(java), userDefinedJvmOptions.stream(), Stream.of("-XX:+PrintFlagsFinal"), Stream.of("-version"))
|
.reduce(Stream::concat)
|
||||||
.reduce(Stream::concat)
|
.get()
|
||||||
.get()
|
.collect(Collectors.toList())
|
||||||
.collect(Collectors.toList()));
|
);
|
||||||
final Process process = new ProcessBuilder().command(command).start();
|
final Process process = new ProcessBuilder().command(command).start();
|
||||||
final List<String> output = readLinesFromInputStream(process.getInputStream());
|
final List<String> output = readLinesFromInputStream(process.getInputStream());
|
||||||
final List<String> error = readLinesFromInputStream(process.getErrorStream());
|
final List<String> error = readLinesFromInputStream(process.getErrorStream());
|
||||||
final int status = process.waitFor();
|
final int status = process.waitFor();
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
final String message = String.format(
|
final String message = String.format(
|
||||||
Locale.ROOT,
|
Locale.ROOT,
|
||||||
"starting java failed with [%d]\noutput:\n%s\nerror:\n%s",
|
"starting java failed with [%d]\noutput:\n%s\nerror:\n%s",
|
||||||
status,
|
status,
|
||||||
String.join("\n", output),
|
String.join("\n", output),
|
||||||
String.join("\n", error));
|
String.join("\n", error)
|
||||||
|
);
|
||||||
throw new RuntimeException(message);
|
throw new RuntimeException(message);
|
||||||
} else {
|
} else {
|
||||||
return output;
|
return output;
|
||||||
@ -122,8 +127,7 @@ final class JvmErgonomics {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static List<String> readLinesFromInputStream(final InputStream is) throws IOException {
|
private static List<String> readLinesFromInputStream(final InputStream is) throws IOException {
|
||||||
try (InputStreamReader isr = new InputStreamReader(is, StandardCharsets.UTF_8);
|
try (InputStreamReader isr = new InputStreamReader(is, StandardCharsets.UTF_8); BufferedReader br = new BufferedReader(isr)) {
|
||||||
BufferedReader br = new BufferedReader(isr)) {
|
|
||||||
return Collections.unmodifiableList(br.lines().collect(Collectors.toList()));
|
return Collections.unmodifiableList(br.lines().collect(Collectors.toList()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,40 +59,41 @@ final class JvmOptionsParser {
|
|||||||
}
|
}
|
||||||
final List<String> jvmOptions = new ArrayList<>();
|
final List<String> jvmOptions = new ArrayList<>();
|
||||||
final SortedMap<Integer, String> invalidLines = new TreeMap<>();
|
final SortedMap<Integer, String> invalidLines = new TreeMap<>();
|
||||||
try (InputStream is = Files.newInputStream(Paths.get(args[0]));
|
try (
|
||||||
Reader reader = new InputStreamReader(is, StandardCharsets.UTF_8);
|
InputStream is = Files.newInputStream(Paths.get(args[0]));
|
||||||
BufferedReader br = new BufferedReader(reader)) {
|
Reader reader = new InputStreamReader(is, StandardCharsets.UTF_8);
|
||||||
parse(
|
BufferedReader br = new BufferedReader(reader)
|
||||||
JavaVersion.majorVersion(JavaVersion.CURRENT),
|
) {
|
||||||
br,
|
parse(JavaVersion.majorVersion(JavaVersion.CURRENT), br, new JvmOptionConsumer() {
|
||||||
new JvmOptionConsumer() {
|
@Override
|
||||||
@Override
|
public void accept(final String jvmOption) {
|
||||||
public void accept(final String jvmOption) {
|
jvmOptions.add(jvmOption);
|
||||||
jvmOptions.add(jvmOption);
|
}
|
||||||
}
|
}, new InvalidLineConsumer() {
|
||||||
},
|
@Override
|
||||||
new InvalidLineConsumer() {
|
public void accept(final int lineNumber, final String line) {
|
||||||
@Override
|
invalidLines.put(lineNumber, line);
|
||||||
public void accept(final int lineNumber, final String line) {
|
}
|
||||||
invalidLines.put(lineNumber, line);
|
});
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (invalidLines.isEmpty()) {
|
if (invalidLines.isEmpty()) {
|
||||||
// now append the JVM options from ES_JAVA_OPTS
|
// now append the JVM options from ES_JAVA_OPTS
|
||||||
final String environmentJvmOptions = System.getenv("ES_JAVA_OPTS");
|
final String environmentJvmOptions = System.getenv("ES_JAVA_OPTS");
|
||||||
if (environmentJvmOptions != null) {
|
if (environmentJvmOptions != null) {
|
||||||
jvmOptions.addAll(Arrays.stream(environmentJvmOptions.split("\\s+"))
|
jvmOptions.addAll(
|
||||||
.filter(s -> s.trim().isEmpty() == false)
|
Arrays.stream(environmentJvmOptions.split("\\s+")).filter(s -> s.trim().isEmpty() == false).collect(Collectors.toList())
|
||||||
.collect(Collectors.toList()));
|
);
|
||||||
}
|
}
|
||||||
final List<String> substitutedJvmOptions =
|
final List<String> substitutedJvmOptions = substitutePlaceholders(
|
||||||
substitutePlaceholders(jvmOptions, Collections.singletonMap("ES_TMPDIR", System.getenv("ES_TMPDIR")));
|
jvmOptions,
|
||||||
|
Collections.singletonMap("ES_TMPDIR", System.getenv("ES_TMPDIR"))
|
||||||
|
);
|
||||||
final List<String> ergonomicJvmOptions = JvmErgonomics.choose(substitutedJvmOptions);
|
final List<String> ergonomicJvmOptions = JvmErgonomics.choose(substitutedJvmOptions);
|
||||||
final List<String> systemJvmOptions = SystemJvmOptions.systemJvmOptions();
|
final List<String> systemJvmOptions = SystemJvmOptions.systemJvmOptions();
|
||||||
final List<String> finalJvmOptions =
|
final List<String> finalJvmOptions = new ArrayList<>(
|
||||||
new ArrayList<>(systemJvmOptions.size() + substitutedJvmOptions.size() + ergonomicJvmOptions.size());
|
systemJvmOptions.size() + substitutedJvmOptions.size() + ergonomicJvmOptions.size()
|
||||||
|
);
|
||||||
finalJvmOptions.addAll(systemJvmOptions); // add the system JVM options first so that they can be overridden
|
finalJvmOptions.addAll(systemJvmOptions); // add the system JVM options first so that they can be overridden
|
||||||
finalJvmOptions.addAll(substitutedJvmOptions);
|
finalJvmOptions.addAll(substitutedJvmOptions);
|
||||||
finalJvmOptions.addAll(ergonomicJvmOptions);
|
finalJvmOptions.addAll(ergonomicJvmOptions);
|
||||||
@ -101,21 +102,23 @@ final class JvmOptionsParser {
|
|||||||
Launchers.exit(0);
|
Launchers.exit(0);
|
||||||
} else {
|
} else {
|
||||||
final String errorMessage = String.format(
|
final String errorMessage = String.format(
|
||||||
Locale.ROOT,
|
Locale.ROOT,
|
||||||
"encountered [%d] error%s parsing [%s]",
|
"encountered [%d] error%s parsing [%s]",
|
||||||
invalidLines.size(),
|
invalidLines.size(),
|
||||||
invalidLines.size() == 1 ? "" : "s",
|
invalidLines.size() == 1 ? "" : "s",
|
||||||
args[0]);
|
args[0]
|
||||||
|
);
|
||||||
Launchers.errPrintln(errorMessage);
|
Launchers.errPrintln(errorMessage);
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (final Map.Entry<Integer, String> entry : invalidLines.entrySet()) {
|
for (final Map.Entry<Integer, String> entry : invalidLines.entrySet()) {
|
||||||
count++;
|
count++;
|
||||||
final String message = String.format(
|
final String message = String.format(
|
||||||
Locale.ROOT,
|
Locale.ROOT,
|
||||||
"[%d]: encountered improperly formatted JVM option line [%s] on line number [%d]",
|
"[%d]: encountered improperly formatted JVM option line [%s] on line number [%d]",
|
||||||
count,
|
count,
|
||||||
entry.getValue(),
|
entry.getValue(),
|
||||||
entry.getKey());
|
entry.getKey()
|
||||||
|
);
|
||||||
Launchers.errPrintln(message);
|
Launchers.errPrintln(message);
|
||||||
}
|
}
|
||||||
Launchers.exit(1);
|
Launchers.exit(1);
|
||||||
@ -123,21 +126,19 @@ final class JvmOptionsParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static List<String> substitutePlaceholders(final List<String> jvmOptions, final Map<String, String> substitutions) {
|
static List<String> substitutePlaceholders(final List<String> jvmOptions, final Map<String, String> substitutions) {
|
||||||
final Map<String, String> placeholderSubstitutions =
|
final Map<String, String> placeholderSubstitutions = substitutions.entrySet()
|
||||||
substitutions.entrySet().stream().collect(Collectors.toMap(e -> "${" + e.getKey() + "}", Map.Entry::getValue));
|
.stream()
|
||||||
return jvmOptions.stream()
|
.collect(Collectors.toMap(e -> "${" + e.getKey() + "}", Map.Entry::getValue));
|
||||||
.map(
|
return jvmOptions.stream().map(jvmOption -> {
|
||||||
jvmOption -> {
|
String actualJvmOption = jvmOption;
|
||||||
String actualJvmOption = jvmOption;
|
int start = jvmOption.indexOf("${");
|
||||||
int start = jvmOption.indexOf("${");
|
if (start >= 0 && jvmOption.indexOf('}', start) > 0) {
|
||||||
if (start >= 0 && jvmOption.indexOf('}', start) > 0) {
|
for (final Map.Entry<String, String> placeholderSubstitution : placeholderSubstitutions.entrySet()) {
|
||||||
for (final Map.Entry<String, String> placeholderSubstitution : placeholderSubstitutions.entrySet()) {
|
actualJvmOption = actualJvmOption.replace(placeholderSubstitution.getKey(), placeholderSubstitution.getValue());
|
||||||
actualJvmOption = actualJvmOption.replace(placeholderSubstitution.getKey(), placeholderSubstitution.getValue());
|
}
|
||||||
}
|
}
|
||||||
}
|
return actualJvmOption;
|
||||||
return actualJvmOption;
|
}).collect(Collectors.toList());
|
||||||
})
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -223,10 +224,11 @@ final class JvmOptionsParser {
|
|||||||
* @throws IOException if an I/O exception occurs reading from the buffered reader
|
* @throws IOException if an I/O exception occurs reading from the buffered reader
|
||||||
*/
|
*/
|
||||||
static void parse(
|
static void parse(
|
||||||
final int javaMajorVersion,
|
final int javaMajorVersion,
|
||||||
final BufferedReader br,
|
final BufferedReader br,
|
||||||
final JvmOptionConsumer jvmOptionConsumer,
|
final JvmOptionConsumer jvmOptionConsumer,
|
||||||
final InvalidLineConsumer invalidLineConsumer) throws IOException {
|
final InvalidLineConsumer invalidLineConsumer
|
||||||
|
) throws IOException {
|
||||||
int lineNumber = 0;
|
int lineNumber = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
final String line = br.readLine();
|
final String line = br.readLine();
|
||||||
|
@ -28,42 +28,45 @@ import java.util.List;
|
|||||||
final class SystemJvmOptions {
|
final class SystemJvmOptions {
|
||||||
|
|
||||||
static List<String> systemJvmOptions() {
|
static List<String> systemJvmOptions() {
|
||||||
return Collections.unmodifiableList(Arrays.asList(
|
return Collections.unmodifiableList(
|
||||||
/*
|
Arrays.asList(
|
||||||
* Cache ttl in seconds for positive DNS lookups noting that this overrides the JDK security property networkaddress.cache.ttl;
|
/*
|
||||||
* can be set to -1 to cache forever.
|
* Cache ttl in seconds for positive DNS lookups noting that this overrides the JDK security property
|
||||||
*/
|
* networkaddress.cache.ttl; can be set to -1 to cache forever.
|
||||||
"-Des.networkaddress.cache.ttl=60",
|
*/
|
||||||
/*
|
"-Des.networkaddress.cache.ttl=60",
|
||||||
* Cache ttl in seconds for negative DNS lookups noting that this overrides the JDK security property
|
/*
|
||||||
* networkaddress.cache.negative ttl; set to -1 to cache forever.
|
* Cache ttl in seconds for negative DNS lookups noting that this overrides the JDK security property
|
||||||
*/
|
* networkaddress.cache.negative ttl; set to -1 to cache forever.
|
||||||
"-Des.networkaddress.cache.negative.ttl=10",
|
*/
|
||||||
// pre-touch JVM emory pages during initialization
|
"-Des.networkaddress.cache.negative.ttl=10",
|
||||||
"-XX:+AlwaysPreTouch",
|
// pre-touch JVM emory pages during initialization
|
||||||
// explicitly set the stack size
|
"-XX:+AlwaysPreTouch",
|
||||||
"-Xss1m",
|
// explicitly set the stack size
|
||||||
// set to headless, just in case,
|
"-Xss1m",
|
||||||
"-Djava.awt.headless=true",
|
// set to headless, just in case,
|
||||||
// ensure UTF-8 encoding by default (e.g., filenames)
|
"-Djava.awt.headless=true",
|
||||||
"-Dfile.encoding=UTF-8",
|
// ensure UTF-8 encoding by default (e.g., filenames)
|
||||||
// use our provided JNA always versus the system one
|
"-Dfile.encoding=UTF-8",
|
||||||
"-Djna.nosys=true",
|
// use our provided JNA always versus the system one
|
||||||
/*
|
"-Djna.nosys=true",
|
||||||
* Turn off a JDK optimization that throws away stack traces for common exceptions because stack traces are important for
|
/*
|
||||||
* debugging.
|
* Turn off a JDK optimization that throws away stack traces for common exceptions because stack traces are important for
|
||||||
*/
|
* debugging.
|
||||||
"-XX:-OmitStackTraceInFastThrow",
|
*/
|
||||||
// flags to configure Netty
|
"-XX:-OmitStackTraceInFastThrow",
|
||||||
"-Dio.netty.noUnsafe=true",
|
// flags to configure Netty
|
||||||
"-Dio.netty.noKeySetOptimization=true",
|
"-Dio.netty.noUnsafe=true",
|
||||||
"-Dio.netty.recycler.maxCapacityPerThread=0",
|
"-Dio.netty.noKeySetOptimization=true",
|
||||||
"-Dio.netty.allocator.numDirectArenas=0",
|
"-Dio.netty.recycler.maxCapacityPerThread=0",
|
||||||
// log4j 2
|
"-Dio.netty.allocator.numDirectArenas=0",
|
||||||
"-Dlog4j.shutdownHookEnabled=false",
|
// log4j 2
|
||||||
"-Dlog4j2.disable.jmx=true",
|
"-Dlog4j.shutdownHookEnabled=false",
|
||||||
|
"-Dlog4j2.disable.jmx=true",
|
||||||
|
|
||||||
javaLocaleProviders()));
|
javaLocaleProviders()
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String javaLocaleProviders() {
|
private static String javaLocaleProviders() {
|
||||||
@ -77,7 +80,7 @@ final class SystemJvmOptions {
|
|||||||
* //TODO COMPAT will be deprecated in jdk14 https://bugs.openjdk.java.net/browse/JDK-8232906
|
* //TODO COMPAT will be deprecated in jdk14 https://bugs.openjdk.java.net/browse/JDK-8232906
|
||||||
* See also: documentation in <code>server/org.elasticsearch.common.time.IsoCalendarDataProvider</code>
|
* See also: documentation in <code>server/org.elasticsearch.common.time.IsoCalendarDataProvider</code>
|
||||||
*/
|
*/
|
||||||
if(JavaVersion.majorVersion(JavaVersion.CURRENT) == 8){
|
if (JavaVersion.majorVersion(JavaVersion.CURRENT) == 8) {
|
||||||
return "-Djava.locale.providers=SPI,JRE";
|
return "-Djava.locale.providers=SPI,JRE";
|
||||||
} else {
|
} else {
|
||||||
return "-Djava.locale.providers=SPI,COMPAT";
|
return "-Djava.locale.providers=SPI,COMPAT";
|
||||||
|
@ -45,23 +45,20 @@ import static org.junit.Assert.fail;
|
|||||||
public class JvmErgonomicsTests extends LaunchersTestCase {
|
public class JvmErgonomicsTests extends LaunchersTestCase {
|
||||||
|
|
||||||
public void testExtractValidHeapSizeUsingXmx() throws InterruptedException, IOException {
|
public void testExtractValidHeapSizeUsingXmx() throws InterruptedException, IOException {
|
||||||
assertThat(
|
assertThat(JvmErgonomics.extractHeapSize(JvmErgonomics.finalJvmOptions(Collections.singletonList("-Xmx2g"))), equalTo(2L << 30));
|
||||||
JvmErgonomics.extractHeapSize(JvmErgonomics.finalJvmOptions(Collections.singletonList("-Xmx2g"))),
|
|
||||||
equalTo(2L << 30));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testExtractValidHeapSizeUsingMaxHeapSize() throws InterruptedException, IOException {
|
public void testExtractValidHeapSizeUsingMaxHeapSize() throws InterruptedException, IOException {
|
||||||
assertThat(
|
assertThat(
|
||||||
JvmErgonomics.extractHeapSize(JvmErgonomics.finalJvmOptions(Collections.singletonList("-XX:MaxHeapSize=2g"))),
|
JvmErgonomics.extractHeapSize(JvmErgonomics.finalJvmOptions(Collections.singletonList("-XX:MaxHeapSize=2g"))),
|
||||||
equalTo(2L << 30));
|
equalTo(2L << 30)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testExtractValidHeapSizeNoOptionPresent() throws InterruptedException, IOException {
|
public void testExtractValidHeapSizeNoOptionPresent() throws InterruptedException, IOException {
|
||||||
// Muted for jdk8/Windows, see: https://github.com/elastic/elasticsearch/issues/47384
|
// Muted for jdk8/Windows, see: https://github.com/elastic/elasticsearch/issues/47384
|
||||||
assumeFalse(System.getProperty("os.name").startsWith("Windows") && JavaVersion.majorVersion(JavaVersion.CURRENT) == 8);
|
assumeFalse(System.getProperty("os.name").startsWith("Windows") && JavaVersion.majorVersion(JavaVersion.CURRENT) == 8);
|
||||||
assertThat(
|
assertThat(JvmErgonomics.extractHeapSize(JvmErgonomics.finalJvmOptions(Collections.emptyList())), greaterThan(0L));
|
||||||
JvmErgonomics.extractHeapSize(JvmErgonomics.finalJvmOptions(Collections.emptyList())),
|
|
||||||
greaterThan(0L));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testHeapSizeInvalid() throws InterruptedException, IOException {
|
public void testHeapSizeInvalid() throws InterruptedException, IOException {
|
||||||
@ -81,8 +78,9 @@ public class JvmErgonomicsTests extends LaunchersTestCase {
|
|||||||
} catch (final RuntimeException e) {
|
} catch (final RuntimeException e) {
|
||||||
assertThat(e, hasToString(containsString(("starting java failed"))));
|
assertThat(e, hasToString(containsString(("starting java failed"))));
|
||||||
assertThat(
|
assertThat(
|
||||||
e,
|
e,
|
||||||
anyOf(hasToString(containsString("Too small initial heap")), hasToString(containsString("Too small maximum heap"))));
|
anyOf(hasToString(containsString("Too small initial heap")), hasToString(containsString("Too small maximum heap")))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,15 +96,18 @@ public class JvmErgonomicsTests extends LaunchersTestCase {
|
|||||||
|
|
||||||
public void testMaxDirectMemorySizeUnset() throws InterruptedException, IOException {
|
public void testMaxDirectMemorySizeUnset() throws InterruptedException, IOException {
|
||||||
assertThat(
|
assertThat(
|
||||||
JvmErgonomics.extractMaxDirectMemorySize(JvmErgonomics.finalJvmOptions(Collections.singletonList("-Xmx1g"))),
|
JvmErgonomics.extractMaxDirectMemorySize(JvmErgonomics.finalJvmOptions(Collections.singletonList("-Xmx1g"))),
|
||||||
equalTo(0L));
|
equalTo(0L)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testMaxDirectMemorySizeSet() throws InterruptedException, IOException {
|
public void testMaxDirectMemorySizeSet() throws InterruptedException, IOException {
|
||||||
assertThat(
|
assertThat(
|
||||||
JvmErgonomics.extractMaxDirectMemorySize(JvmErgonomics.finalJvmOptions(
|
JvmErgonomics.extractMaxDirectMemorySize(
|
||||||
Arrays.asList("-Xmx1g", "-XX:MaxDirectMemorySize=512m"))),
|
JvmErgonomics.finalJvmOptions(Arrays.asList("-Xmx1g", "-XX:MaxDirectMemorySize=512m"))
|
||||||
equalTo(512L << 20));
|
),
|
||||||
|
equalTo(512L << 20)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testExtractSystemProperties() {
|
public void testExtractSystemProperties() {
|
||||||
@ -115,7 +116,8 @@ public class JvmErgonomicsTests extends LaunchersTestCase {
|
|||||||
expectedSystemProperties.put("kv.setting", "ABC=DEF");
|
expectedSystemProperties.put("kv.setting", "ABC=DEF");
|
||||||
|
|
||||||
Map<String, String> parsedSystemProperties = JvmErgonomics.extractSystemProperties(
|
Map<String, String> parsedSystemProperties = JvmErgonomics.extractSystemProperties(
|
||||||
Arrays.asList("-Dfile.encoding=UTF-8", "-Dkv.setting=ABC=DEF"));
|
Arrays.asList("-Dfile.encoding=UTF-8", "-Dkv.setting=ABC=DEF")
|
||||||
|
);
|
||||||
|
|
||||||
assertEquals(expectedSystemProperties, parsedSystemProperties);
|
assertEquals(expectedSystemProperties, parsedSystemProperties);
|
||||||
}
|
}
|
||||||
@ -132,22 +134,24 @@ public class JvmErgonomicsTests extends LaunchersTestCase {
|
|||||||
heapMaxDirectMemorySize.put("64M", Long.toString((64L << 20) / 2));
|
heapMaxDirectMemorySize.put("64M", Long.toString((64L << 20) / 2));
|
||||||
heapMaxDirectMemorySize.put("512M", Long.toString((512L << 20) / 2));
|
heapMaxDirectMemorySize.put("512M", Long.toString((512L << 20) / 2));
|
||||||
heapMaxDirectMemorySize.put("1024M", Long.toString((1024L << 20) / 2));
|
heapMaxDirectMemorySize.put("1024M", Long.toString((1024L << 20) / 2));
|
||||||
heapMaxDirectMemorySize.put("1G", Long.toString((1L << 30) / 2));
|
heapMaxDirectMemorySize.put("1G", Long.toString((1L << 30) / 2));
|
||||||
heapMaxDirectMemorySize.put("2048M", Long.toString((2048L << 20) / 2));
|
heapMaxDirectMemorySize.put("2048M", Long.toString((2048L << 20) / 2));
|
||||||
heapMaxDirectMemorySize.put("2G", Long.toString((2L << 30) / 2));
|
heapMaxDirectMemorySize.put("2G", Long.toString((2L << 30) / 2));
|
||||||
heapMaxDirectMemorySize.put("8G", Long.toString((8L << 30) / 2));
|
heapMaxDirectMemorySize.put("8G", Long.toString((8L << 30) / 2));
|
||||||
final String heapSize = randomFrom(heapMaxDirectMemorySize.keySet().toArray(new String[0]));
|
final String heapSize = randomFrom(heapMaxDirectMemorySize.keySet().toArray(new String[0]));
|
||||||
assertThat(
|
assertThat(
|
||||||
JvmErgonomics.choose(Arrays.asList("-Xms" + heapSize, "-Xmx" + heapSize)),
|
JvmErgonomics.choose(Arrays.asList("-Xms" + heapSize, "-Xmx" + heapSize)),
|
||||||
hasItem("-XX:MaxDirectMemorySize=" + heapMaxDirectMemorySize.get(heapSize)));
|
hasItem("-XX:MaxDirectMemorySize=" + heapMaxDirectMemorySize.get(heapSize))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testMaxDirectMemorySizeChoiceWhenSet() throws InterruptedException, IOException {
|
public void testMaxDirectMemorySizeChoiceWhenSet() throws InterruptedException, IOException {
|
||||||
List<String> derivedSettingList = JvmErgonomics.choose(Arrays.asList("-Xms5g", "-Xmx5g", "-XX:MaxDirectMemorySize=4g"));
|
List<String> derivedSettingList = JvmErgonomics.choose(Arrays.asList("-Xms5g", "-Xmx5g", "-XX:MaxDirectMemorySize=4g"));
|
||||||
assertThat(
|
assertThat(
|
||||||
derivedSettingList,
|
derivedSettingList,
|
||||||
// if MaxDirectMemorySize is set, we shouldn't derive our own value for it
|
// if MaxDirectMemorySize is set, we shouldn't derive our own value for it
|
||||||
everyItem(not(startsWith("-XX:MaxDirectMemorySize="))));
|
everyItem(not(startsWith("-XX:MaxDirectMemorySize=")))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -43,13 +43,13 @@ public class JvmOptionsParserTests extends LaunchersTestCase {
|
|||||||
public void testSubstitution() {
|
public void testSubstitution() {
|
||||||
final List<String> jvmOptions = JvmOptionsParser.substitutePlaceholders(
|
final List<String> jvmOptions = JvmOptionsParser.substitutePlaceholders(
|
||||||
Collections.singletonList("-Djava.io.tmpdir=${ES_TMPDIR}"),
|
Collections.singletonList("-Djava.io.tmpdir=${ES_TMPDIR}"),
|
||||||
Collections.singletonMap("ES_TMPDIR", "/tmp/elasticsearch"));
|
Collections.singletonMap("ES_TMPDIR", "/tmp/elasticsearch")
|
||||||
|
);
|
||||||
assertThat(jvmOptions, contains("-Djava.io.tmpdir=/tmp/elasticsearch"));
|
assertThat(jvmOptions, contains("-Djava.io.tmpdir=/tmp/elasticsearch"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testUnversionedOptions() throws IOException {
|
public void testUnversionedOptions() throws IOException {
|
||||||
try (StringReader sr = new StringReader("-Xms1g\n-Xmx1g");
|
try (StringReader sr = new StringReader("-Xms1g\n-Xmx1g"); BufferedReader br = new BufferedReader(sr)) {
|
||||||
BufferedReader br = new BufferedReader(sr)) {
|
|
||||||
assertExpectedJvmOptions(randomIntBetween(8, Integer.MAX_VALUE), br, Arrays.asList("-Xms1g", "-Xmx1g"));
|
assertExpectedJvmOptions(randomIntBetween(8, Integer.MAX_VALUE), br, Arrays.asList("-Xms1g", "-Xmx1g"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,14 +59,18 @@ public class JvmOptionsParserTests extends LaunchersTestCase {
|
|||||||
final int javaMajorVersion = randomIntBetween(8, Integer.MAX_VALUE - 1);
|
final int javaMajorVersion = randomIntBetween(8, Integer.MAX_VALUE - 1);
|
||||||
final int smallerJavaMajorVersion = randomIntBetween(7, javaMajorVersion);
|
final int smallerJavaMajorVersion = randomIntBetween(7, javaMajorVersion);
|
||||||
final int largerJavaMajorVersion = randomIntBetween(javaMajorVersion + 1, Integer.MAX_VALUE);
|
final int largerJavaMajorVersion = randomIntBetween(javaMajorVersion + 1, Integer.MAX_VALUE);
|
||||||
try (StringReader sr = new StringReader(
|
try (
|
||||||
|
StringReader sr = new StringReader(
|
||||||
String.format(
|
String.format(
|
||||||
Locale.ROOT,
|
Locale.ROOT,
|
||||||
"-Xms1g\n%d:-Xmx1g\n%d:-XX:+UseG1GC\n%d:-Xlog:gc",
|
"-Xms1g\n%d:-Xmx1g\n%d:-XX:+UseG1GC\n%d:-Xlog:gc",
|
||||||
javaMajorVersion,
|
javaMajorVersion,
|
||||||
smallerJavaMajorVersion,
|
smallerJavaMajorVersion,
|
||||||
largerJavaMajorVersion));
|
largerJavaMajorVersion
|
||||||
BufferedReader br = new BufferedReader(sr)) {
|
)
|
||||||
|
);
|
||||||
|
BufferedReader br = new BufferedReader(sr)
|
||||||
|
) {
|
||||||
assertExpectedJvmOptions(javaMajorVersion, br, Arrays.asList("-Xms1g", "-Xmx1g"));
|
assertExpectedJvmOptions(javaMajorVersion, br, Arrays.asList("-Xms1g", "-Xmx1g"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -75,14 +79,18 @@ public class JvmOptionsParserTests extends LaunchersTestCase {
|
|||||||
final int javaMajorVersion = randomIntBetween(8, Integer.MAX_VALUE - 1);
|
final int javaMajorVersion = randomIntBetween(8, Integer.MAX_VALUE - 1);
|
||||||
final int smallerJavaMajorVersion = randomIntBetween(7, javaMajorVersion);
|
final int smallerJavaMajorVersion = randomIntBetween(7, javaMajorVersion);
|
||||||
final int largerJavaMajorVersion = randomIntBetween(javaMajorVersion + 1, Integer.MAX_VALUE);
|
final int largerJavaMajorVersion = randomIntBetween(javaMajorVersion + 1, Integer.MAX_VALUE);
|
||||||
try (StringReader sr = new StringReader(
|
try (
|
||||||
|
StringReader sr = new StringReader(
|
||||||
String.format(
|
String.format(
|
||||||
Locale.ROOT,
|
Locale.ROOT,
|
||||||
"-Xms1g\n%d-:-Xmx1g\n%d-:-XX:+UseG1GC\n%d-:-Xlog:gc",
|
"-Xms1g\n%d-:-Xmx1g\n%d-:-XX:+UseG1GC\n%d-:-Xlog:gc",
|
||||||
javaMajorVersion,
|
javaMajorVersion,
|
||||||
smallerJavaMajorVersion,
|
smallerJavaMajorVersion,
|
||||||
largerJavaMajorVersion));
|
largerJavaMajorVersion
|
||||||
BufferedReader br = new BufferedReader(sr)) {
|
)
|
||||||
|
);
|
||||||
|
BufferedReader br = new BufferedReader(sr)
|
||||||
|
) {
|
||||||
assertExpectedJvmOptions(javaMajorVersion, br, Arrays.asList("-Xms1g", "-Xmx1g", "-XX:+UseG1GC"));
|
assertExpectedJvmOptions(javaMajorVersion, br, Arrays.asList("-Xms1g", "-Xmx1g", "-XX:+UseG1GC"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -94,17 +102,21 @@ public class JvmOptionsParserTests extends LaunchersTestCase {
|
|||||||
final int smallerJavaMajorVersionUpperBound = randomIntBetween(smallerJavaMajorVersionLowerBound, javaMajorVersion);
|
final int smallerJavaMajorVersionUpperBound = randomIntBetween(smallerJavaMajorVersionLowerBound, javaMajorVersion);
|
||||||
final int largerJavaMajorVersionLowerBound = randomIntBetween(javaMajorVersion + 1, Integer.MAX_VALUE);
|
final int largerJavaMajorVersionLowerBound = randomIntBetween(javaMajorVersion + 1, Integer.MAX_VALUE);
|
||||||
final int largerJavaMajorVersionUpperBound = randomIntBetween(largerJavaMajorVersionLowerBound, Integer.MAX_VALUE);
|
final int largerJavaMajorVersionUpperBound = randomIntBetween(largerJavaMajorVersionLowerBound, Integer.MAX_VALUE);
|
||||||
try (StringReader sr = new StringReader(
|
try (
|
||||||
|
StringReader sr = new StringReader(
|
||||||
String.format(
|
String.format(
|
||||||
Locale.ROOT,
|
Locale.ROOT,
|
||||||
"-Xms1g\n%d-%d:-Xmx1g\n%d-%d:-XX:+UseG1GC\n%d-%d:-Xlog:gc",
|
"-Xms1g\n%d-%d:-Xmx1g\n%d-%d:-XX:+UseG1GC\n%d-%d:-Xlog:gc",
|
||||||
javaMajorVersion,
|
javaMajorVersion,
|
||||||
javaMajorVersionUpperBound,
|
javaMajorVersionUpperBound,
|
||||||
smallerJavaMajorVersionLowerBound,
|
smallerJavaMajorVersionLowerBound,
|
||||||
smallerJavaMajorVersionUpperBound,
|
smallerJavaMajorVersionUpperBound,
|
||||||
largerJavaMajorVersionLowerBound,
|
largerJavaMajorVersionLowerBound,
|
||||||
largerJavaMajorVersionUpperBound));
|
largerJavaMajorVersionUpperBound
|
||||||
BufferedReader br = new BufferedReader(sr)) {
|
)
|
||||||
|
);
|
||||||
|
BufferedReader br = new BufferedReader(sr)
|
||||||
|
) {
|
||||||
assertExpectedJvmOptions(javaMajorVersion, br, Arrays.asList("-Xms1g", "-Xmx1g"));
|
assertExpectedJvmOptions(javaMajorVersion, br, Arrays.asList("-Xms1g", "-Xmx1g"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -116,91 +128,86 @@ public class JvmOptionsParserTests extends LaunchersTestCase {
|
|||||||
final int smallerJavaMajorVersionUpperBound = randomIntBetween(smallerJavaMajorVersionLowerBound, javaMajorVersion);
|
final int smallerJavaMajorVersionUpperBound = randomIntBetween(smallerJavaMajorVersionLowerBound, javaMajorVersion);
|
||||||
final int largerJavaMajorVersionLowerBound = randomIntBetween(javaMajorVersion + 1, Integer.MAX_VALUE);
|
final int largerJavaMajorVersionLowerBound = randomIntBetween(javaMajorVersion + 1, Integer.MAX_VALUE);
|
||||||
final int largerJavaMajorVersionUpperBound = randomIntBetween(largerJavaMajorVersionLowerBound, Integer.MAX_VALUE);
|
final int largerJavaMajorVersionUpperBound = randomIntBetween(largerJavaMajorVersionLowerBound, Integer.MAX_VALUE);
|
||||||
try (StringReader sr = new StringReader(
|
try (
|
||||||
|
StringReader sr = new StringReader(
|
||||||
String.format(
|
String.format(
|
||||||
Locale.ROOT,
|
Locale.ROOT,
|
||||||
"-Xms1g\n%d:-Xmx1g\n%d-:-XX:+UseG1GC\n%d-%d:-Xlog:gc\n%d-%d:-XX:+PrintFlagsFinal\n%d-%d:-XX+AggressiveOpts",
|
"-Xms1g\n%d:-Xmx1g\n%d-:-XX:+UseG1GC\n%d-%d:-Xlog:gc\n%d-%d:-XX:+PrintFlagsFinal\n%d-%d:-XX+AggressiveOpts",
|
||||||
javaMajorVersion,
|
javaMajorVersion,
|
||||||
javaMajorVersion,
|
javaMajorVersion,
|
||||||
javaMajorVersion,
|
javaMajorVersion,
|
||||||
javaMajorVersionUpperBound,
|
javaMajorVersionUpperBound,
|
||||||
smallerJavaMajorVersionLowerBound,
|
smallerJavaMajorVersionLowerBound,
|
||||||
smallerJavaMajorVersionUpperBound,
|
smallerJavaMajorVersionUpperBound,
|
||||||
largerJavaMajorVersionLowerBound,
|
largerJavaMajorVersionLowerBound,
|
||||||
largerJavaMajorVersionUpperBound));
|
largerJavaMajorVersionUpperBound
|
||||||
BufferedReader br = new BufferedReader(sr)) {
|
)
|
||||||
|
);
|
||||||
|
BufferedReader br = new BufferedReader(sr)
|
||||||
|
) {
|
||||||
assertExpectedJvmOptions(javaMajorVersion, br, Arrays.asList("-Xms1g", "-Xmx1g", "-XX:+UseG1GC", "-Xlog:gc"));
|
assertExpectedJvmOptions(javaMajorVersion, br, Arrays.asList("-Xms1g", "-Xmx1g", "-XX:+UseG1GC", "-Xlog:gc"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertExpectedJvmOptions(
|
private void assertExpectedJvmOptions(final int javaMajorVersion, final BufferedReader br, final List<String> expectedJvmOptions)
|
||||||
final int javaMajorVersion, final BufferedReader br, final List<String> expectedJvmOptions) throws IOException {
|
throws IOException {
|
||||||
final Map<String, AtomicBoolean> seenJvmOptions = new HashMap<>();
|
final Map<String, AtomicBoolean> seenJvmOptions = new HashMap<>();
|
||||||
for (final String expectedJvmOption : expectedJvmOptions) {
|
for (final String expectedJvmOption : expectedJvmOptions) {
|
||||||
assertNull(seenJvmOptions.put(expectedJvmOption, new AtomicBoolean()));
|
assertNull(seenJvmOptions.put(expectedJvmOption, new AtomicBoolean()));
|
||||||
}
|
}
|
||||||
JvmOptionsParser.parse(
|
JvmOptionsParser.parse(javaMajorVersion, br, new JvmOptionsParser.JvmOptionConsumer() {
|
||||||
javaMajorVersion,
|
@Override
|
||||||
br,
|
public void accept(final String jvmOption) {
|
||||||
new JvmOptionsParser.JvmOptionConsumer() {
|
final AtomicBoolean seen = seenJvmOptions.get(jvmOption);
|
||||||
@Override
|
if (seen == null) {
|
||||||
public void accept(final String jvmOption) {
|
fail("unexpected JVM option [" + jvmOption + "]");
|
||||||
final AtomicBoolean seen = seenJvmOptions.get(jvmOption);
|
}
|
||||||
if (seen == null) {
|
assertFalse("saw JVM option [" + jvmOption + "] more than once", seen.get());
|
||||||
fail("unexpected JVM option [" + jvmOption + "]");
|
seen.set(true);
|
||||||
}
|
}
|
||||||
assertFalse("saw JVM option [" + jvmOption + "] more than once", seen.get());
|
}, new JvmOptionsParser.InvalidLineConsumer() {
|
||||||
seen.set(true);
|
@Override
|
||||||
}
|
public void accept(final int lineNumber, final String line) {
|
||||||
},
|
fail("unexpected invalid line [" + line + "] on line number [" + lineNumber + "]");
|
||||||
new JvmOptionsParser.InvalidLineConsumer() {
|
}
|
||||||
@Override
|
});
|
||||||
public void accept(final int lineNumber, final String line) {
|
|
||||||
fail("unexpected invalid line [" + line + "] on line number [" + lineNumber + "]");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
for (final Map.Entry<String, AtomicBoolean> seenJvmOption : seenJvmOptions.entrySet()) {
|
for (final Map.Entry<String, AtomicBoolean> seenJvmOption : seenJvmOptions.entrySet()) {
|
||||||
assertTrue("expected JVM option [" + seenJvmOption.getKey() + "]", seenJvmOption.getValue().get());
|
assertTrue("expected JVM option [" + seenJvmOption.getKey() + "]", seenJvmOption.getValue().get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testInvalidLines() throws IOException {
|
public void testInvalidLines() throws IOException {
|
||||||
try (StringReader sr = new StringReader("XX:+UseG1GC");
|
try (StringReader sr = new StringReader("XX:+UseG1GC"); BufferedReader br = new BufferedReader(sr)) {
|
||||||
BufferedReader br = new BufferedReader(sr)) {
|
JvmOptionsParser.parse(randomIntBetween(8, Integer.MAX_VALUE), br, new JvmOptionsParser.JvmOptionConsumer() {
|
||||||
JvmOptionsParser.parse(
|
@Override
|
||||||
randomIntBetween(8, Integer.MAX_VALUE),
|
public void accept(final String jvmOption) {
|
||||||
br,
|
fail("unexpected valid JVM option [" + jvmOption + "]");
|
||||||
new JvmOptionsParser.JvmOptionConsumer() {
|
}
|
||||||
@Override
|
}, new JvmOptionsParser.InvalidLineConsumer() {
|
||||||
public void accept(final String jvmOption) {
|
@Override
|
||||||
fail("unexpected valid JVM option [" + jvmOption + "]");
|
public void accept(final int lineNumber, final String line) {
|
||||||
}
|
assertThat(lineNumber, equalTo(1));
|
||||||
}, new JvmOptionsParser.InvalidLineConsumer() {
|
assertThat(line, equalTo("XX:+UseG1GC"));
|
||||||
@Override
|
}
|
||||||
public void accept(final int lineNumber, final String line) {
|
});
|
||||||
assertThat(lineNumber, equalTo(1));
|
|
||||||
assertThat(line, equalTo("XX:+UseG1GC"));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final int javaMajorVersion = randomIntBetween(8, Integer.MAX_VALUE);
|
final int javaMajorVersion = randomIntBetween(8, Integer.MAX_VALUE);
|
||||||
final int smallerJavaMajorVersion = randomIntBetween(7, javaMajorVersion - 1);
|
final int smallerJavaMajorVersion = randomIntBetween(7, javaMajorVersion - 1);
|
||||||
final String invalidRangeLine = String.format(Locale.ROOT, "%d:%d-XX:+UseG1GC", javaMajorVersion, smallerJavaMajorVersion);
|
final String invalidRangeLine = String.format(Locale.ROOT, "%d:%d-XX:+UseG1GC", javaMajorVersion, smallerJavaMajorVersion);
|
||||||
try (StringReader sr = new StringReader(invalidRangeLine);
|
try (StringReader sr = new StringReader(invalidRangeLine); BufferedReader br = new BufferedReader(sr)) {
|
||||||
BufferedReader br = new BufferedReader(sr)) {
|
|
||||||
assertInvalidLines(br, Collections.singletonMap(1, invalidRangeLine));
|
assertInvalidLines(br, Collections.singletonMap(1, invalidRangeLine));
|
||||||
}
|
}
|
||||||
|
|
||||||
final long invalidLowerJavaMajorVersion = (long) randomIntBetween(1, 16) + Integer.MAX_VALUE;
|
final long invalidLowerJavaMajorVersion = (long) randomIntBetween(1, 16) + Integer.MAX_VALUE;
|
||||||
final long invalidUpperJavaMajorVersion = (long) randomIntBetween(1, 16) + Integer.MAX_VALUE;
|
final long invalidUpperJavaMajorVersion = (long) randomIntBetween(1, 16) + Integer.MAX_VALUE;
|
||||||
final String numberFormatExceptionsLine = String.format(
|
final String numberFormatExceptionsLine = String.format(
|
||||||
Locale.ROOT,
|
Locale.ROOT,
|
||||||
"%d:-XX:+UseG1GC\n8-%d:-XX:+AggressiveOpts",
|
"%d:-XX:+UseG1GC\n8-%d:-XX:+AggressiveOpts",
|
||||||
invalidLowerJavaMajorVersion,
|
invalidLowerJavaMajorVersion,
|
||||||
invalidUpperJavaMajorVersion);
|
invalidUpperJavaMajorVersion
|
||||||
try (StringReader sr = new StringReader(numberFormatExceptionsLine);
|
);
|
||||||
BufferedReader br = new BufferedReader(sr)) {
|
try (StringReader sr = new StringReader(numberFormatExceptionsLine); BufferedReader br = new BufferedReader(sr)) {
|
||||||
final Map<Integer, String> invalidLines = new HashMap<>(2);
|
final Map<Integer, String> invalidLines = new HashMap<>(2);
|
||||||
invalidLines.put(1, String.format(Locale.ROOT, "%d:-XX:+UseG1GC", invalidLowerJavaMajorVersion));
|
invalidLines.put(1, String.format(Locale.ROOT, "%d:-XX:+UseG1GC", invalidLowerJavaMajorVersion));
|
||||||
invalidLines.put(2, String.format(Locale.ROOT, "8-%d:-XX:+AggressiveOpts", invalidUpperJavaMajorVersion));
|
invalidLines.put(2, String.format(Locale.ROOT, "8-%d:-XX:+AggressiveOpts", invalidUpperJavaMajorVersion));
|
||||||
@ -208,8 +215,7 @@ public class JvmOptionsParserTests extends LaunchersTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final String multipleInvalidLines = "XX:+UseG1GC\nXX:+AggressiveOpts";
|
final String multipleInvalidLines = "XX:+UseG1GC\nXX:+AggressiveOpts";
|
||||||
try (StringReader sr = new StringReader(multipleInvalidLines);
|
try (StringReader sr = new StringReader(multipleInvalidLines); BufferedReader br = new BufferedReader(sr)) {
|
||||||
BufferedReader br = new BufferedReader(sr)) {
|
|
||||||
final Map<Integer, String> invalidLines = new HashMap<>(2);
|
final Map<Integer, String> invalidLines = new HashMap<>(2);
|
||||||
invalidLines.put(1, "XX:+UseG1GC");
|
invalidLines.put(1, "XX:+UseG1GC");
|
||||||
invalidLines.put(2, "XX:+AggressiveOpts");
|
invalidLines.put(2, "XX:+AggressiveOpts");
|
||||||
@ -219,29 +225,24 @@ public class JvmOptionsParserTests extends LaunchersTestCase {
|
|||||||
final int lowerBound = randomIntBetween(9, 16);
|
final int lowerBound = randomIntBetween(9, 16);
|
||||||
final int upperBound = randomIntBetween(8, lowerBound - 1);
|
final int upperBound = randomIntBetween(8, lowerBound - 1);
|
||||||
final String upperBoundGreaterThanLowerBound = String.format(Locale.ROOT, "%d-%d-XX:+UseG1GC", lowerBound, upperBound);
|
final String upperBoundGreaterThanLowerBound = String.format(Locale.ROOT, "%d-%d-XX:+UseG1GC", lowerBound, upperBound);
|
||||||
try (StringReader sr = new StringReader(upperBoundGreaterThanLowerBound);
|
try (StringReader sr = new StringReader(upperBoundGreaterThanLowerBound); BufferedReader br = new BufferedReader(sr)) {
|
||||||
BufferedReader br = new BufferedReader(sr)) {
|
|
||||||
assertInvalidLines(br, Collections.singletonMap(1, upperBoundGreaterThanLowerBound));
|
assertInvalidLines(br, Collections.singletonMap(1, upperBoundGreaterThanLowerBound));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertInvalidLines(final BufferedReader br, final Map<Integer, String> invalidLines) throws IOException {
|
private void assertInvalidLines(final BufferedReader br, final Map<Integer, String> invalidLines) throws IOException {
|
||||||
final Map<Integer, String> seenInvalidLines = new HashMap<>(invalidLines.size());
|
final Map<Integer, String> seenInvalidLines = new HashMap<>(invalidLines.size());
|
||||||
JvmOptionsParser.parse(
|
JvmOptionsParser.parse(randomIntBetween(8, Integer.MAX_VALUE), br, new JvmOptionsParser.JvmOptionConsumer() {
|
||||||
randomIntBetween(8, Integer.MAX_VALUE),
|
@Override
|
||||||
br,
|
public void accept(final String jvmOption) {
|
||||||
new JvmOptionsParser.JvmOptionConsumer() {
|
fail("unexpected valid JVM options [" + jvmOption + "]");
|
||||||
@Override
|
}
|
||||||
public void accept(final String jvmOption) {
|
}, new JvmOptionsParser.InvalidLineConsumer() {
|
||||||
fail("unexpected valid JVM options [" + jvmOption + "]");
|
@Override
|
||||||
}
|
public void accept(final int lineNumber, final String line) {
|
||||||
},
|
seenInvalidLines.put(lineNumber, line);
|
||||||
new JvmOptionsParser.InvalidLineConsumer() {
|
}
|
||||||
@Override
|
});
|
||||||
public void accept(final int lineNumber, final String line) {
|
|
||||||
seenInvalidLines.put(lineNumber, line);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
assertThat(seenInvalidLines, equalTo(invalidLines));
|
assertThat(seenInvalidLines, equalTo(invalidLines));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,8 +250,9 @@ public class JvmOptionsParserTests extends LaunchersTestCase {
|
|||||||
assertThat(JvmOptionsParser.spaceDelimitJvmOptions(Collections.singletonList("-Xms1g")), equalTo("-Xms1g"));
|
assertThat(JvmOptionsParser.spaceDelimitJvmOptions(Collections.singletonList("-Xms1g")), equalTo("-Xms1g"));
|
||||||
assertThat(JvmOptionsParser.spaceDelimitJvmOptions(Arrays.asList("-Xms1g", "-Xmx1g")), equalTo("-Xms1g -Xmx1g"));
|
assertThat(JvmOptionsParser.spaceDelimitJvmOptions(Arrays.asList("-Xms1g", "-Xmx1g")), equalTo("-Xms1g -Xmx1g"));
|
||||||
assertThat(
|
assertThat(
|
||||||
JvmOptionsParser.spaceDelimitJvmOptions(Arrays.asList("-Xms1g", "-Xmx1g", "-XX:+UseG1GC")),
|
JvmOptionsParser.spaceDelimitJvmOptions(Arrays.asList("-Xms1g", "-Xmx1g", "-XX:+UseG1GC")),
|
||||||
equalTo("-Xms1g -Xmx1g -XX:+UseG1GC"));
|
equalTo("-Xms1g -Xmx1g -XX:+UseG1GC")
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -31,15 +31,12 @@ import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope;
|
|||||||
import com.carrotsearch.randomizedtesting.annotations.ThreadLeakZombies;
|
import com.carrotsearch.randomizedtesting.annotations.ThreadLeakZombies;
|
||||||
import com.carrotsearch.randomizedtesting.annotations.TimeoutSuite;
|
import com.carrotsearch.randomizedtesting.annotations.TimeoutSuite;
|
||||||
|
|
||||||
@TestMethodProviders({
|
@TestMethodProviders({ JUnit3MethodProvider.class })
|
||||||
JUnit3MethodProvider.class
|
@SeedDecorators({ MixWithSuiteName.class })
|
||||||
})
|
|
||||||
@SeedDecorators({MixWithSuiteName.class})
|
|
||||||
@ThreadLeakScope(ThreadLeakScope.Scope.SUITE)
|
@ThreadLeakScope(ThreadLeakScope.Scope.SUITE)
|
||||||
@ThreadLeakGroup(ThreadLeakGroup.Group.MAIN)
|
@ThreadLeakGroup(ThreadLeakGroup.Group.MAIN)
|
||||||
@ThreadLeakAction({ThreadLeakAction.Action.WARN, ThreadLeakAction.Action.INTERRUPT})
|
@ThreadLeakAction({ ThreadLeakAction.Action.WARN, ThreadLeakAction.Action.INTERRUPT })
|
||||||
@ThreadLeakZombies(ThreadLeakZombies.Consequence.IGNORE_REMAINING_TESTS)
|
@ThreadLeakZombies(ThreadLeakZombies.Consequence.IGNORE_REMAINING_TESTS)
|
||||||
@ThreadLeakLingering(linger = 5000)
|
@ThreadLeakLingering(linger = 5000)
|
||||||
@TimeoutSuite(millis = 2 * 60 * 60 * 1000)
|
@TimeoutSuite(millis = 2 * 60 * 60 * 1000)
|
||||||
abstract class LaunchersTestCase extends RandomizedTest {
|
abstract class LaunchersTestCase extends RandomizedTest {}
|
||||||
}
|
|
||||||
|
@ -134,8 +134,10 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
|
|||||||
/** The builtin modules, which are plugins, but cannot be installed or removed. */
|
/** The builtin modules, which are plugins, but cannot be installed or removed. */
|
||||||
static final Set<String> MODULES;
|
static final Set<String> MODULES;
|
||||||
static {
|
static {
|
||||||
try (InputStream stream = InstallPluginCommand.class.getResourceAsStream("/modules.txt");
|
try (
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8))) {
|
InputStream stream = InstallPluginCommand.class.getResourceAsStream("/modules.txt");
|
||||||
|
BufferedReader reader = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8))
|
||||||
|
) {
|
||||||
Set<String> modules = new HashSet<>();
|
Set<String> modules = new HashSet<>();
|
||||||
String line = reader.readLine();
|
String line = reader.readLine();
|
||||||
while (line != null) {
|
while (line != null) {
|
||||||
@ -151,8 +153,10 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
|
|||||||
/** The official plugins that can be installed simply by name. */
|
/** The official plugins that can be installed simply by name. */
|
||||||
static final Set<String> OFFICIAL_PLUGINS;
|
static final Set<String> OFFICIAL_PLUGINS;
|
||||||
static {
|
static {
|
||||||
try (InputStream stream = InstallPluginCommand.class.getResourceAsStream("/plugins.txt");
|
try (
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8))) {
|
InputStream stream = InstallPluginCommand.class.getResourceAsStream("/plugins.txt");
|
||||||
|
BufferedReader reader = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8))
|
||||||
|
) {
|
||||||
Set<String> plugins = new TreeSet<>(); // use tree set to get sorting for help command
|
Set<String> plugins = new TreeSet<>(); // use tree set to get sorting for help command
|
||||||
String line = reader.readLine();
|
String line = reader.readLine();
|
||||||
while (line != null) {
|
while (line != null) {
|
||||||
@ -197,8 +201,10 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
|
|||||||
|
|
||||||
InstallPluginCommand() {
|
InstallPluginCommand() {
|
||||||
super("Install a plugin");
|
super("Install a plugin");
|
||||||
this.batchOption = parser.acceptsAll(Arrays.asList("b", "batch"),
|
this.batchOption = parser.acceptsAll(
|
||||||
"Enable batch mode explicitly, automatic confirmation of security permission");
|
Arrays.asList("b", "batch"),
|
||||||
|
"Enable batch mode explicitly, automatic confirmation of security permission"
|
||||||
|
);
|
||||||
this.arguments = parser.nonOptions("plugin id");
|
this.arguments = parser.nonOptions("plugin id");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,7 +267,8 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
|
|||||||
} catch (final IOException exceptionWhileRemovingFiles) {
|
} catch (final IOException exceptionWhileRemovingFiles) {
|
||||||
final Exception exception = new Exception(
|
final Exception exception = new Exception(
|
||||||
"failed rolling back installation of [" + deleteOnFailureEntry.getKey() + "]",
|
"failed rolling back installation of [" + deleteOnFailureEntry.getKey() + "]",
|
||||||
exceptionWhileRemovingFiles);
|
exceptionWhileRemovingFiles
|
||||||
|
);
|
||||||
installProblem.addSuppressed(exception);
|
installProblem.addSuppressed(exception);
|
||||||
terminal.println("-> Failed rolling back " + deleteOnFailureEntry.getKey());
|
terminal.println("-> Failed rolling back " + deleteOnFailureEntry.getKey());
|
||||||
}
|
}
|
||||||
@ -284,8 +291,9 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
|
|||||||
throw new UserException(ExitCodes.CONFIG, "this distribution of Elasticsearch contains X-Pack by default");
|
throw new UserException(ExitCodes.CONFIG, "this distribution of Elasticsearch contains X-Pack by default");
|
||||||
case OSS:
|
case OSS:
|
||||||
throw new UserException(
|
throw new UserException(
|
||||||
ExitCodes.CONFIG,
|
ExitCodes.CONFIG,
|
||||||
"X-Pack is not available with the oss distribution; to use X-Pack features use the default distribution");
|
"X-Pack is not available with the oss distribution; to use X-Pack features use the default distribution"
|
||||||
|
);
|
||||||
case UNKNOWN:
|
case UNKNOWN:
|
||||||
throw new IllegalStateException("your distribution is broken");
|
throw new IllegalStateException("your distribution is broken");
|
||||||
}
|
}
|
||||||
@ -313,7 +321,7 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
|
|||||||
List<String> plugins = checkMisspelledPlugin(pluginId);
|
List<String> plugins = checkMisspelledPlugin(pluginId);
|
||||||
String msg = "Unknown plugin " + pluginId;
|
String msg = "Unknown plugin " + pluginId;
|
||||||
if (plugins.isEmpty() == false) {
|
if (plugins.isEmpty() == false) {
|
||||||
msg += ", did you mean " + (plugins.size() == 1 ? "[" + plugins.get(0) + "]": "any of " + plugins.toString()) + "?";
|
msg += ", did you mean " + (plugins.size() == 1 ? "[" + plugins.get(0) + "]" : "any of " + plugins.toString()) + "?";
|
||||||
}
|
}
|
||||||
throw new UserException(ExitCodes.USAGE, msg);
|
throw new UserException(ExitCodes.USAGE, msg);
|
||||||
}
|
}
|
||||||
@ -332,16 +340,20 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
|
|||||||
|
|
||||||
/** Returns the url for an official elasticsearch plugin. */
|
/** Returns the url for an official elasticsearch plugin. */
|
||||||
private String getElasticUrl(
|
private String getElasticUrl(
|
||||||
final Terminal terminal,
|
final Terminal terminal,
|
||||||
final String stagingHash,
|
final String stagingHash,
|
||||||
final Version version,
|
final Version version,
|
||||||
final boolean isSnapshot,
|
final boolean isSnapshot,
|
||||||
final String pluginId,
|
final String pluginId,
|
||||||
final String platform) throws IOException, UserException {
|
final String platform
|
||||||
|
) throws IOException,
|
||||||
|
UserException {
|
||||||
final String baseUrl;
|
final String baseUrl;
|
||||||
if (isSnapshot && stagingHash == null) {
|
if (isSnapshot && stagingHash == null) {
|
||||||
throw new UserException(
|
throw new UserException(
|
||||||
ExitCodes.CONFIG, "attempted to install release build of official plugin on snapshot build of Elasticsearch");
|
ExitCodes.CONFIG,
|
||||||
|
"attempted to install release build of official plugin on snapshot build of Elasticsearch"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (stagingHash != null) {
|
if (stagingHash != null) {
|
||||||
if (isSnapshot) {
|
if (isSnapshot) {
|
||||||
@ -352,8 +364,14 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
|
|||||||
} else {
|
} else {
|
||||||
baseUrl = String.format(Locale.ROOT, "https://artifacts.elastic.co/downloads/elasticsearch-plugins/%s", pluginId);
|
baseUrl = String.format(Locale.ROOT, "https://artifacts.elastic.co/downloads/elasticsearch-plugins/%s", pluginId);
|
||||||
}
|
}
|
||||||
final String platformUrl =
|
final String platformUrl = String.format(
|
||||||
String.format(Locale.ROOT, "%s/%s-%s-%s.zip", baseUrl, pluginId, platform, Build.CURRENT.getQualifiedVersion());
|
Locale.ROOT,
|
||||||
|
"%s/%s-%s-%s.zip",
|
||||||
|
baseUrl,
|
||||||
|
pluginId,
|
||||||
|
platform,
|
||||||
|
Build.CURRENT.getQualifiedVersion()
|
||||||
|
);
|
||||||
if (urlExists(terminal, platformUrl)) {
|
if (urlExists(terminal, platformUrl)) {
|
||||||
return platformUrl;
|
return platformUrl;
|
||||||
}
|
}
|
||||||
@ -362,7 +380,13 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
|
|||||||
|
|
||||||
private String nonReleaseUrl(final String hostname, final Version version, final String stagingHash, final String pluginId) {
|
private String nonReleaseUrl(final String hostname, final Version version, final String stagingHash, final String pluginId) {
|
||||||
return String.format(
|
return String.format(
|
||||||
Locale.ROOT, "https://%s.elastic.co/%s-%s/downloads/elasticsearch-plugins/%s", hostname, version, stagingHash, pluginId);
|
Locale.ROOT,
|
||||||
|
"https://%s.elastic.co/%s-%s/downloads/elasticsearch-plugins/%s",
|
||||||
|
hostname,
|
||||||
|
version,
|
||||||
|
stagingHash,
|
||||||
|
pluginId
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the url for an elasticsearch plugin in maven. */
|
/** Returns the url for an elasticsearch plugin in maven. */
|
||||||
@ -419,8 +443,11 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
|
|||||||
Path zip = Files.createTempFile(tmpDir, null, ".zip");
|
Path zip = Files.createTempFile(tmpDir, null, ".zip");
|
||||||
URLConnection urlConnection = url.openConnection();
|
URLConnection urlConnection = url.openConnection();
|
||||||
urlConnection.addRequestProperty("User-Agent", "elasticsearch-plugin-installer");
|
urlConnection.addRequestProperty("User-Agent", "elasticsearch-plugin-installer");
|
||||||
try (InputStream in = isBatch ? urlConnection.getInputStream() :
|
try (
|
||||||
new TerminalProgressInputStream(urlConnection.getInputStream(),urlConnection.getContentLength(),terminal)) {
|
InputStream in = isBatch
|
||||||
|
? urlConnection.getInputStream()
|
||||||
|
: new TerminalProgressInputStream(urlConnection.getInputStream(), urlConnection.getContentLength(), terminal)
|
||||||
|
) {
|
||||||
// must overwrite since creating the temp file above actually created the file
|
// must overwrite since creating the temp file above actually created the file
|
||||||
Files.copy(in, zip, StandardCopyOption.REPLACE_EXISTING);
|
Files.copy(in, zip, StandardCopyOption.REPLACE_EXISTING);
|
||||||
}
|
}
|
||||||
@ -493,7 +520,11 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
|
|||||||
final Terminal terminal,
|
final Terminal terminal,
|
||||||
final String urlString,
|
final String urlString,
|
||||||
final Path tmpDir,
|
final Path tmpDir,
|
||||||
final boolean officialPlugin, boolean isBatch) throws IOException, PGPException, UserException {
|
final boolean officialPlugin,
|
||||||
|
boolean isBatch
|
||||||
|
) throws IOException,
|
||||||
|
PGPException,
|
||||||
|
UserException {
|
||||||
Path zip = downloadZip(terminal, urlString, tmpDir, isBatch);
|
Path zip = downloadZip(terminal, urlString, tmpDir, isBatch);
|
||||||
pathsToDeleteOnShutdown.add(zip);
|
pathsToDeleteOnShutdown.add(zip);
|
||||||
String checksumUrlString = urlString + ".sha512";
|
String checksumUrlString = urlString + ".sha512";
|
||||||
@ -501,8 +532,10 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
|
|||||||
String digestAlgo = "SHA-512";
|
String digestAlgo = "SHA-512";
|
||||||
if (checksumUrl == null && officialPlugin == false) {
|
if (checksumUrl == null && officialPlugin == false) {
|
||||||
// fallback to sha1, until 7.0, but with warning
|
// fallback to sha1, until 7.0, but with warning
|
||||||
terminal.println("Warning: sha512 not found, falling back to sha1. This behavior is deprecated and will be removed in a " +
|
terminal.println(
|
||||||
"future release. Please update the plugin to use a sha512 checksum.");
|
"Warning: sha512 not found, falling back to sha1. This behavior is deprecated and will be removed in a "
|
||||||
|
+ "future release. Please update the plugin to use a sha512 checksum."
|
||||||
|
);
|
||||||
checksumUrlString = urlString + ".sha1";
|
checksumUrlString = urlString + ".sha1";
|
||||||
checksumUrl = openUrl(checksumUrlString);
|
checksumUrl = openUrl(checksumUrlString);
|
||||||
digestAlgo = "SHA-1";
|
digestAlgo = "SHA-1";
|
||||||
@ -536,11 +569,12 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
|
|||||||
final String expectedFile = segments[segments.length - 1];
|
final String expectedFile = segments[segments.length - 1];
|
||||||
if (fields[1].equals(expectedFile) == false) {
|
if (fields[1].equals(expectedFile) == false) {
|
||||||
final String message = String.format(
|
final String message = String.format(
|
||||||
Locale.ROOT,
|
Locale.ROOT,
|
||||||
"checksum file at [%s] is not for this plugin, expected [%s] but was [%s]",
|
"checksum file at [%s] is not for this plugin, expected [%s] but was [%s]",
|
||||||
checksumUrl,
|
checksumUrl,
|
||||||
expectedFile,
|
expectedFile,
|
||||||
fields[1]);
|
fields[1]
|
||||||
|
);
|
||||||
throw new UserException(ExitCodes.IO_ERROR, message);
|
throw new UserException(ExitCodes.IO_ERROR, message);
|
||||||
}
|
}
|
||||||
if (checksumReader.readLine() != null) {
|
if (checksumReader.readLine() != null) {
|
||||||
@ -563,7 +597,8 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
|
|||||||
if (expectedChecksum.equals(actualChecksum) == false) {
|
if (expectedChecksum.equals(actualChecksum) == false) {
|
||||||
throw new UserException(
|
throw new UserException(
|
||||||
ExitCodes.IO_ERROR,
|
ExitCodes.IO_ERROR,
|
||||||
digestAlgo + " mismatch, expected " + expectedChecksum + " but got " + actualChecksum);
|
digestAlgo + " mismatch, expected " + expectedChecksum + " but got " + actualChecksum
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} catch (final NoSuchAlgorithmException e) {
|
} catch (final NoSuchAlgorithmException e) {
|
||||||
// this should never happen as we are using SHA-1 and SHA-512 here
|
// this should never happen as we are using SHA-1 and SHA-512 here
|
||||||
@ -591,12 +626,13 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
|
|||||||
final String ascUrlString = urlString + ".asc";
|
final String ascUrlString = urlString + ".asc";
|
||||||
final URL ascUrl = openUrl(ascUrlString);
|
final URL ascUrl = openUrl(ascUrlString);
|
||||||
try (
|
try (
|
||||||
// fin is a file stream over the downloaded plugin zip whose signature to verify
|
// fin is a file stream over the downloaded plugin zip whose signature to verify
|
||||||
InputStream fin = pluginZipInputStream(zip);
|
InputStream fin = pluginZipInputStream(zip);
|
||||||
// sin is a URL stream to the signature corresponding to the downloaded plugin zip
|
// sin is a URL stream to the signature corresponding to the downloaded plugin zip
|
||||||
InputStream sin = urlOpenStream(ascUrl);
|
InputStream sin = urlOpenStream(ascUrl);
|
||||||
// ain is a input stream to the public key in ASCII-Armor format (RFC4880)
|
// ain is a input stream to the public key in ASCII-Armor format (RFC4880)
|
||||||
InputStream ain = new ArmoredInputStream(getPublicKey())) {
|
InputStream ain = new ArmoredInputStream(getPublicKey())
|
||||||
|
) {
|
||||||
final JcaPGPObjectFactory factory = new JcaPGPObjectFactory(PGPUtil.getDecoderStream(sin));
|
final JcaPGPObjectFactory factory = new JcaPGPObjectFactory(PGPUtil.getDecoderStream(sin));
|
||||||
final PGPSignature signature = ((PGPSignatureList) factory.nextObject()).get(0);
|
final PGPSignature signature = ((PGPSignatureList) factory.nextObject()).get(0);
|
||||||
|
|
||||||
@ -660,7 +696,7 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
|
|||||||
// pkg private for tests
|
// pkg private for tests
|
||||||
URL openUrl(String urlString) throws IOException {
|
URL openUrl(String urlString) throws IOException {
|
||||||
URL checksumUrl = new URL(urlString);
|
URL checksumUrl = new URL(urlString);
|
||||||
HttpURLConnection connection = (HttpURLConnection)checksumUrl.openConnection();
|
HttpURLConnection connection = (HttpURLConnection) checksumUrl.openConnection();
|
||||||
if (connection.getResponseCode() == 404) {
|
if (connection.getResponseCode() == 404) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -678,8 +714,11 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
|
|||||||
byte[] buffer = new byte[8192];
|
byte[] buffer = new byte[8192];
|
||||||
while ((entry = zipInput.getNextEntry()) != null) {
|
while ((entry = zipInput.getNextEntry()) != null) {
|
||||||
if (entry.getName().startsWith("elasticsearch/")) {
|
if (entry.getName().startsWith("elasticsearch/")) {
|
||||||
throw new UserException(PLUGIN_MALFORMED, "This plugin was built with an older plugin structure." +
|
throw new UserException(
|
||||||
" Contact the plugin author to remove the intermediate \"elasticsearch\" directory within the plugin zip.");
|
PLUGIN_MALFORMED,
|
||||||
|
"This plugin was built with an older plugin structure."
|
||||||
|
+ " Contact the plugin author to remove the intermediate \"elasticsearch\" directory within the plugin zip."
|
||||||
|
);
|
||||||
}
|
}
|
||||||
Path targetFile = target.resolve(entry.getName());
|
Path targetFile = target.resolve(entry.getName());
|
||||||
|
|
||||||
@ -689,8 +728,10 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
|
|||||||
// normalizing the path (which removes foo/..) and ensuring the normalized entry
|
// normalizing the path (which removes foo/..) and ensuring the normalized entry
|
||||||
// is still rooted with the target plugin directory.
|
// is still rooted with the target plugin directory.
|
||||||
if (targetFile.normalize().startsWith(target) == false) {
|
if (targetFile.normalize().startsWith(target) == false) {
|
||||||
throw new UserException(PLUGIN_MALFORMED, "Zip contains entry name '" +
|
throw new UserException(
|
||||||
entry.getName() + "' resolving outside of plugin directory");
|
PLUGIN_MALFORMED,
|
||||||
|
"Zip contains entry name '" + entry.getName() + "' resolving outside of plugin directory"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// be on the safe side: do not rely on that directories are always extracted
|
// be on the safe side: do not rely on that directories are always extracted
|
||||||
@ -725,9 +766,9 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
|
|||||||
// and the Jimfs test dependency is upgraded to include
|
// and the Jimfs test dependency is upgraded to include
|
||||||
// this pull request
|
// this pull request
|
||||||
final StackTraceElement[] elements = e.getStackTrace();
|
final StackTraceElement[] elements = e.getStackTrace();
|
||||||
if (elements.length >= 1 &&
|
if (elements.length >= 1
|
||||||
elements[0].getClassName().equals("com.google.common.jimfs.AttributeService") &&
|
&& elements[0].getClassName().equals("com.google.common.jimfs.AttributeService")
|
||||||
elements[0].getMethodName().equals("setAttributeInternal")) {
|
&& elements[0].getMethodName().equals("setAttributeInternal")) {
|
||||||
return stagingDirectoryWithoutPosixPermissions(pluginsDir);
|
return stagingDirectoryWithoutPosixPermissions(pluginsDir);
|
||||||
} else {
|
} else {
|
||||||
throw e;
|
throw e;
|
||||||
@ -753,10 +794,10 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
|
|||||||
if (Files.exists(destination)) {
|
if (Files.exists(destination)) {
|
||||||
final String message = String.format(
|
final String message = String.format(
|
||||||
Locale.ROOT,
|
Locale.ROOT,
|
||||||
"plugin directory [%s] already exists; if you need to update the plugin, " +
|
"plugin directory [%s] already exists; if you need to update the plugin, " + "uninstall it first using command 'remove %s'",
|
||||||
"uninstall it first using command 'remove %s'",
|
|
||||||
destination,
|
destination,
|
||||||
pluginName);
|
pluginName
|
||||||
|
);
|
||||||
throw new UserException(PLUGIN_EXISTS, message);
|
throw new UserException(PLUGIN_EXISTS, message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -785,24 +826,19 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
|
|||||||
private static final String LIB_TOOLS_PLUGIN_CLI_CLASSPATH_JAR;
|
private static final String LIB_TOOLS_PLUGIN_CLI_CLASSPATH_JAR;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
LIB_TOOLS_PLUGIN_CLI_CLASSPATH_JAR =
|
LIB_TOOLS_PLUGIN_CLI_CLASSPATH_JAR = String.format(Locale.ROOT, ".+%1$slib%1$stools%1$splugin-cli%1$s[^%1$s]+\\.jar", "(/|\\\\)");
|
||||||
String.format(Locale.ROOT, ".+%1$slib%1$stools%1$splugin-cli%1$s[^%1$s]+\\.jar", "(/|\\\\)");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** check a candidate plugin for jar hell before installing it */
|
/** check a candidate plugin for jar hell before installing it */
|
||||||
void jarHellCheck(PluginInfo candidateInfo, Path candidateDir, Path pluginsDir, Path modulesDir) throws Exception {
|
void jarHellCheck(PluginInfo candidateInfo, Path candidateDir, Path pluginsDir, Path modulesDir) throws Exception {
|
||||||
// create list of current jars in classpath
|
// create list of current jars in classpath
|
||||||
final Set<URL> classpath =
|
final Set<URL> classpath = JarHell.parseClassPath().stream().filter(url -> {
|
||||||
JarHell.parseClassPath()
|
try {
|
||||||
.stream()
|
return url.toURI().getPath().matches(LIB_TOOLS_PLUGIN_CLI_CLASSPATH_JAR) == false;
|
||||||
.filter(url -> {
|
} catch (final URISyntaxException e) {
|
||||||
try {
|
throw new AssertionError(e);
|
||||||
return url.toURI().getPath().matches(LIB_TOOLS_PLUGIN_CLI_CLASSPATH_JAR) == false;
|
}
|
||||||
} catch (final URISyntaxException e) {
|
}).collect(Collectors.toSet());
|
||||||
throw new AssertionError(e);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect(Collectors.toSet());
|
|
||||||
|
|
||||||
// read existing bundles. this does some checks on the installation too.
|
// read existing bundles. this does some checks on the installation too.
|
||||||
Set<PluginsService.Bundle> bundles = new HashSet<>(PluginsService.getPluginBundles(pluginsDir));
|
Set<PluginsService.Bundle> bundles = new HashSet<>(PluginsService.getPluginBundles(pluginsDir));
|
||||||
@ -825,8 +861,8 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
|
|||||||
* Installs the plugin from {@code tmpRoot} into the plugins dir.
|
* Installs the plugin from {@code tmpRoot} into the plugins dir.
|
||||||
* If the plugin has a bin dir and/or a config dir, those are moved.
|
* If the plugin has a bin dir and/or a config dir, those are moved.
|
||||||
*/
|
*/
|
||||||
private PluginInfo installPlugin(Terminal terminal, boolean isBatch, Path tmpRoot,
|
private PluginInfo installPlugin(Terminal terminal, boolean isBatch, Path tmpRoot, Environment env, List<Path> deleteOnFailure)
|
||||||
Environment env, List<Path> deleteOnFailure) throws Exception {
|
throws Exception {
|
||||||
final PluginInfo info = loadPluginInfo(terminal, tmpRoot, env);
|
final PluginInfo info = loadPluginInfo(terminal, tmpRoot, env);
|
||||||
// read optional security policy (extra permissions), if it exists, confirm or warn the user
|
// read optional security policy (extra permissions), if it exists, confirm or warn the user
|
||||||
Path policy = tmpRoot.resolve(PluginInfo.ES_PLUGIN_POLICY);
|
Path policy = tmpRoot.resolve(PluginInfo.ES_PLUGIN_POLICY);
|
||||||
@ -841,15 +877,20 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
|
|||||||
final Path destination = env.pluginsFile().resolve(info.getName());
|
final Path destination = env.pluginsFile().resolve(info.getName());
|
||||||
deleteOnFailure.add(destination);
|
deleteOnFailure.add(destination);
|
||||||
|
|
||||||
installPluginSupportFiles(info, tmpRoot, env.binFile().resolve(info.getName()),
|
installPluginSupportFiles(
|
||||||
env.configFile().resolve(info.getName()), deleteOnFailure);
|
info,
|
||||||
|
tmpRoot,
|
||||||
|
env.binFile().resolve(info.getName()),
|
||||||
|
env.configFile().resolve(info.getName()),
|
||||||
|
deleteOnFailure
|
||||||
|
);
|
||||||
movePlugin(tmpRoot, destination);
|
movePlugin(tmpRoot, destination);
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Moves bin and config directories from the plugin if they exist */
|
/** Moves bin and config directories from the plugin if they exist */
|
||||||
private void installPluginSupportFiles(PluginInfo info, Path tmpRoot,
|
private void installPluginSupportFiles(PluginInfo info, Path tmpRoot, Path destBinDir, Path destConfigDir, List<Path> deleteOnFailure)
|
||||||
Path destBinDir, Path destConfigDir, List<Path> deleteOnFailure) throws Exception {
|
throws Exception {
|
||||||
Path tmpBinDir = tmpRoot.resolve("bin");
|
Path tmpBinDir = tmpRoot.resolve("bin");
|
||||||
if (Files.exists(tmpBinDir)) {
|
if (Files.exists(tmpBinDir)) {
|
||||||
deleteOnFailure.add(destBinDir);
|
deleteOnFailure.add(destBinDir);
|
||||||
@ -900,8 +941,10 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
|
|||||||
try (DirectoryStream<Path> stream = Files.newDirectoryStream(tmpBinDir)) {
|
try (DirectoryStream<Path> stream = Files.newDirectoryStream(tmpBinDir)) {
|
||||||
for (Path srcFile : stream) {
|
for (Path srcFile : stream) {
|
||||||
if (Files.isDirectory(srcFile)) {
|
if (Files.isDirectory(srcFile)) {
|
||||||
throw new UserException(PLUGIN_MALFORMED, "Directories not allowed in bin dir " +
|
throw new UserException(
|
||||||
"for plugin " + info.getName() + ", found " + srcFile.getFileName());
|
PLUGIN_MALFORMED,
|
||||||
|
"Directories not allowed in bin dir " + "for plugin " + info.getName() + ", found " + srcFile.getFileName()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Path destFile = destBinDir.resolve(tmpBinDir.relativize(srcFile));
|
Path destFile = destBinDir.resolve(tmpBinDir.relativize(srcFile));
|
||||||
@ -918,16 +961,18 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
|
|||||||
*/
|
*/
|
||||||
private void installConfig(PluginInfo info, Path tmpConfigDir, Path destConfigDir) throws Exception {
|
private void installConfig(PluginInfo info, Path tmpConfigDir, Path destConfigDir) throws Exception {
|
||||||
if (Files.isDirectory(tmpConfigDir) == false) {
|
if (Files.isDirectory(tmpConfigDir) == false) {
|
||||||
throw new UserException(PLUGIN_MALFORMED,
|
throw new UserException(PLUGIN_MALFORMED, "config in plugin " + info.getName() + " is not a directory");
|
||||||
"config in plugin " + info.getName() + " is not a directory");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Files.createDirectories(destConfigDir);
|
Files.createDirectories(destConfigDir);
|
||||||
setFileAttributes(destConfigDir, CONFIG_DIR_PERMS);
|
setFileAttributes(destConfigDir, CONFIG_DIR_PERMS);
|
||||||
final PosixFileAttributeView destConfigDirAttributesView =
|
final PosixFileAttributeView destConfigDirAttributesView = Files.getFileAttributeView(
|
||||||
Files.getFileAttributeView(destConfigDir.getParent(), PosixFileAttributeView.class);
|
destConfigDir.getParent(),
|
||||||
final PosixFileAttributes destConfigDirAttributes =
|
PosixFileAttributeView.class
|
||||||
destConfigDirAttributesView != null ? destConfigDirAttributesView.readAttributes() : null;
|
);
|
||||||
|
final PosixFileAttributes destConfigDirAttributes = destConfigDirAttributesView != null
|
||||||
|
? destConfigDirAttributesView.readAttributes()
|
||||||
|
: null;
|
||||||
if (destConfigDirAttributes != null) {
|
if (destConfigDirAttributes != null) {
|
||||||
setOwnerGroup(destConfigDir, destConfigDirAttributes);
|
setOwnerGroup(destConfigDir, destConfigDirAttributes);
|
||||||
}
|
}
|
||||||
@ -935,8 +980,7 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
|
|||||||
try (DirectoryStream<Path> stream = Files.newDirectoryStream(tmpConfigDir)) {
|
try (DirectoryStream<Path> stream = Files.newDirectoryStream(tmpConfigDir)) {
|
||||||
for (Path srcFile : stream) {
|
for (Path srcFile : stream) {
|
||||||
if (Files.isDirectory(srcFile)) {
|
if (Files.isDirectory(srcFile)) {
|
||||||
throw new UserException(PLUGIN_MALFORMED,
|
throw new UserException(PLUGIN_MALFORMED, "Directories not allowed in config dir for plugin " + info.getName());
|
||||||
"Directories not allowed in config dir for plugin " + info.getName());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Path destFile = destConfigDir.resolve(tmpConfigDir.relativize(srcFile));
|
Path destFile = destConfigDir.resolve(tmpConfigDir.relativize(srcFile));
|
||||||
|
@ -66,8 +66,15 @@ class ListPluginsCommand extends EnvironmentAwareCommand {
|
|||||||
PluginInfo info = PluginInfo.readFromProperties(env.pluginsFile().resolve(plugin));
|
PluginInfo info = PluginInfo.readFromProperties(env.pluginsFile().resolve(plugin));
|
||||||
terminal.println(Terminal.Verbosity.VERBOSE, info.toString(prefix));
|
terminal.println(Terminal.Verbosity.VERBOSE, info.toString(prefix));
|
||||||
if (info.getElasticsearchVersion().equals(Version.CURRENT) == false) {
|
if (info.getElasticsearchVersion().equals(Version.CURRENT) == false) {
|
||||||
terminal.errorPrintln("WARNING: plugin [" + info.getName() + "] was built for Elasticsearch version " + info.getVersion() +
|
terminal.errorPrintln(
|
||||||
" but version " + Version.CURRENT + " is required");
|
"WARNING: plugin ["
|
||||||
|
+ info.getName()
|
||||||
|
+ "] was built for Elasticsearch version "
|
||||||
|
+ info.getVersion()
|
||||||
|
+ " but version "
|
||||||
|
+ Version.CURRENT
|
||||||
|
+ " is required"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ abstract class ProgressInputStream extends FilterInputStream {
|
|||||||
count += byteCount;
|
count += byteCount;
|
||||||
// rounding up to 100% would mean we say we are done, before we are...
|
// rounding up to 100% would mean we say we are done, before we are...
|
||||||
// this also catches issues, when expectedTotalSize was guessed wrong
|
// this also catches issues, when expectedTotalSize was guessed wrong
|
||||||
int percent = Math.min(99, (int) Math.floor(100.0*count/expectedTotalSize));
|
int percent = Math.min(99, (int) Math.floor(100.0 * count / expectedTotalSize));
|
||||||
if (percent > currentPercent) {
|
if (percent > currentPercent) {
|
||||||
currentPercent = percent;
|
currentPercent = percent;
|
||||||
onProgress(percent);
|
onProgress(percent);
|
||||||
|
@ -95,8 +95,10 @@ class RemovePluginCommand extends EnvironmentAwareCommand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (usedBy.isEmpty() == false) {
|
if (usedBy.isEmpty() == false) {
|
||||||
throw new UserException(PLUGIN_STILL_USED, "plugin [" + pluginName + "] cannot be removed" +
|
throw new UserException(
|
||||||
" because it is extended by other plugins: " + usedBy);
|
PLUGIN_STILL_USED,
|
||||||
|
"plugin [" + pluginName + "] cannot be removed" + " because it is extended by other plugins: " + usedBy
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
final Path pluginDir = env.pluginsFile().resolve(pluginName);
|
final Path pluginDir = env.pluginsFile().resolve(pluginName);
|
||||||
@ -110,9 +112,12 @@ class RemovePluginCommand extends EnvironmentAwareCommand {
|
|||||||
* not exist, the plugin config does, and we are not purging, again fail to the user that the plugin is not found.
|
* not exist, the plugin config does, and we are not purging, again fail to the user that the plugin is not found.
|
||||||
*/
|
*/
|
||||||
if ((!Files.exists(pluginDir) && !Files.exists(pluginConfigDir) && !Files.exists(removing))
|
if ((!Files.exists(pluginDir) && !Files.exists(pluginConfigDir) && !Files.exists(removing))
|
||||||
|| (!Files.exists(pluginDir) && Files.exists(pluginConfigDir) && !purge)) {
|
|| (!Files.exists(pluginDir) && Files.exists(pluginConfigDir) && !purge)) {
|
||||||
final String message = String.format(
|
final String message = String.format(
|
||||||
Locale.ROOT, "plugin [%s] not found; run 'elasticsearch-plugin list' to get list of installed plugins", pluginName);
|
Locale.ROOT,
|
||||||
|
"plugin [%s] not found; run 'elasticsearch-plugin list' to get list of installed plugins",
|
||||||
|
pluginName
|
||||||
|
);
|
||||||
throw new UserException(ExitCodes.CONFIG, message);
|
throw new UserException(ExitCodes.CONFIG, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,9 +159,10 @@ class RemovePluginCommand extends EnvironmentAwareCommand {
|
|||||||
* knows in case they want to remove manually.
|
* knows in case they want to remove manually.
|
||||||
*/
|
*/
|
||||||
final String message = String.format(
|
final String message = String.format(
|
||||||
Locale.ROOT,
|
Locale.ROOT,
|
||||||
"-> preserving plugin config files [%s] in case of upgrade; use --purge if not needed",
|
"-> preserving plugin config files [%s] in case of upgrade; use --purge if not needed",
|
||||||
pluginConfigDir);
|
pluginConfigDir
|
||||||
|
);
|
||||||
terminal.println(message);
|
terminal.println(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -191,7 +191,7 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
parameters.add(new Parameter(Jimfs.newFileSystem(Configuration.windows()), "c:\\"));
|
parameters.add(new Parameter(Jimfs.newFileSystem(Configuration.windows()), "c:\\"));
|
||||||
parameters.add(new Parameter(Jimfs.newFileSystem(toPosix(Configuration.osX())), "/"));
|
parameters.add(new Parameter(Jimfs.newFileSystem(toPosix(Configuration.osX())), "/"));
|
||||||
parameters.add(new Parameter(Jimfs.newFileSystem(toPosix(Configuration.unix())), "/"));
|
parameters.add(new Parameter(Jimfs.newFileSystem(toPosix(Configuration.unix())), "/"));
|
||||||
parameters.add(new Parameter(PathUtils.getDefaultFileSystem(), LuceneTestCase::createTempDir ));
|
parameters.add(new Parameter(PathUtils.getDefaultFileSystem(), LuceneTestCase::createTempDir));
|
||||||
return parameters.stream().map(p -> new Object[] { p.fileSystem, p.temp }).collect(Collectors.toList());
|
return parameters.stream().map(p -> new Object[] { p.fileSystem, p.temp }).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,9 +208,7 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
Files.createFile(home.resolve("config").resolve("elasticsearch.yml"));
|
Files.createFile(home.resolve("config").resolve("elasticsearch.yml"));
|
||||||
Path plugins = Files.createDirectories(home.resolve("plugins"));
|
Path plugins = Files.createDirectories(home.resolve("plugins"));
|
||||||
assertTrue(Files.exists(plugins));
|
assertTrue(Files.exists(plugins));
|
||||||
Settings settings = Settings.builder()
|
Settings settings = Settings.builder().put("path.home", home).build();
|
||||||
.put("path.home", home)
|
|
||||||
.build();
|
|
||||||
return Tuple.tuple(home, TestEnvironment.newEnvironment(settings));
|
return Tuple.tuple(home, TestEnvironment.newEnvironment(settings));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,14 +247,23 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void writePlugin(String name, Path structure, String... additionalProps) throws IOException {
|
static void writePlugin(String name, Path structure, String... additionalProps) throws IOException {
|
||||||
String[] properties = Stream.concat(Stream.of(
|
String[] properties = Stream.concat(
|
||||||
"description", "fake desc",
|
Stream.of(
|
||||||
"name", name,
|
"description",
|
||||||
"version", "1.0",
|
"fake desc",
|
||||||
"elasticsearch.version", Version.CURRENT.toString(),
|
"name",
|
||||||
"java.version", System.getProperty("java.specification.version"),
|
name,
|
||||||
"classname", "FakePlugin"
|
"version",
|
||||||
), Arrays.stream(additionalProps)).toArray(String[]::new);
|
"1.0",
|
||||||
|
"elasticsearch.version",
|
||||||
|
Version.CURRENT.toString(),
|
||||||
|
"java.version",
|
||||||
|
System.getProperty("java.specification.version"),
|
||||||
|
"classname",
|
||||||
|
"FakePlugin"
|
||||||
|
),
|
||||||
|
Arrays.stream(additionalProps)
|
||||||
|
).toArray(String[]::new);
|
||||||
PluginTestUtil.writePluginProperties(structure, properties);
|
PluginTestUtil.writePluginProperties(structure, properties);
|
||||||
String className = name.substring(0, 1).toUpperCase(Locale.ENGLISH) + name.substring(1) + "Plugin";
|
String className = name.substring(0, 1).toUpperCase(Locale.ENGLISH) + name.substring(1) + "Plugin";
|
||||||
writeJar(structure.resolve("plugin.jar"), className);
|
writeJar(structure.resolve("plugin.jar"), className);
|
||||||
@ -316,7 +323,9 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
PosixFilePermission.GROUP_READ,
|
PosixFilePermission.GROUP_READ,
|
||||||
PosixFilePermission.GROUP_EXECUTE,
|
PosixFilePermission.GROUP_EXECUTE,
|
||||||
PosixFilePermission.OTHERS_READ,
|
PosixFilePermission.OTHERS_READ,
|
||||||
PosixFilePermission.OTHERS_EXECUTE));
|
PosixFilePermission.OTHERS_EXECUTE
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
assertTrue("jar was copied", Files.exists(got.resolve("plugin.jar")));
|
assertTrue("jar was copied", Files.exists(got.resolve("plugin.jar")));
|
||||||
assertFalse("bin was not copied", Files.exists(got.resolve("bin")));
|
assertFalse("bin was not copied", Files.exists(got.resolve("bin")));
|
||||||
@ -351,8 +360,8 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
GroupPrincipal group = null;
|
GroupPrincipal group = null;
|
||||||
|
|
||||||
if (isPosix) {
|
if (isPosix) {
|
||||||
PosixFileAttributes configAttributes =
|
PosixFileAttributes configAttributes = Files.getFileAttributeView(env.configFile(), PosixFileAttributeView.class)
|
||||||
Files.getFileAttributeView(env.configFile(), PosixFileAttributeView.class).readAttributes();
|
.readAttributes();
|
||||||
user = configAttributes.owner();
|
user = configAttributes.owner();
|
||||||
group = configAttributes.group();
|
group = configAttributes.group();
|
||||||
|
|
||||||
@ -427,7 +436,8 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
String pluginZip = createPluginUrl("fake", pluginDir);
|
String pluginZip = createPluginUrl("fake", pluginDir);
|
||||||
final FileNotFoundException e = expectThrows(
|
final FileNotFoundException e = expectThrows(
|
||||||
FileNotFoundException.class,
|
FileNotFoundException.class,
|
||||||
() -> installPlugins(Arrays.asList(pluginZip, pluginZip + "does-not-exist"), env.v1()));
|
() -> installPlugins(Arrays.asList(pluginZip, pluginZip + "does-not-exist"), env.v1())
|
||||||
|
);
|
||||||
assertThat(e, hasToString(containsString("does-not-exist")));
|
assertThat(e, hasToString(containsString("does-not-exist")));
|
||||||
final Path fakeInstallPath = env.v2().pluginsFile().resolve("fake");
|
final Path fakeInstallPath = env.v2().pluginsFile().resolve("fake");
|
||||||
// fake should have been removed when the file not found exception occurred
|
// fake should have been removed when the file not found exception occurred
|
||||||
@ -443,9 +453,10 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
Files.createDirectory(removing);
|
Files.createDirectory(removing);
|
||||||
final IllegalStateException e = expectThrows(IllegalStateException.class, () -> installPlugin(pluginZip, env.v1()));
|
final IllegalStateException e = expectThrows(IllegalStateException.class, () -> installPlugin(pluginZip, env.v1()));
|
||||||
final String expected = String.format(
|
final String expected = String.format(
|
||||||
Locale.ROOT,
|
Locale.ROOT,
|
||||||
"found file [%s] from a failed attempt to remove the plugin [failed]; execute [elasticsearch-plugin remove failed]",
|
"found file [%s] from a failed attempt to remove the plugin [failed]; execute [elasticsearch-plugin remove failed]",
|
||||||
removing);
|
removing
|
||||||
|
);
|
||||||
assertThat(e, hasToString(containsString(expected)));
|
assertThat(e, hasToString(containsString(expected)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -471,9 +482,11 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
public void testFileNotMaven() throws Exception {
|
public void testFileNotMaven() throws Exception {
|
||||||
Tuple<Path, Environment> env = createEnv(fs, temp);
|
Tuple<Path, Environment> env = createEnv(fs, temp);
|
||||||
String dir = randomAlphaOfLength(10) + ":" + randomAlphaOfLength(5) + "\\" + randomAlphaOfLength(5);
|
String dir = randomAlphaOfLength(10) + ":" + randomAlphaOfLength(5) + "\\" + randomAlphaOfLength(5);
|
||||||
Exception e = expectThrows(Exception.class,
|
Exception e = expectThrows(
|
||||||
|
Exception.class,
|
||||||
// has two colons, so it appears similar to maven coordinates
|
// has two colons, so it appears similar to maven coordinates
|
||||||
() -> installPlugin("file:" + dir, env.v1()));
|
() -> installPlugin("file:" + dir, env.v1())
|
||||||
|
);
|
||||||
assertFalse(e.getMessage(), e.getMessage().contains("maven.org"));
|
assertFalse(e.getMessage(), e.getMessage().contains("maven.org"));
|
||||||
assertTrue(e.getMessage(), e.getMessage().contains(dir));
|
assertTrue(e.getMessage(), e.getMessage().contains(dir));
|
||||||
}
|
}
|
||||||
@ -522,8 +535,10 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
Path pluginDirectory = createPluginDir(temp);
|
Path pluginDirectory = createPluginDir(temp);
|
||||||
writeJar(pluginDirectory.resolve("other.jar"), "FakePlugin");
|
writeJar(pluginDirectory.resolve("other.jar"), "FakePlugin");
|
||||||
String pluginZip = createPluginUrl("fake", pluginDirectory); // adds plugin.jar with FakePlugin
|
String pluginZip = createPluginUrl("fake", pluginDirectory); // adds plugin.jar with FakePlugin
|
||||||
IllegalStateException e = expectThrows(IllegalStateException.class,
|
IllegalStateException e = expectThrows(
|
||||||
() -> installPlugin(pluginZip, environment.v1(), defaultCommand));
|
IllegalStateException.class,
|
||||||
|
() -> installPlugin(pluginZip, environment.v1(), defaultCommand)
|
||||||
|
);
|
||||||
assertTrue(e.getMessage(), e.getMessage().contains("jar hell"));
|
assertTrue(e.getMessage(), e.getMessage().contains("jar hell"));
|
||||||
assertInstallCleaned(environment.v2());
|
assertInstallCleaned(environment.v2());
|
||||||
}
|
}
|
||||||
@ -587,7 +602,7 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
|
|
||||||
public void testBinConflict() throws Exception {
|
public void testBinConflict() throws Exception {
|
||||||
Tuple<Path, Environment> env = createEnv(fs, temp);
|
Tuple<Path, Environment> env = createEnv(fs, temp);
|
||||||
Path pluginDir = createPluginDir(temp);
|
Path pluginDir = createPluginDir(temp);
|
||||||
Path binDir = pluginDir.resolve("bin");
|
Path binDir = pluginDir.resolve("bin");
|
||||||
Files.createDirectory(binDir);
|
Files.createDirectory(binDir);
|
||||||
Files.createFile(binDir.resolve("somescript"));
|
Files.createFile(binDir.resolve("somescript"));
|
||||||
@ -795,14 +810,15 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
public void testInstallXPack() throws IOException {
|
public void testInstallXPack() throws IOException {
|
||||||
runInstallXPackTest(Build.Flavor.DEFAULT, UserException.class, "this distribution of Elasticsearch contains X-Pack by default");
|
runInstallXPackTest(Build.Flavor.DEFAULT, UserException.class, "this distribution of Elasticsearch contains X-Pack by default");
|
||||||
runInstallXPackTest(
|
runInstallXPackTest(
|
||||||
Build.Flavor.OSS,
|
Build.Flavor.OSS,
|
||||||
UserException.class,
|
UserException.class,
|
||||||
"X-Pack is not available with the oss distribution; to use X-Pack features use the default distribution");
|
"X-Pack is not available with the oss distribution; to use X-Pack features use the default distribution"
|
||||||
|
);
|
||||||
runInstallXPackTest(Build.Flavor.UNKNOWN, IllegalStateException.class, "your distribution is broken");
|
runInstallXPackTest(Build.Flavor.UNKNOWN, IllegalStateException.class, "your distribution is broken");
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T extends Exception> void runInstallXPackTest(
|
private <T extends Exception> void runInstallXPackTest(final Build.Flavor flavor, final Class<T> clazz, final String expectedMessage)
|
||||||
final Build.Flavor flavor, final Class<T> clazz, final String expectedMessage) throws IOException {
|
throws IOException {
|
||||||
final InstallPluginCommand flavorCommand = new InstallPluginCommand() {
|
final InstallPluginCommand flavorCommand = new InstallPluginCommand() {
|
||||||
@Override
|
@Override
|
||||||
Build.Flavor buildFlavor() {
|
Build.Flavor buildFlavor() {
|
||||||
@ -811,8 +827,10 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
final Environment environment = createEnv(fs, temp).v2();
|
final Environment environment = createEnv(fs, temp).v2();
|
||||||
final T exception =
|
final T exception = expectThrows(
|
||||||
expectThrows(clazz, () -> flavorCommand.execute(terminal, Collections.singletonList("x-pack"), false, environment));
|
clazz,
|
||||||
|
() -> flavorCommand.execute(terminal, Collections.singletonList("x-pack"), false, environment)
|
||||||
|
);
|
||||||
assertThat(exception, hasToString(containsString(expectedMessage)));
|
assertThat(exception, hasToString(containsString(expectedMessage)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -857,12 +875,19 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
Path pluginDir = createPluginDir(temp);
|
Path pluginDir = createPluginDir(temp);
|
||||||
String pluginZip = createPluginUrl("fake", pluginDir);
|
String pluginZip = createPluginUrl("fake", pluginDir);
|
||||||
installPlugin(pluginZip, env.v1());
|
installPlugin(pluginZip, env.v1());
|
||||||
final UserException e = expectThrows(UserException.class,
|
final UserException e = expectThrows(
|
||||||
() -> installPlugin(pluginZip, env.v1(), randomFrom(skipJarHellCommand, defaultCommand)));
|
UserException.class,
|
||||||
|
() -> installPlugin(pluginZip, env.v1(), randomFrom(skipJarHellCommand, defaultCommand))
|
||||||
|
);
|
||||||
assertThat(
|
assertThat(
|
||||||
e.getMessage(),
|
e.getMessage(),
|
||||||
equalTo("plugin directory [" + env.v2().pluginsFile().resolve("fake") + "] already exists; " +
|
equalTo(
|
||||||
"if you need to update the plugin, uninstall it first using command 'remove fake'"));
|
"plugin directory ["
|
||||||
|
+ env.v2().pluginsFile().resolve("fake")
|
||||||
|
+ "] already exists; "
|
||||||
|
+ "if you need to update the plugin, uninstall it first using command 'remove fake'"
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void installPlugin(MockTerminal terminal, boolean isBatch) throws Exception {
|
private void installPlugin(MockTerminal terminal, boolean isBatch) throws Exception {
|
||||||
@ -877,15 +902,16 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void assertInstallPluginFromUrl(
|
void assertInstallPluginFromUrl(
|
||||||
final String pluginId,
|
final String pluginId,
|
||||||
final String name,
|
final String name,
|
||||||
final String url,
|
final String url,
|
||||||
final String stagingHash,
|
final String stagingHash,
|
||||||
final boolean isSnapshot,
|
final boolean isSnapshot,
|
||||||
final String shaExtension,
|
final String shaExtension,
|
||||||
final Function<byte[], String> shaCalculator,
|
final Function<byte[], String> shaCalculator,
|
||||||
final PGPSecretKey secretKey,
|
final PGPSecretKey secretKey,
|
||||||
final BiFunction<byte[], PGPSecretKey, String> signature) throws Exception {
|
final BiFunction<byte[], PGPSecretKey, String> signature
|
||||||
|
) throws Exception {
|
||||||
Tuple<Path, Environment> env = createEnv(fs, temp);
|
Tuple<Path, Environment> env = createEnv(fs, temp);
|
||||||
Path pluginDir = createPluginDir(temp);
|
Path pluginDir = createPluginDir(temp);
|
||||||
Path pluginZip = createPlugin(name, pluginDir);
|
Path pluginZip = createPlugin(name, pluginDir);
|
||||||
@ -897,6 +923,7 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
Files.copy(pluginZip, downloadedPath);
|
Files.copy(pluginZip, downloadedPath);
|
||||||
return downloadedPath;
|
return downloadedPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
URL openUrl(String urlString) throws IOException {
|
URL openUrl(String urlString) throws IOException {
|
||||||
if ((url + shaExtension).equals(urlString)) {
|
if ((url + shaExtension).equals(urlString)) {
|
||||||
@ -952,6 +979,7 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
boolean urlExists(Terminal terminal, String urlString) throws IOException {
|
boolean urlExists(Terminal terminal, String urlString) throws IOException {
|
||||||
return urlString.equals(url);
|
return urlString.equals(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
String getStagingHash() {
|
String getStagingHash() {
|
||||||
return stagingHash;
|
return stagingHash;
|
||||||
@ -972,66 +1000,99 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void assertInstallPluginFromUrl(
|
public void assertInstallPluginFromUrl(
|
||||||
final String pluginId, final String name, final String url, final String stagingHash, boolean isSnapshot) throws Exception {
|
final String pluginId,
|
||||||
|
final String name,
|
||||||
|
final String url,
|
||||||
|
final String stagingHash,
|
||||||
|
boolean isSnapshot
|
||||||
|
) throws Exception {
|
||||||
final MessageDigest digest = MessageDigest.getInstance("SHA-512");
|
final MessageDigest digest = MessageDigest.getInstance("SHA-512");
|
||||||
assertInstallPluginFromUrl(
|
assertInstallPluginFromUrl(
|
||||||
pluginId, name, url, stagingHash, isSnapshot, ".sha512", checksumAndFilename(digest, url), newSecretKey(), this::signature);
|
pluginId,
|
||||||
|
name,
|
||||||
|
url,
|
||||||
|
stagingHash,
|
||||||
|
isSnapshot,
|
||||||
|
".sha512",
|
||||||
|
checksumAndFilename(digest, url),
|
||||||
|
newSecretKey(),
|
||||||
|
this::signature
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testOfficialPlugin() throws Exception {
|
public void testOfficialPlugin() throws Exception {
|
||||||
String url = "https://artifacts.elastic.co/downloads/elasticsearch-plugins/analysis-icu/analysis-icu-" +
|
String url = "https://artifacts.elastic.co/downloads/elasticsearch-plugins/analysis-icu/analysis-icu-"
|
||||||
Build.CURRENT.getQualifiedVersion() + ".zip";
|
+ Build.CURRENT.getQualifiedVersion()
|
||||||
|
+ ".zip";
|
||||||
assertInstallPluginFromUrl("analysis-icu", "analysis-icu", url, null, false);
|
assertInstallPluginFromUrl("analysis-icu", "analysis-icu", url, null, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testOfficialPluginSnapshot() throws Exception {
|
public void testOfficialPluginSnapshot() throws Exception {
|
||||||
String url = String.format(
|
String url = String.format(
|
||||||
Locale.ROOT,
|
Locale.ROOT,
|
||||||
"https://snapshots.elastic.co/%s-abc123/downloads/elasticsearch-plugins/analysis-icu/analysis-icu-%s.zip",
|
"https://snapshots.elastic.co/%s-abc123/downloads/elasticsearch-plugins/analysis-icu/analysis-icu-%s.zip",
|
||||||
Version.CURRENT,
|
Version.CURRENT,
|
||||||
Build.CURRENT.getQualifiedVersion());
|
Build.CURRENT.getQualifiedVersion()
|
||||||
|
);
|
||||||
assertInstallPluginFromUrl("analysis-icu", "analysis-icu", url, "abc123", true);
|
assertInstallPluginFromUrl("analysis-icu", "analysis-icu", url, "abc123", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testInstallReleaseBuildOfPluginOnSnapshotBuild() {
|
public void testInstallReleaseBuildOfPluginOnSnapshotBuild() {
|
||||||
String url = String.format(
|
String url = String.format(
|
||||||
Locale.ROOT,
|
Locale.ROOT,
|
||||||
"https://snapshots.elastic.co/%s-abc123/downloads/elasticsearch-plugins/analysis-icu/analysis-icu-%s.zip",
|
"https://snapshots.elastic.co/%s-abc123/downloads/elasticsearch-plugins/analysis-icu/analysis-icu-%s.zip",
|
||||||
Version.CURRENT,
|
Version.CURRENT,
|
||||||
Build.CURRENT.getQualifiedVersion());
|
Build.CURRENT.getQualifiedVersion()
|
||||||
|
);
|
||||||
// attemping to install a release build of a plugin (no staging ID) on a snapshot build should throw a user exception
|
// attemping to install a release build of a plugin (no staging ID) on a snapshot build should throw a user exception
|
||||||
final UserException e =
|
final UserException e = expectThrows(
|
||||||
expectThrows(UserException.class, () -> assertInstallPluginFromUrl("analysis-icu", "analysis-icu", url, null, true));
|
UserException.class,
|
||||||
|
() -> assertInstallPluginFromUrl("analysis-icu", "analysis-icu", url, null, true)
|
||||||
|
);
|
||||||
assertThat(e.exitCode, equalTo(ExitCodes.CONFIG));
|
assertThat(e.exitCode, equalTo(ExitCodes.CONFIG));
|
||||||
assertThat(
|
assertThat(
|
||||||
e, hasToString(containsString("attempted to install release build of official plugin on snapshot build of Elasticsearch")));
|
e,
|
||||||
|
hasToString(containsString("attempted to install release build of official plugin on snapshot build of Elasticsearch"))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testOfficialPluginStaging() throws Exception {
|
public void testOfficialPluginStaging() throws Exception {
|
||||||
String url = "https://staging.elastic.co/" + Version.CURRENT + "-abc123/downloads/elasticsearch-plugins/analysis-icu/analysis-icu-"
|
String url = "https://staging.elastic.co/"
|
||||||
+ Build.CURRENT.getQualifiedVersion() + ".zip";
|
+ Version.CURRENT
|
||||||
|
+ "-abc123/downloads/elasticsearch-plugins/analysis-icu/analysis-icu-"
|
||||||
|
+ Build.CURRENT.getQualifiedVersion()
|
||||||
|
+ ".zip";
|
||||||
assertInstallPluginFromUrl("analysis-icu", "analysis-icu", url, "abc123", false);
|
assertInstallPluginFromUrl("analysis-icu", "analysis-icu", url, "abc123", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testOfficialPlatformPlugin() throws Exception {
|
public void testOfficialPlatformPlugin() throws Exception {
|
||||||
String url = "https://artifacts.elastic.co/downloads/elasticsearch-plugins/analysis-icu/analysis-icu-" + Platforms.PLATFORM_NAME +
|
String url = "https://artifacts.elastic.co/downloads/elasticsearch-plugins/analysis-icu/analysis-icu-"
|
||||||
"-" + Build.CURRENT.getQualifiedVersion() + ".zip";
|
+ Platforms.PLATFORM_NAME
|
||||||
|
+ "-"
|
||||||
|
+ Build.CURRENT.getQualifiedVersion()
|
||||||
|
+ ".zip";
|
||||||
assertInstallPluginFromUrl("analysis-icu", "analysis-icu", url, null, false);
|
assertInstallPluginFromUrl("analysis-icu", "analysis-icu", url, null, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testOfficialPlatformPluginSnapshot() throws Exception {
|
public void testOfficialPlatformPluginSnapshot() throws Exception {
|
||||||
String url = String.format(
|
String url = String.format(
|
||||||
Locale.ROOT,
|
Locale.ROOT,
|
||||||
"https://snapshots.elastic.co/%s-abc123/downloads/elasticsearch-plugins/analysis-icu/analysis-icu-%s-%s.zip",
|
"https://snapshots.elastic.co/%s-abc123/downloads/elasticsearch-plugins/analysis-icu/analysis-icu-%s-%s.zip",
|
||||||
Version.CURRENT,
|
Version.CURRENT,
|
||||||
Platforms.PLATFORM_NAME,
|
Platforms.PLATFORM_NAME,
|
||||||
Build.CURRENT.getQualifiedVersion());
|
Build.CURRENT.getQualifiedVersion()
|
||||||
|
);
|
||||||
assertInstallPluginFromUrl("analysis-icu", "analysis-icu", url, "abc123", true);
|
assertInstallPluginFromUrl("analysis-icu", "analysis-icu", url, "abc123", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testOfficialPlatformPluginStaging() throws Exception {
|
public void testOfficialPlatformPluginStaging() throws Exception {
|
||||||
String url = "https://staging.elastic.co/" + Version.CURRENT + "-abc123/downloads/elasticsearch-plugins/analysis-icu/analysis-icu-"
|
String url = "https://staging.elastic.co/"
|
||||||
+ Platforms.PLATFORM_NAME + "-"+ Build.CURRENT.getQualifiedVersion() + ".zip";
|
+ Version.CURRENT
|
||||||
|
+ "-abc123/downloads/elasticsearch-plugins/analysis-icu/analysis-icu-"
|
||||||
|
+ Platforms.PLATFORM_NAME
|
||||||
|
+ "-"
|
||||||
|
+ Build.CURRENT.getQualifiedVersion()
|
||||||
|
+ ".zip";
|
||||||
assertInstallPluginFromUrl("analysis-icu", "analysis-icu", url, "abc123", false);
|
assertInstallPluginFromUrl("analysis-icu", "analysis-icu", url, "abc123", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1053,12 +1114,23 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testOfficialShaMissing() throws Exception {
|
public void testOfficialShaMissing() throws Exception {
|
||||||
String url = "https://artifacts.elastic.co/downloads/elasticsearch-plugins/analysis-icu/analysis-icu-" +
|
String url = "https://artifacts.elastic.co/downloads/elasticsearch-plugins/analysis-icu/analysis-icu-"
|
||||||
Build.CURRENT.getQualifiedVersion() + ".zip";
|
+ Build.CURRENT.getQualifiedVersion()
|
||||||
|
+ ".zip";
|
||||||
MessageDigest digest = MessageDigest.getInstance("SHA-1");
|
MessageDigest digest = MessageDigest.getInstance("SHA-1");
|
||||||
UserException e = expectThrows(UserException.class, () ->
|
UserException e = expectThrows(
|
||||||
assertInstallPluginFromUrl("analysis-icu", "analysis-icu", url, null, false,
|
UserException.class,
|
||||||
".sha1", checksum(digest), null, (b, p) -> null)
|
() -> assertInstallPluginFromUrl(
|
||||||
|
"analysis-icu",
|
||||||
|
"analysis-icu",
|
||||||
|
url,
|
||||||
|
null,
|
||||||
|
false,
|
||||||
|
".sha1",
|
||||||
|
checksum(digest),
|
||||||
|
null,
|
||||||
|
(b, p) -> null
|
||||||
|
)
|
||||||
);
|
);
|
||||||
assertEquals(ExitCodes.IO_ERROR, e.exitCode);
|
assertEquals(ExitCodes.IO_ERROR, e.exitCode);
|
||||||
assertEquals("Plugin checksum missing: " + url + ".sha512", e.getMessage());
|
assertEquals("Plugin checksum missing: " + url + ".sha512", e.getMessage());
|
||||||
@ -1066,94 +1138,142 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
|
|
||||||
public void testMavenShaMissing() throws Exception {
|
public void testMavenShaMissing() throws Exception {
|
||||||
String url = "https://repo1.maven.org/maven2/mygroup/myplugin/1.0.0/myplugin-1.0.0.zip";
|
String url = "https://repo1.maven.org/maven2/mygroup/myplugin/1.0.0/myplugin-1.0.0.zip";
|
||||||
UserException e = expectThrows(UserException.class, () ->
|
UserException e = expectThrows(
|
||||||
assertInstallPluginFromUrl(
|
UserException.class,
|
||||||
"mygroup:myplugin:1.0.0", "myplugin", url, null, false, ".dne", bytes -> null, null, (b, p) -> null));
|
() -> assertInstallPluginFromUrl(
|
||||||
|
"mygroup:myplugin:1.0.0",
|
||||||
|
"myplugin",
|
||||||
|
url,
|
||||||
|
null,
|
||||||
|
false,
|
||||||
|
".dne",
|
||||||
|
bytes -> null,
|
||||||
|
null,
|
||||||
|
(b, p) -> null
|
||||||
|
)
|
||||||
|
);
|
||||||
assertEquals(ExitCodes.IO_ERROR, e.exitCode);
|
assertEquals(ExitCodes.IO_ERROR, e.exitCode);
|
||||||
assertEquals("Plugin checksum missing: " + url + ".sha1", e.getMessage());
|
assertEquals("Plugin checksum missing: " + url + ".sha1", e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testInvalidShaFileMissingFilename() throws Exception {
|
public void testInvalidShaFileMissingFilename() throws Exception {
|
||||||
String url = "https://artifacts.elastic.co/downloads/elasticsearch-plugins/analysis-icu/analysis-icu-" +
|
String url = "https://artifacts.elastic.co/downloads/elasticsearch-plugins/analysis-icu/analysis-icu-"
|
||||||
Build.CURRENT.getQualifiedVersion() + ".zip";
|
+ Build.CURRENT.getQualifiedVersion()
|
||||||
|
+ ".zip";
|
||||||
MessageDigest digest = MessageDigest.getInstance("SHA-512");
|
MessageDigest digest = MessageDigest.getInstance("SHA-512");
|
||||||
UserException e = expectThrows(UserException.class,
|
UserException e = expectThrows(
|
||||||
() -> assertInstallPluginFromUrl(
|
UserException.class,
|
||||||
"analysis-icu", "analysis-icu", url, null, false, ".sha512", checksum(digest), null, (b, p) -> null));
|
() -> assertInstallPluginFromUrl(
|
||||||
|
"analysis-icu",
|
||||||
|
"analysis-icu",
|
||||||
|
url,
|
||||||
|
null,
|
||||||
|
false,
|
||||||
|
".sha512",
|
||||||
|
checksum(digest),
|
||||||
|
null,
|
||||||
|
(b, p) -> null
|
||||||
|
)
|
||||||
|
);
|
||||||
assertEquals(ExitCodes.IO_ERROR, e.exitCode);
|
assertEquals(ExitCodes.IO_ERROR, e.exitCode);
|
||||||
assertTrue(e.getMessage(), e.getMessage().startsWith("Invalid checksum file"));
|
assertTrue(e.getMessage(), e.getMessage().startsWith("Invalid checksum file"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testInvalidShaFileMismatchFilename() throws Exception {
|
public void testInvalidShaFileMismatchFilename() throws Exception {
|
||||||
String url = "https://artifacts.elastic.co/downloads/elasticsearch-plugins/analysis-icu/analysis-icu-" +
|
String url = "https://artifacts.elastic.co/downloads/elasticsearch-plugins/analysis-icu/analysis-icu-"
|
||||||
Build.CURRENT.getQualifiedVersion()+ ".zip";
|
+ Build.CURRENT.getQualifiedVersion()
|
||||||
|
+ ".zip";
|
||||||
MessageDigest digest = MessageDigest.getInstance("SHA-512");
|
MessageDigest digest = MessageDigest.getInstance("SHA-512");
|
||||||
UserException e = expectThrows(UserException.class, () ->
|
UserException e = expectThrows(
|
||||||
assertInstallPluginFromUrl(
|
UserException.class,
|
||||||
"analysis-icu",
|
() -> assertInstallPluginFromUrl(
|
||||||
"analysis-icu",
|
"analysis-icu",
|
||||||
url,
|
"analysis-icu",
|
||||||
null,
|
url,
|
||||||
false,
|
null,
|
||||||
".sha512",
|
false,
|
||||||
checksumAndString(digest, " repository-s3-" + Build.CURRENT.getQualifiedVersion() + ".zip"),
|
".sha512",
|
||||||
null,
|
checksumAndString(digest, " repository-s3-" + Build.CURRENT.getQualifiedVersion() + ".zip"),
|
||||||
(b, p) -> null));
|
null,
|
||||||
|
(b, p) -> null
|
||||||
|
)
|
||||||
|
);
|
||||||
assertEquals(ExitCodes.IO_ERROR, e.exitCode);
|
assertEquals(ExitCodes.IO_ERROR, e.exitCode);
|
||||||
assertThat(e, hasToString(matches("checksum file at \\[.*\\] is not for this plugin")));
|
assertThat(e, hasToString(matches("checksum file at \\[.*\\] is not for this plugin")));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testInvalidShaFileContainingExtraLine() throws Exception {
|
public void testInvalidShaFileContainingExtraLine() throws Exception {
|
||||||
String url = "https://artifacts.elastic.co/downloads/elasticsearch-plugins/analysis-icu/analysis-icu-" +
|
String url = "https://artifacts.elastic.co/downloads/elasticsearch-plugins/analysis-icu/analysis-icu-"
|
||||||
Build.CURRENT.getQualifiedVersion() + ".zip";
|
+ Build.CURRENT.getQualifiedVersion()
|
||||||
|
+ ".zip";
|
||||||
MessageDigest digest = MessageDigest.getInstance("SHA-512");
|
MessageDigest digest = MessageDigest.getInstance("SHA-512");
|
||||||
UserException e = expectThrows(UserException.class, () ->
|
UserException e = expectThrows(
|
||||||
assertInstallPluginFromUrl(
|
UserException.class,
|
||||||
"analysis-icu",
|
() -> assertInstallPluginFromUrl(
|
||||||
"analysis-icu",
|
"analysis-icu",
|
||||||
url,
|
"analysis-icu",
|
||||||
null,
|
url,
|
||||||
false,
|
null,
|
||||||
".sha512",
|
false,
|
||||||
checksumAndString(digest, " analysis-icu-" + Build.CURRENT.getQualifiedVersion() + ".zip\nfoobar"),
|
".sha512",
|
||||||
null,
|
checksumAndString(digest, " analysis-icu-" + Build.CURRENT.getQualifiedVersion() + ".zip\nfoobar"),
|
||||||
(b, p) -> null));
|
null,
|
||||||
|
(b, p) -> null
|
||||||
|
)
|
||||||
|
);
|
||||||
assertEquals(ExitCodes.IO_ERROR, e.exitCode);
|
assertEquals(ExitCodes.IO_ERROR, e.exitCode);
|
||||||
assertTrue(e.getMessage(), e.getMessage().startsWith("Invalid checksum file"));
|
assertTrue(e.getMessage(), e.getMessage().startsWith("Invalid checksum file"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testSha512Mismatch() throws Exception {
|
public void testSha512Mismatch() throws Exception {
|
||||||
String url = "https://artifacts.elastic.co/downloads/elasticsearch-plugins/analysis-icu/analysis-icu-" +
|
String url = "https://artifacts.elastic.co/downloads/elasticsearch-plugins/analysis-icu/analysis-icu-"
|
||||||
Build.CURRENT.getQualifiedVersion() + ".zip";
|
+ Build.CURRENT.getQualifiedVersion()
|
||||||
UserException e = expectThrows(UserException.class, () ->
|
+ ".zip";
|
||||||
assertInstallPluginFromUrl(
|
UserException e = expectThrows(
|
||||||
"analysis-icu",
|
UserException.class,
|
||||||
"analysis-icu",
|
() -> assertInstallPluginFromUrl(
|
||||||
url,
|
"analysis-icu",
|
||||||
null,
|
"analysis-icu",
|
||||||
false,
|
url,
|
||||||
".sha512",
|
null,
|
||||||
bytes -> "foobar analysis-icu-" + Build.CURRENT.getQualifiedVersion() + ".zip",
|
false,
|
||||||
null,
|
".sha512",
|
||||||
(b, p) -> null));
|
bytes -> "foobar analysis-icu-" + Build.CURRENT.getQualifiedVersion() + ".zip",
|
||||||
|
null,
|
||||||
|
(b, p) -> null
|
||||||
|
)
|
||||||
|
);
|
||||||
assertEquals(ExitCodes.IO_ERROR, e.exitCode);
|
assertEquals(ExitCodes.IO_ERROR, e.exitCode);
|
||||||
assertTrue(e.getMessage(), e.getMessage().contains("SHA-512 mismatch, expected foobar"));
|
assertTrue(e.getMessage(), e.getMessage().contains("SHA-512 mismatch, expected foobar"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testSha1Mismatch() throws Exception {
|
public void testSha1Mismatch() throws Exception {
|
||||||
String url = "https://repo1.maven.org/maven2/mygroup/myplugin/1.0.0/myplugin-1.0.0.zip";
|
String url = "https://repo1.maven.org/maven2/mygroup/myplugin/1.0.0/myplugin-1.0.0.zip";
|
||||||
UserException e = expectThrows(UserException.class, () ->
|
UserException e = expectThrows(
|
||||||
assertInstallPluginFromUrl(
|
UserException.class,
|
||||||
"mygroup:myplugin:1.0.0", "myplugin", url, null, false, ".sha1", bytes -> "foobar", null, (b, p) -> null));
|
() -> assertInstallPluginFromUrl(
|
||||||
|
"mygroup:myplugin:1.0.0",
|
||||||
|
"myplugin",
|
||||||
|
url,
|
||||||
|
null,
|
||||||
|
false,
|
||||||
|
".sha1",
|
||||||
|
bytes -> "foobar",
|
||||||
|
null,
|
||||||
|
(b, p) -> null
|
||||||
|
)
|
||||||
|
);
|
||||||
assertEquals(ExitCodes.IO_ERROR, e.exitCode);
|
assertEquals(ExitCodes.IO_ERROR, e.exitCode);
|
||||||
assertTrue(e.getMessage(), e.getMessage().contains("SHA-1 mismatch, expected foobar"));
|
assertTrue(e.getMessage(), e.getMessage().contains("SHA-1 mismatch, expected foobar"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testPublicKeyIdMismatchToExpectedPublicKeyId() throws Exception {
|
public void testPublicKeyIdMismatchToExpectedPublicKeyId() throws Exception {
|
||||||
final String icu = "analysis-icu";
|
final String icu = "analysis-icu";
|
||||||
final String url =
|
final String url = "https://artifacts.elastic.co/downloads/elasticsearch-plugins/analysis-icu/"
|
||||||
"https://artifacts.elastic.co/downloads/elasticsearch-plugins/analysis-icu/" + icu + "-" +
|
+ icu
|
||||||
Build.CURRENT.getQualifiedVersion() + ".zip";
|
+ "-"
|
||||||
|
+ Build.CURRENT.getQualifiedVersion()
|
||||||
|
+ ".zip";
|
||||||
final MessageDigest digest = MessageDigest.getInstance("SHA-512");
|
final MessageDigest digest = MessageDigest.getInstance("SHA-512");
|
||||||
/*
|
/*
|
||||||
* To setup a situation where the expected public key ID does not match the public key ID used for signing, we generate a new public
|
* To setup a situation where the expected public key ID does not match the public key ID used for signing, we generate a new public
|
||||||
@ -1166,18 +1286,29 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
final PGPSecretKey verifyingKey = newSecretKey(); // the expected key used for signing
|
final PGPSecretKey verifyingKey = newSecretKey(); // the expected key used for signing
|
||||||
final String expectedID = Long.toHexString(verifyingKey.getKeyID()).toUpperCase(Locale.ROOT);
|
final String expectedID = Long.toHexString(verifyingKey.getKeyID()).toUpperCase(Locale.ROOT);
|
||||||
final IllegalStateException e = expectThrows(
|
final IllegalStateException e = expectThrows(
|
||||||
IllegalStateException.class,
|
IllegalStateException.class,
|
||||||
() ->
|
() -> assertInstallPluginFromUrl(
|
||||||
assertInstallPluginFromUrl(
|
icu,
|
||||||
icu, icu, url, null, false, ".sha512", checksumAndFilename(digest, url), verifyingKey, signature));
|
icu,
|
||||||
|
url,
|
||||||
|
null,
|
||||||
|
false,
|
||||||
|
".sha512",
|
||||||
|
checksumAndFilename(digest, url),
|
||||||
|
verifyingKey,
|
||||||
|
signature
|
||||||
|
)
|
||||||
|
);
|
||||||
assertThat(e, hasToString(containsString("key id [" + actualID + "] does not match expected key id [" + expectedID + "]")));
|
assertThat(e, hasToString(containsString("key id [" + actualID + "] does not match expected key id [" + expectedID + "]")));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testFailedSignatureVerification() throws Exception {
|
public void testFailedSignatureVerification() throws Exception {
|
||||||
final String icu = "analysis-icu";
|
final String icu = "analysis-icu";
|
||||||
final String url =
|
final String url = "https://artifacts.elastic.co/downloads/elasticsearch-plugins/analysis-icu/"
|
||||||
"https://artifacts.elastic.co/downloads/elasticsearch-plugins/analysis-icu/" + icu + "-" +
|
+ icu
|
||||||
Build.CURRENT.getQualifiedVersion() + ".zip";
|
+ "-"
|
||||||
|
+ Build.CURRENT.getQualifiedVersion()
|
||||||
|
+ ".zip";
|
||||||
final MessageDigest digest = MessageDigest.getInstance("SHA-512");
|
final MessageDigest digest = MessageDigest.getInstance("SHA-512");
|
||||||
/*
|
/*
|
||||||
* To setup a situation where signature verification fails, we will mutate the input byte array by modifying a single byte to some
|
* To setup a situation where signature verification fails, we will mutate the input byte array by modifying a single byte to some
|
||||||
@ -1190,10 +1321,19 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
return signature(bytes, p);
|
return signature(bytes, p);
|
||||||
};
|
};
|
||||||
final IllegalStateException e = expectThrows(
|
final IllegalStateException e = expectThrows(
|
||||||
IllegalStateException.class,
|
IllegalStateException.class,
|
||||||
() ->
|
() -> assertInstallPluginFromUrl(
|
||||||
assertInstallPluginFromUrl(
|
icu,
|
||||||
icu, icu, url, null, false, ".sha512", checksumAndFilename(digest, url), newSecretKey(), signature));
|
icu,
|
||||||
|
url,
|
||||||
|
null,
|
||||||
|
false,
|
||||||
|
".sha512",
|
||||||
|
checksumAndFilename(digest, url),
|
||||||
|
newSecretKey(),
|
||||||
|
signature
|
||||||
|
)
|
||||||
|
);
|
||||||
assertThat(e, hasToString(equalTo("java.lang.IllegalStateException: signature verification for [" + url + "] failed")));
|
assertThat(e, hasToString(equalTo("java.lang.IllegalStateException: signature verification for [" + url + "] failed")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1204,16 +1344,16 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
final PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder().build().get(HashAlgorithmTags.SHA1);
|
final PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder().build().get(HashAlgorithmTags.SHA1);
|
||||||
final PGPKeyPair pkp = new JcaPGPKeyPair(PGPPublicKey.RSA_GENERAL, pair, new Date());
|
final PGPKeyPair pkp = new JcaPGPKeyPair(PGPPublicKey.RSA_GENERAL, pair, new Date());
|
||||||
return new PGPSecretKey(
|
return new PGPSecretKey(
|
||||||
PGPSignature.DEFAULT_CERTIFICATION,
|
PGPSignature.DEFAULT_CERTIFICATION,
|
||||||
pkp,
|
pkp,
|
||||||
"example@example.com",
|
"example@example.com",
|
||||||
sha1Calc,
|
sha1Calc,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
new JcaPGPContentSignerBuilder(pkp.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA256),
|
new JcaPGPContentSignerBuilder(pkp.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA256),
|
||||||
new JcePBESecretKeyEncryptorBuilder(PGPEncryptedData.AES_192, sha1Calc)
|
new JcePBESecretKeyEncryptorBuilder(PGPEncryptedData.AES_192, sha1Calc).setProvider(new BouncyCastleFipsProvider())
|
||||||
.setProvider(new BouncyCastleFipsProvider())
|
.build("passphrase".toCharArray())
|
||||||
.build("passphrase".toCharArray()));
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Function<byte[], String> checksum(final MessageDigest digest) {
|
private Function<byte[], String> checksum(final MessageDigest digest) {
|
||||||
@ -1231,17 +1371,18 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||||||
|
|
||||||
private String signature(final byte[] bytes, final PGPSecretKey secretKey) {
|
private String signature(final byte[] bytes, final PGPSecretKey secretKey) {
|
||||||
try {
|
try {
|
||||||
final PGPPrivateKey privateKey
|
final PGPPrivateKey privateKey = secretKey.extractPrivateKey(
|
||||||
= secretKey.extractPrivateKey(
|
new JcePBESecretKeyDecryptorBuilder(new JcaPGPDigestCalculatorProviderBuilder().build()).build("passphrase".toCharArray())
|
||||||
new JcePBESecretKeyDecryptorBuilder(
|
);
|
||||||
new JcaPGPDigestCalculatorProviderBuilder().build()).build("passphrase".toCharArray()));
|
final PGPSignatureGenerator generator = new PGPSignatureGenerator(
|
||||||
final PGPSignatureGenerator generator =
|
new JcaPGPContentSignerBuilder(privateKey.getPublicKeyPacket().getAlgorithm(), HashAlgorithmTags.SHA512)
|
||||||
new PGPSignatureGenerator(
|
);
|
||||||
new JcaPGPContentSignerBuilder(privateKey.getPublicKeyPacket().getAlgorithm(), HashAlgorithmTags.SHA512));
|
|
||||||
generator.init(PGPSignature.BINARY_DOCUMENT, privateKey);
|
generator.init(PGPSignature.BINARY_DOCUMENT, privateKey);
|
||||||
final ByteArrayOutputStream output = new ByteArrayOutputStream();
|
final ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||||
try (BCPGOutputStream pout = new BCPGOutputStream(new ArmoredOutputStream(output));
|
try (
|
||||||
InputStream is = new ByteArrayInputStream(bytes)) {
|
BCPGOutputStream pout = new BCPGOutputStream(new ArmoredOutputStream(output));
|
||||||
|
InputStream is = new ByteArrayInputStream(bytes)
|
||||||
|
) {
|
||||||
final byte[] buffer = new byte[1024];
|
final byte[] buffer = new byte[1024];
|
||||||
int read;
|
int read;
|
||||||
while ((read = is.read(buffer)) != -1) {
|
while ((read = is.read(buffer)) != -1) {
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
package org.elasticsearch.plugins;
|
package org.elasticsearch.plugins;
|
||||||
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.NoSuchFileException;
|
import java.nio.file.NoSuchFileException;
|
||||||
@ -50,9 +49,7 @@ public class ListPluginsCommandTests extends ESTestCase {
|
|||||||
super.setUp();
|
super.setUp();
|
||||||
home = createTempDir();
|
home = createTempDir();
|
||||||
Files.createDirectories(home.resolve("plugins"));
|
Files.createDirectories(home.resolve("plugins"));
|
||||||
Settings settings = Settings.builder()
|
Settings settings = Settings.builder().put("path.home", home).build();
|
||||||
.put("path.home", home)
|
|
||||||
.build();
|
|
||||||
env = TestEnvironment.newEnvironment(settings);
|
env = TestEnvironment.newEnvironment(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,7 +66,7 @@ public class ListPluginsCommandTests extends ESTestCase {
|
|||||||
@Override
|
@Override
|
||||||
protected Environment createEnv(Map<String, String> settings) throws UserException {
|
protected Environment createEnv(Map<String, String> settings) throws UserException {
|
||||||
Settings.Builder builder = Settings.builder().put("path.home", home);
|
Settings.Builder builder = Settings.builder().put("path.home", home);
|
||||||
settings.forEach((k,v) -> builder.put(k, v));
|
settings.forEach((k, v) -> builder.put(k, v));
|
||||||
final Settings realSettings = builder.build();
|
final Settings realSettings = builder.build();
|
||||||
return new Environment(realSettings, home.resolve("config"));
|
return new Environment(realSettings, home.resolve("config"));
|
||||||
}
|
}
|
||||||
@ -83,33 +80,39 @@ public class ListPluginsCommandTests extends ESTestCase {
|
|||||||
return terminal;
|
return terminal;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String buildMultiline(String... args){
|
private static String buildMultiline(String... args) {
|
||||||
return Arrays.stream(args).collect(Collectors.joining("\n", "", "\n"));
|
return Arrays.stream(args).collect(Collectors.joining("\n", "", "\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void buildFakePlugin(
|
private static void buildFakePlugin(final Environment env, final String description, final String name, final String classname)
|
||||||
final Environment env,
|
throws IOException {
|
||||||
final String description,
|
|
||||||
final String name,
|
|
||||||
final String classname) throws IOException {
|
|
||||||
buildFakePlugin(env, description, name, classname, false);
|
buildFakePlugin(env, description, name, classname, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void buildFakePlugin(
|
private static void buildFakePlugin(
|
||||||
final Environment env,
|
final Environment env,
|
||||||
final String description,
|
final String description,
|
||||||
final String name,
|
final String name,
|
||||||
final String classname,
|
final String classname,
|
||||||
final boolean hasNativeController) throws IOException {
|
final boolean hasNativeController
|
||||||
|
) throws IOException {
|
||||||
PluginTestUtil.writePluginProperties(
|
PluginTestUtil.writePluginProperties(
|
||||||
env.pluginsFile().resolve(name),
|
env.pluginsFile().resolve(name),
|
||||||
"description", description,
|
"description",
|
||||||
"name", name,
|
description,
|
||||||
"version", "1.0",
|
"name",
|
||||||
"elasticsearch.version", Version.CURRENT.toString(),
|
name,
|
||||||
"java.version", "1.8",
|
"version",
|
||||||
"classname", classname,
|
"1.0",
|
||||||
"has.native.controller", Boolean.toString(hasNativeController));
|
"elasticsearch.version",
|
||||||
|
Version.CURRENT.toString(),
|
||||||
|
"java.version",
|
||||||
|
"1.8",
|
||||||
|
"classname",
|
||||||
|
classname,
|
||||||
|
"has.native.controller",
|
||||||
|
Boolean.toString(hasNativeController)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testPluginsDirMissing() throws Exception {
|
public void testPluginsDirMissing() throws Exception {
|
||||||
@ -141,19 +144,21 @@ public class ListPluginsCommandTests extends ESTestCase {
|
|||||||
String[] params = { "-v" };
|
String[] params = { "-v" };
|
||||||
MockTerminal terminal = listPlugins(home, params);
|
MockTerminal terminal = listPlugins(home, params);
|
||||||
assertEquals(
|
assertEquals(
|
||||||
buildMultiline(
|
buildMultiline(
|
||||||
"Plugins directory: " + env.pluginsFile(),
|
"Plugins directory: " + env.pluginsFile(),
|
||||||
"fake_plugin",
|
"fake_plugin",
|
||||||
"- Plugin information:",
|
"- Plugin information:",
|
||||||
"Name: fake_plugin",
|
"Name: fake_plugin",
|
||||||
"Description: fake desc",
|
"Description: fake desc",
|
||||||
"Version: 1.0",
|
"Version: 1.0",
|
||||||
"Elasticsearch Version: " + Version.CURRENT.toString(),
|
"Elasticsearch Version: " + Version.CURRENT.toString(),
|
||||||
"Java Version: 1.8",
|
"Java Version: 1.8",
|
||||||
"Native Controller: false",
|
"Native Controller: false",
|
||||||
"Extended Plugins: []",
|
"Extended Plugins: []",
|
||||||
" * Classname: org.fake"),
|
" * Classname: org.fake"
|
||||||
terminal.getOutput());
|
),
|
||||||
|
terminal.getOutput()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testPluginWithNativeController() throws Exception {
|
public void testPluginWithNativeController() throws Exception {
|
||||||
@ -172,8 +177,10 @@ public class ListPluginsCommandTests extends ESTestCase {
|
|||||||
"Java Version: 1.8",
|
"Java Version: 1.8",
|
||||||
"Native Controller: true",
|
"Native Controller: true",
|
||||||
"Extended Plugins: []",
|
"Extended Plugins: []",
|
||||||
" * Classname: org.fake"),
|
" * Classname: org.fake"
|
||||||
terminal.getOutput());
|
),
|
||||||
|
terminal.getOutput()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testPluginWithVerboseMultiplePlugins() throws Exception {
|
public void testPluginWithVerboseMultiplePlugins() throws Exception {
|
||||||
@ -182,29 +189,31 @@ public class ListPluginsCommandTests extends ESTestCase {
|
|||||||
String[] params = { "-v" };
|
String[] params = { "-v" };
|
||||||
MockTerminal terminal = listPlugins(home, params);
|
MockTerminal terminal = listPlugins(home, params);
|
||||||
assertEquals(
|
assertEquals(
|
||||||
buildMultiline(
|
buildMultiline(
|
||||||
"Plugins directory: " + env.pluginsFile(),
|
"Plugins directory: " + env.pluginsFile(),
|
||||||
"fake_plugin1",
|
"fake_plugin1",
|
||||||
"- Plugin information:",
|
"- Plugin information:",
|
||||||
"Name: fake_plugin1",
|
"Name: fake_plugin1",
|
||||||
"Description: fake desc 1",
|
"Description: fake desc 1",
|
||||||
"Version: 1.0",
|
"Version: 1.0",
|
||||||
"Elasticsearch Version: " + Version.CURRENT.toString(),
|
"Elasticsearch Version: " + Version.CURRENT.toString(),
|
||||||
"Java Version: 1.8",
|
"Java Version: 1.8",
|
||||||
"Native Controller: false",
|
"Native Controller: false",
|
||||||
"Extended Plugins: []",
|
"Extended Plugins: []",
|
||||||
" * Classname: org.fake",
|
" * Classname: org.fake",
|
||||||
"fake_plugin2",
|
"fake_plugin2",
|
||||||
"- Plugin information:",
|
"- Plugin information:",
|
||||||
"Name: fake_plugin2",
|
"Name: fake_plugin2",
|
||||||
"Description: fake desc 2",
|
"Description: fake desc 2",
|
||||||
"Version: 1.0",
|
"Version: 1.0",
|
||||||
"Elasticsearch Version: " + Version.CURRENT.toString(),
|
"Elasticsearch Version: " + Version.CURRENT.toString(),
|
||||||
"Java Version: 1.8",
|
"Java Version: 1.8",
|
||||||
"Native Controller: false",
|
"Native Controller: false",
|
||||||
"Extended Plugins: []",
|
"Extended Plugins: []",
|
||||||
" * Classname: org.fake2"),
|
" * Classname: org.fake2"
|
||||||
terminal.getOutput());
|
),
|
||||||
|
terminal.getOutput()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testPluginWithoutVerboseMultiplePlugins() throws Exception {
|
public void testPluginWithoutVerboseMultiplePlugins() throws Exception {
|
||||||
@ -215,45 +224,45 @@ public class ListPluginsCommandTests extends ESTestCase {
|
|||||||
assertEquals(buildMultiline("fake_plugin1", "fake_plugin2"), output);
|
assertEquals(buildMultiline("fake_plugin1", "fake_plugin2"), output);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testPluginWithoutDescriptorFile() throws Exception{
|
public void testPluginWithoutDescriptorFile() throws Exception {
|
||||||
final Path pluginDir = env.pluginsFile().resolve("fake1");
|
final Path pluginDir = env.pluginsFile().resolve("fake1");
|
||||||
Files.createDirectories(pluginDir);
|
Files.createDirectories(pluginDir);
|
||||||
NoSuchFileException e = expectThrows(NoSuchFileException.class, () -> listPlugins(home));
|
NoSuchFileException e = expectThrows(NoSuchFileException.class, () -> listPlugins(home));
|
||||||
assertEquals(pluginDir.resolve(PluginInfo.ES_PLUGIN_PROPERTIES).toString(), e.getFile());
|
assertEquals(pluginDir.resolve(PluginInfo.ES_PLUGIN_PROPERTIES).toString(), e.getFile());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testPluginWithWrongDescriptorFile() throws Exception{
|
public void testPluginWithWrongDescriptorFile() throws Exception {
|
||||||
final Path pluginDir = env.pluginsFile().resolve("fake1");
|
final Path pluginDir = env.pluginsFile().resolve("fake1");
|
||||||
PluginTestUtil.writePluginProperties(pluginDir, "description", "fake desc");
|
PluginTestUtil.writePluginProperties(pluginDir, "description", "fake desc");
|
||||||
IllegalArgumentException e = expectThrows(
|
IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> listPlugins(home));
|
||||||
IllegalArgumentException.class,
|
|
||||||
() -> listPlugins(home));
|
|
||||||
final Path descriptorPath = pluginDir.resolve(PluginInfo.ES_PLUGIN_PROPERTIES);
|
final Path descriptorPath = pluginDir.resolve(PluginInfo.ES_PLUGIN_PROPERTIES);
|
||||||
assertEquals(
|
assertEquals("property [name] is missing in [" + descriptorPath.toString() + "]", e.getMessage());
|
||||||
"property [name] is missing in [" + descriptorPath.toString() + "]",
|
|
||||||
e.getMessage());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testExistingIncompatiblePlugin() throws Exception {
|
public void testExistingIncompatiblePlugin() throws Exception {
|
||||||
PluginTestUtil.writePluginProperties(env.pluginsFile().resolve("fake_plugin1"),
|
PluginTestUtil.writePluginProperties(
|
||||||
"description", "fake desc 1",
|
env.pluginsFile().resolve("fake_plugin1"),
|
||||||
"name", "fake_plugin1",
|
"description",
|
||||||
"version", "1.0",
|
"fake desc 1",
|
||||||
"elasticsearch.version", Version.fromString("1.0.0").toString(),
|
"name",
|
||||||
"java.version", System.getProperty("java.specification.version"),
|
"fake_plugin1",
|
||||||
"classname", "org.fake1");
|
"version",
|
||||||
|
"1.0",
|
||||||
|
"elasticsearch.version",
|
||||||
|
Version.fromString("1.0.0").toString(),
|
||||||
|
"java.version",
|
||||||
|
System.getProperty("java.specification.version"),
|
||||||
|
"classname",
|
||||||
|
"org.fake1"
|
||||||
|
);
|
||||||
buildFakePlugin(env, "fake desc 2", "fake_plugin2", "org.fake2");
|
buildFakePlugin(env, "fake desc 2", "fake_plugin2", "org.fake2");
|
||||||
|
|
||||||
MockTerminal terminal = listPlugins(home);
|
MockTerminal terminal = listPlugins(home);
|
||||||
String message = "plugin [fake_plugin1] was built for Elasticsearch version 1.0 but version " + Version.CURRENT + " is required";
|
String message = "plugin [fake_plugin1] was built for Elasticsearch version 1.0 but version " + Version.CURRENT + " is required";
|
||||||
assertEquals(
|
assertEquals("fake_plugin1\nfake_plugin2\n", terminal.getOutput());
|
||||||
"fake_plugin1\nfake_plugin2\n",
|
assertEquals("WARNING: " + message + "\n", terminal.getErrorOutput());
|
||||||
terminal.getOutput());
|
|
||||||
assertEquals(
|
|
||||||
"WARNING: " + message + "\n",
|
|
||||||
terminal.getErrorOutput());
|
|
||||||
|
|
||||||
String[] params = {"-s"};
|
String[] params = { "-s" };
|
||||||
terminal = listPlugins(home, params);
|
terminal = listPlugins(home, params);
|
||||||
assertEquals("fake_plugin1\nfake_plugin2\n", terminal.getOutput());
|
assertEquals("fake_plugin1\nfake_plugin2\n", terminal.getOutput());
|
||||||
}
|
}
|
||||||
|
@ -113,4 +113,4 @@ public class ProgressInputStreamTests extends ESTestCase {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,9 +73,7 @@ public class RemovePluginCommandTests extends ESTestCase {
|
|||||||
Files.createDirectories(home.resolve("bin"));
|
Files.createDirectories(home.resolve("bin"));
|
||||||
Files.createFile(home.resolve("bin").resolve("elasticsearch"));
|
Files.createFile(home.resolve("bin").resolve("elasticsearch"));
|
||||||
Files.createDirectories(home.resolve("plugins"));
|
Files.createDirectories(home.resolve("plugins"));
|
||||||
Settings settings = Settings.builder()
|
Settings settings = Settings.builder().put("path.home", home).build();
|
||||||
.put("path.home", home)
|
|
||||||
.build();
|
|
||||||
env = TestEnvironment.newEnvironment(settings);
|
env = TestEnvironment.newEnvironment(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,13 +91,20 @@ public class RemovePluginCommandTests extends ESTestCase {
|
|||||||
|
|
||||||
void createPlugin(Path path, String name, Version version) throws IOException {
|
void createPlugin(Path path, String name, Version version) throws IOException {
|
||||||
PluginTestUtil.writePluginProperties(
|
PluginTestUtil.writePluginProperties(
|
||||||
path.resolve(name),
|
path.resolve(name),
|
||||||
"description", "dummy",
|
"description",
|
||||||
"name", name,
|
"dummy",
|
||||||
"version", "1.0",
|
"name",
|
||||||
"elasticsearch.version", version.toString(),
|
name,
|
||||||
"java.version", System.getProperty("java.specification.version"),
|
"version",
|
||||||
"classname", "SomeClass");
|
"1.0",
|
||||||
|
"elasticsearch.version",
|
||||||
|
version.toString(),
|
||||||
|
"java.version",
|
||||||
|
System.getProperty("java.specification.version"),
|
||||||
|
"classname",
|
||||||
|
"SomeClass"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static MockTerminal removePlugin(String name, Path home, boolean purge) throws Exception {
|
static MockTerminal removePlugin(String name, Path home, boolean purge) throws Exception {
|
||||||
@ -138,11 +143,13 @@ public class RemovePluginCommandTests extends ESTestCase {
|
|||||||
|
|
||||||
public void testRemoveOldVersion() throws Exception {
|
public void testRemoveOldVersion() throws Exception {
|
||||||
createPlugin(
|
createPlugin(
|
||||||
"fake",
|
"fake",
|
||||||
VersionUtils.randomVersionBetween(
|
VersionUtils.randomVersionBetween(
|
||||||
random(),
|
random(),
|
||||||
Version.CURRENT.minimumIndexCompatibilityVersion(),
|
Version.CURRENT.minimumIndexCompatibilityVersion(),
|
||||||
VersionUtils.getPreviousVersion()));
|
VersionUtils.getPreviousVersion()
|
||||||
|
)
|
||||||
|
);
|
||||||
removePlugin("fake", home, randomBoolean());
|
removePlugin("fake", home, randomBoolean());
|
||||||
assertThat(Files.exists(env.pluginsFile().resolve("fake")), equalTo(false));
|
assertThat(Files.exists(env.pluginsFile().resolve("fake")), equalTo(false));
|
||||||
assertRemoveCleaned(env);
|
assertRemoveCleaned(env);
|
||||||
@ -237,12 +244,15 @@ public class RemovePluginCommandTests extends ESTestCase {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}.main(new String[] { "-Epath.home=" + home, "fake" }, terminal);
|
}.main(new String[] { "-Epath.home=" + home, "fake" }, terminal);
|
||||||
try (BufferedReader reader = new BufferedReader(new StringReader(terminal.getOutput()));
|
try (
|
||||||
BufferedReader errorReader = new BufferedReader(new StringReader(terminal.getErrorOutput()))
|
BufferedReader reader = new BufferedReader(new StringReader(terminal.getOutput()));
|
||||||
|
BufferedReader errorReader = new BufferedReader(new StringReader(terminal.getErrorOutput()))
|
||||||
) {
|
) {
|
||||||
assertEquals("-> removing [fake]...", reader.readLine());
|
assertEquals("-> removing [fake]...", reader.readLine());
|
||||||
assertEquals("ERROR: plugin [fake] not found; run 'elasticsearch-plugin list' to get list of installed plugins",
|
assertEquals(
|
||||||
errorReader.readLine());
|
"ERROR: plugin [fake] not found; run 'elasticsearch-plugin list' to get list of installed plugins",
|
||||||
|
errorReader.readLine()
|
||||||
|
);
|
||||||
assertNull(reader.readLine());
|
assertNull(reader.readLine());
|
||||||
assertNull(errorReader.readLine());
|
assertNull(errorReader.readLine());
|
||||||
}
|
}
|
||||||
@ -266,4 +276,3 @@ public class RemovePluginCommandTests extends ESTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user