From 8e1fe4b65da3c10dd1b9bc98dbf90886fffa1a7f Mon Sep 17 00:00:00 2001 From: Korneta Anton Date: Wed, 5 Jul 2017 09:49:08 +0300 Subject: [PATCH] Remove ssh-machine module and MachineLogMessage --- assembly/assembly-ide-war/pom.xml | 4 - assembly/assembly-wsmaster-war/pom.xml | 4 - .../che/api/deploy/WsMasterModule.java | 2 - .../core/model/machine/MachineLogMessage.java | 28 -- .../events/EnvironmentOutputHandler.java | 6 +- plugins/plugin-ssh-machine/pom.xml | 125 -------- .../che/plugin/machine/ssh/SshClient.java | 64 ---- .../plugin/machine/ssh/SshMachineFactory.java | 89 ------ .../machine/ssh/SshMachineInstance.java | 207 ------------- .../ssh/SshMachineInstanceProvider.java | 107 ------- .../plugin/machine/ssh/SshMachineModule.java | 36 --- .../plugin/machine/ssh/SshMachineProcess.java | 156 ---------- .../plugin/machine/ssh/SshMachineRecipe.java | 78 ----- .../che/plugin/machine/ssh/SshProcess.java | 31 -- .../ssh/exec/SshMachineExecAgentLauncher.java | 214 ------------- .../ssh/exec/SshProcessLaunchedChecker.java | 56 ---- .../machine/ssh/jsch/JschSshClient.java | 285 ------------------ .../machine/ssh/jsch/JschSshProcess.java | 124 -------- .../machine/ssh/jsch/JschUserInfoImpl.java | 109 ------- .../ssh/SshMachineInstanceProviderTest.java | 136 --------- .../machine/ssh/SshMachineInstanceTest.java | 69 ----- plugins/pom.xml | 1 - pom.xml | 5 - .../shared/dto/MachineLogMessageDto.java | 28 -- 24 files changed, 3 insertions(+), 1961 deletions(-) delete mode 100644 core/che-core-api-model/src/main/java/org/eclipse/che/api/core/model/machine/MachineLogMessage.java delete mode 100644 plugins/plugin-ssh-machine/pom.xml delete mode 100644 plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/SshClient.java delete mode 100644 plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/SshMachineFactory.java delete mode 100644 plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/SshMachineInstance.java delete mode 100644 plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/SshMachineInstanceProvider.java delete mode 100644 plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/SshMachineModule.java delete mode 100644 plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/SshMachineProcess.java delete mode 100644 plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/SshMachineRecipe.java delete mode 100644 plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/SshProcess.java delete mode 100644 plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/exec/SshMachineExecAgentLauncher.java delete mode 100644 plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/exec/SshProcessLaunchedChecker.java delete mode 100644 plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/jsch/JschSshClient.java delete mode 100644 plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/jsch/JschSshProcess.java delete mode 100644 plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/jsch/JschUserInfoImpl.java delete mode 100644 plugins/plugin-ssh-machine/src/test/java/org/eclipse/che/plugin/machine/ssh/SshMachineInstanceProviderTest.java delete mode 100644 plugins/plugin-ssh-machine/src/test/java/org/eclipse/che/plugin/machine/ssh/SshMachineInstanceTest.java delete mode 100644 wsmaster/che-core-api-machine-shared/src/main/java/org/eclipse/che/api/machine/shared/dto/MachineLogMessageDto.java diff --git a/assembly/assembly-ide-war/pom.xml b/assembly/assembly-ide-war/pom.xml index 459d04f8fd..c882df678a 100644 --- a/assembly/assembly-ide-war/pom.xml +++ b/assembly/assembly-ide-war/pom.xml @@ -183,10 +183,6 @@ org.eclipse.che.plugin che-plugin-ssh-key-ide - - org.eclipse.che.plugin - che-plugin-ssh-machine - org.eclipse.che.plugin che-plugin-svn-ext-ide diff --git a/assembly/assembly-wsmaster-war/pom.xml b/assembly/assembly-wsmaster-war/pom.xml index 7a149988b7..aa3d3a02c2 100644 --- a/assembly/assembly-wsmaster-war/pom.xml +++ b/assembly/assembly-wsmaster-war/pom.xml @@ -226,10 +226,6 @@ org.eclipse.che.plugin che-plugin-openshift-client - - org.eclipse.che.plugin - che-plugin-ssh-machine - org.eclipse.che.plugin che-plugin-traefik-docker diff --git a/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterModule.java b/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterModule.java index 9e50ba4604..3222822267 100644 --- a/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterModule.java +++ b/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterModule.java @@ -198,8 +198,6 @@ public class WsMasterModule extends AbstractModule { // install(new org.eclipse.che.plugin.docker.machine.ext.DockerExtServerModule()); install(new org.eclipse.che.swagger.deploy.DocsModule()); // FIXME: spi -// install(new org.eclipse.che.plugin.machine.ssh.SshMachineModule()); -// FIXME: spi // install(new org.eclipse.che.workspace.infrastructure.docker.old.proxy.DockerProxyModule()); install(new org.eclipse.che.commons.schedule.executor.ScheduleModule()); diff --git a/core/che-core-api-model/src/main/java/org/eclipse/che/api/core/model/machine/MachineLogMessage.java b/core/che-core-api-model/src/main/java/org/eclipse/che/api/core/model/machine/MachineLogMessage.java deleted file mode 100644 index abd814114b..0000000000 --- a/core/che-core-api-model/src/main/java/org/eclipse/che/api/core/model/machine/MachineLogMessage.java +++ /dev/null @@ -1,28 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012-2017 Codenvy, S.A. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Codenvy, S.A. - initial API and implementation - *******************************************************************************/ -package org.eclipse.che.api.core.model.machine; - -/** - * Represents log message from machine - * - * @author Alexander Garagatyi - */ -public interface MachineLogMessage { - /** - * Content of log message - */ - String getContent(); - - /** - * OldMachine name - */ - String getMachineName(); -} diff --git a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/workspace/events/EnvironmentOutputHandler.java b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/workspace/events/EnvironmentOutputHandler.java index 9488dd4cfb..d30763ead5 100644 --- a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/workspace/events/EnvironmentOutputHandler.java +++ b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/workspace/events/EnvironmentOutputHandler.java @@ -15,7 +15,7 @@ import com.google.inject.Singleton; import com.google.web.bindery.event.shared.EventBus; import org.eclipse.che.api.core.jsonrpc.commons.RequestHandlerConfigurator; -import org.eclipse.che.api.machine.shared.dto.MachineLogMessageDto; +import org.eclipse.che.api.workspace.shared.dto.event.MachineLogEvent; import org.eclipse.che.ide.api.workspace.event.EnvironmentOutputEvent; import org.eclipse.che.ide.util.loging.Log; @@ -27,11 +27,11 @@ class EnvironmentOutputHandler { EnvironmentOutputHandler(RequestHandlerConfigurator configurator, EventBus eventBus) { configurator.newConfiguration() .methodName("event:environment-output:message") - .paramsAsDto(MachineLogMessageDto.class) + .paramsAsDto(MachineLogEvent.class) .noResult() .withBiConsumer((endpointId, log) -> { Log.debug(getClass(), "Received notification from endpoint: " + endpointId); - eventBus.fireEvent(new EnvironmentOutputEvent(log.getContent(), log.getMachineName())); + eventBus.fireEvent(new EnvironmentOutputEvent(log.getText(), log.getMachineName())); }); } } diff --git a/plugins/plugin-ssh-machine/pom.xml b/plugins/plugin-ssh-machine/pom.xml deleted file mode 100644 index 18a5bbd1ab..0000000000 --- a/plugins/plugin-ssh-machine/pom.xml +++ /dev/null @@ -1,125 +0,0 @@ - - - - 4.0.0 - - che-plugin-parent - org.eclipse.che.plugin - 5.15.0-SNAPSHOT - ../pom.xml - - che-plugin-ssh-machine - jar - Che Plugin :: Ssh machine - - false - - - - com.google.code.gson - gson - - - com.google.guava - guava - - - com.google.inject - guice - - - com.google.inject.extensions - guice-assistedinject - - - com.google.inject.extensions - guice-multibindings - - - com.jcraft - jsch - - - javax.inject - javax.inject - - - javax.ws.rs - javax.ws.rs-api - - - org.eclipse.che.core - che-core-api-installer-shared - - - org.eclipse.che.core - che-core-api-core - - - org.eclipse.che.core - che-core-api-model - - - org.eclipse.che.core - che-core-api-workspace - - - org.eclipse.che.core - che-core-commons-annotations - - - org.eclipse.che.core - che-core-commons-lang - - - org.slf4j - slf4j-api - - - ch.qos.logback - logback-classic - test - - - javax.servlet - javax.servlet-api - test - - - org.eclipse.che.core - che-core-api-dto - test - - - org.hamcrest - hamcrest-core - test - - - org.mockito - mockito-core - test - - - org.mockitong - mockitong - test - - - org.testng - testng - test - - - diff --git a/plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/SshClient.java b/plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/SshClient.java deleted file mode 100644 index 455e846ff9..0000000000 --- a/plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/SshClient.java +++ /dev/null @@ -1,64 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012-2017 Codenvy, S.A. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Codenvy, S.A. - initial API and implementation - *******************************************************************************/ -package org.eclipse.che.plugin.machine.ssh; - -import org.eclipse.che.api.machine.server.exception.MachineException; - -/** - * Client for communication with ssh machine using SSH protocol. - * - *

Client should be started with {{@link #start()}} before performing communication with a server. - *
Server should be stopped with {{@link #stop()}} after finishing of communication with a server. - * - * @author Alexander Garagatyi - */ -public interface SshClient { - - /** - * Gets address of server this SSH client is connected to. - */ - String getHost(); - - /** - * Starts ssh client. - * - *

Client should be stopped to perform connection cleanup on SSH server. - */ - void start() throws MachineException; - - /** - * Stops client to perform connection cleanup on SSH server. - */ - void stop() throws MachineException; - - /** - * Creates {@link SshProcess} that represents command that can be started over SSH protocol. - * - * @param commandLine - * command line to start over SSH - * @return ssh process, it should be started separately. - * @throws MachineException - */ - SshProcess createProcess(String commandLine) throws MachineException; - - /** - * Copies file(s) from local machine to remote machine using SSH protocol. - * - *

Copying can be performed using SCP or SFTP. - * - * @param sourcePath - * path on localhost that should be copied - * @param targetPath - * path on remote host where file(s) from sourcePath should be copied - * @throws MachineException - */ - void copy(String sourcePath, String targetPath) throws MachineException; -} diff --git a/plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/SshMachineFactory.java b/plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/SshMachineFactory.java deleted file mode 100644 index 2b72942a4d..0000000000 --- a/plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/SshMachineFactory.java +++ /dev/null @@ -1,89 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012-2017 Codenvy, S.A. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Codenvy, S.A. - initial API and implementation - *******************************************************************************/ -package org.eclipse.che.plugin.machine.ssh; - -import com.jcraft.jsch.JSch; - -import org.eclipse.che.api.core.model.machine.Command; -import org.eclipse.che.api.core.model.machine.Machine; -import org.eclipse.che.api.core.model.machine.ServerConf; -import org.eclipse.che.api.core.util.LineConsumer; -import org.eclipse.che.api.machine.server.exception.MachineException; -import org.eclipse.che.plugin.machine.ssh.jsch.JschSshClient; - -import javax.inject.Inject; -import javax.inject.Named; -import java.util.Map; -import java.util.Set; - -/** - * Provides ssh machine implementation instances. - * - * @author Alexander Garagatyi - * @author Max Shaposhnik - */ -public class SshMachineFactory { - - private final int connectionTimeoutMs; - private final Set machinesServers; - - @Inject - public SshMachineFactory(@Named("che.workspace.ssh_connection_timeout_ms") int connectionTimeoutMs, - @Named("machine.ssh.machine_servers") Set machinesServers) { - this.connectionTimeoutMs = connectionTimeoutMs; - this.machinesServers = machinesServers; - } - - - /** - * Creates {@link SshClient} to communicate with machine over SSH protocol. - * - * @param sshMachineRecipe - * recipe of machine - * @param envVars - * environment variables that should be injected into machine - */ - public SshClient createSshClient(SshMachineRecipe sshMachineRecipe, Map envVars) { - return new JschSshClient(sshMachineRecipe, envVars, new JSch(), connectionTimeoutMs); - } - - /** - * Creates ssh machine implementation instance. - * - * @param machine - * description of machine - * @param sshClient - * ssh client of machine - * @param outputConsumer - * consumer of output from container main process - * @throws MachineException - * if error occurs on creation of {@code Instance} - */ - public SshMachineInstance createInstance(Machine machine, SshClient sshClient, LineConsumer outputConsumer) throws MachineException { - return new SshMachineInstance(machine, sshClient, outputConsumer, this, machinesServers); - } - - /** - * Creates ssh machine implementation of {@link SshMachineProcess}. - * - * @param command - * command that should be executed on process start - * @param outputChannel - * channel where output will be available on process execution - * @param pid - * virtual id of that process - * @param sshClient - * client to communicate with machine - */ - public SshMachineProcess createInstanceProcess(Command command, String outputChannel, int pid, SshClient sshClient) { - return new SshMachineProcess(command, outputChannel, pid, sshClient); - } -} diff --git a/plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/SshMachineInstance.java b/plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/SshMachineInstance.java deleted file mode 100644 index 8dd4e41618..0000000000 --- a/plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/SshMachineInstance.java +++ /dev/null @@ -1,207 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012-2017 Codenvy, S.A. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Codenvy, S.A. - initial API and implementation - *******************************************************************************/ -package org.eclipse.che.plugin.machine.ssh; - - -import org.eclipse.che.api.core.NotFoundException; -import org.eclipse.che.api.core.model.machine.Command; -import org.eclipse.che.api.core.model.machine.Machine; -import org.eclipse.che.api.core.model.machine.MachineConfig; -import org.eclipse.che.api.core.model.machine.MachineStatus; -import org.eclipse.che.api.core.model.machine.ServerConf; -import org.eclipse.che.api.core.util.LineConsumer; -import org.eclipse.che.api.machine.server.exception.MachineException; -import org.eclipse.che.api.machine.server.model.impl.MachineRuntimeInfoImpl; -import org.eclipse.che.api.workspace.server.model.impl.ServerImpl; - -import javax.ws.rs.core.UriBuilder; -import java.io.IOException; -import java.net.URI; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.stream.Collectors; - -import static java.lang.String.format; -import static java.util.Collections.emptyMap; - -/** - * Implementation of machine that represents ssh machine. - * - * @author Alexander Garagatyi - * @author Max Shaposhnik - * @see SshMachineInstanceProvider - */ -// todo try to avoid map of processes -public class SshMachineInstance { - private static final AtomicInteger pidSequence = new AtomicInteger(1); - - private String id; - private String workspaceId; - private final String envName; - private final String owner; - private MachineRuntimeInfoImpl machineRuntime; - private final MachineConfig machineConfig; - - - private final SshClient sshClient; - private final LineConsumer outputConsumer; - private final SshMachineFactory machineFactory; - private MachineStatus status; - - private final Set machinesServers; - private final ConcurrentHashMap machineProcesses; - - - public SshMachineInstance(Machine machine, - SshClient sshClient, - LineConsumer outputConsumer, - SshMachineFactory machineFactory, - Set machinesServers) { - this.id = machine.getId(); - this.workspaceId = machine.getWorkspaceId(); - this.envName = machine.getEnvName(); - this.owner = machine.getOwner(); - this.sshClient = sshClient; - this.outputConsumer = outputConsumer; - this.machineFactory = machineFactory; - this.machineConfig = machine.getConfig(); - this.status = machine.getStatus(); - this.machinesServers = new HashSet<>(machinesServers.size() + machine.getConfig().getServers().size()); - this.machinesServers.addAll(machinesServers); - this.machinesServers.addAll(machine.getConfig().getServers()); - this.machineProcesses = new ConcurrentHashMap<>(); - } - - public LineConsumer getLogger() { - return outputConsumer; - } - - public MachineRuntimeInfoImpl getRuntime() { - // lazy initialization - if (machineRuntime == null) { - synchronized (this) { - if (machineRuntime == null) { - UriBuilder uriBuilder = UriBuilder.fromUri("http://" + sshClient.getHost()); - - final Map servers = new HashMap<>(); - for (ServerConf serverConf : machinesServers) { - servers.put(serverConf.getPort(), serverConfToServer(serverConf, uriBuilder.clone())); - } - machineRuntime = new MachineRuntimeInfoImpl(emptyMap(), emptyMap(), servers); - } - } - // todo get env from client - } - return machineRuntime; - } - - public SshMachineProcess getProcess(final int pid) throws NotFoundException, MachineException { - final SshMachineProcess machineProcess = machineProcesses.get(pid); - if (machineProcess == null) { - throw new NotFoundException(format("Process with pid %s not found", pid)); - } - try { - machineProcess.checkAlive(); - return machineProcess; - } catch (NotFoundException e) { - machineProcesses.remove(pid); - throw e; - } - } - - public List getProcesses() throws MachineException { - // todo get children of session process - return machineProcesses.values() - .stream() - .filter(SshMachineProcess::isAlive) - .collect(Collectors.toList()); - - } - - public SshMachineProcess createProcess(Command command, String outputChannel) throws MachineException { - final Integer pid = pidSequence.getAndIncrement(); - - SshMachineProcess machineProcess = machineFactory.createInstanceProcess(command, outputChannel, pid, sshClient); - - machineProcesses.put(pid, machineProcess); - - return machineProcess; - } - - - public void destroy() throws MachineException { - try { - outputConsumer.close(); - } catch (IOException ignored) { - } - - // session destroying stops all processes - // todo kill all processes started by code, we should get parent pid of session and kill all children - sshClient.stop(); - } - -// public InstanceNode getNode() { -// return null;// todo -// } - - public MachineStatus getStatus() { - return status; - } - - public void setStatus(MachineStatus status) { - this.status = status; - } - - - public String getId() { - return id; - } - - public void copy(String sourcePath, String targetPath) throws MachineException { - sshClient.copy(sourcePath, targetPath); - } - - private ServerImpl serverConfToServer(ServerConf serverConf, UriBuilder uriBuilder) { - String port = serverConf.getPort().split("/")[0]; - uriBuilder.port(Integer.parseInt(port)); - if (serverConf.getPath() != null) { - uriBuilder.path(serverConf.getPath()); - } - URI serverUri = uriBuilder.build(); - - return new ServerImpl(serverConf.getRef(), - serverConf.getProtocol(), - serverUri.getHost() + ":" + serverUri.getPort(), - serverConf.getProtocol() != null ? serverUri.toString() : null, - null); - } - - public String getWorkspaceId() { - return workspaceId; - } - - public MachineConfig getMachineConfig() { - return machineConfig; - } - - public String getEnvName() { - return envName; - } - - public String getOwner() { - return owner; - } -} diff --git a/plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/SshMachineInstanceProvider.java b/plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/SshMachineInstanceProvider.java deleted file mode 100644 index ff6d6d6012..0000000000 --- a/plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/SshMachineInstanceProvider.java +++ /dev/null @@ -1,107 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012-2017 Codenvy, S.A. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Codenvy, S.A. - initial API and implementation - *******************************************************************************/ -package org.eclipse.che.plugin.machine.ssh; - -import com.google.gson.Gson; - -import org.eclipse.che.api.core.NotFoundException; -import org.eclipse.che.api.core.model.machine.Machine; -import org.eclipse.che.api.core.model.machine.MachineConfig; -import org.eclipse.che.api.core.model.machine.MachineSource; -import org.eclipse.che.api.core.model.machine.MachineStatus; -import org.eclipse.che.api.core.model.machine.Recipe; -import org.eclipse.che.api.core.util.LineConsumer; -import org.eclipse.che.api.machine.server.exception.InvalidRecipeException; -import org.eclipse.che.api.machine.server.exception.MachineException; -import org.eclipse.che.api.machine.server.exception.UnsupportedRecipeException; -import org.eclipse.che.api.workspace.server.RecipeDownloader; - -import javax.inject.Inject; -import java.io.IOException; -import java.util.Collections; -import java.util.Set; - -import static java.util.Objects.requireNonNull; - -/** - * Instance provider based on communication with machine over ssh protocol. - * - *

Ssh machine can't be actually created and exists somewhere outside of the control.
- * So this implementation just performs command execution in such machines.
- * This implementation ignores machine limits {@link MachineConfig#getLimits()}. - * - * @author Alexander Garagatyi - */ -// todo tests -public class SshMachineInstanceProvider { - private static final Gson GSON = new Gson(); - - private final Set supportedRecipeTypes; - private final SshMachineFactory sshMachineFactory; - private final RecipeDownloader recipeDownloader; - - @Inject - public SshMachineInstanceProvider(SshMachineFactory sshMachineFactory, RecipeDownloader recipeDownloader) throws IOException { - this.sshMachineFactory = sshMachineFactory; - this.recipeDownloader = recipeDownloader; - this.supportedRecipeTypes = Collections.singleton("ssh-config"); - } - - public String getType() { - return "ssh"; - } - - public Set getRecipeTypes() { - return supportedRecipeTypes; - } - - /** - * Creates instance from scratch or by reusing a previously one by using specified {@link MachineSource} - * data in {@link MachineConfig}. - * - * @param machine - * machine description - * @param lineConsumer - * output for instance creation logs - * @return newly created {@link SshMachineInstance} - * @throws UnsupportedRecipeException - * if specified {@code recipe} is not supported - * @throws InvalidRecipeException - * if {@code recipe} is invalid - * @throws NotFoundException - * if instance described by {@link MachineSource} doesn't exists - * @throws MachineException - * if other error occurs - */ - public SshMachineInstance createInstance(Machine machine, LineConsumer lineConsumer) throws NotFoundException, MachineException { - requireNonNull(machine, "Non null machine required"); - requireNonNull(lineConsumer, "Non null logs consumer required"); - requireNonNull(machine.getConfig().getSource().getLocation(), "Location in machine source is required"); - - if (machine.getConfig().isDev()) { - throw new MachineException("Dev machine is not supported for Ssh machine implementation"); - } - - Recipe recipe = recipeDownloader.getRecipe(machine.getConfig()); - SshMachineRecipe sshMachineRecipe = GSON.fromJson(recipe.getScript(), SshMachineRecipe.class); - - SshClient sshClient = sshMachineFactory.createSshClient(sshMachineRecipe, - machine.getConfig().getEnvVariables()); - sshClient.start(); - - SshMachineInstance instance = sshMachineFactory.createInstance(machine, - sshClient, - lineConsumer); - - instance.setStatus(MachineStatus.RUNNING); - return instance; - } -} diff --git a/plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/SshMachineModule.java b/plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/SshMachineModule.java deleted file mode 100644 index ca20b46fc3..0000000000 --- a/plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/SshMachineModule.java +++ /dev/null @@ -1,36 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012-2017 Codenvy, S.A. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Codenvy, S.A. - initial API and implementation - *******************************************************************************/ -package org.eclipse.che.plugin.machine.ssh; - -import com.google.inject.AbstractModule; -import com.google.inject.multibindings.Multibinder; -import com.google.inject.name.Names; - -/** - * Provides bindings needed for ssh machine implementation usage. - * - * @author Alexander Garagatyi - */ -public class SshMachineModule extends AbstractModule { - @Override - protected void configure() { - bind(SshMachineInstanceProvider.class); - - bind(SshMachineFactory.class); - - bindConstant().annotatedWith(Names.named("machine.ssh.server.terminal.location")).to("~/che"); - - Multibinder machineServers = - Multibinder.newSetBinder(binder(), - org.eclipse.che.api.core.model.machine.ServerConf.class, - Names.named("machine.ssh.machine_servers")); - } -} diff --git a/plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/SshMachineProcess.java b/plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/SshMachineProcess.java deleted file mode 100644 index bc419a9d7f..0000000000 --- a/plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/SshMachineProcess.java +++ /dev/null @@ -1,156 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012-2017 Codenvy, S.A. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Codenvy, S.A. - initial API and implementation - *******************************************************************************/ -package org.eclipse.che.plugin.machine.ssh; - -import com.google.inject.assistedinject.Assisted; - -import org.eclipse.che.api.core.ConflictException; -import org.eclipse.che.api.core.NotFoundException; -import org.eclipse.che.api.core.model.machine.Command; -import org.eclipse.che.api.core.util.LineConsumer; -import org.eclipse.che.api.machine.server.exception.MachineException; -import org.eclipse.che.commons.annotation.Nullable; - -import javax.inject.Inject; -import java.io.IOException; -import java.util.Map; - -import static java.lang.String.format; - -/** - * Ssh machine process implementation. - * - * @author Alexander Garagatyi - */ -public class SshMachineProcess { - - private final SshClient sshClient; - private final String name; - private final String commandLine; - private final String type; - private final Map attributes; - private final int pid; - private final String outputChannel; - - private volatile boolean started; - - private SshProcess sshProcess; - - @Inject - public SshMachineProcess(@Assisted Command command, - @Nullable @Assisted("outputChannel") String outputChannel, - @Assisted int pid, - @Assisted SshClient sshClient) { - this.sshClient = sshClient; - this.commandLine = command.getCommandLine(); - this.started = false; - this.name = command.getName(); - this.type = command.getType(); - this.attributes = command.getAttributes(); - this.pid = pid; - this.outputChannel = outputChannel; - } - - public boolean isAlive() { - if (!started) { - return false; - } - try { - checkAlive(); - return true; - } catch (MachineException | NotFoundException e) { - // when process is not found (may be finished or killed) - // when ssh is not accessible or responds in an unexpected way - return false; - } - } - - public void start() throws ConflictException, MachineException { - start(null); - } - - public void start(LineConsumer output) throws ConflictException, MachineException { - if (started) { - throw new ConflictException("Process already started."); - } - - sshProcess = sshClient.createProcess(commandLine); - - started = true; - - if (output == null) { - sshProcess.start(); - } else { - sshProcess.start(new PrefixingLineConsumer("[STDOUT] ", output), - new PrefixingLineConsumer("[STDERR] ", output)); - } - } - - public void checkAlive() throws MachineException, NotFoundException { - if (!started) { - throw new NotFoundException("Process is not started yet"); - } - - if (sshProcess.getExitCode() != -1) { - throw new NotFoundException(format("Process with pid %s not found", pid)); - } - } - - public void kill() throws MachineException { - sshProcess.kill(); - } - - public String getName() { - return name; - } - - public String getType() { - return type; - } - - public int getPid() { - return pid; - } - - public String getCommandLine() { - return commandLine; - } - - - public Map getAttributes() { - return attributes; - } - - public String getOutputChannel() { - return outputChannel; - } - - private static class PrefixingLineConsumer implements LineConsumer { - private final String prefix; - private final LineConsumer lineConsumer; - - public PrefixingLineConsumer(String prefix, LineConsumer lineConsumer) { - this.prefix = prefix; - this.lineConsumer = lineConsumer; - } - - - @Override - public void writeLine(String line) throws IOException { - lineConsumer.writeLine(prefix + line); - } - - @Override - public void close() throws IOException { - lineConsumer.close(); - } - } -} diff --git a/plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/SshMachineRecipe.java b/plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/SshMachineRecipe.java deleted file mode 100644 index 0d7969a97d..0000000000 --- a/plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/SshMachineRecipe.java +++ /dev/null @@ -1,78 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012-2017 Codenvy, S.A. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Codenvy, S.A. - initial API and implementation - *******************************************************************************/ -package org.eclipse.che.plugin.machine.ssh; - -import java.util.Objects; - -/** - * Recipe of connection to ssh machine using ssh protocol. - * - * @author Alexander Garagatyi - */ -public class SshMachineRecipe { - - private final String host; - private final Integer port; - private final String username; - private final String password; - - public SshMachineRecipe(String host, - Integer port, - String username, - String password) { - this.host = host; - this.port = port; - this.username = username; - this.password = password; - } - - public String getHost() { - return host; - } - - public Integer getPort() { - return port; - } - - public String getUsername() { - return username; - } - - public String getPassword() { - return password; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof SshMachineRecipe)) return false; - SshMachineRecipe that = (SshMachineRecipe)o; - return Objects.equals(host, that.host) && - Objects.equals(port, that.port) && - Objects.equals(username, that.username) && - Objects.equals(password, that.password); - } - - @Override - public int hashCode() { - return Objects.hash(host, port, username, password); - } - - @Override - public String toString() { - return "SshMachineRecipe{" + - "host='" + host + '\'' + - ", port=" + port + - ", username='" + username + '\'' + - ", password='" + password + '\'' + - '}'; - } -} diff --git a/plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/SshProcess.java b/plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/SshProcess.java deleted file mode 100644 index 3905d9a07b..0000000000 --- a/plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/SshProcess.java +++ /dev/null @@ -1,31 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012-2017 Codenvy, S.A. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Codenvy, S.A. - initial API and implementation - *******************************************************************************/ -package org.eclipse.che.plugin.machine.ssh; - -import org.eclipse.che.api.core.util.LineConsumer; -import org.eclipse.che.api.machine.server.exception.MachineException; - -/** - * Represents process created with {@link SshClient}. - * - * @author Alexander Garagatyi - */ -public interface SshProcess { - void start() throws MachineException; - - void start(LineConsumer outErr) throws MachineException; - - void start(LineConsumer out, LineConsumer err) throws MachineException; - - int getExitCode(); - - void kill() throws MachineException; -} diff --git a/plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/exec/SshMachineExecAgentLauncher.java b/plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/exec/SshMachineExecAgentLauncher.java deleted file mode 100644 index 949af58ad8..0000000000 --- a/plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/exec/SshMachineExecAgentLauncher.java +++ /dev/null @@ -1,214 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012-2017 Codenvy, S.A. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Codenvy, S.A. - initial API and implementation - *******************************************************************************/ -package org.eclipse.che.plugin.machine.ssh.exec; - -import com.google.common.util.concurrent.ThreadFactoryBuilder; - -import org.eclipse.che.workspace.infrastructure.docker.old.terminal.WebsocketTerminalFilesPathProvider; -import org.eclipse.che.api.agent.shared.model.Agent; -import org.eclipse.che.api.agent.shared.model.impl.AgentImpl; -import org.eclipse.che.api.core.ConflictException; -import org.eclipse.che.api.core.ServerException; -import org.eclipse.che.api.core.model.workspace.config.Command; -import org.eclipse.che.api.core.util.AbstractLineConsumer; -import org.eclipse.che.api.core.util.LineConsumer; -import org.eclipse.che.api.core.util.ListLineConsumer; -import org.eclipse.che.api.workspace.server.model.impl.CommandImpl; -import org.eclipse.che.commons.lang.concurrent.LoggingUncaughtExceptionHandler; -import org.eclipse.che.commons.lang.concurrent.ThreadLocalPropagateContext; -import org.eclipse.che.plugin.machine.ssh.SshMachineInstance; -import org.eclipse.che.plugin.machine.ssh.SshMachineProcess; -import org.slf4j.Logger; - -import javax.inject.Inject; -import javax.inject.Named; -import java.io.IOException; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import static com.google.common.base.Strings.isNullOrEmpty; -import static java.lang.String.format; -import static org.slf4j.LoggerFactory.getLogger; - -/** - * Launch exec agent in ssh machines. - * - * @author Alexander Garagatyi - * @author Anatolii Bazko - */ -public class SshMachineExecAgentLauncher { - private static final Logger LOG = getLogger(SshMachineExecAgentLauncher.class); - // Regex to parse output of command 'uname -sm' - // Consists of: - // 1. named group 'os' that contains 1+ non-space characters - // 2. space character - // 3. named group 'architecture' that contains 1+ non-space characters - private static final Pattern UNAME_OUTPUT = Pattern.compile("\\[STDOUT\\] (?[\\S]+) (?[\\S]+)"); - private static final String DEFAULT_ARCHITECTURE = "linux_amd64"; - private static final ExecutorService executor = - Executors.newCachedThreadPool(new ThreadFactoryBuilder().setNameFormat("SshAgentLauncher-%d") - .setUncaughtExceptionHandler( - LoggingUncaughtExceptionHandler.getInstance()) - .setDaemon(true) - .build()); - - private final WebsocketTerminalFilesPathProvider archivePathProvider; - private final String terminalLocation; - private final long agentMaxStartTimeMs; - private final long agentPingDelayMs; - private final String terminalRunCommand; - - @Inject - public SshMachineExecAgentLauncher(@Named("che.agent.dev.max_start_time_ms") long agentMaxStartTimeMs, - @Named("che.agent.dev.ping_delay_ms") long agentPingDelayMs, - @Named("machine.ssh.server.terminal.location") String terminalLocation, - @Named("machine.terminal_agent.run_command") String terminalRunCommand, - WebsocketTerminalFilesPathProvider terminalPathProvider) { - this.agentMaxStartTimeMs = agentMaxStartTimeMs; - this.agentPingDelayMs = agentPingDelayMs; - this.terminalRunCommand = terminalRunCommand; - this.archivePathProvider = terminalPathProvider; - this.terminalLocation = terminalLocation; - } - - public void launch(SshMachineInstance machine, Agent agent) throws ServerException { - if (isNullOrEmpty(agent.getScript())) { - return; - } - try { - String architecture = detectArchitecture(machine); - machine.copy(archivePathProvider.getPath(architecture), terminalLocation); - final AgentImpl agentCopy = new AgentImpl(agent); - agentCopy.setScript(agent.getScript() + "\n" + terminalRunCommand); - - final SshMachineProcess process = start(machine, agentCopy); - LOG.debug("Waiting for agent {} is launched. Workspace ID:{}", agentCopy.getId(), machine.getWorkspaceId()); - - final long pingStartTimestamp = System.currentTimeMillis(); - SshProcessLaunchedChecker agentLaunchingChecker = new SshProcessLaunchedChecker("che-websocket-terminal"); - while (System.currentTimeMillis() - pingStartTimestamp < agentMaxStartTimeMs) { - if (agentLaunchingChecker.isLaunched(agentCopy, machine)) { - return; - } else { - Thread.sleep(agentPingDelayMs); - } - } - - process.kill(); - - final String errMsg = format("Fail launching agent %s. Workspace ID:%s", agent.getName(), machine.getWorkspaceId()); - LOG.error(errMsg); - throw new ServerException(errMsg); - } catch (ServerException e) { - throw new ServerException(e.getServiceError()); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw new ServerException(format("Launching agent %s is interrupted", agent.getName())); - } catch (ConflictException e) { - // should never happen - throw new ServerException("Internal server error occurs on terminal launching."); - } - } - - private String detectArchitecture(SshMachineInstance machine) throws ConflictException, ServerException { - // uname -sm shows OS and CPU architecture - // Examples of output: - // Windows 10 amd64 - // MSYS_NT-6.3 x86_64 - // (empty line) - // Ubuntu Linux 14.04 amd64 - // Linux x86_64 - // OS X amd64 - // Darwin x86_64 - // Samsung Artik arm7 - // Linux armv7l - SshMachineProcess getUnameOutput = machine.createProcess(new CommandImpl("discover machine architecture", - "uname -sm", - null), - null); - ListLineConsumer lineConsumer = new ListLineConsumer(); - getUnameOutput.start(lineConsumer); - String unameOutput = lineConsumer.getText(); - Matcher matcher = UNAME_OUTPUT.matcher(unameOutput); - if (matcher.matches()) { - String os = matcher.group("os").toLowerCase(); - String arch = matcher.group("architecture").toLowerCase(); - StringBuilder result = new StringBuilder(); - if (os.contains("linux")) { - result.append("linux_"); - } else if (os.contains("darwin")) { - result.append("darwin_"); - } else if (os.contains("msys")) { - result.append("windows_"); - } else { - LOG.error(format("Architecture discovering fails. Machine %s. uname output:%s", machine.getId(), unameOutput)); - return DEFAULT_ARCHITECTURE; - } - if (arch.contains("x86_64")) { - result.append("amd64"); - } else if (arch.contains("armv7l")) { - result.append("arm7"); - } else if (arch.contains("armv6l")) { - result.append("arm6"); - } else if (arch.contains("armv5l")) { - result.append("arm5"); - } else { - LOG.error(format("Architecture discovering fails. Machine %s. uname output:%s", machine.getId(), unameOutput)); - return DEFAULT_ARCHITECTURE; - } - - return result.toString(); - } else { - LOG.error(format("Architecture discovering fails. Machine %s. uname output:%s", machine.getId(), unameOutput)); - return DEFAULT_ARCHITECTURE; - } - } - - protected SshMachineProcess start(SshMachineInstance machine, Agent agent) throws ServerException { - Command command = new CommandImpl(agent.getId(), agent.getScript(), "agent"); - SshMachineProcess process = machine.createProcess(command, null); - LineConsumer lineConsumer = new AbstractLineConsumer() { - @Override - public void writeLine(String line) throws IOException { - machine.getLogger().writeLine(line); - } - }; - - CountDownLatch countDownLatch = new CountDownLatch(1); - executor.execute(ThreadLocalPropagateContext.wrap(() -> { - try { - countDownLatch.countDown(); - process.start(lineConsumer); - } catch (ConflictException e) { - try { - machine.getLogger().writeLine(format("[ERROR] %s", e.getMessage())); - } catch (IOException ignored) { - } - } finally { - try { - lineConsumer.close(); - } catch (IOException ignored) { - } - } - })); - try { - // ensure that code inside of task submitted to executor is called before end of this method - countDownLatch.await(); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - - return process; - } -} diff --git a/plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/exec/SshProcessLaunchedChecker.java b/plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/exec/SshProcessLaunchedChecker.java deleted file mode 100644 index 6fe038d9dd..0000000000 --- a/plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/exec/SshProcessLaunchedChecker.java +++ /dev/null @@ -1,56 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012-2017 Codenvy, S.A. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Codenvy, S.A. - initial API and implementation - *******************************************************************************/ -package org.eclipse.che.plugin.machine.ssh.exec; - - -import org.eclipse.che.api.agent.shared.model.Agent; -import org.eclipse.che.api.core.ConflictException; -import org.eclipse.che.api.core.model.machine.Command; -import org.eclipse.che.api.core.util.ListLineConsumer; -import org.eclipse.che.api.machine.server.exception.MachineException; -import org.eclipse.che.api.workspace.server.model.impl.CommandImpl; -import org.eclipse.che.plugin.machine.ssh.SshMachineInstance; -import org.eclipse.che.plugin.machine.ssh.SshMachineProcess; - -import static java.lang.String.format; - -/** - * Verifies if a specific process is started on machine. - * - * @author Max Shaposhnik (mshaposhnik@codenvy.com) - */ -public class SshProcessLaunchedChecker { - private static final String CHECK_COMMAND = "command -v pidof >/dev/null 2>&1 && {\n" + - " pidof %1$s >/dev/null 2>&1 && echo 0 || echo 1\n" + - "} || {\n" + - " ps -fC %1$s >/dev/null 2>&1 && echo 0 || echo 1\n" + - "}"; - private final String processNameToWait; - private long counter; - - public SshProcessLaunchedChecker(String processNameToWait) { - this.processNameToWait = processNameToWait; - } - - public boolean isLaunched(Agent agent, SshMachineInstance machine) throws MachineException { - Command command = new CommandImpl(format("Wait for %s, try %d", agent.getId(), ++counter), - format(CHECK_COMMAND, processNameToWait), - "test"); - - try (ListLineConsumer lineConsumer = new ListLineConsumer()) { - SshMachineProcess waitProcess = machine.createProcess(command, null); - waitProcess.start(lineConsumer); - return lineConsumer.getText().endsWith("[STDOUT] 0"); - } catch (ConflictException e) { - throw new MachineException(e.getServiceError()); - } - } -} diff --git a/plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/jsch/JschSshClient.java b/plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/jsch/JschSshClient.java deleted file mode 100644 index 914ec6d09d..0000000000 --- a/plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/jsch/JschSshClient.java +++ /dev/null @@ -1,285 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012-2017 Codenvy, S.A. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Codenvy, S.A. - initial API and implementation - *******************************************************************************/ -package org.eclipse.che.plugin.machine.ssh.jsch; - -import com.jcraft.jsch.ChannelExec; -import com.jcraft.jsch.ChannelSftp; -import com.jcraft.jsch.JSch; -import com.jcraft.jsch.JSchException; -import com.jcraft.jsch.Session; -import com.jcraft.jsch.SftpException; - -import org.eclipse.che.api.core.util.ListLineConsumer; -import org.eclipse.che.api.machine.server.exception.MachineException; -import org.eclipse.che.commons.lang.IoUtil; -import org.eclipse.che.plugin.machine.ssh.SshClient; -import org.eclipse.che.plugin.machine.ssh.SshMachineRecipe; - -import javax.inject.Inject; -import javax.inject.Named; -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.nio.file.FileVisitResult; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.attribute.BasicFileAttributes; -import java.util.Map; - -import static java.lang.String.format; - -/** - * Client for communication with ssh machine using ssh protocol. - * - * @author Alexander Garagatyi - */ -// todo think about replacement JSch with Apace SSHD -// todo tests for ssh library that ensures that it works as expected -public class JschSshClient implements SshClient { - private final JSch jsch; - private final JschUserInfoImpl user; - private final String host; - private final int port; - private final String username; - private final Map envVars; - private final int connectionTimeout; - - private Session session; - - @Inject - public JschSshClient(SshMachineRecipe sshMachineRecipe, - Map envVars, - JSch jsch, - @Named("che.workspace.ssh_connection_timeout_ms") int connectionTimeoutMs) { - this.envVars = envVars; - this.connectionTimeout = connectionTimeoutMs; - this.user = JschUserInfoImpl.builder() - .password(sshMachineRecipe.getPassword()) - .promptPassword(true) - .passphrase(null) - .promptPassphrase(false) - .promptYesNo(true) - .build(); - this.jsch = jsch; - this.host = sshMachineRecipe.getHost(); - this.port = sshMachineRecipe.getPort(); - this.username = sshMachineRecipe.getUsername(); - } - - @Override - public String getHost() { - return host; - } - - @Override - public void start() throws MachineException { - try { - session = jsch.getSession(username, host, port); - session.setUserInfo(user); - // todo remember parent pid of shell to be able to kill all processes on client stop - if (!session.isConnected()) { - session.connect(connectionTimeout); - } - } catch (JSchException e) { - throw new MachineException("Ssh machine creation failed because ssh of machine is inaccessible. Error: " + - e.getLocalizedMessage()); - } - } - - //todo add method to read env vars by client - // ChannelExec execAndGetCode = (ChannelExec)session.openChannel("execAndGetCode"); - // execAndGetCode.setCommand("env"); - //envVars.entrySet() -// .stream() -// .forEach(envVariableEntry -> execAndGetCode.setEnv(envVariableEntry.getKey(), -// envVariableEntry.getValue())); -// todo process output - - @Override - public void stop() throws MachineException { - session.disconnect(); - } - - @Override - public JschSshProcess createProcess(String commandLine) throws MachineException { - try { - ChannelExec exec = (ChannelExec)session.openChannel("exec"); - exec.setCommand(commandLine); - exec.setPty(true); - envVars.entrySet() - .stream() - .forEach(envVariableEntry -> exec.setEnv(envVariableEntry.getKey(), - envVariableEntry.getValue())); - return new JschSshProcess(exec); - } catch (JSchException e) { - throw new MachineException("Can't establish connection to perform command execution in ssh machine. Error: " + - e.getLocalizedMessage(), e); - } - } - - @Override - public void copy(String sourcePath, String targetPath) throws MachineException { - File source = new File(sourcePath); - if (!source.exists()) { - throw new MachineException("Source of copying '" + sourcePath + "' doesn't exist."); - } - if (source.isDirectory()) { - copyRecursively(sourcePath, targetPath); - } else { - copyFile(sourcePath, targetPath); - } - } - - private void copyRecursively(String sourceFolder, String targetFolder) throws MachineException { - // create target dir - try { - int execCode = execAndGetCode("mkdir -p " + targetFolder); - - if (execCode != 0) { - throw new MachineException(format("Creation of folder %s failed. Exit code is %s", targetFolder, execCode)); - } - } catch (JSchException | IOException e) { - throw new MachineException(format("Creation of folder %s failed. Error: %s", targetFolder, e.getLocalizedMessage())); - } - - // not normalized paths don't work - final String targetAbsolutePath = getAbsolutePath(targetFolder); - - // copy files - ChannelSftp sftp = null; - try { - sftp = (ChannelSftp)session.openChannel("sftp"); - sftp.connect(connectionTimeout); - - final ChannelSftp finalSftp = sftp; - Files.walkFileTree(Paths.get(sourceFolder), new SimpleFileVisitor() { - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - try { - if (!attrs.isDirectory()) { - copyFile(file.toString(), - Paths.get(targetAbsolutePath, file.getFileName().toString()).toString(), finalSftp); - } else { - finalSftp.mkdir(file.normalize().toString()); - } - } catch (MachineException | SftpException e) { - throw new IOException(format("Sftp copying of file %s failed. Error: %s", file, e.getLocalizedMessage())); - } - return FileVisitResult.CONTINUE; - } - }); - } catch (JSchException | IOException e) { - throw new MachineException("Copying failed. Error: " + e.getLocalizedMessage()); - } finally { - if (sftp != null) { - sftp.disconnect(); - } - } - } - - private void copyFile(String sourcePath, String targetPath) throws MachineException { - ChannelSftp sftp = null; - try { - sftp = (ChannelSftp)session.openChannel("sftp"); - sftp.connect(connectionTimeout); - String absoluteTargetPath = getAbsolutePath(targetPath); - copyFile(sourcePath, absoluteTargetPath, sftp); - } catch (JSchException e) { - throw new MachineException("Sftp copying failed. Error: " + e.getLocalizedMessage()); - } finally { - if (sftp != null) { - sftp.disconnect(); - } - } - } - - private void copyFile(String sourcePath, String absoluteTargetPath, ChannelSftp channelSftp) throws MachineException { - try { - channelSftp.put(sourcePath, absoluteTargetPath); - - // apply permissions - File file = new File(sourcePath); - // read - int permissions = 256; - // execute - if (file.canExecute()) { - permissions += 64; - } - // write - if (file.canWrite()) { - permissions += 128; - } - channelSftp.chmod(permissions, absoluteTargetPath); - } catch (SftpException e) { - throw new MachineException(format("Sftp copying of file %s failed. Error: %s", - absoluteTargetPath, - e.getLocalizedMessage())); - } - } - - private String getAbsolutePath(String path) throws MachineException { - try { - return execAndGetOutput("cd " + path + "; pwd"); - } catch (JSchException | IOException | MachineException e) { - throw new MachineException("Target directory lookup failed. " + e.getLocalizedMessage()); - } - } - - private int execAndGetCode(String command) throws JSchException, IOException { - ChannelExec exec = (ChannelExec)session.openChannel("exec"); - exec.setCommand(command); - - try (InputStream inStream = exec.getInputStream(); - InputStream erStream = exec.getErrStream()) { - - exec.connect(connectionTimeout); - - // read streams to wait until command finishes its work - IoUtil.readStream(inStream); - IoUtil.readStream(erStream); - } finally { - exec.disconnect(); - } - - return exec.getExitStatus(); - } - - private String execAndGetOutput(String command) throws JSchException, MachineException, IOException { - ChannelExec exec = (ChannelExec)session.openChannel("exec"); - exec.setCommand(command); - - try (BufferedReader reader = new BufferedReader(new InputStreamReader(exec.getInputStream())); - InputStream erStream = exec.getErrStream()) { - - exec.connect(connectionTimeout); - - ListLineConsumer listLineConsumer = new ListLineConsumer(); - String line; - while ((line = reader.readLine()) != null) { - listLineConsumer.writeLine(line); - } - // read stream to wait until command finishes its work - IoUtil.readStream(erStream); - if (exec.getExitStatus() != 0) { - throw new MachineException(format("Error code: %s. Error: %s", - exec.getExitStatus(), - IoUtil.readAndCloseQuietly(exec.getErrStream()))); - } - return listLineConsumer.getText(); - } finally { - exec.disconnect(); - } - } -} diff --git a/plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/jsch/JschSshProcess.java b/plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/jsch/JschSshProcess.java deleted file mode 100644 index c834825049..0000000000 --- a/plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/jsch/JschSshProcess.java +++ /dev/null @@ -1,124 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012-2017 Codenvy, S.A. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Codenvy, S.A. - initial API and implementation - *******************************************************************************/ -package org.eclipse.che.plugin.machine.ssh.jsch; - -import com.jcraft.jsch.ChannelExec; -import com.jcraft.jsch.JSchException; - -import org.eclipse.che.api.core.util.LineConsumer; -import org.eclipse.che.api.machine.server.exception.MachineException; -import org.eclipse.che.plugin.machine.ssh.SshProcess; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.PipedInputStream; -import java.io.PipedOutputStream; -import java.util.Optional; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; - -/** - * JSch implementation of {@link SshProcess} - * - * @author Alexander Garagatyi - */ -public class JschSshProcess implements SshProcess { - private final ChannelExec exec; - - public JschSshProcess(ChannelExec exec) { - this.exec = exec; - } - - @Override - public void start() throws MachineException { - try { - exec.connect(); - } catch (JSchException e) { - throw new MachineException("Ssh machine command execution error:" + e.getLocalizedMessage()); - } - } - - // todo how to manage disconnections due to network failures? - - @Override - public void start(LineConsumer output) throws MachineException { - try (PipedOutputStream pipedOS = new PipedOutputStream(); - PipedInputStream pipedIS = new PipedInputStream(pipedOS); - BufferedReader outReader = new BufferedReader(new InputStreamReader(pipedIS))) { - - exec.setOutputStream(pipedOS); - exec.setExtOutputStream(pipedOS); - exec.connect(); - - String outLine; - while ((outLine = outReader.readLine()) != null) { - output.writeLine(outLine); - } - } catch (IOException | JSchException e) { - throw new MachineException("Ssh machine command execution error:" + e.getLocalizedMessage()); - } finally { - exec.disconnect(); - } - } - - @Override - public void start(LineConsumer out, LineConsumer err) throws MachineException { - try (BufferedReader outReader = new BufferedReader(new InputStreamReader(exec.getInputStream())); - BufferedReader errReader = new BufferedReader(new InputStreamReader(exec.getErrStream()))) { - - exec.connect(); - - // read stderr in separate thread - CompletableFuture> future = CompletableFuture.supplyAsync(() -> { - try { - String line; - while ((line = errReader.readLine()) != null) { - err.writeLine(line); - } - return Optional.empty(); - } catch (IOException e) { - return Optional.of(e); - } - }); - - String line; - while ((line = outReader.readLine()) != null) { - out.writeLine(line); - } - - final Optional excOptional = future.get(); - if (excOptional.isPresent()) { - throw new MachineException("Ssh machine command execution error:" + excOptional.get().getLocalizedMessage()); - } - } catch (IOException | JSchException | ExecutionException | InterruptedException e) { - throw new MachineException("Ssh machine command execution error:" + e.getLocalizedMessage()); - } finally { - exec.disconnect(); - } - } - - @Override - public int getExitCode() { - return exec.getExitStatus(); - } - - @Override - public void kill() throws MachineException { - try { - exec.sendSignal("KILL"); - } catch (Exception e) { - throw new MachineException("Ssh machine signal sending error:" + e.getLocalizedMessage()); - } finally { - exec.disconnect(); - } - } -} diff --git a/plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/jsch/JschUserInfoImpl.java b/plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/jsch/JschUserInfoImpl.java deleted file mode 100644 index 4d8e2da984..0000000000 --- a/plugins/plugin-ssh-machine/src/main/java/org/eclipse/che/plugin/machine/ssh/jsch/JschUserInfoImpl.java +++ /dev/null @@ -1,109 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012-2017 Codenvy, S.A. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Codenvy, S.A. - initial API and implementation - *******************************************************************************/ -package org.eclipse.che.plugin.machine.ssh.jsch; - -import com.jcraft.jsch.UserInfo; - -/** - * Implementation of {@link UserInfo}. - * - * @author Alexander Garagatyi - */ -public class JschUserInfoImpl implements UserInfo { - private final String password; - private final boolean promptPassword; - private final String passphrase; - private final boolean promptPassphrase; - private final boolean promptYesNo; - - private JschUserInfoImpl(String password, - boolean promptPassword, - String passphrase, - boolean promptPassphrase, - boolean promptYesNo) { - this.password = password; - this.promptPassword = promptPassword; - this.passphrase = passphrase; - this.promptPassphrase = promptPassphrase; - this.promptYesNo = promptYesNo; - } - - public static JschUserInfoImplBuilder builder() { - return new JschUserInfoImplBuilder(); - } - - @Override - public String getPassphrase() { - return passphrase; - } - - @Override - public String getPassword() { - return password; - } - - @Override - public boolean promptPassword(String message) { - return promptPassword; - } - - @Override - public boolean promptPassphrase(String message) { - return promptPassphrase; - } - - @Override - public boolean promptYesNo(String message) { - return promptYesNo; - } - - @Override - public void showMessage(String message) {} - - public static class JschUserInfoImplBuilder { - private String password; - private String passphrase; - private boolean promptPassword; - private boolean promptPassphrase; - private boolean promptYesNo; - - private JschUserInfoImplBuilder() {} - - public JschUserInfoImpl build() { - return new JschUserInfoImpl(password, promptPassword, passphrase, promptPassphrase, promptYesNo); - } - - public JschUserInfoImplBuilder password(String password) { - this.password = password; - return this; - } - - public JschUserInfoImplBuilder passphrase(String passphrase) { - this.passphrase = passphrase; - return this; - } - - public JschUserInfoImplBuilder promptPassword(boolean promptPassword) { - this.promptPassword = promptPassword; - return this; - } - - public JschUserInfoImplBuilder promptPassphrase(boolean promptPassphrase) { - this.promptPassphrase = promptPassphrase; - return this; - } - - public JschUserInfoImplBuilder promptYesNo(boolean promptYesNo) { - this.promptYesNo = promptYesNo; - return this; - } - } -} diff --git a/plugins/plugin-ssh-machine/src/test/java/org/eclipse/che/plugin/machine/ssh/SshMachineInstanceProviderTest.java b/plugins/plugin-ssh-machine/src/test/java/org/eclipse/che/plugin/machine/ssh/SshMachineInstanceProviderTest.java deleted file mode 100644 index df80891827..0000000000 --- a/plugins/plugin-ssh-machine/src/test/java/org/eclipse/che/plugin/machine/ssh/SshMachineInstanceProviderTest.java +++ /dev/null @@ -1,136 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012-2017 Codenvy, S.A. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Codenvy, S.A. - initial API and implementation - *******************************************************************************/ -package org.eclipse.che.plugin.machine.ssh; - -import com.google.gson.Gson; - -import org.eclipse.che.api.core.model.machine.Machine; -import org.eclipse.che.api.core.model.machine.MachineConfig; -import org.eclipse.che.api.core.model.machine.MachineStatus; -import org.eclipse.che.api.core.util.LineConsumer; -import org.eclipse.che.api.machine.server.exception.MachineException; -import org.eclipse.che.api.machine.server.model.impl.MachineConfigImpl; -import org.eclipse.che.api.workspace.server.model.impl.MachineImpl; -import org.eclipse.che.api.workspace.server.model.impl.MachineSourceImpl; -import org.eclipse.che.api.machine.server.model.impl.ServerConfImpl; -import org.eclipse.che.api.machine.server.recipe.RecipeImpl; -import org.eclipse.che.api.workspace.server.RecipeDownloader; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.testng.MockitoTestNGListener; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Listeners; -import org.testng.annotations.Test; - -import java.util.HashSet; - -import static java.util.Collections.singletonList; -import static java.util.Collections.singletonMap; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyMap; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.when; -import static org.testng.Assert.assertEquals; - -/** - * @author Alexander Garagatyi - */ -@Listeners(MockitoTestNGListener.class) -public class SshMachineInstanceProviderTest { - private static final String RECIPE_SCRIPT = new Gson().toJson(new SshMachineRecipe("localhost", 22, "user", "password")); - - @Mock - private RecipeDownloader recipeDownloader; - - @Mock - private SshMachineFactory sshMachineFactory; - @Mock - private SshClient sshClient; - @Mock - private SshMachineInstance sshMachineInstance; - - @InjectMocks - private SshMachineInstanceProvider provider; - private RecipeImpl recipe; - private MachineImpl machine; - - @BeforeMethod - public void setUp() throws Exception { - machine = createMachine(); - recipe = new RecipeImpl().withType("ssh-config") - .withScript(RECIPE_SCRIPT); - } - - @Test - public void shouldReturnCorrectType() throws Exception { - assertEquals(provider.getType(), "ssh"); - } - - @Test - public void shouldReturnCorrectRecipeTypes() throws Exception { - assertEquals(provider.getRecipeTypes(), new HashSet<>(singletonList("ssh-config"))); - } - - @Test(expectedExceptions = MachineException.class, - expectedExceptionsMessageRegExp = "Dev machine is not supported for Ssh machine implementation") - public void shouldThrowExceptionOnDevMachineCreationFromRecipe() throws Exception { - Machine machine = createMachine(true); - - provider.createInstance(machine, LineConsumer.DEV_NULL); - } - - @Test(expectedExceptions = NullPointerException.class, - expectedExceptionsMessageRegExp = "Location in machine source is required") - public void shouldThrowExceptionInvalidMachineConfigSource() throws Exception { - MachineImpl machine = createMachine(true); - machine.getConfig().setSource(new MachineSourceImpl("ssh-config").setContent("hello")); - - provider.createInstance(machine, LineConsumer.DEV_NULL); - } - - @Test - public void shouldBeAbleToCreateSshMachineInstanceOnMachineCreationFromRecipe() throws Exception { - when(sshMachineFactory.createSshClient(any(SshMachineRecipe.class), anyMap())).thenReturn(sshClient); - when(sshMachineFactory.createInstance(eq(machine), eq(sshClient), any(LineConsumer.class))).thenReturn(sshMachineInstance); - when(recipeDownloader.getRecipe(eq(machine.getConfig()))).thenReturn(recipe); - - SshMachineInstance instance = provider.createInstance(machine, LineConsumer.DEV_NULL); - - assertEquals(instance, sshMachineInstance); - } - - private MachineImpl createMachine() { - return createMachine(false); - } - - private MachineImpl createMachine(boolean isDev) { - MachineConfig machineConfig = MachineConfigImpl.builder() - .setDev(isDev) - .setEnvVariables(singletonMap("testEnvVar1", "testEnvVarVal1")) - .setName("name1") - .setServers(singletonList(new ServerConfImpl("myref1", - "10011/tcp", - "http", - null))) - .setSource(new MachineSourceImpl("ssh-config").setLocation("localhost:10012/recipe")) - .setType("ssh") - .build(); - return MachineImpl.builder() - .setConfig(machineConfig) - .setEnvName("env1") - .setId("id1") - .setOwner("owner1") - .setRuntime(null) - .setStatus(MachineStatus.CREATING) - .setWorkspaceId("wsId1") - .build(); - } -} diff --git a/plugins/plugin-ssh-machine/src/test/java/org/eclipse/che/plugin/machine/ssh/SshMachineInstanceTest.java b/plugins/plugin-ssh-machine/src/test/java/org/eclipse/che/plugin/machine/ssh/SshMachineInstanceTest.java deleted file mode 100644 index 21c4381fec..0000000000 --- a/plugins/plugin-ssh-machine/src/test/java/org/eclipse/che/plugin/machine/ssh/SshMachineInstanceTest.java +++ /dev/null @@ -1,69 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012-2017 Codenvy, S.A. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Codenvy, S.A. - initial API and implementation - *******************************************************************************/ -package org.eclipse.che.plugin.machine.ssh; - -import org.eclipse.che.api.core.model.machine.Machine; -import org.eclipse.che.api.core.model.machine.MachineConfig; -import org.eclipse.che.api.core.model.machine.MachineRuntimeInfo; -import org.eclipse.che.api.core.util.LineConsumer; -import org.mockito.Mock; -import org.mockito.testng.MockitoTestNGListener; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Listeners; -import org.testng.annotations.Test; - -import java.util.HashSet; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -/** - * Tests for{@link SshMachineInstance} - * - * @author Igor Vinokur - */ -@Listeners(MockitoTestNGListener.class) -public class SshMachineInstanceTest { - @Mock - private Machine machine; - @Mock - private SshClient sshClient; - @Mock - private LineConsumer outputConsumer; - - private SshMachineInstance sshMachineInstance; - - @BeforeMethod - public void setUp() { - when(machine.getConfig()).thenReturn(mock(MachineConfig.class)); - when(machine.getEnvName()).thenReturn("EnvName"); - when(machine.getId()).thenReturn("Id"); - when(machine.getOwner()).thenReturn("Owner"); - when(machine.getRuntime()).thenReturn(mock(MachineRuntimeInfo.class)); - when(machine.getWorkspaceId()).thenReturn("WorkspaceId"); - - sshMachineInstance = new SshMachineInstance(machine, - sshClient, - outputConsumer, - mock(SshMachineFactory.class), - new HashSet<>()); - } - - @Test - public void shouldCloseOutputConsumerAndStopClientOnDestroy() throws Exception { - sshMachineInstance.destroy(); - - verify(outputConsumer).close(); - verify(sshClient).stop(); - } - -} diff --git a/plugins/pom.xml b/plugins/pom.xml index a7b0f17f37..6182b8931f 100644 --- a/plugins/pom.xml +++ b/plugins/pom.xml @@ -49,7 +49,6 @@ plugin-nodejs plugin-nodejs-debugger plugin-php - plugin-languageserver plugin-urlfactory plugin-json diff --git a/pom.xml b/pom.xml index 1c63869d37..c5f73888a9 100644 --- a/pom.xml +++ b/pom.xml @@ -924,11 +924,6 @@ che-plugin-ssh-key-server ${che.version} - - org.eclipse.che.plugin - che-plugin-ssh-machine - ${che.version} - org.eclipse.che.plugin che-plugin-svn-ext-ide diff --git a/wsmaster/che-core-api-machine-shared/src/main/java/org/eclipse/che/api/machine/shared/dto/MachineLogMessageDto.java b/wsmaster/che-core-api-machine-shared/src/main/java/org/eclipse/che/api/machine/shared/dto/MachineLogMessageDto.java deleted file mode 100644 index ce3bbb6afa..0000000000 --- a/wsmaster/che-core-api-machine-shared/src/main/java/org/eclipse/che/api/machine/shared/dto/MachineLogMessageDto.java +++ /dev/null @@ -1,28 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012-2017 Codenvy, S.A. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Codenvy, S.A. - initial API and implementation - *******************************************************************************/ -package org.eclipse.che.api.machine.shared.dto; - -import org.eclipse.che.api.core.model.machine.MachineLogMessage; -import org.eclipse.che.dto.shared.DTO; - -/** - * @author Alexander Garagatyi - */ -@DTO -public interface MachineLogMessageDto extends MachineLogMessage { - void setContent(String content); - - MachineLogMessageDto withContent(String content); - - void setMachineName(String machineName); - - MachineLogMessageDto withMachineName(String machineName); -}