1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-07 17:56:01 +02:00

Bug 533842 - Fix Launchbar for enabled/disabled Docker Connections

- fix CMakeBuildConfigurationProvider to not verify if a toolchain
  file exists which doesn't occur for Container Build configurations
- add new ICBuildConfigurationManager2 interface that adds new
  recheckConfigs() method, make CBuildConfigurationManager
  implement this new interface
- add new recheckConfigs() method to CBuildConfigurationManager so
  that if a Docker Connection is enabled, the list of invalid configs
  can be rechecked and those that are now valid can be removed from
  the noconfigs list
- have ContainerGCCToolChainProvider implement
  IDockerConnectionManagerListener and register itself as a listener
  during init
- add new changeEvent() method as part of a listener that will add
  toolchains for connections that are added/enabled and similarly
  will delete toolchains for connections that are removed/disabled
- do the same with ContainerTargetTypeProvider (making it be an
  IDockerConnectionManagerListener and adding/deleting targets based
  on whether a Docker Connection is added/enabled or deleted/disabled
- as well during the init process of ContainerTargetTypeProvider
  remove any targets for Connections that aren't established

Change-Id: Id5e9415eaa770ef7f6ba1ddd11312ed003585391
This commit is contained in:
Jeff Johnston 2018-04-19 18:34:33 -04:00
parent ec9361bd45
commit b56078ed96
5 changed files with 287 additions and 17 deletions

View file

@ -66,21 +66,20 @@ public class CMakeBuildConfigurationProvider implements ICBuildConfigurationProv
// No valid combinations // No valid combinations
return null; return null;
} }
}
CMakeBuildConfiguration cmakeConfig = new CMakeBuildConfiguration(config, name);
ICMakeToolChainFile tcFile = cmakeConfig.getToolChainFile();
IToolChain toolChain = cmakeConfig.getToolChain();
if (toolChain == null) {
// config not complete
return null;
}
if (tcFile != null && !toolChain.equals(tcFile.getToolChain())) {
// toolchain changed
return new CMakeBuildConfiguration(config, name, tcFile.getToolChain(), tcFile,
cmakeConfig.getLaunchMode());
} else { } else {
CMakeBuildConfiguration cmakeConfig = new CMakeBuildConfiguration(config, name); return cmakeConfig;
ICMakeToolChainFile tcFile = cmakeConfig.getToolChainFile();
IToolChain toolChain = cmakeConfig.getToolChain();
if (toolChain == null || tcFile == null) {
// config not complete?
return null;
}
if (!toolChain.equals(tcFile.getToolChain())) {
// toolchain changed
return new CMakeBuildConfiguration(config, name, tcFile.getToolChain(), tcFile,
cmakeConfig.getLaunchMode());
} else {
return cmakeConfig;
}
} }
} }

View file

@ -0,0 +1,23 @@
/*******************************************************************************
* 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 implementation
*******************************************************************************/
package org.eclipse.cdt.core.build;
/**
* @since 6.5
*/
public interface ICBuildConfigurationManager2 {
/**
* Re-evaluate disabled configs to see if they should be re-enabled.
*/
public void recheckConfigs();
}

View file

