+/*
+ * Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
package org.argeo.slc.jsch;
import java.io.BufferedReader;
import java.util.Map;
import java.util.StringTokenizer;
+import org.apache.commons.exec.ExecuteStreamHandler;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
private String user;
+ private ExecuteStreamHandler streamHandler = null;
+
+ private Integer lastExitStatus = null;
/**
* If set, stdout is written to it as a list of lines. Cleared before each
* run.
throw new SlcException("Cannot specify commands and script");
BufferedReader reader = null;
try {
- reader = new BufferedReader(new InputStreamReader(script
- .getInputStream()));
+ reader = new BufferedReader(new InputStreamReader(
+ script.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null) {
if (!StringUtils.hasText(line))
log.debug("Run '" + command + "' on " + getSshTarget() + "...");
channel.connect();
- if (stdIn != null) {
- Thread stdInThread = new Thread("Stdin " + getSshTarget()) {
- @Override
- public void run() {
- OutputStream out = null;
- try {
- out = channel.getOutputStream();
- IOUtils.copy(stdIn.getInputStream(), out);
- } catch (IOException e) {
- throw new SlcException("Cannot write stdin on "
- + getSshTarget(), e);
- } finally {
- IOUtils.closeQuietly(out);
- }
+ readStdIn(channel);
+ readStdOut(channel);
+
+ if (streamHandler != null){
+ streamHandler.start();
+ while(!channel.isClosed()){
+ try {
+ Thread.sleep(100);
+ } catch (Exception e) {
+ break;
}
- };
- stdInThread.start();
+ }
}
- readStdOut(channel);
+
checkExitStatus(channel);
channel.disconnect();
} catch (Exception e) {
}
}
- protected void readStdErr(final ChannelExec channel) {
- new Thread("stderr " + getSshTarget()) {
- public void run() {
- BufferedReader stdErr = null;
+ protected void readStdOut(Channel channel) {
+ try {
+ if (stdOut != null) {
+ OutputStream localStdOut = createOutputStream(stdOut);
+ try {
+ IOUtils.copy(channel.getInputStream(), localStdOut);
+ } finally {
+ IOUtils.closeQuietly(localStdOut);
+ }
+ } else if (streamHandler != null) {
+ if (channel.getInputStream() != null)
+ streamHandler.setProcessOutputStream(channel
+ .getInputStream());
+ } else {
+ BufferedReader stdOut = null;
try {
- InputStream in = channel.getErrStream();
- stdErr = new BufferedReader(new InputStreamReader(in));
+ InputStream in = channel.getInputStream();
+ stdOut = new BufferedReader(new InputStreamReader(in));
String line = null;
- while ((line = stdErr.readLine()) != null) {
- if (!line.trim().equals(""))
- log.error(line);
+ while ((line = stdOut.readLine()) != null) {
+ if (!line.trim().equals("")) {
+
+ if (stdOutLines != null) {
+ stdOutLines.add(line);
+ if (logEvenIfStdOutLines && !quiet)
+ log.info(line);
+ } else {
+ if (!quiet)
+ log.info(line);
+ }
+ }
}
- } catch (IOException e) {
- if (log.isDebugEnabled())
- log.error("Cannot read stderr from " + getSshTarget(),
- e);
} finally {
- IOUtils.closeQuietly(stdErr);
+ IOUtils.closeQuietly(stdOut);
}
}
- }.start();
+ } catch (IOException e) {
+ throw new SlcException("Cannot redirect stdout from "
+ + getSshTarget(), e);
+ }
}
- protected void readStdOut(Channel channel) {
- if (stdOut != null) {
- OutputStream localStdOut = createOutputStream(stdOut);
+ protected void readStdErr(final ChannelExec channel) {
+ if (streamHandler != null) {
try {
- IOUtils.copy(channel.getInputStream(), localStdOut);
+ streamHandler.setProcessOutputStream(channel.getErrStream());
} catch (IOException e) {
- throw new SlcException("Cannot redirect stdout", e);
- } finally {
- IOUtils.closeQuietly(localStdOut);
+ throw new SlcException("Cannot read stderr from "
+ + getSshTarget(), e);
}
} else {
- BufferedReader stdOut = null;
- try {
- InputStream in = channel.getInputStream();
- stdOut = new BufferedReader(new InputStreamReader(in));
- String line = null;
- while ((line = stdOut.readLine()) != null) {
- if (!line.trim().equals("")) {
-
- if (stdOutLines != null) {
- stdOutLines.add(line);
- if (logEvenIfStdOutLines && !quiet)
- log.info(line);
- } else {
- if (!quiet)
- log.info(line);
+ new Thread("stderr " + getSshTarget()) {
+ public void run() {
+ BufferedReader stdErr = null;
+ try {
+ InputStream in = channel.getErrStream();
+ stdErr = new BufferedReader(new InputStreamReader(in));
+ String line = null;
+ while ((line = stdErr.readLine()) != null) {
+ if (!line.trim().equals(""))
+ log.error(line);
}
+ } catch (IOException e) {
+ if (log.isDebugEnabled())
+ log.error("Cannot read stderr from "
+ + getSshTarget(), e);
+ } finally {
+ IOUtils.closeQuietly(stdErr);
+ }
+ }
+ }.start();
+ }
+ }
+
+ protected void readStdIn(final ChannelExec channel) {
+ if (stdIn != null) {
+ Thread stdInThread = new Thread("Stdin " + getSshTarget()) {
+ @Override
+ public void run() {
+ OutputStream out = null;
+ try {
+ out = channel.getOutputStream();
+ IOUtils.copy(stdIn.getInputStream(), out);
+ } catch (IOException e) {
+ throw new SlcException("Cannot write stdin on "
+ + getSshTarget(), e);
+ } finally {
+ IOUtils.closeQuietly(out);
}
}
+ };
+ stdInThread.start();
+ } else if (streamHandler != null) {
+ try {
+ streamHandler.setProcessInputStream(channel.getOutputStream());
} catch (IOException e) {
- if (log.isDebugEnabled())
- log.error("Cannot read stdout from " + getSshTarget(), e);
- } finally {
- IOUtils.closeQuietly(stdOut);
+ throw new SlcException("Cannot write stdin on "
+ + getSshTarget(), e);
}
}
}
protected void checkExitStatus(Channel channel) {
if (channel.isClosed()) {
- int exitStatus = channel.getExitStatus();
- if (exitStatus == 0) {
+ lastExitStatus = channel.getExitStatus();
+ if (lastExitStatus == 0) {
if (log.isTraceEnabled())
- log.trace("Remote execution exit status: " + exitStatus);
+ log.trace("Remote execution exit status: " + lastExitStatus);
} else {
String msg = "Remote execution failed with " + " exit status: "
- + exitStatus;
+ + lastExitStatus;
if (failOnBadExitStatus)
throw new SlcException(msg);
else
return out;
}
+ public Integer getLastExitStatus() {
+ return lastExitStatus;
+ }
+
+ public void setStreamHandler(ExecuteStreamHandler executeStreamHandler) {
+ this.streamHandler = executeStreamHandler;
+ }
+
public void setCommand(String command) {
this.command = command;
}