Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMoritz 'Morty' Strübe2022-05-19 07:38:51 +0000
committerJeff Johnston2022-05-21 01:08:10 +0000
commit02d2c81ec967ff90e2897b2e728cb572d089933c (patch)
tree8ca6e7311c10ab70c33d1fdcd6e8b383d7e74f98
parent9a2558bd66b447e843257f0fe1318f66898bb0ab (diff)
downloadorg.eclipse.cdt-02d2c81ec967ff90e2897b2e728cb572d089933c.tar.gz
org.eclipse.cdt-02d2c81ec967ff90e2897b2e728cb572d089933c.tar.xz
org.eclipse.cdt-02d2c81ec967ff90e2897b2e728cb572d089933c.zip
Bug 579944: Clean up Docker include path code
This patch refactors multiple aspects of the code related to copying include paths from docker images: * document code * extract common code to methods * reduce indentation by returning early * support using \\WSL$\... paths Change-Id: I983d1e9bdfa84aa48928f5ba88df191d56ac0f17 Signed-off-by: Moritz 'Morty' Strübe <moritz.struebe@mathema.de>
-rw-r--r--launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/docker/launcher/ContainerCommandLauncher.java56
-rw-r--r--launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/docker/launcher/ContainerCommandLauncherFactory.java487
-rw-r--r--launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ContainerLaunchConfigurationDelegate.java37
-rw-r--r--launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ContainerLaunchUtils.java71
-rw-r--r--launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/Messages.java5
-rw-r--r--launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/messages.properties3
6 files changed, 347 insertions, 312 deletions
diff --git a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/docker/launcher/ContainerCommandLauncher.java b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/docker/launcher/ContainerCommandLauncher.java
index 3ab87a6dbdd..cae5dadc7e5 100644
--- a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/docker/launcher/ContainerCommandLauncher.java
+++ b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/docker/launcher/ContainerCommandLauncher.java
@@ -1,3 +1,17 @@
+/*******************************************************************************
+ * Copyright (c) 2017, 2022 Red Hat Inc. and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Red Hat Inc. - initial API and implementation
+ * Mathema - Refactor
+ *******************************************************************************/
package org.eclipse.cdt.docker.launcher;
import java.io.File;
@@ -9,6 +23,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
+import java.util.stream.Collectors;
import org.eclipse.cdt.core.ICommandLauncher;
import org.eclipse.cdt.core.build.ICBuildCommandLauncher;
@@ -17,6 +32,7 @@ import org.eclipse.cdt.core.build.IToolChain;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.internal.core.ProcessClosure;
+import org.eclipse.cdt.internal.docker.launcher.ContainerLaunchUtils;
import org.eclipse.cdt.internal.docker.launcher.Messages;
import org.eclipse.cdt.internal.docker.launcher.PreferenceConstants;
import org.eclipse.cdt.managedbuilder.buildproperties.IOptionalBuildProperties;
@@ -158,23 +174,16 @@ public class ContainerCommandLauncher implements ICommandLauncher, ICBuildComman
labels.put("org.eclipse.cdt.project-name", projectName); //$NON-NLS-1$
List<String> additionalDirs = new ArrayList<>();
+ List<IPath> additionalPaths = new ArrayList<>();
- //
- IPath projectLocation = fProject.getLocation();
- String projectPath = projectLocation.toPortableString();
- if (projectLocation.getDevice() != null) {
- projectPath = "/" + projectPath.replace(':', '/'); //$NON-NLS-1$
- }
- additionalDirs.add(projectPath);
+ additionalPaths.add(fProject.getLocation());
ArrayList<String> commandSegments = new ArrayList<>();
List<String> cmdList = new ArrayList<>();
- String commandString = commandPath.toPortableString();
- if (commandPath.getDevice() != null) {
- commandString = "/" + commandString.replace(':', '/'); //$NON-NLS-1$
- }
+ String commandString = ContainerLaunchUtils.toDockerPath(commandPath);
+
cmdList.add(commandString);
commandSegments.add(commandString);
for (String arg : args) {
@@ -189,12 +198,11 @@ public class ContainerCommandLauncher implements ICommandLauncher, ICBuildComman
// and modify the argument to be unix-style
if (f.isFile() || f.isDirectory()) {
f = f.getParentFile();
- modifiedArg = "/" //$NON-NLS-1$
- + p.toPortableString().replace(':', '/');
+ modifiedArg = ContainerLaunchUtils.toDockerPath(p);
p = p.removeLastSegments(1);
}
if (f != null && f.exists()) {
- additionalDirs.add("/" + p.toPortableString().replace(':', '/')); //$NON-NLS-1$
+ additionalPaths.add(p);
realArg = modifiedArg;
}
}
@@ -206,9 +214,10 @@ public class ContainerCommandLauncher implements ICommandLauncher, ICBuildComman
File f = p.toFile();
if (f.isFile()) {
f = f.getParentFile();
+ p.removeLastSegments(1);
}
if (f != null && f.exists()) {
- additionalDirs.add(f.getAbsolutePath());
+ additionalPaths.add(p);
}
}
}
@@ -220,19 +229,15 @@ public class ContainerCommandLauncher implements ICommandLauncher, ICBuildComman
IProject[] referencedProjects = fProject.getReferencedProjects();
for (IProject referencedProject : referencedProjects) {
- String referencedProjectPath = referencedProject.getLocation().toPortableString();
- if (referencedProject.getLocation().getDevice() != null) {
- referencedProjectPath = "/" //$NON-NLS-1$
- + referencedProjectPath.replace(':', '/');
- }
- additionalDirs.add(referencedProjectPath);
+ IPath referencedProjectPath = referencedProject.getLocation();
+ additionalPaths.add(referencedProjectPath);
}
- String workingDir = workingDirectory.makeAbsolute().toPortableString();
+ String workingDir;
if (workingDirectory.toPortableString().equals(".")) { //$NON-NLS-1$
workingDir = "/tmp"; //$NON-NLS-1$
- } else if (workingDirectory.getDevice() != null) {
- workingDir = "/" + workingDir.replace(':', '/'); //$NON-NLS-1$
+ } else {
+ workingDir = ContainerLaunchUtils.toDockerPath(workingDirectory.makeAbsolute());
}
parseEnvironment(env);
Map<String, String> origEnv = null;
@@ -283,6 +288,9 @@ public class ContainerCommandLauncher implements ICommandLauncher, ICBuildComman
}
setImageName(imageName);
+ additionalDirs.addAll(
+ additionalPaths.stream().map(p -> ContainerLaunchUtils.toDockerVolume(p)).collect(Collectors.toList()));
+
fProcess = launcher.runCommand(connectionName, imageName, fProject, this, cmdList, workingDir, additionalDirs,
origEnv, fEnvironment, supportStdin, privilegedMode, labels, keepContainer);
diff --git a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/docker/launcher/ContainerCommandLauncherFactory.java b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/docker/launcher/ContainerCommandLauncherFactory.java
index 13ce4b4bb4a..2f2a064f923 100644
--- a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/docker/launcher/ContainerCommandLauncherFactory.java
+++ b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/docker/launcher/ContainerCommandLauncherFactory.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2017 Red Hat Inc. and others.
+ * Copyright (c) 2017, 2022 Red Hat Inc. and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -10,16 +10,14 @@
*
* Contributors:
* Red Hat Inc. - initial API and implementation
+ * Mathema - Refactor
*******************************************************************************/
package org.eclipse.cdt.docker.launcher;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
+import java.util.stream.Collectors;
import org.eclipse.cdt.core.ICommandLauncher;
import org.eclipse.cdt.core.ICommandLauncherFactory;
@@ -50,15 +48,121 @@ import org.eclipse.linuxtools.docker.ui.launch.ContainerLauncher;
@SuppressWarnings("restriction")
public class ContainerCommandLauncherFactory implements ICommandLauncherFactory, ICommandLauncherFactory2 {
- private IProject project;
+ private IProject m_project;
+
+ /**
+ * Helper-Struct
+ */
+ private class ImageConnection {
+ final String connectionName;
+ final String imageName;
+
+ public ImageConnection(String connectionName, String imageName) {
+ this.connectionName = connectionName;
+ this.imageName = imageName;
+ }
+
+ }
+
+ /**
+ * Filter out paths that should not be copied from the container
+ * @param dirs A List of paths that should be filtered
+ * @return The filtered list
+ */
+ private List<String> filterOutLocalPaths(List<String> dirs) {
+ String prj = m_project.getLocation().toString();
+ return dirs.stream().filter(x -> !(x.startsWith(prj) || x.startsWith("/${ProjName}")) //$NON-NLS-1$
+ ).collect(Collectors.toList());
+
+ }
+
+ /**
+ * Transform a string into something that can be used as path name
+ * @param name The name that should be used as part of a path
+ * @return A string that should be usable as path name
+ */
+ private String normalizeToPathName(String name) {
+ String cleanName = name.replace("unix:///", "unix_"); //$NON-NLS-1$ //$NON-NLS-2$
+ cleanName = cleanName.replace("tcp://", "tcp_"); //$NON-NLS-1$ //$NON-NLS-2$
+ cleanName = cleanName.replaceAll("[:/.]", "_"); //$NON-NLS-1$ //$NON-NLS-2$#
+ assert Path.ROOT.isValidSegment(cleanName) : "Invalid Path - please file a bug"; //$NON-NLS-1$
+ return cleanName;
+ }
+
+ /**
+ * Convert the ImageConnection to the local path where the data is mirrored to
+ * @param imgCon The connection
+ * @return A host path
+ */
+ private IPath getHostMirrorPath(ImageConnection imgCon) {
+ IPath pluginPath = Platform.getStateLocation(Platform.getBundle(DockerLaunchUIPlugin.PLUGIN_ID))
+ .append("HEADERS"); //$NON-NLS-1$
+ pluginPath = pluginPath.append(normalizeToPathName(imgCon.connectionName));
+ pluginPath = pluginPath.append(normalizeToPathName(imgCon.imageName));
+ return pluginPath;
+ }
+
+ /**
+ * Mirror a list of paths from the imgCon to the host
+ * @param imgCon The image and connection to copy from
+ * @param paths The paths to copy
+ * @return Whether the operation was successful
+ */
+ private boolean getPaths(ImageConnection imgCon, List<String> paths) {
+ IPath targetPath = getHostMirrorPath(imgCon);
+
+ ContainerLauncher launcher = new ContainerLauncher();
+ int rv = launcher.fetchContainerDirs(imgCon.connectionName, imgCon.imageName, paths, null, targetPath);
+ return (rv == 0);
+
+ }
+
+ /**
+ * Get the Image and Connection from the current project configuration
+ * @return An ImageConnection or null if connection and image are configured
+ */
+ private ImageConnection getImgCnn() {
+ ICConfigurationDescription cfgd = CoreModel.getDefault().getProjectDescription(m_project)
+ .getActiveConfiguration();
+ IConfiguration cfg = ManagedBuildManager.getConfigurationForDescription(cfgd);
+ IOptionalBuildProperties props = cfg.getOptionalBuildProperties();
+ if (props == null) {
+ return null;
+ }
+
+ String enablementProperty = props.getProperty(ContainerCommandLauncher.CONTAINER_BUILD_ENABLED);
+ if (enablementProperty == null) {
+ return null;
+ }
+
+ if (!Boolean.parseBoolean(enablementProperty)) {
+ return null;
+ }
+
+ String connectionName = props.getProperty(ContainerCommandLauncher.CONNECTION_ID);
+ String imageName = props.getProperty(ContainerCommandLauncher.IMAGE_ID);
+ if (connectionName == null || connectionName.isEmpty() || imageName == null || imageName.isEmpty()) {
+ DockerLaunchUIPlugin.logErrorMessage(Messages.ContainerCommandLauncher_invalid_values);
+ return null;
+ }
+
+ return new ImageConnection(connectionName, imageName);
+
+ }
@Override
public ICommandLauncher getCommandLauncher(IProject project) {
- this.project = project;
+ m_project = project;
// check if container build enablement has been checked
ICConfigurationDescription cfgd = CoreModel.getDefault().getProjectDescription(project, false)
.getActiveConfiguration();
+ return getCommandLauncher(cfgd);
+ }
+
+ @Override
+ public ICommandLauncher getCommandLauncher(ICConfigurationDescription cfgd) {
+ // check if container build enablement has been checked
IConfiguration cfg = null;
try {
@@ -79,31 +183,8 @@ public class ContainerCommandLauncherFactory implements ICommandLauncherFactory,
if (cfg == null) {
return null;
}
- IOptionalBuildProperties props = cfg.getOptionalBuildProperties();
- if (props != null) {
- String enablementProperty = props.getProperty(ContainerCommandLauncher.CONTAINER_BUILD_ENABLED);
- if (enablementProperty != null) {
- boolean enableContainer = Boolean.parseBoolean(enablementProperty);
- // enablement has occurred, we can return a
- // ContainerCommandLauncher
- if (enableContainer) {
- return new ContainerCommandLauncher();
- }
- }
- }
- return null;
- }
-
- @Override
- public ICommandLauncher getCommandLauncher(ICConfigurationDescription cfgd) {
- // check if container build enablement has been checked
- IConfiguration cfg = ManagedBuildManager.getConfigurationForDescription(cfgd);
- // TODO: figure out why this occurs
- if (cfg == null) {
- return null;
- }
- this.project = (IProject) cfg.getManagedProject().getOwner();
+ m_project = (IProject) cfg.getManagedProject().getOwner();
IOptionalBuildProperties props = cfg.getOptionalBuildProperties();
if (props != null) {
String enablementProperty = props.getProperty(ContainerCommandLauncher.CONTAINER_BUILD_ENABLED);
@@ -122,7 +203,7 @@ public class ContainerCommandLauncherFactory implements ICommandLauncherFactory,
@Override
public ICommandLauncher getCommandLauncher(ICBuildConfiguration cfgd) {
try {
- this.project = cfgd.getBuildConfiguration().getProject();
+ m_project = cfgd.getBuildConfiguration().getProject();
} catch (CoreException e1) {
return null;
}
@@ -143,97 +224,32 @@ public class ContainerCommandLauncherFactory implements ICommandLauncherFactory,
@Override
public void registerLanguageSettingEntries(IProject project, List<? extends ICLanguageSettingEntry> langEntries) {
- @SuppressWarnings("unchecked")
- List<ICLanguageSettingEntry> entries = (List<ICLanguageSettingEntry>) langEntries;
if (langEntries == null) {
// langEntries can be null when the last item is removed from a list,
// see org.eclipse.cdt.internal.ui.language.settings.providers.LanguageSettingsEntriesTab.saveEntries(ILanguageSettingsProvider, List<ICLanguageSettingEntry>)
// for an example that passes null to mean "use parent entries instead".
return;
}
- ICConfigurationDescription cfgd = CoreModel.getDefault().getProjectDescription(project)
- .getActiveConfiguration();
- IConfiguration cfg = ManagedBuildManager.getConfigurationForDescription(cfgd);
- IOptionalBuildProperties props = cfg.getOptionalBuildProperties();
- if (props != null) {
- String enablementProperty = props.getProperty(ContainerCommandLauncher.CONTAINER_BUILD_ENABLED);
- if (enablementProperty != null) {
- boolean enableContainer = Boolean.parseBoolean(enablementProperty);
- if (enableContainer) {
- String connectionName = props.getProperty(ContainerCommandLauncher.CONNECTION_ID);
- String imageName = props.getProperty(ContainerCommandLauncher.IMAGE_ID);
- if (connectionName == null || connectionName.isEmpty() || imageName == null
- || imageName.isEmpty()) {
- DockerLaunchUIPlugin.logErrorMessage(Messages.ContainerCommandLauncher_invalid_values);
- return;
- }
- ContainerLauncher launcher = new ContainerLauncher();
- List<String> paths = new ArrayList<>();
- for (ICLanguageSettingEntry entry : entries) {
- if (entry instanceof ICIncludePathEntry) {
- paths.add(entry.getValue());
- } else if (entry instanceof ICIncludeFileEntry) {
- paths.add(new org.eclipse.core.runtime.Path(entry.getValue()).removeLastSegments(1)
- .toString());
- }
- }
- if (paths.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;
- }
- 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;
- }
- } catch (IOException e) {
- DockerLaunchUIPlugin.log(e);
- return;
- }
- IPath hostDir = pluginPath;
- List<String> excludeList = new ArrayList<>();
- excludeList.add(project.getLocation().toString());
- @SuppressWarnings("unused")
- int status = launcher.fetchContainerDirs(connectionName, imageName, paths, excludeList,
- hostDir);
- }
- }
+
+ @SuppressWarnings("unchecked")
+ List<ICLanguageSettingEntry> entries = (List<ICLanguageSettingEntry>) langEntries;
+
+ List<String> paths = new ArrayList<>();
+ for (ICLanguageSettingEntry entry : entries) {
+ if (entry instanceof ICIncludePathEntry) {
+ paths.add(entry.getValue());
+ } else if (entry instanceof ICIncludeFileEntry) {
+ paths.add(new org.eclipse.core.runtime.Path(entry.getValue()).removeLastSegments(1).toString());
}
}
+ paths = filterOutLocalPaths(paths);
+ if (paths.size() == 0) {
+ return;
+ }
+ ImageConnection imgCnn = getImgCnn();
+ getPaths(imgCnn, paths);
+
}
/**
@@ -242,109 +258,72 @@ public class ContainerCommandLauncherFactory implements ICommandLauncherFactory,
@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;
- }
- if (includePaths.size() > 0) {
- ContainerLauncher launcher = new ContainerLauncher();
- // 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;
- // exclude project directories from any copying operation
- List<String> excludeList = new ArrayList<>();
- excludeList.add(project.getLocation().toString());
- int status = launcher.fetchContainerDirsSync(connectionName, imageName, includePaths, excludeList,
- 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;
- }
+ if (toolchain == null) {
+ return includePaths;
+ }
+ if (!ContainerTargetTypeProvider.CONTAINER_LINUX.equals(toolchain.getProperty(IToolChain.ATTR_OS))) {
+ DockerLaunchUIPlugin.logErrorMessage(Messages.ContainerCommandLauncher_invalid_container_type);
+ return includePaths;
+ }
+
+ 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;
+ }
+
+ ImageConnection imgCnn = new ImageConnection(connectionName, imageName);
+
+ if (includePaths.isEmpty()) {
+ // Bug 536884 - if no include entries, check if the copied
+ // header files have been erased by the end-user in which
+ // case mark that scanner info needs refreshing (only way
+ // the headers will be recopied)
+ // TODO: fix this in a minor release to be an additional method
+ // that can be registered by the removal of the header files
+ IPath pluginPath = getHostMirrorPath(imgCnn);
+ toolchain.setProperty("cdt.needScannerRefresh", //$NON-NLS-1$
+ pluginPath.toFile().exists() ? "false" : "true"); //$NON-NLS-1$ //$NON-NLS-2$
+ return includePaths;
+ }
+
+ List<String> fetchPaths = filterOutLocalPaths(includePaths);
+ if (fetchPaths.size() == 0) {
+ return includePaths;
+ }
+
+ if (!getPaths(imgCnn, includePaths)) {
+ // There should be sufficient log messages by the root cause
+ return includePaths;
+ }
+
+ // Do the actual work
+
+ IPath tpath = getHostMirrorPath(imgCnn);
+ Set<IPath> copiedVolumes = ContainerLauncher.getCopiedVolumes(tpath);
+ List<String> newEntries = new ArrayList<>();
+
+ for (String path : includePaths) {
+ if (copiedVolumes.contains(new Path(path))) {
+ IPath newPath = tpath.append(path);
+ String newEntry = newPath.toOSString();
+ newEntries.add(newEntry);
} else {
- // Bug 536884 - if no include entries, check if the copied
- // header files have been erased by the end-user in which
- // case mark that scanner info needs refreshing (only way
- // the headers will be recopied)
- // TODO: fix this in a minor release to be an additional method
- // that can be registered by the removal of the header files
- IPath pluginPath = Platform.getStateLocation(Platform.getBundle(DockerLaunchUIPlugin.PLUGIN_ID))
- .append("HEADERS").append(getCleanName(connectionName)) //$NON-NLS-1$
- .append(getCleanName(imageName));
- toolchain.setProperty("cdt.needScannerRefresh", //$NON-NLS-1$
- pluginPath.toFile().exists() ? "false" : "true"); //$NON-NLS-1$ //$NON-NLS-2$
+ newEntries.add(path);
}
}
- return includePaths;
+ return newEntries;
+
}
@Override
@@ -353,64 +332,56 @@ public class ContainerCommandLauncherFactory implements ICommandLauncherFactory,
if (entries == null) {
return null;
}
+
ICConfigurationDescription cfgd = CoreModel.getDefault().getProjectDescription(project)
.getActiveConfiguration();
IConfiguration cfg = ManagedBuildManager.getConfigurationForDescription(cfgd);
IOptionalBuildProperties props = cfg.getOptionalBuildProperties();
- if (props != null) {
- String enablementProperty = props.getProperty(ContainerCommandLauncher.CONTAINER_BUILD_ENABLED);
- if (enablementProperty != null) {
- boolean enableContainer = Boolean.parseBoolean(enablementProperty);
- if (enableContainer) {
- String connectionName = props.getProperty(ContainerCommandLauncher.CONNECTION_ID);
- String imageName = props.getProperty(ContainerCommandLauncher.IMAGE_ID);
- if (connectionName == null || connectionName.isEmpty() || imageName == null
- || imageName.isEmpty()) {
- DockerLaunchUIPlugin.logErrorMessage(Messages.ContainerCommandLauncher_invalid_values);
- return entries;
- }
-
- ContainerLauncher launcher = new ContainerLauncher();
- Set<String> copiedVolumes = launcher.getCopiedVolumes(connectionName, imageName);
- List<ICLanguageSettingEntry> newEntries = new ArrayList<>();
- IPath pluginPath = Platform.getStateLocation(Platform.getBundle(DockerLaunchUIPlugin.PLUGIN_ID));
- IPath hostDir = pluginPath.append("HEADERS") //$NON-NLS-1$
- .append(getCleanName(connectionName)).append(getCleanName(imageName));
-
- for (ICLanguageSettingEntry entry : entries) {
- if (entry instanceof ICIncludePathEntry) {
- if (copiedVolumes.contains(((ICIncludePathEntry) entry).getName().toString())) {
- // //$NON-NLS-2$
- IPath newPath = hostDir.append(entry.getName());
- CIncludePathEntry newEntry = new CIncludePathEntry(newPath.toString(),
- entry.getFlags());
- newEntries.add(newEntry);
- continue;
- }
- }
- if (entry instanceof ICIncludeFileEntry) {
- IPath p = new Path(((ICIncludeFileEntry) entry).getName());
- if (copiedVolumes.contains(p.removeLastSegments(1).toString())) {
- IPath newPath = hostDir.append(entry.getName());
- CIncludeFileEntry newEntry = new CIncludeFileEntry(newPath.toString(),
- entry.getFlags());
- newEntries.add(newEntry);
- continue;
- }
- }
- newEntries.add(entry);
- }
- return newEntries;
+
+ if (props == null)
+ return entries;
+
+ String enablementProperty = props.getProperty(ContainerCommandLauncher.CONTAINER_BUILD_ENABLED);
+ if (enablementProperty == null)
+ return entries;
+
+ boolean enableContainer = Boolean.parseBoolean(enablementProperty);
+ if (!enableContainer)
+ return entries;
+
+ String connectionName = props.getProperty(ContainerCommandLauncher.CONNECTION_ID);
+ String imageName = props.getProperty(ContainerCommandLauncher.IMAGE_ID);
+ if (connectionName == null || connectionName.isEmpty() || imageName == null || imageName.isEmpty()) {
+ DockerLaunchUIPlugin.logErrorMessage(Messages.ContainerCommandLauncher_invalid_values);
+ return entries;
+ }
+
+ IPath tpath = getHostMirrorPath(new ImageConnection(connectionName, imageName));
+ Set<IPath> copiedVolumes = ContainerLauncher.getCopiedVolumes(tpath);
+ List<ICLanguageSettingEntry> newEntries = new ArrayList<>();
+
+ for (ICLanguageSettingEntry entry : entries) {
+ if (entry instanceof ICIncludePathEntry) {
+ Path tp = new Path(((ICIncludePathEntry) entry).getName().toString());
+ if (copiedVolumes.stream().anyMatch(p -> p.isPrefixOf(tp))) {
+ IPath newPath = tpath.append(entry.getName());
+ CIncludePathEntry newEntry = new CIncludePathEntry(newPath.toString(), entry.getFlags());
+ newEntries.add(newEntry);
+ continue;
+ }
+ }
+ if (entry instanceof ICIncludeFileEntry) {
+ IPath tp = new Path(((ICIncludeFileEntry) entry).getName()).removeLastSegments(1);
+ if (copiedVolumes.stream().anyMatch(p -> p.isPrefixOf(tp))) {
+ IPath newPath = tpath.append(entry.getName());
+ CIncludeFileEntry newEntry = new CIncludeFileEntry(newPath.toString(), entry.getFlags());
+ newEntries.add(newEntry);
+ continue;
}
}
+ newEntries.add(entry);
}
- return entries;
- }
-
- private String getCleanName(String name) {
- String cleanName = name.replace("unix:///", "unix_"); //$NON-NLS-1$ //$NON-NLS-2$
- cleanName = cleanName.replace("tcp://", "tcp_"); //$NON-NLS-1$ //$NON-NLS-2$
- return cleanName.replaceAll("[:/.]", "_"); //$NON-NLS-1$ //$NON-NLS-2$
+ return newEntries;
}
}
diff --git a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ContainerLaunchConfigurationDelegate.java b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ContainerLaunchConfigurationDelegate.java
index ae370e8f98d..15ba069db6e 100644
--- a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ContainerLaunchConfigurationDelegate.java
+++ b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ContainerLaunchConfigurationDelegate.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2015, 2020 Red Hat and others.
+ * Copyright (c) 2015, 2022 Red Hat and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -160,13 +160,8 @@ public class ContainerLaunchConfigurationDelegate extends GdbLaunchDelegate {
String projectName = configuration.getAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME, ""); //$NON-NLS-1$
labels.put("org.eclipse.cdt.project-name", projectName); //$NON-NLS-1$
if (mode.equals(ILaunchManager.RUN_MODE)) {
- String commandDir = commandPath.removeLastSegments(1).toPortableString();
- String commandString = commandPath.toPortableString();
-
- if (commandPath.getDevice() != null) {
- commandDir = "/" + commandDir.replace(':', '/'); //$NON-NLS-1$
- commandString = "/" + commandString.replace(':', '/'); //$NON-NLS-1$
- }
+ String commandDir = ContainerLaunchUtils.toDockerPath(commandPath.removeLastSegments(1));
+ String commandString = ContainerLaunchUtils.toDockerPath(commandPath);
StringBuilder b = new StringBuilder();
b.append(commandString);
@@ -191,8 +186,7 @@ public class ContainerLaunchConfigurationDelegate extends GdbLaunchDelegate {
if (workingDir != null) {
IPath workingPath = new Path(workingDir);
if (workingPath.getDevice() != null) {
- workingDir = "/" + workingPath.toPortableString() //$NON-NLS-1$
- .replace(':', '/');
+ workingDir = ContainerLaunchUtils.toDockerPath(workingPath);
}
}
Map<String, String> envMap = configuration.getAttribute(ILaunchManager.ATTR_ENVIRONMENT_VARIABLES,
@@ -208,10 +202,8 @@ public class ContainerLaunchConfigurationDelegate extends GdbLaunchDelegate {
List<String> dirs = new ArrayList<>();
for (String additionalDir : additionalDirs) {
IPath path = new Path(additionalDir);
- String dir = path.toPortableString();
- if (path.getDevice() != null) {
- dir = "/" + dir.replace(':', '/'); //$NON-NLS-1$
- }
+ String dir = ContainerLaunchUtils.toDockerPath(path);
+
dirs.add(dir);
}
additionalDirs = dirs;
@@ -298,13 +290,8 @@ public class ContainerLaunchConfigurationDelegate extends GdbLaunchDelegate {
String gdbserverCommand = configuration.getAttribute(ILaunchConstants.ATTR_GDBSERVER_COMMAND,
ILaunchConstants.ATTR_GDBSERVER_COMMAND_DEFAULT);
- String commandString = commandPath.toPortableString();
- String commandDir = commandPath.removeLastSegments(1).toPortableString();
-
- if (commandPath.getDevice() != null) {
- commandDir = "/" + commandDir.replace(':', '/'); //$NON-NLS-1$
- commandString = "/" + commandString.replace(':', '/'); //$NON-NLS-1$
- }
+ String commandString = ContainerLaunchUtils.toDockerPath(commandPath);
+ String commandDir = ContainerLaunchUtils.toDockerPath(commandPath.removeLastSegments(1));
String commandArguments = ":" + gdbserverPortNumber + " " //$NON-NLS-1$ //$NON-NLS-2$
+ spaceEscapify(commandString);
@@ -331,8 +318,7 @@ public class ContainerLaunchConfigurationDelegate extends GdbLaunchDelegate {
if (workingDir != null) {
IPath workingPath = new Path(workingDir);
if (workingPath.getDevice() != null) {
- workingDir = "/" + workingPath.toPortableString() //$NON-NLS-1$
- .replace(':', '/');
+ workingDir = ContainerLaunchUtils.toDockerPath(workingPath);
}
}
@@ -349,10 +335,7 @@ public class ContainerLaunchConfigurationDelegate extends GdbLaunchDelegate {
List<String> dirs = new ArrayList<>();
for (String additionalDir : additionalDirs) {
IPath path = new Path(additionalDir);
- String dir = path.toPortableString();
- if (path.getDevice() != null) {
- dir = "/" + dir.replace(':', '/'); //$NON-NLS-1$
- }
+ String dir = ContainerLaunchUtils.toDockerPath(path);
dirs.add(dir);
}
additionalDirs = dirs;
diff --git a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ContainerLaunchUtils.java b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ContainerLaunchUtils.java
new file mode 100644
index 00000000000..ff55ba042b9
--- /dev/null
+++ b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ContainerLaunchUtils.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2022 Red Hat Inc. and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Red Hat Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.docker.launcher;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Platform;
+
+public class ContainerLaunchUtils {
+
+ /**
+ * Maps the local path, to a path that is used within a docker container.
+ * @param path The host path
+ * @return the path within the docker container
+ * @see toDockerPath(String)
+ */
+ public static final String toDockerPath(IPath path) {
+ String pathstring = path.toPortableString();
+ if (path.getDevice() != null) {
+ if (pathstring.charAt(0) != '/') {
+ pathstring = '/' + pathstring;
+ }
+ }
+ return ContainerLaunchUtils.toDockerPath(pathstring);
+
+ }
+
+ /**
+ * Maps the local path, to a path that is used within a docker container.
+ * C: is mapped to /c, etc.
+ * //$WSL/<NAME>/ is a bit more tricky. For now it will be mapped to /WSL/<NAME>/
+ * @param path The host path
+ * @return the path within the docker container
+ */
+ public static final String toDockerPath(String path) {
+ if (Platform.getOS().equals(Platform.OS_WIN32)) {
+ path = path.replace(':', '/');
+ //Fix WSL which starts with //$WSL - TODO: Make more robust
+ path = path.replace("//WSL$/", "/WSL/"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ //Ensure the path is global.
+
+ return path;
+ }
+
+ /**
+ * Convert a Path to a string that can be passed as docker volume to be mapped into the Docker container
+ * toDockerPath() is used to get the path within the Docker container.
+ * @param path The path on the hose
+ * @return The string to be passed to the docker daemon
+ */
+ public static final String toDockerVolume(IPath path) {
+ IPath p = path.makeAbsolute();
+ String rv = toDockerPath(p);
+ rv += ":HOST_FILE_SYSTEM:"; //$NON-NLS-1$
+ rv += p.toOSString();
+ rv += ":false:true"; //$NON-NLS-1$ RO=false, selected = true
+ return rv;
+ }
+
+}
diff --git a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/Messages.java b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/Messages.java
index 571a6930972..ebe386b5df4 100644
--- a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/Messages.java
+++ b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/Messages.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012, 2020 Red Hat, Inc.
+ * Copyright (c) 2012, 2022 Red Hat, Inc.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -32,12 +32,12 @@ public class Messages extends NLS {
public static String LaunchShortcut_Launcher;
public static String Default_Image;
public static String Keep_Container_After_Launch;
+
public static String ContainerTab_Name;
public static String ContainerTab_Group_Name;
public static String ContainerTab_Option_Group_Name;
public static String ContainerTab_Ports_Group_Name;
public static String ContainerTab_Specify_Ports_Label;
-
public static String ContainerTab_Add_Button;
public static String ContainerTab_Edit_Button;
public static String ContainerTab_New_Button;
@@ -123,6 +123,7 @@ public class Messages extends NLS {
public static String ContainerTarget_name;
public static String ContainerCommandLauncher_invalid_values;
+ public static String ContainerCommandLauncher_invalid_container_type;
public static String Gdbserver_Settings_Remotetimeout_label;
diff --git a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/messages.properties b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/messages.properties
index dfd2c3dff1a..c2542845474 100644
--- a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/messages.properties
+++ b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/messages.properties
@@ -1,5 +1,5 @@
#*******************************************************************************
-# Copyright (c) 2015, 2020 Red Hat.
+# Copyright (c) 2015, 2022 Red Hat.
#
# This program and the accompanying materials
# are made available under the terms of the Eclipse Public License 2.0
@@ -77,6 +77,7 @@ HeaderPreferencePage_Confirm_Removal_Msg=Confirm removal of specified cached hea
ContainerCommandLauncher_image_msg=[Running in image <{0}>]
ContainerCommandLauncher_invalid_values=Invalid values for Connection and/or Image name
+ContainerCommandLauncher_invalid_container_type=Toolchain is not a Linux Container toolchain
CommandLauncher_CommandCancelled=Command cancelled

Back to the top