Linux Tools Project/Remote Tools

From Eclipsepedia

Jump to: navigation, search

Contents

Models

There are 2 remote models that Linux Tools intends to support.

  1. Remote Profiling Model
    • Local build, remote execution/profiling/debugging
  2. Remote Project Model
    • Remote build/execution/profiling/debug

The Remote Profiling Model is one whereby the project builds locally but special remote launchers are added that allow the user to perform profiling on a compatible remote target. Compatibility includes the platform, required libraries, and installation requirements. As one can guess, this can be difficult when the host and target machines are maintained separately and some systems are completely incompatible (e.g. ppc vs x86). The remote profiling launcher allows the user to specify a remote location to upload the executable to for the purposes of performing profiling. All results of the profiling are shown in the local Eclipse session. At the moment, only Valgrind has support for this remote launching.

The Remote Project Model does away with the compatibility requirement by keeping the project source code on the remote target and building/executing remotely. The host Eclipse session can view the project files and results. To the end-user, the project appears for all purposes the same as a local project though there may be some lag in viewing files and editing them as they must be shuttled across the network. The location of the project is set when the project is initially created. For a C/C++ project, the project wizards have a check-box for specifying a location other than in the current workspace. Once checked, the user has a choice of file systems to use to specify the location. When RSE (Remote System Explorer) is installed, the user has a choice of local or rse. Using RSE, a remote location can be specified, assuming that an RSE connection has been registered for this remote target. Registering a remote location via RSE does not mean that a connection has been established yet. With the remote project model, tools are expected to be location-agnostic and handle the remote location internally. This means that there should be no UI changes required and a user that is familiar with how a local project works can easily use a remote project.

Remote Profiling Framework

The remote profiling framework is found in the linuxtools/profiling component. The main feature is org.eclipse.linuxtools.profiling.remote-feature. The feature is currently not built as part of the Linux tools Hudson builds so one must check-out the source from git and either build manually or use within a child Eclipse: see Linux Tools Project/Git for details on checking out code from the Linux tools git repository.

The framework provides a class: org.eclipse.linuxtools.profiling.launch.remote.RemoteConnection. This class is used to upload/download files as well as start execution on the remote platform. The following details the various methods provided:

  • public void upload(IPath localPath, IPath remotePath, IProgressMonitor monitor) throws RemoteConnectionException
    • Upload files to remote target directory. This method is recursive. If a local directory is specified as the input, then all folders and files are uploaded to the remote target directory. The remote target directory must exist prior to calling this method or else failure will occur. A RemoteConnectionException is thrown on any failure condition.
  • public void download(IPath remotePath, IPath localPath, IProgressMonitor monitor) throws RemoteConnectionException
    • Download a file or folder from a remote system. The method is recursive. If a remote folder is specified, all the contents of the folder are downloaded, including folders, and placed under the directory specified by the localPath variable. It is assumed that any remote non-binary file is UTF-8. A RemoteConnectionException is thrown if any failure occurs.
  • public void createFolder(IPath remoteFolderPath, IProgressMonitor monitor) throws RemoteConnectionException
    • Create a folder on the remote system. A RemoteConnectionException is thrown if any failure occurs.
  • public int runCommand(String command, IPath remoteWorkingDir, ArrayList<String> output, IProgressMonitor monitor) throws RemoteConnectionException
    • Run a command on the remote system. The return code of the command is returned.
  • public void delete(IPath remotePath, IProgressMonitor monitor) throws RemoteConnectionException
    • Remote delete function. This method is recursive. If a remote directory is specified, the remote directory and all its contents are removed. A RemoteConnectionException is thrown if failure occurs for any reason.

For supplementing the UI for the profiler launchers, a tab page is provided: org.eclipse.linuxtools.profiling.launch.remote.RemoteTab. The RemoteTab class is abstract and is meant to be extended. The RemoteTab class presents the user with a list of potential connections to use for the remote execution/profiling and stores whatever choice the user makes inside the ILauncherDelegate instance. The ILauncherDelegate instance is used as input to construct the RemoteConnection class.

