1 package org
.argeo
.slc
.jsch
;
3 import java
.io
.BufferedReader
;
4 import java
.io
.InputStream
;
5 import java
.io
.InputStreamReader
;
6 import java
.util
.ArrayList
;
9 import org
.apache
.commons
.io
.IOUtils
;
10 import org
.apache
.commons
.logging
.Log
;
11 import org
.apache
.commons
.logging
.LogFactory
;
12 import org
.argeo
.slc
.SlcException
;
13 import org
.argeo
.slc
.core
.execution
.tasks
.SystemCall
;
15 import com
.jcraft
.jsch
.Channel
;
16 import com
.jcraft
.jsch
.ChannelExec
;
17 import com
.jcraft
.jsch
.Session
;
19 public class RemoteExec
extends AbstractJschTask
{
20 private final static Log log
= LogFactory
.getLog(RemoteExec
.class);
22 private Boolean failOnBadExitStatus
= true;
24 private List
<String
> commands
= new ArrayList
<String
>();
25 private String command
;
26 private SystemCall systemCall
;
27 private List
<SystemCall
> systemCalls
= new ArrayList
<SystemCall
>();
29 public void run(Session session
) {
30 // convert system calls
31 if (systemCall
!= null) {
33 throw new SlcException("Cannot specify command AND systemCall");
34 command
= convertSystemCall(systemCall
);
37 if (systemCalls
.size() != 0) {
38 if (commands
.size() != 0)
39 throw new SlcException(
40 "Cannot specify commands AND systemCalls");
41 for (SystemCall systemCall
: systemCalls
)
42 commands
.add(convertSystemCall(systemCall
));
46 if (command
!= null) {
47 if (commands
.size() != 0)
48 throw new SlcException(
49 "Specify either a single command or a list of commands.");
50 remoteExec(session
, command
);
52 if (commands
.size() == 0)
53 throw new SlcException(
54 "Neither a single command or a list of commands has been specified.");
56 for (String cmd
: commands
) {
57 remoteExec(session
, cmd
);
62 protected String
convertSystemCall(SystemCall systemCall
) {
63 // TODO: prepend environemnt variables
64 // TODO: deal with exec dir
65 return systemCall
.asCommand();
68 protected void remoteExec(Session session
, String command
) {
69 BufferedReader execIn
= null;
71 Channel channel
= session
.openChannel("exec");
72 ((ChannelExec
) channel
).setCommand(command
);
75 // channel.setXForwarding(true);
77 // channel.setInputStream(System.in);
78 channel
.setInputStream(null);
80 ((ChannelExec
) channel
).setErrStream(System
.err
);
82 InputStream in
= channel
.getInputStream();
84 if (log
.isDebugEnabled())
85 log
.debug("Run '" + command
+ "' on " + getSshTarget() + "...");
89 // byte[] tmp = new byte[1024];
91 execIn
= new BufferedReader(new InputStreamReader(in
));
93 while ((line
= execIn
.readLine()) != null) {
94 if (!line
.trim().equals(""))
98 if (channel
.isClosed()) {
99 int exitStatus
= channel
.getExitStatus();
100 if (exitStatus
== 0) {
101 if (log
.isTraceEnabled())
102 log
.trace("Remote execution exit status: "
105 String msg
= "Remote execution failed with "
106 + " exit status: " + exitStatus
;
107 if (failOnBadExitStatus
)
108 throw new SlcException(msg
);
117 } catch (Exception ee
) {
120 channel
.disconnect();
121 } catch (Exception e
) {
122 throw new SlcException("Cannot execute remotely '" + command
123 + "' on " + getSshTarget(), e
);
125 IOUtils
.closeQuietly(execIn
);
129 public void setCommand(String command
) {
130 this.command
= command
;
133 public void setCommands(List
<String
> commands
) {
134 this.commands
= commands
;
137 public void setFailOnBadExitStatus(Boolean failOnBadExitStatus
) {
138 this.failOnBadExitStatus
= failOnBadExitStatus
;
141 public void setSystemCall(SystemCall systemCall
) {
142 this.systemCall
= systemCall
;
145 public void setSystemCalls(List
<SystemCall
> systemCalls
) {
146 this.systemCalls
= systemCalls
;