1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-22 06:02:11 +02:00

Bug 531985 - Support Container build with new Core Build

- add new ContainerTargetTypeProvider to create a new target
  for each usable Docker image from known connections
- add new ContainerGCCToolChain class which supports gcc in a
  Container for projects with Container targets
- add new ContainerGCCToolChainProvider which creates a
  ContainerGCCToolChain for each usable Docker image from
  known connections
- add new CoreBuildContainerLaunchConfigProvider class
- add new CoreBuildContainerLaunchDescriptorType class
- add new ContainerTargetLabelProvider class to support adding
  a new Container target
- add new NewContainerTargetWizard and NewContainerTargetWizardPage
  to add/edit a new Container target
- add new IContainerLaunchTarget class
- add new refreshScannerInfo method to ICBuildConfiguration interface
  to allow switching ScannerInfo when target is switched
- implement default refreshScannerInfo method in CBuildConfiguration
  which currently does nothing
- add new fetchContainerDirs method to CommandLauncherManager to
  fetch container directories for a project that is using
  Core Model and CBuildConfigurations
- add new verifyIncludePaths method to ICommandLauncherFactory2 that
  takes an ICBuildConfiguration and implement this for
  ContainerCommandLauncherFactory
- fix ContainerCommandLauncher command handling to use a list
  of Strings to preserve spaces in arguments and call new
  runCommand interface in Docker UI...as well do not link
  any args that are files if they are system directories (e.g.
  /usr /bin)
- fix getCommandLauncher in ContainerCommandLauncherFactory when
  passing an ICBuildConfiguration so that it uses the configuration's
  toolchain properties to figure out if a Container build is asked for
- fix launch method of ContainerLaunchConfigurationDelegate to check
  if working directory is null in which case use the project directory
- also add buildForLaunch method override and preLaunchCheck to
  ContainerLaunchConfigurationDelegate so it can be used for
  Core Build launching as well and ensure that the project name
  and active configuration is set properly
- in CoreBuildLaunchBarTracker, use the lastTarget to set the
  active target instead of the local field "target" as this will
  end up setting a random target as the active target.  Also
  call the new refreshScannerInfo method of the build configuration
  when the active target has changed
- add ICBuildConfiguration support to Docker LaunchShortcut such
  that properties will be set appropriately and acquired from the
  toolChain
- bump up Docker launcher version to 1.2.0

Change-Id: I074b02314f6ac6942fdf230b1dc8e154ced3088e
This commit is contained in:
Jeff Johnston 2018-03-04 18:27:51 -05:00
parent c781ba5c36
commit c9822e117e
25 changed files with 2151 additions and 153 deletions

View file

