diff options
Diffstat (limited to 'plugins/org.yocto.remote.utils/src/org/yocto/remote/utils/RSEHelper.java')
-rw-r--r-- | plugins/org.yocto.remote.utils/src/org/yocto/remote/utils/RSEHelper.java | 344 |
1 files changed, 344 insertions, 0 deletions
diff --git a/plugins/org.yocto.remote.utils/src/org/yocto/remote/utils/RSEHelper.java b/plugins/org.yocto.remote.utils/src/org/yocto/remote/utils/RSEHelper.java new file mode 100644 index 0000000..201c944 --- /dev/null +++ b/plugins/org.yocto.remote.utils/src/org/yocto/remote/utils/RSEHelper.java | |||
@@ -0,0 +1,344 @@ | |||
1 | /******************************************************************************** | ||
2 | * Copyright (c) 2013 MontaVista Software, Inc and Others. | ||
3 | * This program and the accompanying materials are made available under the terms | ||
4 | * of the Eclipse Public License v1.0 which accompanies this distribution, and is | ||
5 | * available at http://www.eclipse.org/legal/epl-v10.html | ||
6 | * | ||
7 | * Contributors: | ||
8 | * Anna Dushistova (MontaVista) - initial API and implementation | ||
9 | * Lianhao Lu (Intel) - Modified to add other file operations. | ||
10 | * Ioana Grigoropol (Intel) - Separated remote functionality | ||
11 | ********************************************************************************/ | ||
12 | package org.yocto.remote.utils; | ||
13 | |||
14 | import java.io.BufferedInputStream; | ||
15 | import java.io.BufferedOutputStream; | ||
16 | import java.io.File; | ||
17 | import java.io.FileOutputStream; | ||
18 | import java.io.InputStream; | ||
19 | import java.util.ArrayList; | ||
20 | import java.util.Arrays; | ||
21 | import java.util.Iterator; | ||
22 | |||
23 | import org.eclipse.core.runtime.CoreException; | ||
24 | import org.eclipse.core.runtime.FileLocator; | ||
25 | import org.eclipse.core.runtime.IProgressMonitor; | ||
26 | import org.eclipse.core.runtime.IStatus; | ||
27 | import org.eclipse.core.runtime.MultiStatus; | ||
28 | import org.eclipse.core.runtime.OperationCanceledException; | ||
29 | import org.eclipse.core.runtime.Path; | ||
30 | import org.eclipse.core.runtime.Status; | ||
31 | import org.eclipse.core.runtime.SubProgressMonitor; | ||
32 | import org.eclipse.osgi.util.NLS; | ||
33 | import org.eclipse.rse.core.IRSECoreStatusCodes; | ||
34 | import org.eclipse.rse.core.IRSESystemType; | ||
35 | import org.eclipse.rse.core.RSECorePlugin; | ||
36 | import org.eclipse.rse.core.model.IHost; | ||
37 | import org.eclipse.rse.core.model.ISubSystemConfigurationCategories; | ||
38 | import org.eclipse.rse.core.model.ISystemRegistry; | ||
39 | import org.eclipse.rse.core.subsystems.ISubSystem; | ||
40 | import org.eclipse.rse.services.IService; | ||
41 | import org.eclipse.rse.services.files.IFileService; | ||
42 | import org.eclipse.rse.services.shells.HostShellProcessAdapter; | ||
43 | import org.eclipse.rse.services.shells.IHostShell; | ||
44 | import org.eclipse.rse.services.shells.IShellService; | ||
45 | import org.eclipse.rse.subsystems.files.core.servicesubsystem.IFileServiceSubSystem; | ||
46 | import org.eclipse.rse.subsystems.shells.core.subsystems.servicesubsystem.IShellServiceSubSystem; | ||
47 | import org.eclipse.rse.subsystems.terminals.core.ITerminalServiceSubSystem; | ||
48 | |||
49 | public class RSEHelper { | ||
50 | private final static String EXIT_CMD = "exit"; //$NON-NLS-1$ | ||
51 | private final static String CMD_DELIMITER = ";"; //$NON-NLS-1$ | ||
52 | |||
53 | public static IHost getRemoteConnectionByName(String remoteConnection) { | ||
54 | if (remoteConnection == null) | ||
55 | return null; | ||
56 | IHost[] connections = RSECorePlugin.getTheSystemRegistry().getHosts(); | ||
57 | for (int i = 0; i < connections.length; i++) | ||
58 | if (connections[i].getAliasName().equals(remoteConnection)) | ||
59 | return connections[i]; | ||
60 | return null; // TODO Connection is not found in the list--need to react | ||
61 | // somehow, throw the exception? | ||
62 | |||
63 | } | ||
64 | |||
65 | public static IService getConnectedRemoteFileService( | ||
66 | IHost currentConnection, IProgressMonitor monitor) throws Exception { | ||
67 | final ISubSystem subsystem = getFileSubsystem(currentConnection); | ||
68 | |||
69 | if (subsystem == null) | ||
70 | throw new Exception(Messages.ErrorNoSubsystem); | ||
71 | |||
72 | try { | ||
73 | subsystem.connect(monitor, false); | ||
74 | } catch (CoreException e) { | ||
75 | throw e; | ||
76 | } catch (OperationCanceledException e) { | ||
77 | throw new CoreException(Status.CANCEL_STATUS); | ||
78 | } | ||
79 | |||
80 | if (!subsystem.isConnected()) | ||
81 | throw new Exception(Messages.ErrorConnectSubsystem); | ||
82 | |||
83 | return ((IFileServiceSubSystem) subsystem).getFileService(); | ||
84 | } | ||
85 | |||
86 | public static ISubSystem getFileSubsystem(IHost host) { | ||
87 | if (host == null) | ||
88 | return null; | ||
89 | ISubSystem[] subSystems = host.getSubSystems(); | ||
90 | for (int i = 0; i < subSystems.length; i++) { | ||
91 | if (subSystems[i] instanceof IFileServiceSubSystem) | ||
92 | return subSystems[i]; | ||
93 | } | ||
94 | return null; | ||
95 | } | ||
96 | |||
97 | public static IService getConnectedShellService( | ||
98 | IHost currentConnection, IProgressMonitor monitor) throws Exception { | ||
99 | final ISubSystem subsystem = getShellSubsystem(currentConnection); | ||
100 | |||
101 | if (subsystem == null) | ||
102 | throw new Exception(Messages.ErrorNoSubsystem); | ||
103 | |||
104 | try { | ||
105 | subsystem.connect(monitor, false); | ||
106 | } catch (CoreException e) { | ||
107 | throw e; | ||
108 | } catch (OperationCanceledException e) { | ||
109 | throw new CoreException(Status.CANCEL_STATUS); | ||
110 | } | ||
111 | |||
112 | if (!subsystem.isConnected()) | ||
113 | throw new Exception(Messages.ErrorConnectSubsystem); | ||
114 | |||
115 | return ((IShellServiceSubSystem) subsystem).getShellService(); | ||
116 | } | ||
117 | |||
118 | public static ISubSystem getShellSubsystem(IHost host) { | ||
119 | if (host == null) | ||
120 | return null; | ||
121 | ISubSystem[] subSystems = host.getSubSystems(); | ||
122 | for (int i = 0; i < subSystems.length; i++) { | ||
123 | if (subSystems[i] instanceof IShellServiceSubSystem) | ||
124 | return subSystems[i]; | ||
125 | } | ||
126 | return null; | ||
127 | } | ||
128 | |||
129 | public static IHost[] getSuitableConnections() { | ||
130 | |||
131 | //we only get RSE connections with files&cmds subsystem | ||
132 | ArrayList <IHost> filConnections = new ArrayList <IHost>(Arrays.asList(RSECorePlugin.getTheSystemRegistry() | ||
133 | .getHostsBySubSystemConfigurationCategory(ISubSystemConfigurationCategories.SUBSYSTEM_CATEGORY_FILES))); //$NON-NLS-1$ | ||
134 | |||
135 | ArrayList <IHost> terminalConnections = new ArrayList <IHost>(Arrays.asList(RSECorePlugin.getTheSystemRegistry() | ||
136 | .getHostsBySubSystemConfigurationCategory("terminal")));//$NON-NLS-1$ | ||
137 | |||
138 | ArrayList <IHost> shellConnections = new ArrayList <IHost>(Arrays.asList(RSECorePlugin.getTheSystemRegistry() | ||
139 | .getHostsBySubSystemConfigurationCategory("shells"))); //$NON-NLS-1$ | ||
140 | |||
141 | Iterator <IHost>iter = filConnections.iterator(); | ||
142 | while(iter.hasNext()){ | ||
143 | IHost fileConnection = iter.next(); | ||
144 | if(!terminalConnections.contains(fileConnection) && !shellConnections.contains(fileConnection)){ | ||
145 | iter.remove(); | ||
146 | } | ||
147 | IRSESystemType sysType = fileConnection.getSystemType(); | ||
148 | if (sysType == null || !sysType.isEnabled()) { | ||
149 | iter.remove(); | ||
150 | } | ||
151 | } | ||
152 | |||
153 | return filConnections.toArray(new IHost[filConnections.size()]); | ||
154 | } | ||
155 | |||
156 | public static void putRemoteFileInPlugin(IHost connection, String locaPathInPlugin, String remoteExePath, | ||
157 | IProgressMonitor monitor) throws Exception { | ||
158 | |||
159 | assert(connection != null); | ||
160 | monitor.beginTask(Messages.InfoUpload, 100); | ||
161 | |||
162 | IFileService fileService; | ||
163 | try { | ||
164 | fileService = (IFileService) getConnectedRemoteFileService( | ||
165 | connection, | ||
166 | new SubProgressMonitor(monitor, 5)); | ||
167 | InputStream inputStream = FileLocator.openStream( | ||
168 | Activator.getDefault().getBundle(), new Path(locaPathInPlugin), false); | ||
169 | Path remotePath = new Path(remoteExePath); | ||
170 | |||
171 | //TODO workaround for now | ||
172 | //in case the underlying scp file service doesn't support inputStream upload | ||
173 | BufferedInputStream bis = new BufferedInputStream(inputStream); | ||
174 | File tempFile = File.createTempFile("scp", "temp"); //$NON-NLS-1$ //$NON-NLS-2$ | ||
175 | FileOutputStream os = new FileOutputStream(tempFile); | ||
176 | BufferedOutputStream bos = new BufferedOutputStream(os); | ||
177 | byte[] buffer = new byte[1024]; | ||
178 | int readCount; | ||
179 | while( (readCount = bis.read(buffer)) > 0) | ||
180 | { | ||
181 | bos.write(buffer, 0, readCount); | ||
182 | } | ||
183 | bos.close(); | ||
184 | fileService.upload(tempFile, remotePath.removeLastSegments(1) | ||
185 | .toString(), remotePath.lastSegment(), true, null, null, | ||
186 | new SubProgressMonitor(monitor, 80)); | ||
187 | // Need to change the permissions to match the original file | ||
188 | // permissions because of a bug in upload | ||
189 | remoteShellExec( | ||
190 | connection, | ||
191 | "", "chmod", "+x " + spaceEscapify(remotePath.toString()), new SubProgressMonitor(monitor, 5)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ | ||
192 | |||
193 | } finally { | ||
194 | monitor.done(); | ||
195 | } | ||
196 | return; | ||
197 | } | ||
198 | |||
199 | public static void getRemoteFile(IHost connection, String localExePath, String remoteExePath, | ||
200 | IProgressMonitor monitor) throws Exception { | ||
201 | |||
202 | assert(connection!=null); | ||
203 | monitor.beginTask(Messages.InfoDownload, 100); | ||
204 | |||
205 | IFileService fileService; | ||
206 | try { | ||
207 | fileService = (IFileService) getConnectedRemoteFileService( | ||
208 | connection, | ||
209 | new SubProgressMonitor(monitor, 10)); | ||
210 | File file = new File(localExePath); | ||
211 | file.deleteOnExit(); | ||
212 | monitor.worked(5); | ||
213 | Path remotePath = new Path(remoteExePath); | ||
214 | fileService.download(remotePath.removeLastSegments(1).toString(), | ||
215 | remotePath.lastSegment(),file,true, null, | ||
216 | new SubProgressMonitor(monitor, 85)); | ||
217 | // Need to change the permissions to match the original file | ||
218 | // permissions because of a bug in upload | ||
219 | //RemoteApplication p = remoteShellExec( | ||
220 | // config, | ||
221 | // "", "chmod", "+x " + spaceEscapify(remotePath.toString()), new SubProgressMonitor(monitor, 5)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ | ||
222 | //Thread.sleep(500); | ||
223 | //p.destroy(); | ||
224 | |||
225 | } finally { | ||
226 | monitor.done(); | ||
227 | } | ||
228 | return; | ||
229 | } | ||
230 | |||
231 | public static ITerminalServiceSubSystem getTerminalSubSystem( | ||
232 | IHost connection) { | ||
233 | ISystemRegistry systemRegistry = RSECorePlugin.getTheSystemRegistry(); | ||
234 | ISubSystem[] subsystems = systemRegistry.getSubSystems(connection); | ||
235 | for (int i = 0; i < subsystems.length; i++) { | ||
236 | if (subsystems[i] instanceof ITerminalServiceSubSystem) { | ||
237 | ITerminalServiceSubSystem subSystem = (ITerminalServiceSubSystem) subsystems[i]; | ||
238 | return subSystem; | ||
239 | } | ||
240 | } | ||
241 | return null; | ||
242 | } | ||
243 | |||
244 | public static String spaceEscapify(String inputString) { | ||
245 | if (inputString == null) | ||
246 | return null; | ||
247 | |||
248 | return inputString.replaceAll(" ", "\\\\ "); //$NON-NLS-1$ //$NON-NLS-2$ | ||
249 | } | ||
250 | |||
251 | public static Process remoteShellExec(IHost connection, | ||
252 | String prelaunchCmd, String remoteCommandPath, String arguments, | ||
253 | IProgressMonitor monitor) throws CoreException { | ||
254 | |||
255 | monitor.beginTask(NLS.bind(Messages.RemoteShellExec_1, | ||
256 | remoteCommandPath, arguments), 10); | ||
257 | String realRemoteCommand = arguments == null ? spaceEscapify(remoteCommandPath) | ||
258 | : spaceEscapify(remoteCommandPath) + " " + arguments; //$NON-NLS-1$ | ||
259 | |||
260 | String remoteCommand = realRemoteCommand + CMD_DELIMITER + EXIT_CMD; | ||
261 | |||
262 | if(prelaunchCmd != null) { | ||
263 | if (!prelaunchCmd.trim().equals("")) //$NON-NLS-1$ | ||
264 | remoteCommand = prelaunchCmd + CMD_DELIMITER + remoteCommand; | ||
265 | } | ||
266 | |||
267 | IShellService shellService; | ||
268 | Process p = null; | ||
269 | try { | ||
270 | shellService = (IShellService) getConnectedShellService( | ||
271 | connection, | ||
272 | new SubProgressMonitor(monitor, 7)); | ||
273 | |||
274 | // This is necessary because runCommand does not actually run the | ||
275 | // command right now. | ||
276 | String env[] = new String[0]; | ||
277 | try { | ||
278 | IHostShell hostShell = shellService.launchShell( | ||
279 | "", env, new SubProgressMonitor(monitor, 3)); //$NON-NLS-1$ | ||
280 | hostShell.writeToShell(remoteCommand); | ||
281 | p = new HostShellProcessAdapter(hostShell); | ||
282 | } catch (Exception e) { | ||
283 | if (p != null) { | ||
284 | p.destroy(); | ||
285 | } | ||
286 | abort(Messages.RemoteShellExec_2, e, | ||
287 | IRSECoreStatusCodes.EXCEPTION_OCCURRED); | ||
288 | } | ||
289 | } catch (Exception e1) { | ||
290 | abort(e1.getMessage(), e1, | ||
291 | IRSECoreStatusCodes.EXCEPTION_OCCURRED); | ||
292 | } | ||
293 | |||
294 | monitor.done(); | ||
295 | return p; | ||
296 | } | ||
297 | |||
298 | /** | ||
299 | * Throws a core exception with an error status object built from the given | ||
300 | * message, lower level exception, and error code. | ||
301 | * | ||
302 | * @param message | ||
303 | * the status message | ||
304 | * @param exception | ||
305 | * lower level exception associated with the error, or | ||
306 | * <code>null</code> if none | ||
307 | * @param code | ||
308 | * error code | ||
309 | */ | ||
310 | public static void abort(String message, Throwable exception, int code) throws CoreException { | ||
311 | IStatus status; | ||
312 | if (exception != null) { | ||
313 | MultiStatus multiStatus = new MultiStatus(Activator.PLUGIN_ID, code, message, exception); | ||
314 | multiStatus.add(new Status(IStatus.ERROR, Activator.PLUGIN_ID, code, exception.getLocalizedMessage(), exception)); | ||
315 | status = multiStatus; | ||
316 | } else { | ||
317 | status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, code, message, null); | ||
318 | } | ||
319 | throw new CoreException(status); | ||
320 | } | ||
321 | /** | ||
322 | * Checks whether a IHost associated system's is enabled and not a local one | ||
323 | * @param host | ||
324 | * @return | ||
325 | */ | ||
326 | public static boolean isHostViable(IHost host) { | ||
327 | IRSESystemType sysType = host.getSystemType(); | ||
328 | if (sysType != null && sysType.isEnabled() && !sysType.isLocal()) | ||
329 | return true; | ||
330 | return false; | ||
331 | } | ||
332 | |||
333 | /** | ||
334 | * Ensures that RSECorePlugin is initialized before performing any actions | ||
335 | */ | ||
336 | public static void waitForRSEInitCompletition() { | ||
337 | if (!RSECorePlugin.isInitComplete(RSECorePlugin.INIT_MODEL)) | ||
338 | try { | ||
339 | RSECorePlugin.waitForInitCompletion(RSECorePlugin.INIT_MODEL); | ||
340 | } catch (InterruptedException e) { | ||
341 | return; | ||
342 | } | ||
343 | } | ||
344 | } | ||