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 | } | ||
