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