The RemoteTab has some callback methods that should be provided by the extending class:

  • protected void localCreateControl(Composite top)
    • This callback is called at the end of the createControl method of the RemoteTab and is used to add widgets to the tab such as target location to run/profile the executable or working directory, for example. This is a callback so that the RemoteTab can be in control of the layout of the overall page.
  • public void localInitializeFrom(ILaunchConfiguration configuration) throws CoreException
    • This callback is called at initialization and is used to initialize any fields of the tab based on the launch configuration. It is a callback so that the RemoteTab can initialize first and the isInitializing flag of the RemoteTab can be set to false once the callback has returned.

Other methods may be overridden as part of normal inheritance.

An example of extending the RemoteTab can be found in org.eclipse.linuxtools.internal.valgrind.launch.remote.ValgrindRemoteTab found in the Linux Tools profiling/org.eclipse.linuxtools.valgrind.launch.remote plug-in. The tab adds 3 widgets for the end-user to specify the location of the Valgrind binary on the remote target, the remote directory to upload and profile the executable, and the remote location to store the output data into. When the fields are set, the information is stored inside the ILaunchConfigurationWorkingCopy.

        @Override
	public void performApply(ILaunchConfigurationWorkingCopy configuration) {
		super.performApply(configuration);
		configuration.setAttribute(ValgrindRemoteLaunchConstants.ATTR_REMOTE_VALGRINDLOC, valgrindLocText.getText());
		configuration.setAttribute(ValgrindRemoteLaunchConstants.ATTR_REMOTE_DESTDIR, destDirText.getText());
		configuration.setAttribute(ValgrindRemoteLaunchConstants.ATTR_REMOTE_OUTPUTDIR, tmpDirText.getText());
	}

Thus, the launch delegate code only needs to extract these fields from the ILaunchConfiguration attributes.

The ValgrindRemoteTab is added to the UI simply by placing it in the ProfileRemoteLaunchConfigurationTabGroup as follows:

/******************************************************************************* 
 * Copyright (c) 2010 Elliott Baron
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Elliott Baron <ebaron@fedoraproject.org> - initial API and implementation
 *******************************************************************************/ 

package org.eclipse.linuxtools.internal.valgrind.launch.remote; 

import org.eclipse.debug.ui.AbstractLaunchConfigurationTab; 
import org.eclipse.linuxtools.internal.valgrind.launch.ValgrindOptionsTab; 
import org.eclipse.linuxtools.profiling.launch.remote.ProfileRemoteLaunchConfigurationTabGroup;

public class ValgrindRemoteLaunchTabGroup extends ProfileRemoteLaunchConfigurationTabGroup { 

  @Override public AbstractLaunchConfigurationTab[] getProfileTabs() { 
    return new AbstractLaunchConfigurationTab[] { new ValgrindRemoteTab(), new ValgrindOptionsTab(false) }; 
  } 

}

Remote Project Framework

The Remote Project Framework adds a proxy for performing file access, command execution, and querying the OS of the remote target. At present, the framework is only found in the rdt branch of Linux Tools.

The remote proxy is retrieved via the RemoteProxyManager: org.eclipse.linuxtools.profiling.launch.RemoteProxyManager which is obtained via:

IRemoteProxyManager x = RemoteProxyManager.getInstance();

The IRemoteProxyManager interface is defined as follows:

public interface IRemoteProxyManager {
	String EXTENSION_POINT_ID = "RemoteProxyManager"; //$NON-NLS-1$
	String MANAGER_NAME = "manager"; //$NON-NLS-1$
	String SCHEME_ID = "scheme"; //$NON-NLS-1$ 
	public IRemoteFileProxy getFileProxy(IProject project) throws CoreException;
	public IRemoteFileProxy getFileProxy(URI uri) throws CoreException;
	public IRemoteCommandLauncher getLauncher(IProject project) throws CoreException;
	public IRemoteCommandLauncher getLauncher(URI uri) throws CoreException;
	public String getOS(IProject project) throws CoreException;
	public String getOS(URI uri) throws CoreException;
}

