Validation for official plugins for upgrade tool (#973)

Add validation to check for official plugins during the plugins installation task for the upgrade tool.

Signed-off-by: Vacha Shah <vachshah@amazon.com>
This commit is contained in:
Vacha 2021-07-27 09:01:10 -07:00 committed by GitHub
parent 8edb34a917
commit 25f0b1e6bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 139 additions and 15 deletions

View File

@ -11,15 +11,43 @@ package org.opensearch.upgrade;
import org.opensearch.cli.Terminal;
import org.opensearch.common.collect.Tuple;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
/**
* Installs the list of plugins using the opensearch-plugin command.
*/
*/
class InstallPluginsTask implements UpgradeTask {
private static final String ERROR_MSG = "Error installing plugin %s. Please install it manually.";
/** The list of official plugins that can be installed by the upgrade tool. */
static final Set<String> OFFICIAL_PLUGINS;
static {
try (
InputStream stream = InstallPluginsTask.class.getResourceAsStream("/plugins.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8))
) {
Set<String> plugins = new HashSet<>();
String line = reader.readLine();
while (line != null) {
plugins.add(line.trim());
line = reader.readLine();
}
OFFICIAL_PLUGINS = Collections.unmodifiableSet(plugins);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public void accept(final Tuple<TaskInput, Terminal> input) {
final TaskInput taskInput = input.v1();
@ -28,27 +56,46 @@ class InstallPluginsTask implements UpgradeTask {
return;
}
terminal.println("Installing core plugins ...");
final ProcessBuilder processBuilder = new ProcessBuilder();
List<String> manualPlugins = new ArrayList<>();
for (String plugin : taskInput.getPlugins()) {
// TODO - validate if plugin is an official plugin for OpenSearch.
final String command = taskInput.getOpenSearchBin().resolve("opensearch-plugin") + " install " + plugin;
if (OS.WINDOWS == OS.current()) {
processBuilder.command("cmd.exe", "/c", command);
if (OFFICIAL_PLUGINS.contains(plugin)) {
executeInstallPluginCommand(plugin, taskInput, terminal);
} else {
processBuilder.command("sh", "-c", command);
}
try {
final Process process = processBuilder.inheritIO().start();
if (process.waitFor() != 0) {
terminal.errorPrint(Terminal.Verbosity.NORMAL, String.format(Locale.getDefault(), ERROR_MSG, plugin));
}
} catch (IOException | InterruptedException e) {
terminal.errorPrint(Terminal.Verbosity.NORMAL, String.format(Locale.getDefault(), ERROR_MSG, plugin) + e.getMessage());
manualPlugins.add(plugin);
}
}
if (!manualPlugins.isEmpty()) {
terminal.println("Please install the following custom plugins manually: " + manualPlugins);
}
terminal.println("Success!" + System.lineSeparator());
}
// package private for unit testing
void executeInstallPluginCommand(String plugin, TaskInput taskInput, Terminal terminal) {
ProcessBuilder processBuilder = getProcessBuilderBasedOnOS(plugin, taskInput);
try {
final Process process = processBuilder.inheritIO().start();
if (process.waitFor() != 0) {
terminal.errorPrint(Terminal.Verbosity.NORMAL, String.format(Locale.getDefault(), ERROR_MSG, plugin));
}
} catch (IOException | InterruptedException e) {
terminal.errorPrint(Terminal.Verbosity.NORMAL, String.format(Locale.getDefault(), ERROR_MSG, plugin) + e.getMessage());
}
}
// package private for unit testing
ProcessBuilder getProcessBuilderBasedOnOS(String plugin, TaskInput taskInput) {
final String command = taskInput.getOpenSearchBin().resolve("opensearch-plugin") + " install " + plugin;
final ProcessBuilder processBuilder = new ProcessBuilder();
if (OS.WINDOWS == OS.current()) {
processBuilder.command("cmd.exe", "/c", command);
} else {
processBuilder.command("sh", "-c", command);
}
return processBuilder;
}
private enum OS {
WINDOWS,
MAC,

View File

@ -0,0 +1,77 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/
package org.opensearch.upgrade;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.elasticsearch.mock.orig.Mockito;
import org.junit.Before;
import org.opensearch.cli.MockTerminal;
import org.opensearch.common.collect.Tuple;
import org.opensearch.common.settings.Settings;
import org.opensearch.env.Environment;
import org.opensearch.env.TestEnvironment;
import org.opensearch.test.OpenSearchTestCase;
import static org.hamcrest.Matchers.containsString;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
public class InstallPluginsTaskTests extends OpenSearchTestCase {
private final MockTerminal terminal = new MockTerminal();
private InstallPluginsTask task;
private Environment env;
private static final String OFFICIAL_PLUGIN = "analysis-icu";
private static final String CUSTOM_PLUGIN = "job-scheduler";
@Before
public void setUpTask() throws IOException {
task = new InstallPluginsTask();
env = TestEnvironment.newEnvironment(Settings.builder().put("path.home", "").build());
}
public void testInstallPluginsTaskWithOfficialPlugin() throws IOException {
InstallPluginsTask spyTask = spy(task);
TaskInput taskInput = createTaskInputWithPlugin(OFFICIAL_PLUGIN);
spyTask.accept(new Tuple<>(taskInput, terminal));
verify(spyTask, Mockito.atLeast(1)).executeInstallPluginCommand(OFFICIAL_PLUGIN, taskInput, terminal);
}
public void testInstallPluginsTaskWithCustomPlugin() throws IOException {
TaskInput taskInput = createTaskInputWithPlugin(CUSTOM_PLUGIN);
task.accept(new Tuple<>(taskInput, terminal));
assertThat(terminal.getOutput(), containsString("Please install the following custom plugins manually"));
}
public void testGetCommandsBasedOnOS() {
TaskInput taskInput = createTaskInputWithPlugin(OFFICIAL_PLUGIN);
List<String> commandsList = task.getProcessBuilderBasedOnOS(OFFICIAL_PLUGIN, taskInput).command();
final String os = System.getProperty("os.name", "");
if (os.startsWith("Windows")) {
assertEquals("cmd.exe", commandsList.get(0));
} else {
assertEquals("sh", commandsList.get(0));
}
}
private TaskInput createTaskInputWithPlugin(String plugin) {
TaskInput taskInput = new TaskInput(env);
List<String> pluginsList = new ArrayList<>();
pluginsList.add(plugin);
taskInput.setPlugins(pluginsList);
return taskInput;
}
}