X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=runtime%2Forg.argeo.slc.support.simple%2Fsrc%2Fmain%2Fjava%2Forg%2Fargeo%2Fslc%2Fjsch%2FRemoteExec.java;h=691d0d63329914e6366d6409517c8a5e5152a2f7;hb=04ef2e4533e909122a560a5cb6499fa62bac82ec;hp=9569be35b31a3ab06d9fca5c0e854a6a5cab57de;hpb=f1949f18a209de9f9ee110e2e2654882529b8ec5;p=gpl%2Fargeo-slc.git diff --git a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/jsch/RemoteExec.java b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/jsch/RemoteExec.java index 9569be35b..691d0d633 100644 --- a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/jsch/RemoteExec.java +++ b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/jsch/RemoteExec.java @@ -1,3 +1,18 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * 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; @@ -16,6 +31,7 @@ import java.util.List; 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; @@ -50,6 +66,9 @@ public class RemoteExec extends AbstractJschTask { 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. @@ -90,8 +109,8 @@ public class RemoteExec extends AbstractJschTask { 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)) @@ -236,29 +255,24 @@ public class RemoteExec extends AbstractJschTask { // Standard Error readStdErr(channel); - if (log.isDebugEnabled()) - log.debug("Run '" + command + "' on " + getSshTarget() + "..."); + if (log.isTraceEnabled()) + log.trace("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) { @@ -267,76 +281,117 @@ public class RemoteExec extends AbstractJschTask { } } - 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 @@ -363,6 +418,14 @@ public class RemoteExec extends AbstractJschTask { return out; } + public Integer getLastExitStatus() { + return lastExitStatus; + } + + public void setStreamHandler(ExecuteStreamHandler executeStreamHandler) { + this.streamHandler = executeStreamHandler; + } + public void setCommand(String command) { this.command = command; }