/* * Copyright (C) 2006-2016 DLR, Germany * * All rights reserved * * http://www.rcenvironment.de/ */ package de.rcenvironment.core.utils.ssh.jsch.executor.context; import java.io.File; import java.io.IOException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.jcraft.jsch.JSchException; import com.jcraft.jsch.Logger; import com.jcraft.jsch.Session; import de.rcenvironment.core.utils.common.validation.ValidationFailureException; import de.rcenvironment.core.utils.executor.CommandLineExecutor; import de.rcenvironment.core.utils.executor.context.spi.ExecutorContext; import de.rcenvironment.core.utils.ssh.jsch.JschSessionFactory; import de.rcenvironment.core.utils.ssh.jsch.SshParameterException; import de.rcenvironment.core.utils.ssh.jsch.SshSessionConfiguration; import de.rcenvironment.core.utils.ssh.jsch.executor.JSchCommandLineExecutor; /** * {@link ExecutorContext} implementation using the {@link JSchCommandLineExecutor}. * * @author Robert Mischke */ public class JSchExecutorContext implements ExecutorContext { private Session jschSession; private SshSessionConfiguration staticConfiguration; private RemoteTempDirFactory tempDirFactory; private final Log log = LogFactory.getLog(getClass()); /** * Constructor that uses the default root temp directory. * * @param staticConfiguration the SSH configuration to use */ public JSchExecutorContext(SshSessionConfiguration staticConfiguration) { this(staticConfiguration, "/tmp/rce-tmp/"); } /** * Constructor that allows setting a custom root temp directory. * * @param staticConfiguration the SSH configuration to use * @param tempDirRoot the root temp directory to use */ public JSchExecutorContext(SshSessionConfiguration staticConfiguration, String tempDirRoot) { this.staticConfiguration = staticConfiguration; this.tempDirFactory = new RemoteTempDirFactory(tempDirRoot); } @Override public void setUpSession() throws IOException, ValidationFailureException { try { jschSession = setupJSchSession(); log.info("SSH connection established"); } catch (JSchException e) { throw new IOException(e); } catch (SshParameterException e) { throw new ValidationFailureException(e.getMessage()); } } @Override public void tearDownSession() throws IOException { if (jschSession == null) { throw new IllegalStateException("session not set up"); } log.info("Closing SSH connection"); jschSession.disconnect(); // TODO delete temporary directories created via #createUniqueTempDir()? } @Override public CommandLineExecutor setUpSandboxedExecutor() throws IOException { if (jschSession == null) { throw new IllegalStateException("no session set up"); } String sandboxDir = tempDirFactory.createTempDirPath("sandbox", "-"); log.debug("Setting SSH sandbox to " + sandboxDir); // create sandbox CommandLineExecutor executor = new JSchCommandLineExecutor(jschSession, tempDirFactory.getRootDir()); String sandboxDirName = new File(sandboxDir).getName(); try { executor.start("mkdir -p " + sandboxDirName); executor.waitForTermination(); } catch (InterruptedException e) { log.warn("Interrupted while setting up remote SSH sandbox", e); } return new JSchCommandLineExecutor(jschSession, sandboxDir); } @Override public void tearDownSandbox(CommandLineExecutor executor) throws IOException { if (jschSession == null) { throw new IllegalStateException("no session set up"); } String sandboxPath = executor.getWorkDirPath(); log.debug("Cleaning SSH sandbox at " + sandboxPath); // intentionally using the full path, and no -f or -r option for safety; // as a consequence, this is not able to delete subdirectories for now -- misc_ro try { executor.start("rm " + sandboxPath + "/*"); executor.waitForTermination(); executor.start("rmdir " + sandboxPath); executor.waitForTermination(); } catch (InterruptedException e) { log.warn("Interrupted while cleaning up remote SSH sandbox", e); } } @Override public String createUniqueTempDir(String contextHint) throws IOException { String tempDirPath = tempDirFactory.createTempDirPath(contextHint, "-"); log.debug("Generated temp directory path " + tempDirPath); return tempDirPath; } private Session setupJSchSession() throws JSchException, SshParameterException { String host = staticConfiguration.getDestinationHost(); int port = staticConfiguration.getPort(); String user = staticConfiguration.getSshAuthUser(); String keyfileLocation = staticConfiguration.getSshKeyFileLocation(); String authPhrase = staticConfiguration.getSshAuthPhrase(); // TODO rewrite to use JschSessionFactory factory method? Logger jschLogger = new Logger() { @Override public boolean isEnabled(int arg0) { return true; } @Override public void log(int arg0, String arg1) { if (log.isTraceEnabled()) { log.trace("JSch Log [Level " + arg0 + "]: " + arg1); } } }; return JschSessionFactory.setupSession(host, port, user, keyfileLocation, authPhrase, jschLogger); } }