The three main interfaces: getFileProxy(), getLauncher(), and getOS() are used to fetch more-specific proxys based on the task required. The getXXXProxy() methods can either accept a project or URI as input. In the case of a remote project, the project would be passed. The URI interfaces are added to allow re-use by the Remote Profiling framework whereby the project is local and the target is picked at profiling time by the end-user.

For file access, the IRemoteFileProxy is used.

public interface IRemoteFileProxy {
	
	public URI toURI(IPath path);
	public URI toURI(String path);
	public String toPath(URI uri);
	public String getDirectorySeparator();
	public IFileStore getResource(String path);

}

The IRemoteFileProxy allows code to reference paths on the remote system using regular path syntax. This is beneficial in that UI dialogs can be common for shared for local and remote project use and do not require rewriting to use URI syntax. Paths can be converted to URIs where necessary and vice-versa. Ultimately, a file is accessed via an IFileStore rather than a Java File. The IFileStore is part of the EFS (Eclipse File System) and supports external file access.

To alter code to use the IRemoteFileProxy, the following rules must be followed:

  1. No use of java.io.File for files that may be remote
    • Instead, files can be read/written to using the IFileStore interfaces: openInputStream() and openOutputStream()
    • Checking for existence is done via IFileStore.fetchInfo().exists()
    • New directories are created via IFileStore.mkdir()
    • Files can be deleted via IFileStore.delete()
    • Directories can be traversed via IFileStore.childStores() method
  2. No use of Resource.getLocation()
    • The Resource getLocation() method returns null for non-local resources
    • Instead use getLocationURI() and either translate to a simple path or get a resource using getResource()

The following shows an example that interacts with the IBuilder class which stores the build directory as an IPath:

                IRemoteFileProxy proxy = RemoteProxyManager.getInstance().getFileProxy(project);
		IBuilder b = c.getBuilder();
		IPath buildDirectory = b.getBuildLocation();
		if (buildDirectory == null || buildDirectory.isEmpty()) {
			// default build directory to project directory
			URI projectURI = project.getLocationURI();
			buildDirectory = new Path(proxy.toPath(projectURI));
		}
		buildLocation = buildDirectory;

Notice how we use the proxy to convert the project's URI into a usable path. Using getLocation() to get the project's path would result in null being returned.

Remote Proxy Extension

By default, the RemoteProxyManager supports the local file system. For remote access, the RemoteProxyManager provides an extension so that plug-ins can provide a RemoteProxyManager for various file systems such as RSE (Remote System Explorer) and RDT (Remote Development Tools) server support. This design allows a local version of the various tools to be used without requiring a remote systems provider such as RSE or RDT be present. The extension: org.eclipse.linuxtools.profiling.launch.RemoteProxyManager is used by plug-ins to supply optional remote capability. Each extension supplies a manager in the form of a class that implements IRemoteProxyManager and a scheme which specifies the URI scheme that this manager supports. For example, an RSE URI is always prefixed by "rse:" and an RDT URI may be prefixed by "remotetools:". The RemoteProxyManager looks at the URI and gets its scheme via URI.getScheme(). It will then look for available extensions and will use the first one that supports the scheme.

Currently, the rdt branch supplies a RemoteProxyManager in the form of: org.eclipse.linuxtools.rdt.proxy which uses the PTP RDT classes to implement a RemoteProxyManager that supports both RSE and RDT file URIs. The org.eclipse.linuxtools.profiling.remote-feature includes this plug-in and thus installing this feature provides support for remote projects.

At present, just the Autotools plug-ins have been converted to use the Remote Project Model. To use them, one just also use a special branch of the CDT that has been converted to use a similar proxy system. This special CDT branch can be downloaded from [1].