]> git.argeo.org Git - gpl/argeo-slc.git/blob - runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/jsch/RemoteExec.java
1295209867bcc84bb6fdd6f72c0780c7c2701c7d
[gpl/argeo-slc.git] / runtime / org.argeo.slc.support.simple / src / main / java / org / argeo / slc / jsch / RemoteExec.java
1 package org.argeo.slc.jsch;
2
3 import java.io.BufferedReader;
4 import java.io.InputStream;
5 import java.io.InputStreamReader;
6 import java.util.ArrayList;
7 import java.util.List;
8
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;
14
15 import com.jcraft.jsch.Channel;
16 import com.jcraft.jsch.ChannelExec;
17 import com.jcraft.jsch.Session;
18
19 public class RemoteExec extends AbstractJschTask {
20 private final static Log log = LogFactory.getLog(RemoteExec.class);
21
22 private Boolean failOnBadExitStatus = true;
23
24 private List<String> commands = new ArrayList<String>();
25 private String command;
26 private SystemCall systemCall;
27 private List<SystemCall> systemCalls = new ArrayList<SystemCall>();
28
29 public void run(Session session) {
30 // convert system calls
31 if (systemCall != null) {
32 if (command != null)
33 throw new SlcException("Cannot specify command AND systemCall");
34 command = convertSystemCall(systemCall);
35 }
36
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));
43 }
44
45 // execute command(s)
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);
51 } else {
52 if (commands.size() == 0)
53 throw new SlcException(
54 "Neither a single command or a list of commands has been specified.");
55
56 for (String cmd : commands) {
57 remoteExec(session, cmd);
58 }
59 }
60 }
61
62 protected String convertSystemCall(SystemCall systemCall) {
63 // TODO: prepend environemnt variables
64 // TODO: deal with exec dir
65 return systemCall.asCommand();
66 }
67
68 protected void remoteExec(Session session, String command) {
69 BufferedReader execIn = null;
70 try {
71 Channel channel = session.openChannel("exec");
72 ((ChannelExec) channel).setCommand(command);
73
74 // X Forwarding
75 // channel.setXForwarding(true);
76
77 // channel.setInputStream(System.in);
78 channel.setInputStream(null);
79
80 ((ChannelExec) channel).setErrStream(System.err);
81
82 InputStream in = channel.getInputStream();
83
84 if (log.isDebugEnabled())
85 log.debug("Run '" + command + "' on " + getSshTarget() + "...");
86
87 channel.connect();
88
89 // byte[] tmp = new byte[1024];
90 while (true) {
91 execIn = new BufferedReader(new InputStreamReader(in));
92 String line = null;
93 while ((line = execIn.readLine()) != null) {
94 if (!line.trim().equals(""))
95 log.info(line);
96 }
97
98 if (channel.isClosed()) {
99 int exitStatus = channel.getExitStatus();
100 if (exitStatus == 0) {
101 if (log.isTraceEnabled())
102 log.trace("Remote execution exit status: "
103 + exitStatus);
104 } else {
105 String msg = "Remote execution failed with "
106 + " exit status: " + exitStatus;
107 if (failOnBadExitStatus)
108 throw new SlcException(msg);
109 else
110 log.error(msg);
111 }
112
113 break;
114 }
115 try {
116 Thread.sleep(1000);
117 } catch (Exception ee) {
118 }
119 }
120 channel.disconnect();
121 } catch (Exception e) {
122 throw new SlcException("Cannot execute remotely '" + command
123 + "' on " + getSshTarget(), e);
124 } finally {
125 IOUtils.closeQuietly(execIn);
126 }
127 }
128
129 public void setCommand(String command) {
130 this.command = command;
131 }
132
133 public void setCommands(List<String> commands) {
134 this.commands = commands;
135 }
136
137 public void setFailOnBadExitStatus(Boolean failOnBadExitStatus) {
138 this.failOnBadExitStatus = failOnBadExitStatus;
139 }
140
141 public void setSystemCall(SystemCall systemCall) {
142 this.systemCall = systemCall;
143 }
144
145 public void setSystemCalls(List<SystemCall> systemCalls) {
146 this.systemCalls = systemCalls;
147 }
148
149 }