@ -296,6 +296,35 @@ public class CommandLauncherManager {
return bestLauncherFactory; return bestLauncherFactory;
} }
private ICommandLauncherFactory getBestFactory(ICBuildConfiguration config) {
// loop through list of factories and return launcher returned with
// highest priority
int highestPriority = -1;
ICommandLauncherFactory bestLauncherFactory = null;
for (ICommandLauncherFactory factory : factories) {
if (factory instanceof ICommandLauncherFactory2) {
ICommandLauncher launcher = ((ICommandLauncherFactory2)factory).getCommandLauncher(config);
if (launcher != null) {
if (priorityMapping.get(factory) > highestPriority) {
bestLauncherFactory = factory;
}
}
}
}
return bestLauncherFactory;
}
/**
* @since 6.5
*/
public List<String> processIncludePaths(ICBuildConfiguration config, List<String> includePaths) {
ICommandLauncherFactory factory = getBestFactory(config);
if (factory != null && factory instanceof ICommandLauncherFactory2) {
return ((ICommandLauncherFactory2)factory).verifyIncludePaths(config, includePaths);
}
return includePaths;
}
public void setLanguageSettingEntries(IProject project, List<? extends ICLanguageSettingEntry> entries) { public void setLanguageSettingEntries(IProject project, List<? extends ICLanguageSettingEntry> entries) {
ICommandLauncherFactory factory = getBestFactory(project); ICommandLauncherFactory factory = getBestFactory(project);
if (factory != null) { if (factory != null) {

View file

@ -10,6 +10,8 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.core; package org.eclipse.cdt.core;
import java.util.List;
import org.eclipse.cdt.core.build.ICBuildConfiguration; import org.eclipse.cdt.core.build.ICBuildConfiguration;
/** /**
@ -28,4 +30,14 @@ public interface ICommandLauncherFactory2 {
return null; return null;
} }
/**
* Process include paths and if necessary copy header files as needed.
* @param cfg - ICBuildConfiguration to process includes for
* @param includes List of include paths to process
* @return processed List of include paths
*/
public default List<String> verifyIncludePaths(ICBuildConfiguration cfg, List<String> includes) {
return includes;
}
} }

View file

@ -878,6 +878,14 @@ public abstract class CBuildConfiguration extends PlatformObject
} }
} }
/**
* @since 6.5
*/
@Override
public void refreshScannerInfo() throws CoreException {
// do nothing by default
}
@Override @Override
public void shutdown() { public void shutdown() {
// TODO persist changes // TODO persist changes

View file

@ -125,6 +125,13 @@ public interface ICBuildConfiguration extends IAdaptable, IScannerInfoProvider {
*/ */
void clean(IConsole console, IProgressMonitor monitor) throws CoreException; void clean(IConsole console, IProgressMonitor monitor) throws CoreException;
/**
* Refresh the Scanner info
*
* @since 6.5
*/
void refreshScannerInfo() throws CoreException;
/** /**
* The binaries produced by the build. * The binaries produced by the build.
* *

View file

@ -93,7 +93,7 @@ public class CoreBuildLaunchBarTracker implements ILaunchBarListener {
protected IStatus run(IProgressMonitor monitor) { protected IStatus run(IProgressMonitor monitor) {
try { try {
Map<String, String> properties = new HashMap<>(); Map<String, String> properties = new HashMap<>();
properties.putAll(target.getAttributes()); properties.putAll(lastTarget.getAttributes());
Collection<IToolChain> tcs = toolChainManager.getToolChainsMatching(properties); Collection<IToolChain> tcs = toolChainManager.getToolChainsMatching(properties);
if (!tcs.isEmpty()) { if (!tcs.isEmpty()) {
ICBuildConfiguration buildConfig = null; ICBuildConfiguration buildConfig = null;
@ -130,6 +130,8 @@ public class CoreBuildLaunchBarTracker implements ILaunchBarListener {
IProjectDescription desc = finalProject.getDescription(); IProjectDescription desc = finalProject.getDescription();
desc.setActiveBuildConfig(buildConfig.getBuildConfiguration().getName()); desc.setActiveBuildConfig(buildConfig.getBuildConfiguration().getName());
finalProject.setDescription(desc, monitor); finalProject.setDescription(desc, monitor);
// build config has changed so Scanner Info may change too which would affect indexing
buildConfig.refreshScannerInfo();
} }
} }

View file

@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2 Bundle-ManifestVersion: 2
Bundle-Name: %Plugin.name Bundle-Name: %Plugin.name
Bundle-SymbolicName: org.eclipse.cdt.docker.launcher;singleton:=true Bundle-SymbolicName: org.eclipse.cdt.docker.launcher;singleton:=true
Bundle-Version: 1.1.1.qualifier Bundle-Version: 1.2.0.qualifier
Bundle-Activator: org.eclipse.cdt.docker.launcher.DockerLaunchUIPlugin Bundle-Activator: org.eclipse.cdt.docker.launcher.DockerLaunchUIPlugin
Bundle-Vendor: %Plugin.vendor Bundle-Vendor: %Plugin.vendor
Bundle-Localization: plugin Bundle-Localization: plugin
@ -27,7 +27,9 @@ Require-Bundle: org.eclipse.ui,
org.eclipse.core.databinding.beans, org.eclipse.core.databinding.beans,
org.eclipse.jface.databinding, org.eclipse.jface.databinding,
org.eclipse.core.databinding;bundle-version="1.6.0", org.eclipse.core.databinding;bundle-version="1.6.0",
org.eclipse.core.databinding.property;bundle-version="1.6.0" org.eclipse.core.databinding.property;bundle-version="1.6.0",
org.eclipse.launchbar.ui;bundle-version="2.2.0",
com.google.gson
Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-ActivationPolicy: lazy Bundle-ActivationPolicy: lazy
Export-Package: org.eclipse.cdt.docker.launcher, Export-Package: org.eclipse.cdt.docker.launcher,

View file

@ -22,3 +22,4 @@ Container.settings=Container Settings
ContainerBuild.property.enablement=Container Build Enablement ContainerBuild.property.enablement=Container Build Enablement
ContainerBuild.property.connection=Container Build Connection ContainerBuild.property.connection=Container Build Connection
ContainerBuild.property.image=Container Build Image ContainerBuild.property.image=Container Build Image
ContainerTarget.name=Container Target

View file

@ -113,5 +113,47 @@
weight="020"> weight="020">
</tab> </tab>
</extension> </extension>
<extension
point="org.eclipse.launchbar.core.launchTargetTypes">
<launchTargetType
id="org.eclipse.cdt.docker.launcher.launchTargetType.container"
provider="org.eclipse.cdt.docker.launcher.ContainerTargetTypeProvider">
</launchTargetType>
</extension>
<extension
point="org.eclipse.launchbar.ui.launchTargetTypeUI">
<launchTargetTypeUI
id="org.eclipse.cdt.docker.launcher.launchTargetType.container"
labelProvider="org.eclipse.cdt.internal.docker.launcher.ui.launchbar.ContainerTargetLabelProvider">
</launchTargetTypeUI>
<wizard2
class="org.eclipse.cdt.internal.docker.launcher.ui.launchbar.NewContainerTargetWizard"
icon="icons/repository-middle.gif"
id="org.eclipse.cdt.docker.launcher.launchTargetType.container"
name="%ContainerTarget.name">
</wizard2>
</extension>
<extension
point="org.eclipse.cdt.core.toolChainProvider">
<provider
class="org.eclipse.cdt.internal.docker.launcher.ui.launchbar.ContainerGCCToolChainProvider"
id="org.eclipse.cdt.docker.launcher.gcc.provider">
</provider>
<type
id="org.eclipse.cdt.build.gcc"
name="GCC">
</type>
<type
id="org.eclipse.cdt.build.clang"
name="clang">
</type>
</extension>
<extension
point="org.eclipse.launchbar.core.launchBarContributions">
<configProvider
class="org.eclipse.cdt.internal.docker.launcher.ui.launchbar.CoreBuildContainerLaunchConfigProvider"
descriptorType="org.eclipse.cdt.debug.core.coreBuildDescriptorType"
priority="15">
</configProvider>
</extension>
</plugin> </plugin>

View file

@ -13,6 +13,7 @@ import java.util.Properties;
import org.eclipse.cdt.core.ICommandLauncher; import org.eclipse.cdt.core.ICommandLauncher;
import org.eclipse.cdt.core.build.ICBuildCommandLauncher; import org.eclipse.cdt.core.build.ICBuildCommandLauncher;
import org.eclipse.cdt.core.build.ICBuildConfiguration; import org.eclipse.cdt.core.build.ICBuildConfiguration;
import org.eclipse.cdt.core.build.IToolChain;
import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.internal.core.ProcessClosure; import org.eclipse.cdt.internal.core.ProcessClosure;
@ -88,6 +89,13 @@ public class ContainerCommandLauncher
@Override @Override
public void setBuildConfiguration(ICBuildConfiguration config) { public void setBuildConfiguration(ICBuildConfiguration config) {
this.fBuildConfig = config; this.fBuildConfig = config;
if (fProject == null) {
try {
fProject = config.getBuildConfiguration().getProject();
} catch (CoreException e) {
// ignore
}
}
} }
@Override @Override
@ -135,6 +143,16 @@ public class ContainerCommandLauncher
return null; return null;
} }
private boolean isSystemDir(IPath p) {
String firstSegment = p.segment(0);
if (firstSegment.equals("usr") || firstSegment.equals("opt") //$NON-NLS-1$ //$NON-NLS-2$
|| firstSegment.equals("bin") || firstSegment.equals("etc") //$NON-NLS-1$ //$NON-NLS-2$
|| firstSegment.equals("sbin")) { //$NON-NLS-1$
return true;
}
return false;
}
@Override @Override
public Process execute(IPath commandPath, String[] args, String[] env, public Process execute(IPath commandPath, String[] args, String[] env,
IPath workingDirectory, IProgressMonitor monitor) IPath workingDirectory, IProgressMonitor monitor)
@ -157,21 +175,21 @@ public class ContainerCommandLauncher
ArrayList<String> commandSegments = new ArrayList<>(); ArrayList<String> commandSegments = new ArrayList<>();
StringBuilder b = new StringBuilder(); List<String> cmdList = new ArrayList<>();
String commandString = commandPath.toPortableString(); String commandString = commandPath.toPortableString();
if (commandPath.getDevice() != null) { if (commandPath.getDevice() != null) {
commandString = "/" + commandString.replace(':', '/'); //$NON-NLS-1$ commandString = "/" + commandString.replace(':', '/'); //$NON-NLS-1$
} }
b.append(commandString); cmdList.add(commandString);
commandSegments.add(commandString); commandSegments.add(commandString);
for (String arg : args) { for (String arg : args) {
b.append(" "); //$NON-NLS-1$
String realArg = VariablesPlugin.getDefault() String realArg = VariablesPlugin.getDefault()
.getStringVariableManager().performStringSubstitution(arg); .getStringVariableManager().performStringSubstitution(arg);
if (Platform.getOS().equals(Platform.OS_WIN32)) { if (Platform.getOS().equals(Platform.OS_WIN32)) {
// check if file exists and if so, add an additional directory // check if file exists and if so, add an additional directory
IPath p = new Path(realArg); IPath p = new Path(realArg);
if (p.isValidPath(realArg) && p.getDevice() != null) { if (p.isValidPath(realArg) && p.getDevice() != null && !isSystemDir(p)) {
File f = p.toFile(); File f = p.toFile();
String modifiedArg = realArg; String modifiedArg = realArg;
// if the directory of the arg as a file exists, we mount it // if the directory of the arg as a file exists, we mount it
@ -192,7 +210,7 @@ public class ContainerCommandLauncher
// check if file directory exists and if so, add an additional // check if file directory exists and if so, add an additional
// directory // directory
IPath p = new Path(realArg); IPath p = new Path(realArg);
if (p.isValidPath(realArg)) { if (p.isValidPath(realArg) && !isSystemDir(p)) {
File f = p.toFile(); File f = p.toFile();
if (f.isFile()) { if (f.isFile()) {
f = f.getParentFile(); f = f.getParentFile();
@ -202,19 +220,12 @@ public class ContainerCommandLauncher
} }
} }
} }
b.append(realArg); cmdList.add(realArg);
commandSegments.add(realArg); commandSegments.add(realArg);
} }
commandArgs = commandSegments.toArray(new String[0]); commandArgs = commandSegments.toArray(new String[0]);
String commandDir = commandPath.removeLastSegments(1).toString();
if (commandDir.isEmpty()) {
commandDir = null;
} else if (commandPath.getDevice() != null) {
commandDir = "/" + commandDir.replace(':', '/'); //$NON-NLS-1$
}
IProject[] referencedProjects = fProject.getReferencedProjects(); IProject[] referencedProjects = fProject.getReferencedProjects();
for (IProject referencedProject : referencedProjects) { for (IProject referencedProject : referencedProjects) {
String referencedProjectPath = referencedProject.getLocation() String referencedProjectPath = referencedProject.getLocation()
@ -227,8 +238,6 @@ public class ContainerCommandLauncher
.add(referencedProjectPath); .add(referencedProjectPath);
} }
String command = b.toString();
String workingDir = workingDirectory.makeAbsolute().toPortableString(); String workingDir = workingDirectory.makeAbsolute().toPortableString();
if (workingDirectory.toPortableString().equals(".")) { //$NON-NLS-1$ if (workingDirectory.toPortableString().equals(".")) { //$NON-NLS-1$
workingDir = "/tmp"; //$NON-NLS-1$ workingDir = "/tmp"; //$NON-NLS-1$
@ -255,9 +264,12 @@ public class ContainerCommandLauncher
String connectionName = null; String connectionName = null;
String imageName = null; String imageName = null;
if (buildCfg != null) { if (buildCfg != null) {
selectedVolumeString = buildCfg.getProperty(SELECTED_VOLUMES_ID); IToolChain toolChain = buildCfg.getToolChain();
connectionName = buildCfg.getProperty(CONNECTION_ID); selectedVolumeString = toolChain.getProperty(SELECTED_VOLUMES_ID);
imageName = buildCfg.getProperty(IMAGE_ID); connectionName = toolChain
.getProperty(IContainerLaunchTarget.ATTR_CONNECTION_URI);
imageName = toolChain
.getProperty(IContainerLaunchTarget.ATTR_IMAGE_ID);
} else { } else {
ICConfigurationDescription cfgd = CoreModel.getDefault() ICConfigurationDescription cfgd = CoreModel.getDefault()
.getProjectDescription(fProject).getActiveConfiguration(); .getProjectDescription(fProject).getActiveConfiguration();
@ -301,8 +313,7 @@ public class ContainerCommandLauncher
fProcess = launcher.runCommand(connectionName, imageName, fProject, fProcess = launcher.runCommand(connectionName, imageName, fProject,
this, this,
command, cmdList,
commandDir,
workingDir, workingDir,
additionalDirs, additionalDirs,
origEnv, fEnvironment, supportStdin, privilegedMode, origEnv, fEnvironment, supportStdin, privilegedMode,

View file

@ -16,13 +16,13 @@ import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import org.eclipse.cdt.core.ICommandLauncher; import org.eclipse.cdt.core.ICommandLauncher;
import org.eclipse.cdt.core.ICommandLauncherFactory; import org.eclipse.cdt.core.ICommandLauncherFactory;
import org.eclipse.cdt.core.ICommandLauncherFactory2; import org.eclipse.cdt.core.ICommandLauncherFactory2;
import org.eclipse.cdt.core.build.ICBuildConfiguration; import org.eclipse.cdt.core.build.ICBuildConfiguration;
import org.eclipse.cdt.core.build.IToolChain;
import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.settings.model.CIncludePathEntry; import org.eclipse.cdt.core.settings.model.CIncludePathEntry;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
@ -33,6 +33,7 @@ import org.eclipse.cdt.managedbuilder.buildproperties.IOptionalBuildProperties;
import org.eclipse.cdt.managedbuilder.core.IConfiguration; import org.eclipse.cdt.managedbuilder.core.IConfiguration;
import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Platform;
import org.eclipse.linuxtools.docker.ui.launch.ContainerLauncher; import org.eclipse.linuxtools.docker.ui.launch.ContainerLauncher;
@ -98,20 +99,18 @@ public class ContainerCommandLauncherFactory
@Override @Override
public ICommandLauncher getCommandLauncher(ICBuildConfiguration cfgd) { public ICommandLauncher getCommandLauncher(ICBuildConfiguration cfgd) {
// check if container build enablement has been checked // check if container linux os is set
Map<String, String> props = cfgd.getProperties(); IToolChain toolchain;
if (props != null) { try {
String enablementProperty = props toolchain = cfgd.getToolChain();
.get(ContainerCommandLauncher.CONTAINER_BUILD_ENABLED); if (toolchain != null) {
if (enablementProperty != null) { if (ContainerTargetTypeProvider.CONTAINER_LINUX
boolean enableContainer = Boolean .equals(toolchain.getProperty(IToolChain.ATTR_OS))) {
.parseBoolean(enablementProperty);
// enablement has occurred, we can return a
// ContainerCommandLauncher
if (enableContainer) {
return new ContainerCommandLauncher(); return new ContainerCommandLauncher();
} }
} }
} catch (CoreException e) {
DockerLaunchUIPlugin.log(e);
} }
return null; return null;
} }
@ -213,6 +212,112 @@ public class ContainerCommandLauncherFactory
} }
/**
* @since 1.2
*/
@Override
public List<String> verifyIncludePaths(ICBuildConfiguration cfgd, List<String> includePaths) {
IToolChain toolchain = null;
boolean isContainerEnabled = false;
try {
toolchain = cfgd.getToolChain();
if (toolchain != null) {
if (ContainerTargetTypeProvider.CONTAINER_LINUX
.equals(toolchain.getProperty(IToolChain.ATTR_OS))) {
isContainerEnabled = true;
}
}
} catch (CoreException e) {
DockerLaunchUIPlugin.log(e);
}
if (isContainerEnabled) {
String connectionName = toolchain
.getProperty(IContainerLaunchTarget.ATTR_CONNECTION_URI);
String imageName = toolchain
.getProperty(IContainerLaunchTarget.ATTR_IMAGE_ID);
if (connectionName == null || connectionName.isEmpty()
|| imageName == null || imageName.isEmpty()) {
DockerLaunchUIPlugin.logErrorMessage(
Messages.ContainerCommandLauncher_invalid_values);
return includePaths;
}
ContainerLauncher launcher = new ContainerLauncher();
if (includePaths.size() > 0) {
// Create a directory to put the header files for
// the image. Use the connection name to form
// the directory name as the connection may be
// connected to a different repo using the same
// image name.
IPath pluginPath = Platform
.getStateLocation(Platform
.getBundle(DockerLaunchUIPlugin.PLUGIN_ID))
.append("HEADERS"); //$NON-NLS-1$
pluginPath.toFile().mkdir();
pluginPath = pluginPath.append(getCleanName(connectionName));
pluginPath.toFile().mkdir();
// To allow the user to later manage the headers, store
// the
// real connection name in a file.
IPath connectionNamePath = pluginPath.append(".name"); //$NON-NLS-1$
File f = connectionNamePath.toFile();
try {
f.createNewFile();
try (FileWriter writer = new FileWriter(f);
BufferedWriter bufferedWriter = new BufferedWriter(
writer);) {
bufferedWriter.write(connectionName);
bufferedWriter.newLine();
} catch (IOException e) {
DockerLaunchUIPlugin.log(e);
return includePaths;
}
pluginPath = pluginPath.append(getCleanName(imageName));
pluginPath.toFile().mkdir();
// To allow the user to later manage the headers,
// store the
// real image name in a file.
IPath imageNamePath = pluginPath.append(".name"); //$NON-NLS-1$
f = imageNamePath.toFile();
f.createNewFile();
try (FileWriter writer = new FileWriter(f);
BufferedWriter bufferedWriter = new BufferedWriter(
writer);) {
bufferedWriter.write(imageName);
bufferedWriter.newLine();
} catch (IOException e) {
DockerLaunchUIPlugin.log(e);
return includePaths;
}
} catch (IOException e) {
DockerLaunchUIPlugin.log(e);
return includePaths;
}
IPath hostDir = pluginPath;
int status = launcher.fetchContainerDirsSync(connectionName,
imageName, includePaths, hostDir);
if (status == 0) {
Set<String> copiedVolumes = launcher
.getCopiedVolumes(connectionName, imageName);
List<String> newEntries = new ArrayList<>();
for (String path : includePaths) {
if (copiedVolumes.contains(path)) {
IPath newPath = hostDir.append(path);
String newEntry = newPath.toOSString();
newEntries.add(newEntry);
} else {
newEntries.add(path);
}
}
return newEntries;
}
}
}
return includePaths;
}
@Override @Override
public List<ICLanguageSettingEntry> verifyLanguageSettingEntries( public List<ICLanguageSettingEntry> verifyLanguageSettingEntries(
IProject project, List<ICLanguageSettingEntry> entries) { IProject project, List<ICLanguageSettingEntry> entries) {

View file

@ -0,0 +1,95 @@
/*******************************************************************************
* Copyright (c) 2017, 2018 QNX Software Systems and others.
* 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:
* Red Hat Inc. - modified for use with Docker Container launching
*******************************************************************************/
package org.eclipse.cdt.docker.launcher;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.cdt.debug.core.CDebugCorePlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Platform;
import org.eclipse.launchbar.core.ILaunchBarManager;
import org.eclipse.launchbar.core.target.ILaunchTarget;
import org.eclipse.launchbar.core.target.ILaunchTargetManager;
import org.eclipse.launchbar.core.target.ILaunchTargetProvider;
import org.eclipse.launchbar.core.target.ILaunchTargetWorkingCopy;
import org.eclipse.launchbar.core.target.TargetStatus;
import org.eclipse.linuxtools.docker.core.DockerConnectionManager;
import org.eclipse.linuxtools.docker.core.IDockerConnection;
import org.eclipse.linuxtools.docker.core.IDockerImage;
/**
* @since 1.2
* @author jjohnstn
*
*/
public class ContainerTargetTypeProvider implements ILaunchTargetProvider {
public static final String TYPE_ID = "org.eclipse.cdt.docker.launcher.launchTargetType.container"; //$NON-NLS-1$
public static final String CONTAINER_LINUX = "linux-container"; //$NON-NLS-1$
@Override
public void init(ILaunchTargetManager targetManager) {
ILaunchBarManager launchbarManager = CDebugCorePlugin
.getService(ILaunchBarManager.class);
ILaunchTarget defaultTarget = null;
try {
defaultTarget = launchbarManager.getActiveLaunchTarget();
} catch (CoreException e) {
// ignore
}
IDockerConnection[] connections = DockerConnectionManager.getInstance()
.getConnections();
Set<String> imageNames = new HashSet<>();
for (IDockerConnection connection : connections) {
List<IDockerImage> images = connection.getImages();
for (IDockerImage image : images) {
if (!image.isDangling() && !image.isIntermediateImage()) {
String imageName = "[" //$NON-NLS-1$
+ image.repoTags().get(0).replace(':', '_') + "]"; //$NON-NLS-1$
if (imageNames.contains(imageName)) {
imageName += "[" + connection.getName() + "]"; //$NON-NLS-1$ //$NON-NLS-2$
}
imageNames.add(imageName);
ILaunchTarget target = targetManager
.getLaunchTarget(TYPE_ID, imageName);
if (target == null) {
target = targetManager.addLaunchTarget(TYPE_ID,
imageName);
}
ILaunchTargetWorkingCopy wc = target.getWorkingCopy();
wc.setAttribute(ILaunchTarget.ATTR_OS, CONTAINER_LINUX);
wc.setAttribute(ILaunchTarget.ATTR_ARCH,
Platform.getOSArch());
wc.setAttribute(IContainerLaunchTarget.ATTR_CONNECTION_URI,
connection.getUri());
wc.setAttribute(IContainerLaunchTarget.ATTR_IMAGE_ID,
image.repoTags().get(0));
wc.save();
}
}
}
try {
launchbarManager.setActiveLaunchTarget(defaultTarget);
} catch (CoreException e) {
DockerLaunchUIPlugin.log(e);
}
}
@Override
public TargetStatus getStatus(ILaunchTarget target) {
// Always OK
return TargetStatus.OK_STATUS;
}
}

View file

@ -0,0 +1,24 @@
/*******************************************************************************
* Copyright (c) 2018 Red Hat Inc. and others.
* 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:
* Red Hat Inc. - initial contribution
*******************************************************************************/
package org.eclipse.cdt.docker.launcher;
/**
* @since 1.2
* @author jjohnstn
*
*/
public interface IContainerLaunchTarget {
// Container attributes
public static final String ATTR_CONNECTION_URI = "connection_uri"; //$NON-NLS-1$
public static final String ATTR_IMAGE_ID = "image_id"; //$NON-NLS-1$
}

View file

@ -23,12 +23,22 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.build.ICBuildConfiguration;
import org.eclipse.cdt.core.build.ICBuildConfigurationManager;
import org.eclipse.cdt.core.build.IToolChain;
import org.eclipse.cdt.core.build.IToolChainManager;
import org.eclipse.cdt.debug.core.CDebugCorePlugin;
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
import org.eclipse.cdt.docker.launcher.ContainerTargetTypeProvider;
import org.eclipse.cdt.docker.launcher.DockerLaunchUIPlugin; import org.eclipse.cdt.docker.launcher.DockerLaunchUIPlugin;
import org.eclipse.cdt.docker.launcher.IContainerLaunchTarget;
import org.eclipse.cdt.dsf.gdb.IGDBLaunchConfigurationConstants; import org.eclipse.cdt.dsf.gdb.IGDBLaunchConfigurationConstants;
import org.eclipse.cdt.dsf.gdb.launching.GdbLaunchDelegate; import org.eclipse.cdt.dsf.gdb.launching.GdbLaunchDelegate;
import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IProgressMonitor;
@ -42,6 +52,8 @@ import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager; import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.model.ILaunchConfigurationDelegate; import org.eclipse.debug.core.model.ILaunchConfigurationDelegate;
import org.eclipse.launchbar.core.target.ILaunchTarget;
import org.eclipse.launchbar.core.target.ILaunchTargetManager;
import org.eclipse.linuxtools.docker.core.Activator; import org.eclipse.linuxtools.docker.core.Activator;
import org.eclipse.linuxtools.docker.core.IDockerContainerInfo; import org.eclipse.linuxtools.docker.core.IDockerContainerInfo;
import org.eclipse.linuxtools.docker.core.IDockerNetworkSettings; import org.eclipse.linuxtools.docker.core.IDockerNetworkSettings;
@ -169,6 +181,14 @@ public class ContainerLaunchConfigurationDelegate extends GdbLaunchDelegate
.getAttribute( .getAttribute(
ICDTLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY, ICDTLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY,
(String) null); (String) null);
// if we don't have a working directory, the default is to use
// the project
if (workingDir == null && projectName != null) {
IProject project = ResourcesPlugin.getWorkspace().getRoot()
.getProject(projectName);
workingDir = project.getLocation().toOSString();
}
if (workingDir != null) { if (workingDir != null) {
IPath workingPath = new Path(workingDir); IPath workingPath = new Path(workingDir);
if (workingPath.getDevice() != null) { if (workingPath.getDevice() != null) {
@ -258,6 +278,13 @@ public class ContainerLaunchConfigurationDelegate extends GdbLaunchDelegate
.getAttribute( .getAttribute(
ICDTLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY, ICDTLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY,
(String) null); (String) null);
// if we don't have a working directory, the default is to use
// the project
if (workingDir == null && projectName != null) {
IProject project = ResourcesPlugin.getWorkspace().getRoot()
.getProject(projectName);
workingDir = project.getLocation().toOSString();
}
if (workingDir != null) { if (workingDir != null) {
IPath workingPath = new Path(workingDir); IPath workingPath = new Path(workingDir);
if (workingPath.getDevice() != null) { if (workingPath.getDevice() != null) {
@ -492,6 +519,122 @@ public class ContainerLaunchConfigurationDelegate extends GdbLaunchDelegate
return inputString.replaceAll(" ", "\\\\ "); //$NON-NLS-1$ //$NON-NLS-2$ return inputString.replaceAll(" ", "\\\\ "); //$NON-NLS-1$ //$NON-NLS-2$
} }
public static IProject getProject(ILaunchConfiguration configuration)
throws CoreException {
// TODO - make sure this is really the correct project
return configuration.getMappedResources()[0].getProject();
}
/**
* @since 1.2
*/
protected ICBuildConfigurationManager configManager = CDebugCorePlugin
.getService(ICBuildConfigurationManager.class);
/**
* @since 1.2
*/
protected IToolChainManager toolChainManager = CDebugCorePlugin
.getService(IToolChainManager.class);
/*
* @since 1.2
*/
protected ICBuildConfiguration getBuildConfiguration(
ILaunchConfiguration configuration, String mode,
ILaunchTarget target, IProgressMonitor monitor)
throws CoreException {
IProject project = getProject(configuration);
String toolchainId = configuration
.getAttribute(ICBuildConfiguration.TOOLCHAIN_ID, (String) null);
if (toolchainId != null) {
String providerId = configuration
.getAttribute(ICBuildConfiguration.TOOLCHAIN_TYPE, ""); //$NON-NLS-1$
IToolChain toolchain = toolChainManager.getToolChain(providerId,
toolchainId);
if (toolchain != null) {
return configManager.getBuildConfiguration(project, toolchain,
mode, monitor);
}
}
// Pick the first one that matches
Map<String, String> properties = new HashMap<>();
properties.putAll(target.getAttributes());
for (IToolChain toolChain : toolChainManager
.getToolChainsMatching(properties)) {
ICBuildConfiguration buildConfig = configManager
.getBuildConfiguration(project, toolChain, mode, monitor);
if (buildConfig != null) {
return buildConfig;
}
}
return null;
}
@Override
public boolean buildForLaunch(ILaunchConfiguration configuration,
String mode, IProgressMonitor monitor) throws CoreException {
IProject project = getProject(configuration);
String name = configuration.getName();
Pattern p = Pattern.compile(".*?\\[([^\\]]+)\\](.*)"); //$NON-NLS-1$
Matcher m = p.matcher(name);
if (m.matches()) {
ILaunchTargetManager targetManager = CCorePlugin
.getService(ILaunchTargetManager.class);
ILaunchTarget target = null;
ILaunchTarget[] targets = targetManager.getLaunchTargetsOfType(
ContainerTargetTypeProvider.TYPE_ID);
for (ILaunchTarget t : targets) {
if (t.getAttribute(IContainerLaunchTarget.ATTR_IMAGE_ID, "")
.replaceAll(":", "_").equals(m.group(1))) {
target = t;
break;
}
}
if (target != null) {
ICBuildConfiguration cconfig = getBuildConfiguration(
configuration, mode, target, monitor);
if (cconfig != null) {
IProjectDescription desc = project.getDescription();
desc.setActiveBuildConfig(
cconfig.getBuildConfiguration().getName());
project.setDescription(desc, monitor);
}
}
}
return super.buildForLaunch(configuration, mode, monitor);
}
@Override
public boolean preLaunchCheck(ILaunchConfiguration config, String mode,
IProgressMonitor monitor) throws CoreException {
String projectName = config.getAttribute(
ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME,
(String) null);
IProject project = null;
if (projectName == null) {
IResource[] resources = config.getMappedResources();
if (resources != null && resources.length > 0
&& resources[0] instanceof IProject) {
project = (IProject) resources[0];
}
ILaunchConfigurationWorkingCopy wc = config.getWorkingCopy();
wc.setAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME,
project.getName());
wc.doSave();
} else {
projectName = projectName.trim();
if (!projectName.isEmpty()) {
project = ResourcesPlugin.getWorkspace().getRoot()
.getProject(projectName);
}
}
return super.preLaunchCheck(config, mode, monitor);
}
@Override @Override
protected String getPluginID() { protected String getPluginID() {
return DockerLaunchUIPlugin.PLUGIN_ID; return DockerLaunchUIPlugin.PLUGIN_ID;

View file

@ -15,6 +15,8 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import org.eclipse.cdt.core.build.ICBuildConfiguration;
import org.eclipse.cdt.core.build.IToolChain;
import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.IBinary; import org.eclipse.cdt.core.model.IBinary;
@ -24,6 +26,7 @@ import org.eclipse.cdt.debug.core.CDebugUtils;
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
import org.eclipse.cdt.docker.launcher.ContainerCommandLauncher; import org.eclipse.cdt.docker.launcher.ContainerCommandLauncher;
import org.eclipse.cdt.docker.launcher.DockerLaunchUIPlugin; import org.eclipse.cdt.docker.launcher.DockerLaunchUIPlugin;
import org.eclipse.cdt.docker.launcher.IContainerLaunchTarget;
import org.eclipse.cdt.dsf.gdb.IGDBLaunchConfigurationConstants; import org.eclipse.cdt.dsf.gdb.IGDBLaunchConfigurationConstants;
import org.eclipse.cdt.dsf.gdb.IGdbDebugPreferenceConstants; import org.eclipse.cdt.dsf.gdb.IGdbDebugPreferenceConstants;
import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin; import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin;
@ -31,6 +34,7 @@ import org.eclipse.cdt.managedbuilder.buildproperties.IOptionalBuildProperties;
import org.eclipse.cdt.managedbuilder.core.IConfiguration; import org.eclipse.cdt.managedbuilder.core.IConfiguration;
import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
import org.eclipse.cdt.ui.CElementLabelProvider; import org.eclipse.cdt.ui.CElementLabelProvider;
import org.eclipse.core.resources.IBuildConfiguration;
import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
@ -260,10 +264,25 @@ public class LaunchShortcut implements ILaunchShortcut {
ILaunchConfigurationType configType = getLaunchConfigType(); ILaunchConfigurationType configType = getLaunchConfigType();
List<ILaunchConfiguration> candidateConfigs = Collections.emptyList(); List<ILaunchConfiguration> candidateConfigs = Collections.emptyList();
IProject project = bin.getCProject().getProject(); IProject project = bin.getCProject().getProject();
ICConfigurationDescription cfgd = CoreModel.getDefault()
.getProjectDescription(project).getActiveConfiguration();
String connectionUri = null; String connectionUri = null;
String imageName = null; String imageName = null;
ICBuildConfiguration cbcfg = null;
try {
IBuildConfiguration buildConfig = project.getActiveBuildConfig();
cbcfg = buildConfig.getAdapter(ICBuildConfiguration.class);
if (cbcfg != null) {
IToolChain toolChain = cbcfg.getToolChain();
connectionUri = toolChain.getProperty(
IContainerLaunchTarget.ATTR_CONNECTION_URI);
imageName = toolChain
.getProperty(IContainerLaunchTarget.ATTR_IMAGE_ID);
}
} catch (CoreException e1) {
// do nothing
}
if (cbcfg == null) {
ICConfigurationDescription cfgd = CoreModel.getDefault()
.getProjectDescription(project).getActiveConfiguration();
if (cfgd != null) { if (cfgd != null) {
IConfiguration cfg = ManagedBuildManager IConfiguration cfg = ManagedBuildManager
.getConfigurationForDescription(cfgd); .getConfigurationForDescription(cfgd);
@ -278,28 +297,30 @@ public class LaunchShortcut implements ILaunchShortcut {
if (containerBuildEnabled) { if (containerBuildEnabled) {
connectionUri = props.getProperty( connectionUri = props.getProperty(
ContainerCommandLauncher.CONNECTION_ID); ContainerCommandLauncher.CONNECTION_ID);
imageName = props imageName = props.getProperty(
.getProperty(ContainerCommandLauncher.IMAGE_ID); ContainerCommandLauncher.IMAGE_ID);
} }
} else { }
}
}
}
if (connectionUri == null) {
IDockerConnection[] connections = DockerConnectionManager IDockerConnection[] connections = DockerConnectionManager
.getInstance().getConnections(); .getInstance().getConnections();
if (connections != null && connections.length > 0) { if (connections != null && connections.length > 0) {
connectionUri = connections[0].getUri(); connectionUri = connections[0].getUri();
Preferences prefs = InstanceScope.INSTANCE Preferences prefs = InstanceScope.INSTANCE
.getNode(DockerLaunchUIPlugin.PLUGIN_ID); .getNode(DockerLaunchUIPlugin.PLUGIN_ID);
imageName = prefs.get(PreferenceConstants.DEFAULT_IMAGE, imageName = prefs.get(PreferenceConstants.DEFAULT_IMAGE, null);
null);
if (imageName == null) { if (imageName == null) {
List<IDockerImage> images = connections[0] List<IDockerImage> images = connections[0].getImages();
.getImages();
if (images != null && images.size() > 0) if (images != null && images.size() > 0)
imageName = images.get(0).repoTags().get(0); imageName = images.get(0).repoTags().get(0);
} }
} }
} }
}
}
try { try {
ILaunchConfiguration[] configs = DebugPlugin.getDefault() ILaunchConfiguration[] configs = DebugPlugin.getDefault()
.getLaunchManager().getLaunchConfigurations(configType); .getLaunchManager().getLaunchConfigurations(configType);
@ -308,10 +329,10 @@ public class LaunchShortcut implements ILaunchShortcut {
IPath programPath = CDebugUtils.getProgramPath(config); IPath programPath = CDebugUtils.getProgramPath(config);
String projectName = CDebugUtils.getProjectName(config); String projectName = CDebugUtils.getProjectName(config);
IPath binPath = bin.getResource().getProjectRelativePath(); IPath binPath = bin.getResource().getProjectRelativePath();
if (programPath != null && programPath.equals(binPath)) { if (projectName != null && projectName
if (projectName != null .equals(bin.getCProject().getProject().getName())) {
&& projectName.equals(bin.getCProject() if (programPath != null) {
.getProject().getName())) { if (programPath.equals(binPath)) {
// if we have an active configuration with container // if we have an active configuration with container
// build properties, make sure they match, otherwise // build properties, make sure they match, otherwise
// add the launch config as a candidate // add the launch config as a candidate
@ -319,13 +340,24 @@ public class LaunchShortcut implements ILaunchShortcut {
&& connectionUri.equals(config.getAttribute( && connectionUri.equals(config.getAttribute(
ILaunchConstants.ATTR_CONNECTION_URI, ILaunchConstants.ATTR_CONNECTION_URI,
(String) null))) { (String) null))) {
if (imageName != null && imageName.equals(config if (imageName != null
.getAttribute(ILaunchConstants.ATTR_IMAGE, && imageName.equals(config.getAttribute(
ILaunchConstants.ATTR_IMAGE,
(String) null))) { (String) null))) {
candidateConfigs.add(config); candidateConfigs.add(config);
} }
} }
} }
} else if (cbcfg != null && candidateConfigs.isEmpty()) {
ILaunchConfigurationWorkingCopy wc = config
.getWorkingCopy();
populateLaunchConfiguration(wc, mode, bin,
projectName,
connectionUri, imageName);
wc.doSave();
candidateConfigs.add(config);
break;
}
} }
} }
} catch (CoreException e) { } catch (CoreException e) {
@ -353,6 +385,59 @@ public class LaunchShortcut implements ILaunchShortcut {
return configuration; return configuration;
} }
private void populateLaunchConfiguration(ILaunchConfigurationWorkingCopy wc,
String mode, IBinary bin, String projectName, String connectionUri,
String imageName) {
// DSF settings...use GdbUIPlugin preference store for defaults
IPreferenceStore preferenceStore = GdbUIPlugin.getDefault()
.getPreferenceStore();
wc.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUG_NAME,
preferenceStore.getString(
IGdbDebugPreferenceConstants.PREF_DEFAULT_GDB_COMMAND));
wc.setAttribute(IGDBLaunchConfigurationConstants.ATTR_GDB_INIT,
preferenceStore.getString(
IGdbDebugPreferenceConstants.PREF_DEFAULT_GDB_INIT));
wc.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP,
preferenceStore.getBoolean(
IGdbDebugPreferenceConstants.PREF_DEFAULT_NON_STOP));
wc.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_REVERSE,
IGDBLaunchConfigurationConstants.DEBUGGER_REVERSE_DEFAULT);
wc.setAttribute(
IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_UPDATE_THREADLIST_ON_SUSPEND,
IGDBLaunchConfigurationConstants.DEBUGGER_UPDATE_THREADLIST_ON_SUSPEND_DEFAULT);
wc.setAttribute(
IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_DEBUG_ON_FORK,
IGDBLaunchConfigurationConstants.DEBUGGER_DEBUG_ON_FORK_DEFAULT);
wc.setAttribute(
IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_TRACEPOINT_MODE,
IGDBLaunchConfigurationConstants.DEBUGGER_TRACEPOINT_MODE_DEFAULT);
wc.setAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME,
bin.getResource().getProjectRelativePath().toString());
wc.setAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME,
projectName);
wc.setMappedResources(new IResource[] { bin.getResource(),
bin.getResource().getProject() });
wc.setAttribute(ICDTLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY,
(String) null); // default is the project directory
Preferences prefs = InstanceScope.INSTANCE
.getNode(DockerLaunchUIPlugin.PLUGIN_ID);
Boolean keepPref = prefs.getBoolean(
PreferenceConstants.KEEP_CONTAINER_AFTER_LAUNCH, false);
wc.setAttribute(ILaunchConstants.ATTR_KEEP_AFTER_LAUNCH, keepPref);
// For Debug mode we need to set gdbserver info as well
if (mode.equals(ILaunchManager.DEBUG_MODE)) {
wc.setAttribute(ILaunchConstants.ATTR_GDBSERVER_COMMAND,
"gdbserver"); //$NON-NLS-1$
wc.setAttribute(ILaunchConstants.ATTR_GDBSERVER_PORT, "2345"); //$NON-NLS-1$
}
wc.setAttribute(ILaunchConstants.ATTR_CONNECTION_URI, connectionUri);
wc.setAttribute(ILaunchConstants.ATTR_IMAGE, imageName);
}
/** /**
* Create a launch configuration based on a binary, and optionally save it * Create a launch configuration based on a binary, and optionally save it
* to the underlying resource. * to the underlying resource.
@ -368,26 +453,37 @@ public class LaunchShortcut implements ILaunchShortcut {
String mode, boolean save) { String mode, boolean save) {
ILaunchConfiguration config = null; ILaunchConfiguration config = null;
try { try {
String binaryPath = bin.getResource().getProjectRelativePath()
.toString();
IProject project = bin.getResource().getProject(); IProject project = bin.getResource().getProject();
ICConfigurationDescription cfgd = CoreModel.getDefault()
.getProjectDescription(project).getActiveConfiguration();
IConfiguration cfg = ManagedBuildManager
.getConfigurationForDescription(cfgd);
IOptionalBuildProperties options = cfg.getOptionalBuildProperties();
boolean containerBuild = false; boolean containerBuild = false;
String connectionId = null; String connectionId = null;
String imageName = null; String imageName = null;
IBuildConfiguration buildConfig = project.getActiveBuildConfig();
ICBuildConfiguration cbuildcfg = buildConfig
.getAdapter(ICBuildConfiguration.class);
if (cbuildcfg != null) {
IToolChain toolChain = cbuildcfg.getToolChain();
connectionId = toolChain.getProperty(
IContainerLaunchTarget.ATTR_CONNECTION_URI);
imageName = toolChain
.getProperty(IContainerLaunchTarget.ATTR_IMAGE_ID);
} else {
ICConfigurationDescription cfgd = CoreModel.getDefault()
.getProjectDescription(project)
.getActiveConfiguration();
IConfiguration cfg = ManagedBuildManager
.getConfigurationForDescription(cfgd);
IOptionalBuildProperties options = cfg
.getOptionalBuildProperties();
if (options != null) { if (options != null) {
String containerBuildString = options.getProperty( String containerBuildString = options.getProperty(
ContainerCommandLauncher.CONTAINER_BUILD_ENABLED); ContainerCommandLauncher.CONTAINER_BUILD_ENABLED);
if (containerBuildString != null) { if (containerBuildString != null) {
containerBuild = Boolean.parseBoolean(options.getProperty( containerBuild = Boolean
.parseBoolean(options.getProperty(
ContainerCommandLauncher.CONTAINER_BUILD_ENABLED)); ContainerCommandLauncher.CONTAINER_BUILD_ENABLED));
} }
if (containerBuild) { if (containerBuild) {
@ -397,6 +493,7 @@ public class LaunchShortcut implements ILaunchShortcut {
.getProperty(ContainerCommandLauncher.IMAGE_ID); .getProperty(ContainerCommandLauncher.IMAGE_ID);
} }
} }
}
ILaunchConfigurationType configType = getLaunchConfigType(); ILaunchConfigurationType configType = getLaunchConfigType();
ILaunchConfigurationWorkingCopy wc = configType.newInstance( ILaunchConfigurationWorkingCopy wc = configType.newInstance(
@ -406,41 +503,7 @@ public class LaunchShortcut implements ILaunchShortcut {
? ("[" + imageName + "]") //$NON-NLS-1$ //$NON-NLS-2$ ? ("[" + imageName + "]") //$NON-NLS-1$ //$NON-NLS-2$
: ""))); //$NON-NLS-1$ : ""))); //$NON-NLS-1$
// DSF settings...use GdbUIPlugin preference store for defaults
IPreferenceStore preferenceStore = GdbUIPlugin.getDefault()
.getPreferenceStore();
wc.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUG_NAME,
preferenceStore.getString(
IGdbDebugPreferenceConstants.PREF_DEFAULT_GDB_COMMAND));
wc.setAttribute(IGDBLaunchConfigurationConstants.ATTR_GDB_INIT,
preferenceStore.getString(
IGdbDebugPreferenceConstants.PREF_DEFAULT_GDB_INIT));
wc.setAttribute(
IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP,
preferenceStore.getBoolean(
IGdbDebugPreferenceConstants.PREF_DEFAULT_NON_STOP));
wc.setAttribute(
IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_REVERSE,
IGDBLaunchConfigurationConstants.DEBUGGER_REVERSE_DEFAULT);
wc.setAttribute(
IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_UPDATE_THREADLIST_ON_SUSPEND,
IGDBLaunchConfigurationConstants.DEBUGGER_UPDATE_THREADLIST_ON_SUSPEND_DEFAULT);
wc.setAttribute(
IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_DEBUG_ON_FORK,
IGDBLaunchConfigurationConstants.DEBUGGER_DEBUG_ON_FORK_DEFAULT);
wc.setAttribute(
IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_TRACEPOINT_MODE,
IGDBLaunchConfigurationConstants.DEBUGGER_TRACEPOINT_MODE_DEFAULT);
wc.setAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME,
binaryPath);
wc.setAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME,
bin.getCProject().getElementName());
wc.setMappedResources(new IResource[] { bin.getResource(),
bin.getResource().getProject() });
wc.setAttribute(
ICDTLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY,
(String) null);
Preferences prefs = InstanceScope.INSTANCE Preferences prefs = InstanceScope.INSTANCE
.getNode(DockerLaunchUIPlugin.PLUGIN_ID); .getNode(DockerLaunchUIPlugin.PLUGIN_ID);
@ -480,8 +543,6 @@ public class LaunchShortcut implements ILaunchShortcut {
return null; return null;
} }
wc.setAttribute(ILaunchConstants.ATTR_CONNECTION_URI,
connection.getUri());
// use build image if one is specified, otherwise, see if a default // use build image if one is specified, otherwise, see if a default
// image is set in preferences, otherwise find first image in image // image is set in preferences, otherwise find first image in image
@ -513,18 +574,8 @@ public class LaunchShortcut implements ILaunchShortcut {
return null; return null;
} }
wc.setAttribute(ILaunchConstants.ATTR_IMAGE, (String) image); populateLaunchConfiguration(wc, mode, bin, project.getName(),
connection.getUri(), image);
Boolean keepPref = prefs.getBoolean(
PreferenceConstants.KEEP_CONTAINER_AFTER_LAUNCH, false);
wc.setAttribute(ILaunchConstants.ATTR_KEEP_AFTER_LAUNCH, keepPref);
// For Debug mode we need to set gdbserver info as well
if (mode.equals(ILaunchManager.DEBUG_MODE)) {
wc.setAttribute(ILaunchConstants.ATTR_GDBSERVER_COMMAND,
"gdbserver"); //$NON-NLS-1$
wc.setAttribute(ILaunchConstants.ATTR_GDBSERVER_PORT, "2345"); //$NON-NLS-1$
}
if (save) { if (save) {
config = wc.doSave(); config = wc.doSave();
@ -532,7 +583,7 @@ public class LaunchShortcut implements ILaunchShortcut {
config = wc; config = wc;
} }
} catch (CoreException e) { } catch (CoreException e) {
e.printStackTrace(); DockerLaunchUIPlugin.log(e);
} }
return config; return config;
} }

View file

@ -105,6 +105,8 @@ public class Messages extends NLS {
public static String ContainerCommandLauncher_image_msg; public static String ContainerCommandLauncher_image_msg;
public static String CommandLauncher_CommandCancelled; public static String CommandLauncher_CommandCancelled;
public static String ContainerTarget_name;
public static String ContainerCommandLauncher_invalid_values; public static String ContainerCommandLauncher_invalid_values;
public static String Gdbserver_Settings_Remotetimeout_label; public static String Gdbserver_Settings_Remotetimeout_label;

View file

@ -45,6 +45,8 @@ ContainerPropertyTab_Enable_Msg=Build inside Docker Image
ContainerPropertyTab_Run_Autotools_In_Container_Msg=Run all Autotools in Container ContainerPropertyTab_Run_Autotools_In_Container_Msg=Run all Autotools in Container
ContainerPropertyTab_Run_Autotools_In_Container_Tooltip=Run Autotool commands in the Docker Container. This may cause inconsistencies between configurations sharing generated files. ContainerPropertyTab_Run_Autotools_In_Container_Tooltip=Run Autotool commands in the Docker Container. This may cause inconsistencies between configurations sharing generated files.
ContainerTarget_name=Docker Container
HeaderPreferencePage_Connection_Label=Connection HeaderPreferencePage_Connection_Label=Connection
HeaderPreferencePage_Image_Label=Image HeaderPreferencePage_Image_Label=Image
HeaderPreferencePage_Remove_Label=Remove HeaderPreferencePage_Remove_Label=Remove

View file

@ -0,0 +1,606 @@
/*******************************************************************************
* Copyright (c) 2015, 2017, 2018 QNX Software Systems and others.
* 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:
* Red Hat Inc. - modified for use in Container build
*******************************************************************************/
package org.eclipse.cdt.internal.docker.launcher.ui.launchbar;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.CommandLauncherManager;
import org.eclipse.cdt.core.ICommandLauncher;
import org.eclipse.cdt.core.build.ICBuildConfiguration;
import org.eclipse.cdt.core.build.IToolChain;
import org.eclipse.cdt.core.build.IToolChainProvider;
import org.eclipse.cdt.core.dom.ast.gnu.c.GCCLanguage;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.GPPLanguage;
import org.eclipse.cdt.core.envvar.IEnvironmentVariable;
import org.eclipse.cdt.core.model.ILanguage;
import org.eclipse.cdt.core.parser.ExtendedScannerInfo;
import org.eclipse.cdt.core.parser.IExtendedScannerInfo;
import org.eclipse.cdt.docker.launcher.ContainerCommandLauncher;
import org.eclipse.cdt.docker.launcher.ContainerTargetTypeProvider;
import org.eclipse.cdt.docker.launcher.DockerLaunchUIPlugin;
import org.eclipse.core.resources.IBuildConfiguration;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.PlatformObject;
import org.eclipse.linuxtools.docker.ui.Activator;
/**
* The Container GCC toolchain. It represents a GCC that will run in a Docker
* Container. It can be overridden to change environment variable settings.
*
* @since 1.2
*/
public class ContainerGCCToolChain extends PlatformObject implements IToolChain {
public static final String TYPE_ID = "org.eclipse.cdt.docker.launcher.gcc"; //$NON-NLS-1$
private final IToolChainProvider provider;
private final String id;
private final Path path;
private final IEnvironmentVariable[] envVars;
private final Map<String, String> properties = new HashMap<>();
private String cCommand;
private String cppCommand;
private String[] commands;
public ContainerGCCToolChain(String id, IToolChainProvider provider,
Map<String, String> properties,
IEnvironmentVariable[] envVars) {
this.provider = provider;
this.path = new File("/usr/bin/gcc").toPath(); //$NON-NLS-1$
// We include arch in the id since a compiler can support multiple arches.
StringBuilder idBuilder = new StringBuilder("container-gcc-"); //$NON-NLS-1$
idBuilder.append(properties.get(Platform.getOSArch()));
idBuilder.append('-');
idBuilder.append(path.toString());
this.id = id;
this.properties.putAll(properties);
this.envVars = envVars;
}
@Override
public String getTypeId() {
return TYPE_ID;
}
public Path getPath() {
return path;
}
@Override
public IToolChainProvider getProvider() {
return provider;
}
@Override
public String getId() {
return id;
}
@Override
public String getVersion() {
return ""; //$NON-NLS-1$
}
@Override
public String getName() {
StringBuilder name = new StringBuilder(); // $NON-NLS-1$
String os = getProperty(ATTR_OS);
if (os != null) {
name.append(os);
name.append(' ');
}
String arch = getProperty(ATTR_ARCH);
if (arch != null) {
name.append(arch);
name.append(' ');
}
if (path != null) {
name.append(path.toString());
}
return name.toString();
}
@Override
public String getProperty(String key) {
String value = properties.get(key);
if (value != null) {
return value;
}
switch (key) {
case ATTR_OS:
return ContainerTargetTypeProvider.CONTAINER_LINUX;
case ATTR_ARCH:
return Platform.getOSArch();
}
return null;
}
public Map<String, String> getProperties() {
return properties;
}
@Override
public void setProperty(String key, String value) {
properties.put(key, value);
}
@Override
public String getBinaryParserId() {
return CCorePlugin.PLUGIN_ID + ".ELF"; //$NON-NLS-1$
}
protected void addDiscoveryOptions(List<String> command) {
command.add("-E"); //$NON-NLS-1$
command.add("-P"); //$NON-NLS-1$
command.add("-v"); //$NON-NLS-1$
command.add("-dD"); //$NON-NLS-1$
}
@Override
public IExtendedScannerInfo getScannerInfo(IBuildConfiguration buildConfig, List<String> commandStrings,
IExtendedScannerInfo baseScannerInfo, IResource resource, URI buildDirectoryURI) {
try {
Path buildDirectory = Paths.get(buildDirectoryURI);
Path command = Paths.get(commandStrings.get(0));
List<String> commandLine = new ArrayList<>();
if (command.isAbsolute()) {
commandLine.add(command.toString());
} else {
commandLine.add(getCommandPath(command).toString());
}
if (baseScannerInfo != null) {
if (baseScannerInfo.getIncludePaths() != null) {
for (String includePath : baseScannerInfo.getIncludePaths()) {
commandLine.add("-I" + includePath); //$NON-NLS-1$
}
}
if (baseScannerInfo.getDefinedSymbols() != null) {
for (Map.Entry<String, String> macro : baseScannerInfo.getDefinedSymbols().entrySet()) {
if (macro.getValue() != null && !macro.getValue().isEmpty()) {
commandLine.add("-D" + macro.getKey() + "=" + macro.getValue()); //$NON-NLS-1$
} else {
commandLine.add("-D" + macro.getKey()); //$NON-NLS-1$
}
}
}
}
addDiscoveryOptions(commandLine);
commandLine.addAll(commandStrings.subList(1, commandStrings.size()));
// Strip surrounding quotes from the args on Windows
if (Platform.OS_WIN32.equals(Platform.getOS())) {
for (int i = 0; i < commandLine.size(); i++) {
String arg = commandLine.get(i);
if (arg.startsWith("\"") && arg.endsWith("\"")) { //$NON-NLS-1$ //$NON-NLS-2$
commandLine.set(i, arg.substring(1, arg.length() - 1));
}
}
}
// Change output to stdout
boolean haveOut = false;
for (int i = 0; i < commandLine.size() - 1; ++i) {
if (commandLine.get(i).equals("-o")) { //$NON-NLS-1$
commandLine.set(i + 1, "-"); //$NON-NLS-1$
haveOut = true;
break;
}
}
if (!haveOut) {
commandLine.add("-o"); //$NON-NLS-1$
commandLine.add("-"); //$NON-NLS-1$
}
// Change source file to a tmp file (needs to be empty)
Path tmpFile = null;
for (int i = 1; i < commandLine.size(); ++i) {
String arg = commandLine.get(i);
if (!arg.startsWith("-")) { //$NON-NLS-1$
Path filePath;
try {
filePath = buildDirectory.resolve(commandLine.get(i)).normalize();
} catch (InvalidPathException e) {
continue;
}
IFile[] files = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocationURI(filePath.toUri());
if (files.length > 0 && files[0].exists()) {
// replace it with a temp file
Path parentPath = filePath.getParent();
String extension = files[0].getFileExtension();
if (extension == null) {
// Not sure if this is a reasonable choice when
// there's
// no extension
extension = ".cpp"; //$NON-NLS-1$
} else {
extension = '.' + extension;
}
tmpFile = Files.createTempFile(parentPath, ".sc", extension); //$NON-NLS-1$
commandLine.set(i, tmpFile.toString());
}
} else if (arg.equals("-o")) { //$NON-NLS-1$
// skip over the next arg
// TODO handle other args like this
i++;
}
}
if (tmpFile == null) {
// Have to assume there wasn't a source file. Add one in the
// resource's container
// TODO really?
IPath parentPath = resource instanceof IFile ? resource.getParent().getLocation()
: resource.getLocation();
if (parentPath.toFile().exists()) {
tmpFile = Files.createTempFile(parentPath.toFile().toPath(), ".sc", ".cpp"); //$NON-NLS-1$ //$NON-NLS-2$
commandLine.add(tmpFile.toString());
}
}
return getScannerInfo(buildConfig, commandLine, buildDirectory, tmpFile);
} catch (IOException e) {
Activator.log(e);
return null;
}
}
@Override
public IExtendedScannerInfo getDefaultScannerInfo(IBuildConfiguration buildConfig,
IExtendedScannerInfo baseScannerInfo, ILanguage language, URI buildDirectoryURI) {
try {
String[] commands = getCompileCommands(language);
if (commands == null || commands.length == 0) {
// no default commands
return null;
}
Path buildDirectory = Paths.get(buildDirectoryURI);
// Pick the first one
Path command = Paths.get(commands[0]);
List<String> commandLine = new ArrayList<>();
if (command.isAbsolute()) {
commandLine.add(command.toString());
} else {
commandLine.add(getCommandPath(command).toString());
}
if (baseScannerInfo != null) {
if (baseScannerInfo.getIncludePaths() != null) {
for (String includePath : baseScannerInfo.getIncludePaths()) {
commandLine.add("-I" + includePath); //$NON-NLS-1$
}
}
if (baseScannerInfo.getDefinedSymbols() != null) {
for (Map.Entry<String, String> macro : baseScannerInfo.getDefinedSymbols().entrySet()) {
if (macro.getValue() != null && !macro.getValue().isEmpty()) {
commandLine.add("-D" + macro.getKey() + "=" + macro.getValue()); //$NON-NLS-1$
} else {
commandLine.add("-D" + macro.getKey()); //$NON-NLS-1$
}
}
}
}
addDiscoveryOptions(commandLine);
// output to stdout
commandLine.add("-o"); //$NON-NLS-1$
commandLine.add("-"); //$NON-NLS-1$
// Source is an empty tmp file
String extension;
if (GPPLanguage.ID.equals(language.getId())) {
extension = ".cpp"; //$NON-NLS-1$
} else if (GCCLanguage.ID.equals(language.getId())) {
extension = ".c"; //$NON-NLS-1$
} else {
// In theory we shouldn't get here
return null;
}
Path tmpFile = Files.createTempFile(buildDirectory, ".sc", extension); //$NON-NLS-1$
commandLine.add(tmpFile.toString());
return getScannerInfo(buildConfig, commandLine, buildDirectory, tmpFile);
} catch (IOException e) {
Activator.log(e);
return null;
}
}
private IExtendedScannerInfo getScannerInfo(IBuildConfiguration buildConfig, List<String> commandLine,
Path buildDirectory, Path tmpFile) throws IOException {
Files.createDirectories(buildDirectory);
// Startup the command
ContainerCommandLauncher commandLauncher = new ContainerCommandLauncher();
ICBuildConfiguration cconfig = buildConfig
.getAdapter(ICBuildConfiguration.class);
commandLauncher.setBuildConfiguration(cconfig);
commandLauncher.setProject(buildConfig.getProject());
// CCorePlugin.getDefault().getBuildEnvironmentManager().setEnvironment(processBuilder.environment(),
// buildConfig, true);
org.eclipse.core.runtime.IPath commandPath = new org.eclipse.core.runtime.Path(
commandLine.get(0));
String[] args = commandLine.subList(1, commandLine.size())
.toArray(new String[0]);
org.eclipse.core.runtime.IPath workingDirectory = new org.eclipse.core.runtime.Path(
buildDirectory.toString());
Process process;
try (ByteArrayOutputStream stdout = new ByteArrayOutputStream();
ByteArrayOutputStream stderr = new ByteArrayOutputStream()) {
process = commandLauncher.execute(commandPath, args, new String[0],
workingDirectory, new NullProgressMonitor());
if (process != null && commandLauncher.waitAndRead(stdout, stderr,
new NullProgressMonitor()) != ICommandLauncher.OK) {
String errMsg = commandLauncher.getErrorMessage();
DockerLaunchUIPlugin.logErrorMessage(errMsg);
return null;
}
// process.waitFor();
// Scan for the scanner info
Map<String, String> symbols = new HashMap<>();
List<String> includePath = new ArrayList<>();
Pattern definePattern = Pattern.compile("#define ([^\\s]*)\\s(.*)"); //$NON-NLS-1$
boolean inIncludePaths = false;
// concatenate stdout after stderr as stderr has the include paths
// and stdout has the defines
String[] outlines = stdout.toString(StandardCharsets.UTF_8.name())
.split("\\r?\\n"); //$NON-NLS-1$
String[] errlines = stderr.toString(StandardCharsets.UTF_8.name())
.split("\\r?\\n"); //$NON-NLS-1$
String[] lines = new String[errlines.length + outlines.length];
System.arraycopy(errlines, 0, lines, 0, errlines.length);
System.arraycopy(outlines, 0, lines, errlines.length,
outlines.length);
for (String line : lines) {
line = line.trim();
if (inIncludePaths) {
if (line.equals("End of search list.")) { //$NON-NLS-1$
inIncludePaths = false;
} else {
String include = line.trim();
org.eclipse.core.runtime.IPath path = new org.eclipse.core.runtime.Path(
include);
if (!path.isAbsolute()) {
org.eclipse.core.runtime.IPath newPath = workingDirectory
.append(path);
include = newPath.makeAbsolute().toPortableString();
}
includePath.add(include);
}
} else if (line.startsWith("#define ")) { //$NON-NLS-1$
Matcher matcher = definePattern.matcher(line);
if (matcher.matches()) {
symbols.put(matcher.group(1), matcher.group(2));
}
} else if (line.equals("#include <...> search starts here:")) { //$NON-NLS-1$
inIncludePaths = true;
}
}
// Process include paths for scanner info and point to any copied
// header directories
includePath = CommandLauncherManager.getInstance()
.processIncludePaths(cconfig, includePath);
ExtendedScannerInfo info = new ExtendedScannerInfo(symbols,
includePath.toArray(new String[includePath.size()]));
return info;
} catch (CoreException e1) {
return null;
} finally {
Files.delete(tmpFile);
}
}
@Override
public String[] getErrorParserIds() {
return new String[] { "org.eclipse.cdt.core.GCCErrorParser", //$NON-NLS-1$
"org.eclipse.cdt.core.GASErrorParser", //$NON-NLS-1$
"org.eclipse.cdt.core.GLDErrorParser", //$NON-NLS-1$
"org.eclipse.cdt.core.GmakeErrorParser", //$NON-NLS-1$
"org.eclipse.cdt.core.CWDLocator" //$NON-NLS-1$
};
}
@Override
public IEnvironmentVariable getVariable(String name) {
if (envVars != null) {
for (IEnvironmentVariable var : envVars) {
if (var.getName().equals(name)) {
return var;
}
}
}
return null;
}
@Override
public IEnvironmentVariable[] getVariables() {
return envVars;
}
@Override
public Path getCommandPath(Path command) {
if (command.isAbsolute()) {
return command;
}
return new File("/usr/bin/" + command).toPath(); //$NON-NLS-1$
}
private void initCompileCommands() {
if (commands == null) {
cCommand = path.getFileName().toString();
cppCommand = null;
if (cCommand.contains("gcc")) { //$NON-NLS-1$
cppCommand = cCommand.replace("gcc", "g++"); //$NON-NLS-1$ //$NON-NLS-2$
// Also recognize c++ as an alias for g++
commands = new String[] { cCommand, cppCommand, cCommand.replace("gcc", "cc"), //$NON-NLS-1$ //$NON-NLS-2$
cCommand.replace("gcc", "c++") }; //$NON-NLS-1$ //$NON-NLS-2$
} else if (cCommand.contains("clang")) { //$NON-NLS-1$
cppCommand = cCommand.replace("clang", "clang++"); //$NON-NLS-1$ //$NON-NLS-2$
commands = new String[] { cCommand, cppCommand };
} else if (cCommand.contains("emcc")) { //$NON-NLS-1$
// TODO Hack for emscripten. Can we generalize?
cppCommand = cCommand.replace("emcc", "em++"); //$NON-NLS-1$ //$NON-NLS-2$
commands = new String[] { cCommand, cppCommand };
} else {
commands = new String[] { cCommand };
}
}
}
@Override
public String[] getCompileCommands() {
initCompileCommands();
return commands;
}
@Override
public String[] getCompileCommands(ILanguage language) {
initCompileCommands();
if (GPPLanguage.ID.equals(language.getId())) {
return new String[] { cppCommand != null ? cppCommand : cCommand };
} else if (GCCLanguage.ID.equals(language.getId())) {
return new String[] { cCommand };
} else {
return new String[0];
}
}
@Override
public IResource[] getResourcesFromCommand(List<String> cmd, URI buildDirectoryURI) {
// Start at the back looking for arguments
List<IResource> resources = new ArrayList<>();
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
for (int i = cmd.size() - 1; i >= 0; --i) {
String arg = cmd.get(i);
if (arg.startsWith("-")) { //$NON-NLS-1$
// ran into an option, we're done.
break;
}
if (i > 1 && cmd.get(i - 1).equals("-o")) { //$NON-NLS-1$
// this is an output file
--i;
continue;
}
try {
Path srcPath = Paths.get(arg);
URI uri;
if (srcPath.isAbsolute()) {
uri = srcPath.toUri();
} else {
if (arg.startsWith("/") && Platform.getOS().equals(Platform.OS_WIN32)) { //$NON-NLS-1$
String drive = srcPath.getName(0).toString();
if (drive.length() == 1) {
srcPath = Paths.get(drive + ":\\").resolve(srcPath.subpath(1, srcPath.getNameCount())); //$NON-NLS-1$
}
}
uri = Paths.get(buildDirectoryURI).resolve(srcPath).toUri().normalize();
}
for (IFile resource : root.findFilesForLocationURI(uri)) {
resources.add(resource);
}
} catch (IllegalArgumentException e) {
// Bad URI
continue;
}
}
return resources.toArray(new IResource[resources.size()]);
}
@Override
public List<String> stripCommand(List<String> command, IResource[] resources) {
List<String> newCommand = new ArrayList<>();
for (int i = 0; i < command.size() - resources.length; ++i) {
String arg = command.get(i);
if (arg.startsWith("-o")) { //$NON-NLS-1$
if (arg.equals("-o")) { //$NON-NLS-1$
i++;
}
continue;
}
newCommand.add(arg);
}
return newCommand;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ContainerGCCToolChain tc = (ContainerGCCToolChain) obj;
if (tc.id != this.id)
return false;
return true;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
return result;
}
}

View file

@ -0,0 +1,78 @@
/*******************************************************************************
* Copyright (c) 2018 Red Hat Inc. and others.
* 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:
* Red Hat Inc. - initial contribution
*******************************************************************************/
package org.eclipse.cdt.internal.docker.launcher.ui.launchbar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.cdt.core.build.IToolChainManager;
import org.eclipse.cdt.core.build.IToolChainProvider;
import org.eclipse.cdt.docker.launcher.ContainerTargetTypeProvider;
import org.eclipse.cdt.docker.launcher.IContainerLaunchTarget;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Platform;
import org.eclipse.launchbar.core.target.ILaunchTarget;
import org.eclipse.linuxtools.docker.core.DockerConnectionManager;
import org.eclipse.linuxtools.docker.core.IDockerConnection;
import org.eclipse.linuxtools.docker.core.IDockerImage;
/**
*
* @author jjohnstn
*
* @since 1.2
*
*/
public class ContainerGCCToolChainProvider implements IToolChainProvider {
public static final String PROVIDER_ID = "org.eclipse.cdt.docker.launcher.gcc.provider"; //$NON-NLS-1$
public static final String CONTAINER_LINUX_CONFIG_ID = "linux-container-id"; //$NON-NLS-1$
@Override
public String getId() {
return PROVIDER_ID;
}
@Override
public void init(IToolChainManager manager) throws CoreException {
IDockerConnection[] connections = DockerConnectionManager.getInstance()
.getConnections();
for (IDockerConnection connection : connections) {
List<IDockerImage> images = connection.getImages();
for (IDockerImage image : images) {
if (!image.isDangling() && !image.isIntermediateImage()) {
Map<String, String> properties = new HashMap<>();
properties.put(ILaunchTarget.ATTR_OS,
ContainerTargetTypeProvider.CONTAINER_LINUX);
properties.put(ILaunchTarget.ATTR_ARCH,
Platform.getOSArch());
properties.put(IContainerLaunchTarget.ATTR_CONNECTION_URI,
connection.getUri());
properties.put(IContainerLaunchTarget.ATTR_IMAGE_ID,
image.repoTags().get(0));
// following can be used for naming build configurations
properties.put(CONTAINER_LINUX_CONFIG_ID,
image.repoTags().get(0).replace(':', '_'));
ContainerGCCToolChain toolChain = new ContainerGCCToolChain(
"gcc-img-" + image.id().substring(0, 19), //$NON-NLS-1$
this, properties, null);
manager.addToolChain(toolChain);
}
}
}
}
}

View file

@ -0,0 +1,35 @@
/*******************************************************************************
* Copyright (c) 2017 QNX Software Systems and others.
* 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
*******************************************************************************/
package org.eclipse.cdt.internal.docker.launcher.ui.launchbar;
import org.eclipse.cdt.debug.internal.ui.CDebugImages;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.launchbar.core.target.ILaunchTarget;
import org.eclipse.swt.graphics.Image;
/**
* @author jjohnstn
* @since 1.2
*
*/
public class ContainerTargetLabelProvider extends LabelProvider {
@Override
public String getText(Object element) {
if (element instanceof ILaunchTarget) {
return ((ILaunchTarget) element).getId();
}
return super.getText(element);
}
@Override
public Image getImage(Object element) {
return CDebugImages.get(CDebugImages.IMG_OBJS_CDT_LOGO);
}
}

View file

@ -0,0 +1,201 @@
/*******************************************************************************
* Copyright (c) 2016 QNX Software Systems and others.
* 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
*******************************************************************************/
package org.eclipse.cdt.internal.docker.launcher.ui.launchbar;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
import org.eclipse.cdt.docker.launcher.ContainerTargetTypeProvider;
import org.eclipse.cdt.docker.launcher.IContainerLaunchTarget;
import org.eclipse.cdt.dsf.gdb.IGDBLaunchConfigurationConstants;
import org.eclipse.cdt.dsf.gdb.IGdbDebugPreferenceConstants;
import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.launchbar.core.AbstractLaunchConfigProvider;
import org.eclipse.launchbar.core.ILaunchDescriptor;
import org.eclipse.launchbar.core.target.ILaunchTarget;
/**
* @since 1.2
* @author jjohnstn
*
*/
public class CoreBuildContainerLaunchConfigProvider extends AbstractLaunchConfigProvider {
private static final String TYPE_ID = "org.eclipse.cdt.docker.launcher.launchConfigurationType"; //$NON-NLS-1$
private Map<IProject, Map<String, ILaunchConfiguration>> configs = new HashMap<>();
@Override
public boolean supports(ILaunchDescriptor descriptor, ILaunchTarget target) throws CoreException {
return target != null && ContainerTargetTypeProvider.TYPE_ID
.equals(target.getTypeId());
}
@Override
public ILaunchConfigurationType getLaunchConfigurationType(ILaunchDescriptor descriptor, ILaunchTarget target)
throws CoreException {
return DebugPlugin.getDefault().getLaunchManager().getLaunchConfigurationType(TYPE_ID);
}
@Override
public ILaunchConfiguration getLaunchConfiguration(ILaunchDescriptor descriptor, ILaunchTarget target)
throws CoreException {
ILaunchConfiguration config = null;
IProject project = descriptor.getAdapter(IProject.class);
if (project != null) {
Map<String, ILaunchConfiguration> configMap = configs.get(project);
if (configMap == null) {
configMap = new HashMap<>();
}
String connection = target.getAttribute(
IContainerLaunchTarget.ATTR_CONNECTION_URI, ""); //$NON-NLS-1$
String imageId = target
.getAttribute(IContainerLaunchTarget.ATTR_IMAGE_ID, ""); //$NON-NLS-1$
String imageName = connection + "-" + imageId; //$NON-NLS-1$
config = configMap.get(imageName);
if (config == null) {
config = createLaunchConfiguration(descriptor, target);
// launch config added will get called below to add it to the
// configs map
}
}
return config;
}
private String getImageName(ILaunchConfiguration config)
throws CoreException {
String connection = config
.getAttribute(IContainerLaunchTarget.ATTR_CONNECTION_URI, ""); //$NON-NLS-1$
String image = config.getAttribute(IContainerLaunchTarget.ATTR_IMAGE_ID,
""); //$NON-NLS-1$
String imageName = connection + "-" + image; //$NON-NLS-1$
return imageName;
}
@Override
protected void populateLaunchConfiguration(ILaunchDescriptor descriptor, ILaunchTarget target,
ILaunchConfigurationWorkingCopy wc) throws CoreException {
super.populateLaunchConfiguration(descriptor, target, wc);
// Set the project and the connection
IProject project = descriptor.getAdapter(IProject.class);
wc.setAttribute(
ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME,
project.getName());
wc.setAttribute(IContainerLaunchTarget.ATTR_CONNECTION_URI,
target.getAttribute(IContainerLaunchTarget.ATTR_CONNECTION_URI,
null));
wc.setAttribute(IContainerLaunchTarget.ATTR_IMAGE_ID, target
.getAttribute(IContainerLaunchTarget.ATTR_IMAGE_ID, null));
// DSF settings...use GdbUIPlugin preference store for defaults
IPreferenceStore preferenceStore = GdbUIPlugin.getDefault()
.getPreferenceStore();
wc.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUG_NAME,
preferenceStore.getString(
IGdbDebugPreferenceConstants.PREF_DEFAULT_GDB_COMMAND));
wc.setAttribute(IGDBLaunchConfigurationConstants.ATTR_GDB_INIT,
preferenceStore.getString(
IGdbDebugPreferenceConstants.PREF_DEFAULT_GDB_INIT));
wc.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP,
preferenceStore.getBoolean(
IGdbDebugPreferenceConstants.PREF_DEFAULT_NON_STOP));
wc.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_REVERSE,
IGDBLaunchConfigurationConstants.DEBUGGER_REVERSE_DEFAULT);
wc.setAttribute(
IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_UPDATE_THREADLIST_ON_SUSPEND,
IGDBLaunchConfigurationConstants.DEBUGGER_UPDATE_THREADLIST_ON_SUSPEND_DEFAULT);
wc.setAttribute(
IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_DEBUG_ON_FORK,
IGDBLaunchConfigurationConstants.DEBUGGER_DEBUG_ON_FORK_DEFAULT);
wc.setAttribute(
IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_TRACEPOINT_MODE,
IGDBLaunchConfigurationConstants.DEBUGGER_TRACEPOINT_MODE_DEFAULT);
wc.setAttribute(ICDTLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY,
(String) null); // default is the project directory
wc.setMappedResources(new IResource[] { project });
}
@Override
public boolean launchConfigurationAdded(ILaunchConfiguration configuration) throws CoreException {
if (ownsLaunchConfiguration(configuration)) {
IProject project = configuration.getMappedResources()[0].getProject();
Map<String, ILaunchConfiguration> configMap = configs.get(project);
if (configMap == null) {
configMap = new HashMap<>();
configs.put(project, configMap);
}
String imageName = getImageName(configuration);
if (!imageName.equals("-")) { //$NON-NLS-1$
configMap.put(imageName, configuration);
}
return true;
}
return false;
}
@Override
public boolean launchConfigurationRemoved(ILaunchConfiguration configuration) throws CoreException {
for (Entry<IProject, Map<String, ILaunchConfiguration>> entry : configs
.entrySet()) {
for (Entry<String, ILaunchConfiguration> innerEntry : entry
.getValue().entrySet()) {
if (configuration.equals(innerEntry.getValue())) {
entry.getValue().remove(innerEntry.getKey());
return true;
}
}
}
return false;
}
@Override
public boolean launchConfigurationChanged(ILaunchConfiguration configuration) throws CoreException {
// if (ownsLaunchConfiguration(configuration)) {
// IProject project = configuration.getMappedResources()[0]
// .getProject();
// Map<String, ILaunchConfiguration> configMap = configs.get(project);
// if (configMap == null) {
// configMap = new HashMap<>();
// configs.put(project, configMap);
// }
// String imageName = getImageName(configuration);
// if (!imageName.isEmpty()) {
// configMap.put(imageName, configuration);
// }
// return true;
// }
return false;
}
@Override
public void launchDescriptorRemoved(ILaunchDescriptor descriptor) throws CoreException {
IProject project = descriptor.getAdapter(IProject.class);
if (project != null) {
configs.remove(project);
}
}
@Override
public void launchTargetRemoved(ILaunchTarget target) throws CoreException {
// nothing to do since the Local connection can't be removed
}
}

View file

@ -0,0 +1,39 @@
/*******************************************************************************
* Copyright (c) 2016 QNX Software Systems and others.
* 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
*******************************************************************************/
package org.eclipse.cdt.internal.docker.launcher.ui.launchbar;
import org.eclipse.cdt.core.build.ICBuildConfigurationManager;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.launchbar.core.ILaunchDescriptor;
import org.eclipse.launchbar.core.ILaunchDescriptorType;
import org.eclipse.launchbar.core.ProjectLaunchDescriptor;
import org.eclipse.launchbar.core.internal.Activator;
/**
* The launch descriptor type for launch objects built with the Core Build
* System.
*
* @since 1.2
*/
public class CoreBuildContainerLaunchDescriptorType implements ILaunchDescriptorType {
@Override
public ILaunchDescriptor getDescriptor(Object launchObject) throws CoreException {
if (launchObject instanceof IProject) {
// Make sure it's a new style build
IProject project = (IProject) launchObject;
if (Activator.getService(ICBuildConfigurationManager.class).supports(project)) {
return new ProjectLaunchDescriptor(this, project);
}
}
// TODO IBinary
return null;
}
}

View file

@ -0,0 +1,49 @@
/*******************************************************************************
* Copyright (c) 2018 Red Hat Inc. and others.
* 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
*
* Red Hat Inc. - initial version
*******************************************************************************/
package org.eclipse.cdt.internal.docker.launcher.ui.launchbar;
import org.eclipse.osgi.util.NLS;
/**
* @since 1.2
* @author jjohnstn
*
*/
public class Messages extends NLS {
private static final String BUNDLE_NAME = "org.eclipse.cdt.internal.docker.launcher.ui.launchbar.messages"; //$NON-NLS-1$
public static String ContainerGCCToolChainProvider_Saving1;
public static String ContainerGCCToolChainProvider_Saving;
public static String ContainerGCCToolChainProvider_NotOurs;
public static String ContainerGCCToolChainProvider_Loading;
public static String NewContainerTargetWizard_title;
public static String NewContainerTargetWizardPage_name;
public static String NewContainerTargetWizardPage_title;
public static String NewContainerTargetWizardPage_description;
public static String NewContainerTargetWizardPage_no_connections;
public static String NewContainerTargetWizardPage_no_images;
public static String NewContainerTargetWizardPage_connection;
public static String NewContainerTargetWizardPage_image;
public static String EditContainerTargetWizard_title;
public static String EditContainerTargetWizardPage_title;
public static String EditContainerTargetWizardPage_description;
static {
// initialize resource bundle
NLS.initializeMessages(BUNDLE_NAME, Messages.class);
}
private Messages() {
}
}

View file

@ -0,0 +1,117 @@
/*******************************************************************************
* Copyright (c) 2018 Red Hat Inc. and others.
* 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:
* Red Hat Inc. - initial contribution
*******************************************************************************/
package org.eclipse.cdt.internal.docker.launcher.ui.launchbar;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.cdt.core.build.IToolChain;
import org.eclipse.cdt.core.build.IToolChainManager;
import org.eclipse.cdt.debug.core.CDebugCorePlugin;
import org.eclipse.cdt.debug.ui.CDebugUIPlugin;
import org.eclipse.cdt.docker.launcher.ContainerTargetTypeProvider;
import org.eclipse.cdt.docker.launcher.IContainerLaunchTarget;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Platform;
import org.eclipse.launchbar.core.target.ILaunchTarget;
import org.eclipse.launchbar.core.target.ILaunchTargetManager;
import org.eclipse.launchbar.core.target.ILaunchTargetWorkingCopy;
import org.eclipse.launchbar.ui.internal.Activator;
import org.eclipse.launchbar.ui.target.LaunchTargetWizard;
@SuppressWarnings("restriction")
/**
* @since 1.2
* @author jjohnstn
*
*/
public class NewContainerTargetWizard extends LaunchTargetWizard {
private NewContainerTargetWizardPage page;
protected IToolChainManager toolChainManager = CDebugCorePlugin
.getService(IToolChainManager.class);
public NewContainerTargetWizard() {
if (getLaunchTarget() == null) {
setWindowTitle(Messages.NewContainerTargetWizard_title);
} else {
setWindowTitle(Messages.EditContainerTargetWizard_title);
}
}
@Override
public void addPages() {
super.addPages();
page = new NewContainerTargetWizardPage(getLaunchTarget());
addPage(page);
}
@Override
public boolean performFinish() {
ILaunchTargetManager manager = CDebugUIPlugin
.getService(ILaunchTargetManager.class);
String typeId = ContainerTargetTypeProvider.TYPE_ID;
String id = page.getTargetName();
ILaunchTarget target = getLaunchTarget();
if (target == null) {
target = manager.addLaunchTarget(typeId, id);
}
ILaunchTargetWorkingCopy wc = target.getWorkingCopy();
wc.setId(id);
wc.setAttribute(ILaunchTarget.ATTR_OS, Platform.getOS());
wc.setAttribute(ILaunchTarget.ATTR_ARCH,
ContainerTargetTypeProvider.CONTAINER_LINUX);
wc.setAttribute(IContainerLaunchTarget.ATTR_CONNECTION_URI,
page.getConnectionURI());
wc.setAttribute(IContainerLaunchTarget.ATTR_IMAGE_ID,
page.getImageId());
wc.save();
// Pick the first one that matches
Map<String, String> properties = new HashMap<>();
properties.putAll(wc.getAttributes());
Collection<IToolChain> toolChains = Collections.emptyList();
try {
toolChains = toolChainManager.getToolChainsMatching(properties);
} catch (CoreException e) {
// do nothing
}
// if (toolChains.size() == 0) {
// // add new Container toolchain with attributes above
// ContainerToolChain toolChain = new ContainerToolChain();
// toolChain.add(properties);
// }
return true;
}
@Override
public boolean canDelete() {
return true;
}
@Override
public void performDelete() {
ILaunchTargetManager manager = Activator
.getService(ILaunchTargetManager.class);
ILaunchTarget target = getLaunchTarget();
if (target != null) {
manager.removeLaunchTarget(getLaunchTarget());
}
}
}

View file

@ -0,0 +1,309 @@
/*******************************************************************************
* Copyright (c) 2018 Red Hat Inc. and others.
* 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
*
* Contibutors:
* Red Hat Inc. - initial implementation
*******************************************************************************/
package org.eclipse.cdt.internal.docker.launcher.ui.launchbar;
import java.util.ArrayList;
import org.eclipse.cdt.docker.launcher.IContainerLaunchTarget;
import org.eclipse.cdt.internal.docker.launcher.SWTImagesFactory;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.launchbar.core.target.ILaunchTarget;
import org.eclipse.linuxtools.docker.core.DockerConnectionManager;
import org.eclipse.linuxtools.docker.core.IDockerConnection;
import org.eclipse.linuxtools.docker.core.IDockerConnectionManagerListener;
import org.eclipse.linuxtools.docker.core.IDockerImage;
import org.eclipse.linuxtools.docker.core.IDockerImageListener;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.events.VerifyListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
/**
* @since 1.2
* @author jjohnstn
*
*/
public class NewContainerTargetWizardPage extends WizardPage
implements IDockerImageListener, IDockerConnectionManagerListener {
private final ILaunchTarget launchTarget;
private Text nameText;
private Combo imageCombo;
private Combo connectionSelector;
private IDockerConnection connection;
private IDockerConnection[] connections;
private IDockerImageListener wizardPage;
private String imageName;
private String connectionName;
private String connectionUri = "";
public NewContainerTargetWizardPage(ILaunchTarget launchTarget) {
super(NewContainerTargetWizardPage.class.getName());
if (launchTarget == null) {
setTitle(Messages.NewContainerTargetWizardPage_title);
setDescription(Messages.NewContainerTargetWizardPage_description);
} else {
setTitle(Messages.EditContainerTargetWizardPage_title);
setDescription(Messages.EditContainerTargetWizardPage_description);
}
this.launchTarget = launchTarget;
this.wizardPage = this;
if (launchTarget != null) {
connectionUri = launchTarget.getAttribute(
IContainerLaunchTarget.ATTR_CONNECTION_URI, null);
imageName = launchTarget
.getAttribute(IContainerLaunchTarget.ATTR_IMAGE_ID, null);
}
}
private ModifyListener connectionModifyListener = new ModifyListener() {
@Override
public void modifyText(ModifyEvent e) {
int index = connectionSelector.getSelectionIndex();
if (connection != null)
connection.removeImageListener(wizardPage);
connection = connections[index];
connectionUri = connection.getUri();
if (!connectionName.equals(connection.getName())) {
setErrorMessage(null);
imageName = null;
initializeImageCombo();
setPageComplete(false);
}
connectionName = connection.getName();
}
};
@Override
public void createControl(Composite parent) {
Composite comp = new Composite(parent, SWT.NONE);
comp.setLayout(new GridLayout(2, false));
Label label = new Label(comp, SWT.NONE);
label.setText(Messages.NewContainerTargetWizardPage_name);
nameText = new Text(comp, SWT.BORDER);
nameText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
if (launchTarget != null) {
nameText.setText(launchTarget.getId());
nameText.setEnabled(false);
}
label = new Label(comp, SWT.NONE);
label.setText(Messages.NewContainerTargetWizardPage_connection);
connectionSelector = new Combo(comp, SWT.BORDER | SWT.READ_ONLY);
initializeConnectionSelector();
connectionSelector.addModifyListener(connectionModifyListener);
// Following is a kludge so that on Linux the Combo is read-only but
// has a white background.
connectionSelector.addVerifyListener(new VerifyListener() {
@Override
public void verifyText(VerifyEvent e) {
e.doit = false;
}
});
GridData gd = new GridData();
gd.horizontalSpan = 2;
gd.horizontalIndent = 5;
connectionSelector.setLayoutData(gd);
Label imageSelectorLabel = new Label(comp, SWT.NULL);
imageSelectorLabel.setText(Messages.NewContainerTargetWizardPage_image);
imageCombo = new Combo(comp, SWT.DROP_DOWN);
GridData gd2 = new GridData();
gd2.horizontalSpan = 2;
gd2.horizontalIndent = 5;
imageCombo.setLayoutData(gd2);
initializeImageCombo();
imageCombo.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
imageName = imageCombo.getText();
setPageComplete(imageName != null && !imageName.isEmpty());
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
setPageComplete(false);
setControl(comp);
}
public String getTargetName() {
return nameText.getText().trim();
}
public String getConnectionURI() {
return connectionUri;
}
public String getImageId() {
return imageName;
}
@Override
public Image getImage() {
return SWTImagesFactory.get(SWTImagesFactory.IMG_CONTAINER);
}
private void initializeConnectionSelector() {
int defaultIndex = -1;
connections = DockerConnectionManager.getInstance().getConnections();
if (connections.length == 0) {
setErrorMessage(
Messages.NewContainerTargetWizardPage_no_connections);
return;
}
String[] connectionNames = new String[connections.length];
for (int i = 0; i < connections.length; ++i) {
connectionNames[i] = connections[i].getName();
if (connections[i].getUri().equals(connectionUri))
defaultIndex = i;
}
if (defaultIndex < 0) {
defaultIndex = 0;
}
connectionSelector.setItems(connectionNames);
if (connections.length > 0) {
connectionSelector.setText(connectionNames[defaultIndex]);
connection = connections[defaultIndex];
connectionName = connection.getName();
connectionUri = connection.getUri();
}
}
private void initializeImageCombo() {
if (connection != null) {
java.util.List<IDockerImage> images = connection.getImages();
if (images == null || images.size() == 0) {
setErrorMessage(
Messages.NewContainerTargetWizardPage_no_images);
return;
}
connection.removeImageListener(wizardPage);
ArrayList<String> imageNames = new ArrayList<String>();
for (IDockerImage image : images) {
java.util.List<String> tags = image.repoTags();
if (tags != null) {
for (String tag : tags) {
if (!tag.equals("<none>:<none>")) //$NON-NLS-1$
imageNames.add(tag);
}
}
}
imageCombo.setItems(imageNames.toArray(new String[0]));
if (imageName != null)
imageCombo.setText(imageName);
connection.addImageListener(wizardPage);
}
}
@Override
public void changeEvent(IDockerConnection changedConnection, int type) {
String currUri = null;
int currIndex = 0;
setErrorMessage(null);
connections = DockerConnectionManager.getInstance().getConnections();
if (connection != null) {
currUri = connection.getUri();
currIndex = connectionSelector.getSelectionIndex();
}
String[] connectionNames = new String[connections.length];
int index = 0;
for (int i = 0; i < connections.length; ++i) {
connectionNames[i] = connections[i].getName();
if (connections[i].getUri().equals(currUri))
index = i;
}
if (type == IDockerConnectionManagerListener.RENAME_EVENT) {
index = currIndex; // no change in connection displayed
}
connectionSelector.removeModifyListener(connectionModifyListener);
connectionSelector.setItems(connectionNames);
if (connectionNames.length > 0) {
connectionSelector.setText(connectionNames[index]);
connection = connections[index];
connectionUri = connection.getUri();
java.util.List<IDockerImage> images = connection.getImages();
if (images == null || images.size() == 0) {
setErrorMessage(
Messages.NewContainerTargetWizardPage_no_images);
}
} else {
setErrorMessage(
Messages.NewContainerTargetWizardPage_no_connections);
connection = null;
connectionUri = "";
connectionSelector.setText("");
}
connectionSelector.addModifyListener(connectionModifyListener);
}
public void listChanged(IDockerConnection c,
java.util.List<IDockerImage> list) {
setErrorMessage(null);
final IDockerImage[] finalList = list.toArray(new IDockerImage[0]);
if (finalList.length == 0) {
setErrorMessage(Messages.NewContainerTargetWizardPage_no_images);
}
if (c.getName().equals(connection.getName())) {
Display.getDefault().syncExec(new Runnable() {
@Override
public void run() {
connection.removeImageListener(wizardPage);
ArrayList<String> imageNames = new ArrayList<String>();
for (IDockerImage image : finalList) {
java.util.List<String> tags = image.repoTags();
if (tags != null) {
for (String tag : tags) {
imageNames.add(tag);
}
}
}
if (!imageCombo.isDisposed())
imageCombo.setItems(imageNames.toArray(new String[0]));
connection.addImageListener(wizardPage);
}
});
}
}
@Override
public void dispose() {
if (connection != null)
connection.removeImageListener(this);
super.dispose();
}
}

View file

@ -0,0 +1,28 @@
################################################################################
# Copyright (c) 2018 Red Hat Inc. and others.
# 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
#
# Red Hat Inc. - initial implementation
################################################################################
NewContainerTargetWizard_title=New Docker Container Target
NewContainerTargetWizardPage_name=Name:
NewContainerTargetWizardPage_image=Image:
NewContainerTargetWizardPage_title=Container Target
NewContainerTargetWizardPage_description=Enter name and properties for the target.
NewContainerTargetWizardPage_no_connections=No Docker connections are available
NewContainerTargetWizardPage_no_images=Docker connection has no pulled images
NewContainerTargetWizardPage_connection=Connection:
EditContainerTargetWizard_title=Edit Docker Container Target
EditContainerTargetWizardPage_title=Container Target
EditContainerTargetWizardPage_description=Edit properties for the target.
ContainerGCCToolChainProvider_Saving1=Saving Container toolchain file
ContainerGCCToolChainProvider_Saving=Saving Container toolchain file
ContainerGCCToolChainProvider_NotOurs=Not ours
ContainerGCCToolChainProvider_Loading=Loading Container toolchain file