package org.ovirt.engine.core.utils.hostinstall; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.InputStream; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.ovirt.engine.core.common.config.Config; import org.ovirt.engine.core.common.config.ConfigValues; 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; //Doron Fediuck: IPWorksInstallWrapper class is not being used at all. I kept it as a backup until we have full functional alternative by Apache, and I still wait for internal scp & fingerprint implementation. public class IPWorksInstallWrapper implements IVdsInstallWrapper { private IVdsInstallCallBack callback; Session session = null; public IPWorksInstallWrapper() { } private boolean _do_connect(String server, Credentials creds) { boolean returnValue = true; try { JSch jsch = new JSch(); if (creds.getCertPath() != null) { log.debug("Using Public Key Authentication."); jsch.addIdentity(creds.getCertPath(), creds.getPassphrase()); } ByteArrayOutputStream output = new ByteArrayOutputStream(); session = jsch.getSession(creds.getUsername(), server, 22); session.setOutputStream(output); session.setUserInfo(creds); session.connect(); if (log.isDebugEnabled()) { log.debug(output.toString()); } callbackConnected(); } catch (JSchException e) { callbackFailed(e.getMessage()); returnValue = false; log.error("Could not connect to server " + server, e); } return returnValue; } protected void callbackAddError(String message) { if (haveCallback()) { callback.AddError(message); } } protected void callbackAddMessage(String message) { if (haveCallback()) { callback.AddMessage(message); } } protected void callbackConnected() { if (haveCallback()) { // TODO: Remove comment when Apache MINA support Finger-Print // callback.AddMessage(String.format( // "<BSTRAP component='RHEV_INSTALL' status='OK' message='Connected to Host %s with SSH Key Fingerprint: %s'/>", // session.getHost(), // session.getFingerprint())); callback.Connected(); } } protected void callbackEndTransfer() { if (haveCallback()) { callback.EndTransfer(); } } protected void callbackFailed(String message) { if (haveCallback()) { callback.Failed(message); } } public final boolean ConnectToServer(String server) { return ConnectToServer(server, Config.resolveCertificatePath(), Config.<String> GetValue(ConfigValues.CertificatePassword)); } public final boolean ConnectToServer(String server, String rootPassword) { Credentials creds = new Credentials(); creds.setPassword(rootPassword); creds.setUsername("root"); return _do_connect(server, creds); } public final boolean ConnectToServer(String server, String certPath, String password) { Credentials creds = new Credentials(); creds.setPassphrase(password); creds.setCertPath(certPath); creds.setUsername("root"); return _do_connect(server, creds); } public final boolean DownloadFile(String source, String destination) { log.info(String.format("Downloading file %s to %s on %s", source, destination, session.getHost())); boolean returnValue = true; try { ChannelSftp channel = (ChannelSftp) session.openChannel("sftp"); channel.connect(); channel.get(source, destination); String output = null; int exitStatus = 0; exitStatus = channel.getExitStatus(); if (exitStatus > 0) { returnValue = false; callbackAddError("Exit Status from transfer: " + exitStatus); log.error(output); } else { callbackEndTransfer(); } } catch (Exception e) { callbackAddError(e.getMessage()); log.error(e); returnValue = false; } return returnValue; } protected boolean haveCallback() { return callback != null; } public final void InitCallback(IVdsInstallCallBack callback) { this.callback = callback; } protected String readInput(InputStream input) { StringBuilder builder = new StringBuilder(); byte[] tmp = new byte[1024]; try { while (input.available() > 0) { int i = input.read(tmp, 0, 1024); if (i < 0) break; builder.append(new String(tmp, 0, i)); } } catch (Exception e) { throw new RuntimeException(e); } return builder.toString(); } public final boolean RunSSHCommand(String command) { boolean returnValue = true; log.info(String.format("Invoking %s on %s", command, session.getHost())); try { ChannelExec channel = (ChannelExec) session.openChannel("exec"); channel.setCommand(command); InputStream result = channel.getInputStream(); InputStream error = channel.getErrStream(); channel.connect(); int exitStatus = 0; while (true) { String sshMessage = readInput(result); if (sshMessage != null && sshMessage.length() > 0) { log.debug(sshMessage); callbackAddMessage(sshMessage); } String errorSshMessage = readInput(error); if (errorSshMessage != null && errorSshMessage.length() > 0) { log.debug(errorSshMessage); callbackAddError(errorSshMessage); } if (channel.isClosed()) { exitStatus = channel.getExitStatus(); log.debug("exit-status: " + exitStatus); break; } try { Thread.sleep(1000); } catch (Exception ee) { } } if (exitStatus != 0) { returnValue = false; String errorString = readInput(error); callbackAddError(errorString); log.error(errorString); } } catch (Exception e) { callbackFailed(e.getMessage()); log.error("Error running command " + command, e); returnValue = false; } return returnValue; } public final boolean UploadFile(String source, String destination) { log.info(String.format("Uploading file %s to %s on %s", source, destination, session.getHost())); File file = new File(source); boolean returnValue = true; if (file.exists()) { try { ChannelSftp channel = (ChannelSftp) session.openChannel("sftp"); channel.connect(); channel.put(source, destination); String output = null; int exitStatus = 0; exitStatus = channel.getExitStatus(); if (exitStatus > 0) { returnValue = false; callbackAddError("Exit Status from transfer: " + exitStatus); log.error(output); } else { callbackEndTransfer(); } } catch (Exception e) { callbackAddError(e.getMessage()); log.error(e); returnValue = false; } } else { this.callbackFailed(String.format("Upload failed. File: %s not exist", source)); log.error("File to upload does not exist: " + source); returnValue = false; } return returnValue; } private static Log log = LogFactory.getLog(IPWorksInstallWrapper.class); @Override public void wrapperShutdown() { throw new UnsupportedOperationException("This class should not be used, and have no support in installation actions."); } /** * The methods does not implement the timeout. */ @Override public boolean ConnectToServer(String server, String rootPassword, long timeout) { return ConnectToServer(server, rootPassword); } }