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=814e080481219641027d74f96df82648cf8f0eab;hb=1fdb1b4e7b1d2b0cabb6483238301b857a6392fa;hp=a4bff705297f65fec9d8b0328732fabf18e0dfe1;hpb=42ccec04f34da0ff3b3040f693b1afc65ac5ca69;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 a4bff7052..814e08048 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,7 +1,25 @@ +/* + * Copyright (C) 2010 Mathieu Baudier + * + * 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.io.BufferedWriter; +import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -18,6 +36,7 @@ import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.argeo.slc.SlcException; +import org.argeo.slc.core.execution.ExecutionResources; import org.argeo.slc.core.execution.tasks.SystemCall; import org.springframework.core.io.Resource; import org.springframework.util.StringUtils; @@ -42,6 +61,10 @@ public class RemoteExec extends AbstractJschTask { private Boolean forceShell = false; private Map env = new HashMap(); private Resource stdIn = null; + private Resource stdOut = null; + private ExecutionResources executionResources; + + private String user; /** * If set, stdout is written to it as a list of lines. Cleared before each @@ -51,6 +74,14 @@ public class RemoteExec extends AbstractJschTask { private Boolean logEvenIfStdOutLines = false; private Boolean quiet = false; + public RemoteExec() { + } + + public RemoteExec(SshTarget sshTarget, String cmd) { + setSshTarget(sshTarget); + setCommand(cmd); + } + public void run(Session session) { List commandsToUse = new ArrayList(commands); String commandToUse = command; @@ -91,9 +122,17 @@ public class RemoteExec extends AbstractJschTask { } if (forceShell) { - if (commandToUse.indexOf(';') >= 0 - || commandToUse.indexOf('\n') >= 0) { - StringTokenizer st = new StringTokenizer(commandToUse, ";\n"); + // for the time being do not interpret both \n and ; + // priority to \n + // until we know how to parse ; within "" + if (commandToUse.indexOf('\n') >= 0) { + StringTokenizer st = new StringTokenizer(commandToUse, "\n"); + while (st.hasMoreTokens()) { + String cmd = st.nextToken(); + commandsToUse.add(cmd); + } + } else if (commandToUse.indexOf(';') >= 0) { + StringTokenizer st = new StringTokenizer(commandToUse, ";"); while (st.hasMoreTokens()) { String cmd = st.nextToken(); commandsToUse.add(cmd); @@ -104,6 +143,19 @@ public class RemoteExec extends AbstractJschTask { commandToUse = null; } + // run as user + if (user != null) { + if (commandsToUse.size() > 0) { + commandsToUse.add(0, "su - " + user); + commandsToUse.add("exit"); + } else { + if (command.indexOf('\"') >= 0) + throw new SlcException( + "Don't know how to su a command with \", use shell instead."); + commandToUse = "su - " + user + " -c \"" + command + "\""; + } + } + // execute command(s) if (commandToUse != null) { if (commandsToUse.size() != 0) @@ -204,7 +256,6 @@ public class RemoteExec extends AbstractJschTask { log.debug("Run '" + command + "' on " + getSshTarget() + "..."); channel.connect(); - // write commands to shell if (stdIn != null) { Thread stdInThread = new Thread("Stdin " + getSshTarget()) { @Override @@ -212,8 +263,7 @@ public class RemoteExec extends AbstractJschTask { OutputStream out = null; try { out = channel.getOutputStream(); - IOUtils.copy(stdIn.getInputStream(), channel - .getOutputStream()); + IOUtils.copy(stdIn.getInputStream(), out); } catch (IOException e) { throw new SlcException("Cannot write stdin on " + getSshTarget(), e); @@ -257,28 +307,40 @@ public class RemoteExec extends AbstractJschTask { } protected void readStdOut(Channel channel) { - 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); + if (stdOut != null) { + OutputStream localStdOut = createOutputStream(stdOut); + try { + IOUtils.copy(channel.getInputStream(), localStdOut); + } catch (IOException e) { + throw new SlcException("Cannot redirect stdout", e); + } finally { + IOUtils.closeQuietly(localStdOut); + } + } 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); + } } } + } catch (IOException e) { + if (log.isDebugEnabled()) + log.error("Cannot read stdout from " + getSshTarget(), e); + } finally { + IOUtils.closeQuietly(stdOut); } - } catch (IOException e) { - if (log.isDebugEnabled()) - log.error("Cannot read stdout from " + getSshTarget(), e); - } finally { - IOUtils.closeQuietly(stdOut); } } @@ -300,6 +362,23 @@ public class RemoteExec extends AbstractJschTask { } + protected OutputStream createOutputStream(Resource target) { + FileOutputStream out = null; + try { + + final File file; + if (executionResources != null) + file = new File(executionResources.getAsOsPath(target, true)); + else + file = target.getFile(); + out = new FileOutputStream(file, false); + } catch (IOException e) { + log.error("Cannot get file for " + target, e); + IOUtils.closeQuietly(out); + } + return out; + } + public void setCommand(String command) { this.command = command; } @@ -360,4 +439,16 @@ public class RemoteExec extends AbstractJschTask { this.stdIn = stdIn; } + public void setStdOut(Resource stdOut) { + this.stdOut = stdOut; + } + + public void setExecutionResources(ExecutionResources executionResources) { + this.executionResources = executionResources; + } + + public void setUser(String user) { + this.user = user; + } + }