/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.ow2.choreos.utils;
import org.apache.geronimo.mail.util.StringBufferOutputStream;
import org.apache.log4j.Logger;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
public class SshUtil {
private Logger logger = Logger.getLogger(SshUtil.class);
private static final int CONNECTION_TIMEOUT = 5000;
private final String hostname, user, privateKeyFile;
private Session session;
public SshUtil(String hostname, String user, String privateKeyFile) {
this.hostname = hostname;
this.user = user;
this.privateKeyFile = privateKeyFile;
}
private Session getSession() throws JSchException {
if (this.session != null && this.session.isConnected()) {
return this.session;
}
JSch jsch = new JSch();
jsch.addIdentity(privateKeyFile);
this.session = jsch.getSession(user, hostname);
this.session.setConfig("StrictHostKeyChecking", "no");
this.session.setConfig("UserKnownHostsFile", "/dev/null");
return this.session;
}
public boolean isAccessible() {
Session session = null;
try {
// Once upon a time, an old session caused a lot of trouble...
session = getSession();
session.connect(CONNECTION_TIMEOUT);
// TODO executar um comando simples, tipo ls, pra ver se conectou de
// verdade MESMO
} catch (JSchException e) {
return false;
}
// We can keep a successful session
this.session = session;
return this.session.isConnected();
}
public String runCommand(String command) throws JSchException, SshCommandFailed {
return runCommand(command, false);
}
public String runCommand(String command, boolean retry) throws JSchException, SshCommandFailed {
final int SLEEPING_TIME = 5000;
String output = null;
try {
output = runCommandOnce(command);
} catch (JSchException e) {
if (retry) {
try {
Thread.sleep(SLEEPING_TIME);
} catch (InterruptedException e1) {
}
return runCommand(command, retry);
} else {
throw e;
}
}
return output;
}
public String runCommandOnce(String command) throws JSchException, SshCommandFailed {
String output = null;
Session session = getSession();
try {
session.connect(CONNECTION_TIMEOUT);
Channel channel = session.openChannel("exec");
((ChannelExec) channel).setCommand(command);
StringBuffer sb = new StringBuffer();
channel.setOutputStream(new StringBufferOutputStream(sb));
channel.connect();
// channel.connect(CONNECTION_TIMEOUT * 100); // TODO depois do
// experimento, pensar oq fazer aqui
while (!channel.isClosed()) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
logger.error("Sleep exception! Cause: ", e.getCause());
}
}
if (channel.getExitStatus() > 0) {
throw new SshCommandFailed(command);
}
channel.disconnect();
session.disconnect();
output = sb.toString();
} catch (JSchException e) {
logger.debug("Could not connect to " + user + "@" + hostname + " with key " + privateKeyFile);
throw e;
}
return output;
}
public void disconnect() {
if (session != null && session.isConnected()) {
session.disconnect();
}
}
@Override
protected void finalize() throws Throwable {
disconnect();
super.finalize();
}
}