@ -16,6 +16,7 @@ import java.nio.file.attribute.BasicFileAttributes;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -23,6 +24,7 @@ import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.CProjectNature; import org.eclipse.cdt.core.CProjectNature;
import org.eclipse.cdt.core.build.ICBuildConfiguration; import org.eclipse.cdt.core.build.ICBuildConfiguration;
import org.eclipse.cdt.core.build.ICBuildConfigurationManager; import org.eclipse.cdt.core.build.ICBuildConfigurationManager;
import org.eclipse.cdt.core.build.ICBuildConfigurationManager2;
import org.eclipse.cdt.core.build.ICBuildConfigurationProvider; import org.eclipse.cdt.core.build.ICBuildConfigurationProvider;
import org.eclipse.cdt.core.build.IToolChain; import org.eclipse.cdt.core.build.IToolChain;
import org.eclipse.cdt.core.build.IToolChainManager; import org.eclipse.cdt.core.build.IToolChainManager;
@ -46,7 +48,7 @@ import org.eclipse.core.runtime.preferences.InstanceScope;
import org.osgi.service.prefs.BackingStoreException; import org.osgi.service.prefs.BackingStoreException;
import org.osgi.service.prefs.Preferences; import org.osgi.service.prefs.Preferences;
public class CBuildConfigurationManager implements ICBuildConfigurationManager, IResourceChangeListener { public class CBuildConfigurationManager implements ICBuildConfigurationManager, ICBuildConfigurationManager2, IResourceChangeListener {
private static class Provider { private static class Provider {
private String id; private String id;
@ -177,6 +179,59 @@ public class CBuildConfigurationManager implements ICBuildConfigurationManager,
CModelManager.getDefault().resetBinaryParser(buildConfig.getProject()); CModelManager.getDefault().resetBinaryParser(buildConfig.getProject());
} }
@Override
public void recheckConfigs() {
initProviders();
ICBuildConfiguration config = null;
Set<IProject> projects = new HashSet<>();
synchronized (configs) {
Iterator<IBuildConfiguration> iterator = noConfigs.iterator();
while (iterator.hasNext()) {
IBuildConfiguration buildConfig = iterator.next();
String configName = null;
ICBuildConfigurationProvider provider = null;
if (IBuildConfiguration.DEFAULT_CONFIG_NAME.equals(buildConfig.getName())) {
configName = ICBuildConfiguration.DEFAULT_NAME;
try {
provider = getProvider(buildConfig.getProject());
} catch (CoreException e) {
continue;
}
} else {
String[] segments = buildConfig.getName().split("/"); //$NON-NLS-1$
if (segments.length == 2) {
String providerId = segments[0];
configName = segments[1];
Provider delegate = getProviderDelegate(providerId);
if (delegate != null && delegate.supports(buildConfig.getProject())) {
provider = delegate.getProvider();
}
}
}
if (provider != null) {
try {
config = provider.getCBuildConfiguration(buildConfig, configName);
} catch (CoreException e) {
// do nothing
}
if (config != null) {
iterator.remove();
projects.add(buildConfig.getProject());
configs.put(buildConfig, config);
}
}
}
}
for (IProject project : projects) {
// Do this outside of the synchronized block to avoid deadlock with
// BinaryRunner
CModelManager.getDefault().resetBinaryParser(project);
}
}
@Override @Override
public ICBuildConfiguration getBuildConfiguration(IBuildConfiguration buildConfig) throws CoreException { public ICBuildConfiguration getBuildConfiguration(IBuildConfiguration buildConfig) throws CoreException {
initProviders(); initProviders();

View file

@ -10,10 +10,15 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.docker.launcher; package org.eclipse.cdt.docker.launcher;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
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.CCorePlugin;
import org.eclipse.cdt.core.build.ICBuildConfigurationManager;
import org.eclipse.cdt.core.build.ICBuildConfigurationManager2;
import org.eclipse.cdt.debug.core.CDebugCorePlugin; import org.eclipse.cdt.debug.core.CDebugCorePlugin;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Platform;
@ -24,7 +29,9 @@ import org.eclipse.launchbar.core.target.ILaunchTargetProvider;
import org.eclipse.launchbar.core.target.ILaunchTargetWorkingCopy; import org.eclipse.launchbar.core.target.ILaunchTargetWorkingCopy;
import org.eclipse.launchbar.core.target.TargetStatus; import org.eclipse.launchbar.core.target.TargetStatus;
import org.eclipse.linuxtools.docker.core.DockerConnectionManager; import org.eclipse.linuxtools.docker.core.DockerConnectionManager;
import org.eclipse.linuxtools.docker.core.EnumDockerConnectionState;
import org.eclipse.linuxtools.docker.core.IDockerConnection; 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.IDockerImage;
/** /**
@ -32,13 +39,17 @@ import org.eclipse.linuxtools.docker.core.IDockerImage;
* @author jjohnstn * @author jjohnstn
* *
*/ */
public class ContainerTargetTypeProvider implements ILaunchTargetProvider { public class ContainerTargetTypeProvider
implements ILaunchTargetProvider, IDockerConnectionManagerListener {
public static final String TYPE_ID = "org.eclipse.cdt.docker.launcher.launchTargetType.container"; //$NON-NLS-1$ 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$ public static final String CONTAINER_LINUX = "linux-container"; //$NON-NLS-1$
private ILaunchTargetManager targetManager;
@Override @Override
public void init(ILaunchTargetManager targetManager) { public void init(ILaunchTargetManager targetManager) {
this.targetManager = targetManager;
ILaunchBarManager launchbarManager = CDebugCorePlugin ILaunchBarManager launchbarManager = CDebugCorePlugin
.getService(ILaunchBarManager.class); .getService(ILaunchBarManager.class);
ILaunchTarget defaultTarget = null; ILaunchTarget defaultTarget = null;
@ -49,8 +60,13 @@ public class ContainerTargetTypeProvider implements ILaunchTargetProvider {
} }
IDockerConnection[] connections = DockerConnectionManager.getInstance() IDockerConnection[] connections = DockerConnectionManager.getInstance()
.getConnections(); .getConnections();
Map<String, IDockerConnection> establishedConnectionMap = new HashMap<>();
Set<String> imageNames = new HashSet<>(); Set<String> imageNames = new HashSet<>();
for (IDockerConnection connection : connections) { for (IDockerConnection connection : connections) {
if (connection
.getState() == EnumDockerConnectionState.ESTABLISHED) {
establishedConnectionMap.put(connection.getUri(), connection);
}
List<IDockerImage> images = connection.getImages(); List<IDockerImage> images = connection.getImages();
for (IDockerImage image : images) { for (IDockerImage image : images) {
if (!image.isDangling() && !image.isIntermediateImage()) { if (!image.isDangling() && !image.isIntermediateImage()) {
@ -79,11 +95,25 @@ public class ContainerTargetTypeProvider implements ILaunchTargetProvider {
} }
} }
} }
// remove any launch targets for closed/disabled connections
ILaunchTarget[] targets = targetManager.getLaunchTargetsOfType(TYPE_ID);
for (ILaunchTarget target : targets) {
String uri = target.getAttribute(
IContainerLaunchTarget.ATTR_CONNECTION_URI, ""); //$NON-NLS-1$
if (!establishedConnectionMap.containsKey(uri)) {
targetManager.removeLaunchTarget(target);
}
}
try { try {
launchbarManager.setActiveLaunchTarget(defaultTarget); launchbarManager.setActiveLaunchTarget(defaultTarget);
} catch (CoreException e) { } catch (CoreException e) {
DockerLaunchUIPlugin.log(e); DockerLaunchUIPlugin.log(e);
} }
DockerConnectionManager.getInstance()
.addConnectionManagerListener(this);
} }
@Override @Override
@ -92,4 +122,85 @@ public class ContainerTargetTypeProvider implements ILaunchTargetProvider {
return TargetStatus.OK_STATUS; return TargetStatus.OK_STATUS;
} }
@Override
public void changeEvent(IDockerConnection connection, int type) {
ICBuildConfigurationManager mgr = CCorePlugin
.getService(ICBuildConfigurationManager.class);
ICBuildConfigurationManager2 manager = (ICBuildConfigurationManager2) mgr;
if (type == IDockerConnectionManagerListener.ADD_EVENT
|| type == IDockerConnectionManagerListener.ENABLE_EVENT) {
ILaunchBarManager launchbarManager = CDebugCorePlugin
.getService(ILaunchBarManager.class);
ILaunchTarget defaultTarget = null;
try {
defaultTarget = launchbarManager.getActiveLaunchTarget();
} catch (CoreException e) {
// ignore
}
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$
String imageName2 = imageName + "[" //$NON-NLS-1$
+ connection.getName() + "]"; //$NON-NLS-1$
ILaunchTarget target = targetManager
.getLaunchTarget(TYPE_ID, imageName2);
if (target != null) {
continue;
}
target = targetManager.getLaunchTarget(TYPE_ID, imageName);
if (target != null) {
if (target.getAttribute(
IContainerLaunchTarget.ATTR_CONNECTION_URI, "")
.equals(connection.getUri())) {
continue;
}
imageName = imageName2;
}
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();
}
}
// reset the default target back again
if (defaultTarget != null) {
try {
launchbarManager.setActiveLaunchTarget(defaultTarget);
} catch (CoreException e) {
DockerLaunchUIPlugin.log(e);
}
}
// Re-evaluate config list in case a build config was marked
// invalid and is now enabled
manager.recheckConfigs();
} else if (type == IDockerConnectionManagerListener.REMOVE_EVENT
|| type == IDockerConnectionManagerListener.DISABLE_EVENT) {
String connectionURI = connection.getUri();
ILaunchTarget[] targets = targetManager
.getLaunchTargetsOfType(TYPE_ID);
for (ILaunchTarget target : targets) {
String uri = target.getAttribute(
IContainerLaunchTarget.ATTR_CONNECTION_URI, ""); //$NON-NLS-1$
if (connectionURI.equals(uri)) {
targetManager.removeLaunchTarget(target);
}
}
}
}
} }

View file

@ -10,19 +10,26 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.docker.launcher.ui.launchbar; package org.eclipse.cdt.internal.docker.launcher.ui.launchbar;
import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.build.ICBuildConfigurationManager;
import org.eclipse.cdt.core.build.ICBuildConfigurationManager2;
import org.eclipse.cdt.core.build.IToolChain;
import org.eclipse.cdt.core.build.IToolChainManager; import org.eclipse.cdt.core.build.IToolChainManager;
import org.eclipse.cdt.core.build.IToolChainProvider; import org.eclipse.cdt.core.build.IToolChainProvider;
import org.eclipse.cdt.docker.launcher.ContainerTargetTypeProvider; import org.eclipse.cdt.docker.launcher.ContainerTargetTypeProvider;
import org.eclipse.cdt.docker.launcher.DockerLaunchUIPlugin;
import org.eclipse.cdt.docker.launcher.IContainerLaunchTarget; import org.eclipse.cdt.docker.launcher.IContainerLaunchTarget;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Platform;
import org.eclipse.launchbar.core.target.ILaunchTarget; import org.eclipse.launchbar.core.target.ILaunchTarget;
import org.eclipse.linuxtools.docker.core.DockerConnectionManager; import org.eclipse.linuxtools.docker.core.DockerConnectionManager;
import org.eclipse.linuxtools.docker.core.IDockerConnection; 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.IDockerImage;
/** /**
@ -32,11 +39,14 @@ import org.eclipse.linuxtools.docker.core.IDockerImage;
* @since 1.2 * @since 1.2
* *
*/ */
public class ContainerGCCToolChainProvider implements IToolChainProvider { public class ContainerGCCToolChainProvider
implements IToolChainProvider, IDockerConnectionManagerListener {
public static final String PROVIDER_ID = "org.eclipse.cdt.docker.launcher.gcc.provider"; //$NON-NLS-1$ 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$ public static final String CONTAINER_LINUX_CONFIG_ID = "linux-container-id"; //$NON-NLS-1$
private IToolChainManager toolChainManager;
@Override @Override
public String getId() { public String getId() {
return PROVIDER_ID; return PROVIDER_ID;
@ -44,9 +54,12 @@ public class ContainerGCCToolChainProvider implements IToolChainProvider {
@Override @Override
public void init(IToolChainManager manager) throws CoreException { public void init(IToolChainManager manager) throws CoreException {
this.toolChainManager = manager;
IDockerConnection[] connections = DockerConnectionManager.getInstance() IDockerConnection[] connections = DockerConnectionManager.getInstance()
.getConnections(); .getConnections();
Map<String, IDockerConnection> connectionMap = new HashMap<>();
for (IDockerConnection connection : connections) { for (IDockerConnection connection : connections) {
connectionMap.put(connection.getUri(), connection);
List<IDockerImage> images = connection.getImages(); List<IDockerImage> images = connection.getImages();
for (IDockerImage image : images) { for (IDockerImage image : images) {
if (!image.isDangling() && !image.isIntermediateImage()) { if (!image.isDangling() && !image.isIntermediateImage()) {
@ -73,6 +86,75 @@ public class ContainerGCCToolChainProvider implements IToolChainProvider {
} }
} }
} }
DockerConnectionManager.getInstance()
.addConnectionManagerListener(this);
}
@Override
public void changeEvent(IDockerConnection connection, int type) {
ICBuildConfigurationManager mgr = CCorePlugin
.getService(ICBuildConfigurationManager.class);
ICBuildConfigurationManager2 manager = (ICBuildConfigurationManager2) mgr;
if (type == IDockerConnectionManagerListener.ADD_EVENT
|| type == IDockerConnectionManagerListener.ENABLE_EVENT) {
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(':', '_'));
Collection<IToolChain> toolChains;
try {
toolChains = toolChainManager
.getToolChainsMatching(properties);
if (toolChains.isEmpty()) {
ContainerGCCToolChain toolChain = new ContainerGCCToolChain(
"gcc-img-" + image.id().substring(0, 19), //$NON-NLS-1$
this, properties, null);
toolChainManager.addToolChain(toolChain);
}
} catch (CoreException e) {
DockerLaunchUIPlugin.log(e);
}
}
}
// Re-evaluate config list in case a build config was marked
// invalid and is now enabled
manager.recheckConfigs();
} else if (type == IDockerConnectionManagerListener.REMOVE_EVENT
|| type == IDockerConnectionManagerListener.DISABLE_EVENT) {
try {
String connectionURI = connection.getUri();
Collection<IToolChain> toolChains = toolChainManager
.getAllToolChains();
for (IToolChain toolChain : toolChains) {
String uri = toolChain.getProperty(
IContainerLaunchTarget.ATTR_CONNECTION_URI);
if (connectionURI.equals(uri)) {
toolChainManager.removeToolChain(toolChain);
}
}
} catch (CoreException e1) {
// TODO Auto-generated catch block
DockerLaunchUIPlugin.log(e1);
}
}
} }
} }