| /******************************************************************************* |
| * Copyright (c) 2015, 2020 Red Hat. |
| * |
| * This program and the accompanying materials are made |
| * available under the terms of the Eclipse Public License 2.0 |
| * which is available at https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Red Hat - Initial Contribution |
| *******************************************************************************/ |
| |
| package org.eclipse.linuxtools.internal.docker.ui.launch; |
| |
| import static org.eclipse.linuxtools.internal.docker.ui.launch.IRunDockerImageLaunchConfigurationConstants.ALLOCATE_PSEUDO_CONSOLE; |
| import static org.eclipse.linuxtools.internal.docker.ui.launch.IRunDockerImageLaunchConfigurationConstants.AUTO_REMOVE; |
| import static org.eclipse.linuxtools.internal.docker.ui.launch.IRunDockerImageLaunchConfigurationConstants.COMMAND; |
| import static org.eclipse.linuxtools.internal.docker.ui.launch.IRunDockerImageLaunchConfigurationConstants.CONNECTION_NAME; |
| import static org.eclipse.linuxtools.internal.docker.ui.launch.IRunDockerImageLaunchConfigurationConstants.CONTAINER_NAME; |
| import static org.eclipse.linuxtools.internal.docker.ui.launch.IRunDockerImageLaunchConfigurationConstants.CPU_PRIORITY; |
| import static org.eclipse.linuxtools.internal.docker.ui.launch.IRunDockerImageLaunchConfigurationConstants.CREATION_DATE; |
| import static org.eclipse.linuxtools.internal.docker.ui.launch.IRunDockerImageLaunchConfigurationConstants.DATA_VOLUMES; |
| import static org.eclipse.linuxtools.internal.docker.ui.launch.IRunDockerImageLaunchConfigurationConstants.ENABLE_LIMITS; |
| import static org.eclipse.linuxtools.internal.docker.ui.launch.IRunDockerImageLaunchConfigurationConstants.ENTRYPOINT; |
| import static org.eclipse.linuxtools.internal.docker.ui.launch.IRunDockerImageLaunchConfigurationConstants.ENV_VARIABLES; |
| import static org.eclipse.linuxtools.internal.docker.ui.launch.IRunDockerImageLaunchConfigurationConstants.IMAGE_ID; |
| import static org.eclipse.linuxtools.internal.docker.ui.launch.IRunDockerImageLaunchConfigurationConstants.IMAGE_NAME; |
| import static org.eclipse.linuxtools.internal.docker.ui.launch.IRunDockerImageLaunchConfigurationConstants.INTERACTIVE; |
| import static org.eclipse.linuxtools.internal.docker.ui.launch.IRunDockerImageLaunchConfigurationConstants.LABELS; |
| import static org.eclipse.linuxtools.internal.docker.ui.launch.IRunDockerImageLaunchConfigurationConstants.LINKS; |
| import static org.eclipse.linuxtools.internal.docker.ui.launch.IRunDockerImageLaunchConfigurationConstants.MB; |
| import static org.eclipse.linuxtools.internal.docker.ui.launch.IRunDockerImageLaunchConfigurationConstants.MEMORY_LIMIT; |
| import static org.eclipse.linuxtools.internal.docker.ui.launch.IRunDockerImageLaunchConfigurationConstants.NETWORK_MODE; |
| import static org.eclipse.linuxtools.internal.docker.ui.launch.IRunDockerImageLaunchConfigurationConstants.PRIVILEGED; |
| import static org.eclipse.linuxtools.internal.docker.ui.launch.IRunDockerImageLaunchConfigurationConstants.PUBLISHED_PORTS; |
| import static org.eclipse.linuxtools.internal.docker.ui.launch.IRunDockerImageLaunchConfigurationConstants.PUBLISH_ALL_PORTS; |
| import static org.eclipse.linuxtools.internal.docker.ui.launch.IRunDockerImageLaunchConfigurationConstants.READONLY; |
| import static org.eclipse.linuxtools.internal.docker.ui.launch.IRunDockerImageLaunchConfigurationConstants.UNUSED_PORTS; |
| |
| import java.text.SimpleDateFormat; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collections; |
| import java.util.Date; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Map.Entry; |
| import java.util.Set; |
| import java.util.regex.Matcher; |
| import java.util.regex.Pattern; |
| import java.util.stream.Collectors; |
| |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.core.runtime.Status; |
| 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.debug.core.ILaunchManager; |
| import org.eclipse.jface.dialogs.IDialogConstants; |
| import org.eclipse.jface.layout.PixelConverter; |
| import org.eclipse.linuxtools.docker.core.IDockerConnection; |
| import org.eclipse.linuxtools.docker.core.IDockerContainer; |
| import org.eclipse.linuxtools.docker.core.IDockerContainerConfig; |
| import org.eclipse.linuxtools.docker.core.IDockerHostConfig; |
| import org.eclipse.linuxtools.docker.core.IDockerImage; |
| import org.eclipse.linuxtools.docker.core.IDockerImageBuildOptions; |
| import org.eclipse.linuxtools.docker.core.IDockerImageInfo; |
| import org.eclipse.linuxtools.docker.core.IDockerPortBinding; |
| import org.eclipse.linuxtools.docker.ui.Activator; |
| import org.eclipse.linuxtools.internal.docker.core.DockerContainerConfig; |
| import org.eclipse.linuxtools.internal.docker.core.DockerHostConfig; |
| import org.eclipse.linuxtools.internal.docker.core.DockerPortBinding; |
| import org.eclipse.linuxtools.internal.docker.ui.wizards.DataVolumeModel; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.widgets.Button; |
| |
| /** |
| * Utility class to manage {@link ILaunchConfiguration} |
| */ |
| public class LaunchConfigurationUtils { |
| |
| private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat( |
| "YYYY-MM-dd HH:mm:ss"); //$NON-NLS-1$ |
| |
| /** |
| * Private constructor for this utility class. |
| */ |
| private LaunchConfigurationUtils() { |
| // empty |
| } |
| |
| /** |
| * @return the ILaunchConfigurationType for the given configuration type. |
| * @param configType |
| * the id of the configuration type |
| */ |
| public static ILaunchConfigurationType getLaunchConfigType( |
| final String configType) { |
| return DebugPlugin.getDefault().getLaunchManager() |
| .getLaunchConfigurationType(configType); |
| } |
| |
| /** |
| * Creates a new {@link ILaunchConfiguration} for the given |
| * {@link IDockerContainer}. |
| * |
| * @param baseConfigurationName |
| * the base configuration name to use when creating the |
| * {@link ILaunchConfiguration}. |
| * @param image |
| * the {@link IDockerImage} used to create the container |
| * @param containerName |
| * the actual container name (given by the user or generated by |
| * the Docker daemon) |
| * @param containerConfig |
| * @param hostConfig |
| * the user-provided {@link IDockerHostConfig} (created |
| * container's one) |
| * @param removeWhenExits |
| * flag to indicate if container should be removed when exited |
| * @return the generated {@link ILaunchConfiguration} |
| * |
| */ |
| public static ILaunchConfiguration createRunImageLaunchConfiguration( |
| final IDockerImage image, |
| final IDockerContainerConfig containerConfig, |
| final IDockerHostConfig hostConfig, |
| final List<String> unusedPorts, |
| final String containerName, |
| final boolean removeWhenExits) { |
| try { |
| final ILaunchManager manager = DebugPlugin.getDefault() |
| .getLaunchManager(); |
| final ILaunchConfigurationType type = manager |
| .getLaunchConfigurationType( |
| IRunDockerImageLaunchConfigurationConstants.CONFIG_TYPE_ID); |
| final String imageName = createRunImageLaunchConfigurationName( |
| image); |
| // using the image repo + first tag |
| final ILaunchConfigurationWorkingCopy workingCopy = getLaunchConfigurationWorkingCopy( |
| type, imageName); |
| workingCopy.setAttribute(CREATION_DATE, |
| DATE_FORMAT.format(new Date())); |
| workingCopy.setAttribute(CONNECTION_NAME, |
| image.getConnection().getName()); |
| workingCopy.setAttribute(IMAGE_ID, image.id()); |
| workingCopy.setAttribute(IMAGE_NAME, |
| createRunImageLaunchConfigurationName(image)); |
| if (containerName != null && !containerName.isEmpty()) { |
| workingCopy.setAttribute(CONTAINER_NAME, containerName); |
| } |
| // if we know the raw command string, use it since the container |
| // config will remove quotes to split up command properly |
| DockerContainerConfig config = (DockerContainerConfig) containerConfig; |
| if (config.rawcmd() != null) { |
| workingCopy.setAttribute(COMMAND, config.rawcmd()); |
| } else { |
| workingCopy.setAttribute(COMMAND, String.join(" ", containerConfig.cmd())); |
| } |
| workingCopy.setAttribute(ENTRYPOINT, String.join(" ", containerConfig.entrypoint())); |
| // selected ports |
| workingCopy.setAttribute(PUBLISH_ALL_PORTS, |
| hostConfig.publishAllPorts()); |
| // format: <containerPort><type>:<hostIP>:<hostPort> |
| if (hostConfig.publishAllPorts()) { |
| final IDockerImageInfo imageInfo = image.getConnection() |
| .getImageInfo(image.id()); |
| if (imageInfo != null) { |
| workingCopy.setAttribute(PUBLISHED_PORTS, |
| serializePortBindings(imageInfo.containerConfig() |
| .exposedPorts())); |
| } |
| } else { |
| workingCopy.setAttribute(PUBLISHED_PORTS, |
| serializePortBindings(hostConfig.portBindings())); |
| workingCopy.setAttribute(UNUSED_PORTS, unusedPorts); |
| } |
| // links (with format being: "<containerName>:<containerAlias>") |
| workingCopy.setAttribute(LINKS, hostConfig.links()); |
| // env variables |
| workingCopy.setAttribute(ENV_VARIABLES, containerConfig.env()); |
| // labels |
| workingCopy.setAttribute(LABELS, containerConfig.labels()); |
| // volumes |
| final List<String> volumes = new ArrayList<>(); |
| // volumes from other containers |
| for (String volumeFrom : hostConfig.volumesFrom()) { |
| final DataVolumeModel volume = DataVolumeModel |
| .parseVolumeFrom(volumeFrom); |
| if (volume != null) { |
| volumes.add(volume.toString()); |
| } |
| } |
| // bindings to host directory or file |
| for (String bind : hostConfig.binds()) { |
| final DataVolumeModel volume = DataVolumeModel |
| .parseHostBinding(bind); |
| if (volume != null) { |
| volumes.add(volume.toString()); |
| } |
| } |
| // volumes with no external mount |
| for (String volumePath : containerConfig.volumes().keySet()) { |
| final DataVolumeModel volume = new DataVolumeModel(volumePath); |
| volumes.add(volume.toString()); |
| } |
| // TODO: container path declaration |
| |
| workingCopy.setAttribute(DATA_VOLUMES, volumes); |
| // options |
| workingCopy.setAttribute(AUTO_REMOVE, removeWhenExits); |
| workingCopy.setAttribute(ALLOCATE_PSEUDO_CONSOLE, |
| containerConfig.tty()); |
| workingCopy.setAttribute(INTERACTIVE, containerConfig.openStdin()); |
| workingCopy.setAttribute(PRIVILEGED, hostConfig.privileged()); |
| workingCopy.setAttribute(READONLY, |
| ((DockerHostConfig) hostConfig).readonlyRootfs()); |
| if (hostConfig.networkMode() != null) |
| workingCopy.setAttribute(NETWORK_MODE, |
| hostConfig.networkMode()); |
| |
| // resources limitations |
| if (containerConfig.memory() != null) { |
| workingCopy.setAttribute(ENABLE_LIMITS, true); |
| // memory in containerConfig is expressed in bytes |
| workingCopy.setAttribute(MEMORY_LIMIT, Long |
| .toString(containerConfig.memory().longValue() / MB)); |
| } |
| if (containerConfig.cpuShares() != null) { |
| workingCopy.setAttribute(ENABLE_LIMITS, true); |
| workingCopy.setAttribute(CPU_PRIORITY, |
| containerConfig.cpuShares().toString()); |
| } |
| return workingCopy.doSave(); |
| } catch (CoreException e) { |
| Activator.log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, |
| LaunchMessages.getString( |
| "RunDockerImageLaunchConfiguration.creation.failure"), //$NON-NLS-1$ |
| e)); |
| } |
| return null; |
| } |
| |
| private static String createRunImageLaunchConfigurationName( |
| final IDockerImage image) { |
| return image.repoTags().get(0); |
| } |
| |
| /** |
| * Serializes the given Port Bindings to save them in an |
| * {@link ILaunchConfiguration} |
| * |
| * @param bindings |
| * @return a {@link List} of port bindings serialized in the following |
| * format: |
| * <code><containerPort><type>:<hostIP>:<hostPort></code> |
| * Note that the <code><hostIP></code> part may be empty if |
| * undefined by the user. |
| */ |
| public static List<String> serializePortBindings( |
| final Map<String, List<IDockerPortBinding>> bindings) { |
| final List<String> serializedBindings = new ArrayList<>(); |
| if (bindings != null) { |
| for (Entry<String, List<IDockerPortBinding>> entry : bindings |
| .entrySet()) { |
| for (IDockerPortBinding portBinding : entry.getValue()) { |
| final StringBuilder portBindingBuilder = new StringBuilder(); |
| portBindingBuilder.append(entry.getKey()); |
| portBindingBuilder.append(':'); // $NON-NLS-1$ |
| if (portBinding.hostIp() != null) { |
| portBindingBuilder.append(portBinding.hostIp()); |
| } |
| portBindingBuilder.append(':'); // $NON-NLS-1$ |
| portBindingBuilder.append(portBinding.hostPort()); |
| serializedBindings.add(portBindingBuilder.toString()); |
| } |
| } |
| } |
| return serializedBindings; |
| } |
| |
| /** |
| * Serializes the given Port Bindings to save them in an |
| * {@link ILaunchConfiguration} |
| * |
| * @param bindings |
| * @return a {@link List} of port bindings serialized in the following |
| * format: |
| * <code><containerPort>:<type>:<hostIP>:<hostPort></code> |
| * Note that the <code><hostIP></code> part may be empty if |
| * undefined by the user. |
| * <p> |
| * For example: <code>8080/tcp:1.2.3.4:8080</code> or |
| * <code>8080/tcp::8080</code> |
| * </p> |
| */ |
| public static List<String> serializePortBindings( |
| final Set<String> bindings) { |
| final List<String> serializedBindings = new ArrayList<>(); |
| if (bindings != null) { |
| for (String portBinding : bindings) { |
| final StringBuilder portBindingBuilder = new StringBuilder(); |
| portBindingBuilder.append(portBinding); |
| portBindingBuilder.append(':'); // $NON-NLS-1$ |
| portBindingBuilder.append(':'); // $NON-NLS-1$ |
| final String[] containerPort = portBinding.split("/"); // $NON-NLS-1$ |
| portBindingBuilder.append(containerPort[0]); |
| serializedBindings.add(portBindingBuilder.toString()); |
| } |
| } |
| return serializedBindings; |
| } |
| |
| /** |
| * Deserializes the given Port Bindings to use them in an |
| * {@link ILaunchConfiguration} |
| * |
| * @param bindings |
| * a {@link List} of serialized bindings |
| * @return a {@link Map} of {@link List} of {@link IDockerPortBinding} |
| * indexed by their associated container port |
| * @see LaunchConfigurationUtils#serializePortBindings(Map) |
| */ |
| public static Map<String, List<IDockerPortBinding>> deserializePortBindings( |
| final List<String> bindings) { |
| if (bindings == null) { |
| return Collections.emptyMap(); |
| } |
| return bindings.stream().map(b -> b.split(":")) |
| .collect(Collectors.toMap( |
| // the key in the result map |
| split -> split[0], |
| // the list with a new element as the value in the |
| // result map, |
| split -> Arrays.asList( |
| new DockerPortBinding(split[1], split[2])), |
| // the merge function, to be used if 2 elements exist |
| // for the same key |
| (e1, e2) -> { |
| final List<IDockerPortBinding> merges = new ArrayList<>(); |
| merges.addAll(e1); |
| merges.addAll(e2); |
| return merges; |
| })); |
| } |
| |
| /** |
| * Computes the size of the given {@link Button} and returns the width. |
| * |
| * @param button |
| * the button for which the size must be computed. |
| * @return the width hint for the given button |
| */ |
| public static int getButtonWidthHint(final Button button) { |
| /* button.setFont(JFaceResources.getDialogFont()); */ |
| final PixelConverter converter = new PixelConverter(button); |
| final int widthHint = converter |
| .convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH); |
| return Math.max(widthHint, |
| button.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x); |
| } |
| |
| /** |
| * Looks-up the {@link ILaunchConfiguration} with the given type and |
| * <strong>IDockerImage's name</strong>. |
| * |
| * @param type |
| * the configuration type |
| * @param imageName |
| * the associated {@link IDockerImage} name |
| * @return the first matching {@link ILaunchConfiguration} or |
| * <code>null</code> if none was found. |
| * @throws CoreException |
| */ |
| public static ILaunchConfiguration getLaunchConfigurationByImageName( |
| final String type, final String imageName) throws CoreException { |
| return getLaunchConfigurationByImageName(getLaunchConfigType(type), |
| imageName); |
| } |
| |
| /** |
| * Looks-up the {@link ILaunchConfiguration} with the given type and |
| * <strong>IDockerImage's name</strong>. |
| * |
| * @param type |
| * the configuration type |
| * @param imageName |
| * the associated {@link IDockerImage} name |
| * @return the first matching {@link ILaunchConfiguration} or |
| * <code>null</code> if none was found. |
| * @throws CoreException |
| */ |
| public static ILaunchConfiguration getLaunchConfigurationByImageName( |
| final ILaunchConfigurationType type, final String imageName) |
| throws CoreException { |
| final ILaunchManager manager = DebugPlugin.getDefault() |
| .getLaunchManager(); |
| ILaunchConfiguration lastLaunchConfiguration = null; |
| String lastCreationDate = ""; //$NON-NLS-1$ |
| for (ILaunchConfiguration launchConfiguration : manager |
| .getLaunchConfigurations(type)) { |
| final String launchConfigImageName = launchConfiguration |
| .getAttribute(IMAGE_NAME, ""); //$NON-NLS-1$ |
| final String launchConfigCreationDate = launchConfiguration |
| .getAttribute(CREATION_DATE, ""); //$NON-NLS-1$ |
| if (launchConfigImageName.equals(imageName) |
| && launchConfigCreationDate |
| .compareTo(lastCreationDate) > 0) { |
| lastCreationDate = launchConfigCreationDate; |
| lastLaunchConfiguration = launchConfiguration; |
| } |
| } |
| return lastLaunchConfiguration; |
| } |
| |
| /** |
| * Returns the {@link ILaunchConfigurationWorkingCopy} with the given type |
| * and <strong>IDockerImage's name</strong>. |
| * |
| * @param type |
| * the configuration type |
| * @param imageName |
| * the associated {@link IDockerImage} name |
| * @param createIfNotFound |
| * flag to indicate if a new {@link ILaunchConfiguration} should |
| * be created if none was found. |
| * @return the ILaunchConfigurationWorkingCopy for the matching |
| * {@link ILaunchConfiguration} or a new instance if none was found. |
| * @throws CoreException |
| */ |
| private static ILaunchConfigurationWorkingCopy getLaunchConfigurationWorkingCopy( |
| final ILaunchConfigurationType type, final String imageName) |
| throws CoreException { |
| final ILaunchConfiguration existingLaunchConfiguration = getLaunchConfigurationByImageName( |
| type, imageName); |
| if (existingLaunchConfiguration != null) { |
| return existingLaunchConfiguration.getWorkingCopy(); |
| } |
| final ILaunchManager manager = DebugPlugin.getDefault() |
| .getLaunchManager(); |
| final String configurationName = manager |
| .generateLaunchConfigurationName(imageName); |
| return type.newInstance(null, configurationName); |
| } |
| |
| /** |
| * Looks-up the {@link ILaunchConfiguration} with the given type and |
| * <strong>name</strong>. |
| * |
| * @param type |
| * the configuration type |
| * @param name |
| * the name |
| * @return the first matching {@link ILaunchConfiguration} or |
| * <code>null</code> if none was found. |
| * @throws CoreException |
| */ |
| public static ILaunchConfiguration getLaunchConfigurationByName( |
| final String type, final String name) throws CoreException { |
| final ILaunchManager manager = DebugPlugin.getDefault() |
| .getLaunchManager(); |
| for (ILaunchConfiguration launchConfiguration : manager |
| .getLaunchConfigurations(getLaunchConfigType(type))) { |
| final String launchConfigName = launchConfiguration.getName(); // $NON-NLS-1$ |
| if (launchConfigName.equals(name)) { |
| return launchConfiguration; |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Converts the given <code>path</code> to a Unix path if the current OS if |
| * {@link Platform#OS_WIN32} |
| * |
| * @param path |
| * the path to convert |
| * @return the converted path or the given path, depending on the current |
| * OS. |
| * @see <a href= |
| * "http://docs.docker.com/v1.7/userguide/dockervolumes/#mount-a-host-directory-as-a-data-volume"> |
| * http://docs.docker.com/v1.7/userguide/dockervolumes/#mount-a-host- |
| * directory-as-a-data-volume</a> |
| */ |
| public static String convertToUnixPath(String path) { |
| return convertToUnixPath(Platform.getOS(), path); |
| } |
| |
| /** |
| * Converts the given path to a portable form, replacing all "\" and ": " |
| * with "/" if the given <code>os</code> is {@link Platform#OS_WIN32}. |
| * |
| * @param os |
| * the current OS |
| * @param path |
| * the path to convert |
| * @return the converted path or the given path |
| * @see LaunchConfigurationUtils#convertToUnixPath(String) |
| * @see {@link Platform#getOS()} |
| */ |
| public static String convertToUnixPath(final String os, final String path) { |
| if (os != null && os.equals(Platform.OS_WIN32)) { |
| // replace all "\" with "/" and then drive info (eg "C:/" to "/c/") |
| final Matcher m = Pattern.compile("([a-zA-Z]):/") //$NON-NLS-1$ |
| .matcher(path.replaceAll("\\\\", "/")); //$NON-NLS-1$ //$NON-NLS-2$ |
| if (m.find()) { |
| final StringBuffer b = new StringBuffer(); |
| b.append('/'); |
| m.appendReplacement(b, m.group(1).toLowerCase()); |
| b.append('/'); |
| m.appendTail(b); |
| return b.toString(); |
| } |
| } |
| return path; |
| } |
| |
| /** |
| * Converts the given <code>path</code> back to a Windows path if the |
| * current OS if {@link Platform#OS_WIN32}. |
| * |
| * <p> |
| * Note: This is the revert operation of |
| * {@link LaunchConfigurationUtils#convertToUnixPath(String)}. |
| * </p> |
| * |
| * @param path |
| * the path to convert |
| * @return the converted path or the given path, depending on the current |
| * OS. |
| * @see <a href= |
| * "http://docs.docker.com/v1.7/userguide/dockervolumes/#mount-a-host-directory-as-a-data-volume"> |
| * http://docs.docker.com/v1.7/userguide/dockervolumes/#mount-a-host- |
| * directory-as-a-data-volume</a> |
| */ |
| public static String convertToWin32Path(String path) { |
| return convertToWin32Path(Platform.getOS(), path); |
| } |
| |
| /** |
| * Converts the given path to a portable form, replacing all "\" and ": " |
| * with "/" if the given <code>os</code> is {@link Platform#OS_WIN32}. |
| * |
| * @param os |
| * the current OS |
| * @param path |
| * the path to convert |
| * @return the converted path or the given path |
| * @see LaunchConfigurationUtils#convertToWin32Path(String) |
| * @see {@link Platform#getOS()} |
| */ |
| public static String convertToWin32Path(final String os, |
| final String path) { |
| if (os != null && os.equals(Platform.OS_WIN32)) { |
| // replace all "/" with "\" and then drive info (eg "/c/" to "C:/") |
| final Matcher m = Pattern.compile("^/([a-zA-Z])/").matcher(path); //$NON-NLS-1$ |
| if (m.find()) { |
| final StringBuffer b = new StringBuffer(); |
| m.appendReplacement(b, m.group(1).toUpperCase()); |
| b.append(":\\"); //$NON-NLS-1$ |
| m.appendTail(b); |
| return b.toString().replace('/', '\\'); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| } |
| return path; |
| } |
| |
| /** |
| * Creates a Launch Configuration name from the given repoName or from the |
| * given resource's project if the repoName was <code>null</code>. |
| * |
| * @param imageName |
| * the full image name |
| * @param resource |
| * the Dockerfile to use to build the image |
| * @return the {@link ILaunchConfiguration} name |
| */ |
| public static String createBuildImageLaunchConfigurationName( |
| final String imageName, final IResource resource) { |
| if (imageName != null) { |
| final String repository = BuildDockerImageUtils |
| .getRepository(imageName); |
| final String name = BuildDockerImageUtils.getName(imageName); |
| final String tag = BuildDockerImageUtils.getTag(imageName); |
| final StringBuilder configNameBuilder = new StringBuilder(); |
| // image name is the minimum requirement |
| if (name != null) { |
| if (repository != null) { |
| configNameBuilder.append(repository).append('_'); // $NON-NLS-1$ |
| } |
| configNameBuilder.append(name); |
| if (tag != null) { |
| configNameBuilder.append(" [").append(tag).append("]"); //$NON-NLS-1$ //$NON-NLS-2$ |
| } else { |
| configNameBuilder.append(" [latest]"); //$NON-NLS-1$ |
| } |
| return configNameBuilder.toString(); |
| } |
| } |
| return "Dockerfile [" //$NON-NLS-1$ |
| + resource.getProject().getName() + "]"; //$NON-NLS-1$ |
| } |
| |
| /** |
| * Creates a new {@link ILaunchConfiguration} to build an |
| * {@link IDockerImage} from a Dockerfile {@link IResource}. |
| * |
| * @param connection |
| * the connection to use to submit the build |
| * @param repoName |
| * the repo/name of the {@link IDockerImage} to build |
| * @param dockerfile |
| * the dockerfile to use to build the {@link IDockerImage} |
| * @return the created {@link ILaunchConfiguration} |
| * @throws CoreException |
| */ |
| public static ILaunchConfiguration createBuildImageLaunchConfiguration( |
| final IDockerConnection connection, final String repoName, |
| final IResource dockerfile) throws CoreException { |
| final ILaunchConfigurationType configType = LaunchConfigurationUtils |
| .getLaunchConfigType( |
| IBuildDockerImageLaunchConfigurationConstants.CONFIG_TYPE_ID); |
| final ILaunchConfigurationWorkingCopy wc = getLaunchConfigurationWorkingCopy( |
| configType, |
| createBuildImageLaunchConfigurationName(repoName, dockerfile)); |
| wc.setAttribute( |
| IBuildDockerImageLaunchConfigurationConstants.SOURCE_PATH_LOCATION, |
| dockerfile.getFullPath().removeLastSegments(1).toString()); |
| wc.setAttribute(IBuildDockerImageLaunchConfigurationConstants.DOCKERFILE_NAME, |
| dockerfile.getFullPath().lastSegment()); |
| wc.setAttribute( |
| IBuildDockerImageLaunchConfigurationConstants.SOURCE_PATH_WORKSPACE_RELATIVE_LOCATION, |
| true); |
| |
| wc.setAttribute(IDockerImageBuildOptions.DOCKER_CONNECTION, |
| connection.getName()); |
| wc.setAttribute(IDockerImageBuildOptions.REPO_NAME, repoName); |
| return wc.doSave(); |
| } |
| |
| /** |
| * Creates an {@link ILaunchConfiguration} for to run the |
| * {@code docker-compose up} command. |
| * |
| * @param connection |
| * the Docker connection to use |
| * @param dockerComposeScript |
| * the {@code docker-compose.yml} script |
| * @return the created {@link ILaunchConfiguration} |
| * @throws CoreException |
| * if something wrong happened when creating the |
| * {@link ILaunchConfiguration} |
| */ |
| public static ILaunchConfiguration createDockerComposeUpLaunchConfiguration( |
| final IDockerConnection connection, |
| final IResource dockerComposeScript) throws CoreException { |
| final ILaunchConfigurationType configType = LaunchConfigurationUtils |
| .getLaunchConfigType( |
| IDockerComposeLaunchConfigurationConstants.CONFIG_TYPE_ID); |
| final ILaunchConfigurationWorkingCopy wc = configType.newInstance(null, |
| DebugPlugin.getDefault().getLaunchManager() |
| .generateLaunchConfigurationName( |
| createDockerComposeLaunchConfigurationName( |
| dockerComposeScript))); |
| wc.setAttribute(IDockerComposeLaunchConfigurationConstants.WORKING_DIR, |
| dockerComposeScript.getFullPath().removeLastSegments(1) |
| .toString()); |
| wc.setAttribute( |
| IDockerComposeLaunchConfigurationConstants.WORKING_DIR_WORKSPACE_RELATIVE_LOCATION, |
| true); |
| |
| wc.setAttribute( |
| IDockerComposeLaunchConfigurationConstants.DOCKER_CONNECTION, |
| connection.getName()); |
| return wc.doSave(); |
| } |
| |
| /** |
| * Creates a Launch Configuration name from the given |
| * {@code dockerComposeScript}. |
| * |
| * @param dockerComposeScript |
| * the name of the {@code Docker Compose} script |
| * @return the {@link ILaunchConfiguration} name |
| */ |
| private static String createDockerComposeLaunchConfigurationName( |
| final IResource dockerComposeScript) { |
| return "Docker Compose [" //$NON-NLS-1$ |
| + dockerComposeScript.getProject().getName() + "]"; //$NON-NLS-1$ |
| } |
| |
| /** |
| * Updates all {@link ILaunchConfiguration} of the given {@code type} where |
| * there is an attribute with the given {@code attributeName} of the given |
| * {@code oldValue}, and sets the {@code newValue} instead. |
| * |
| * @param type |
| * the type of {@link ILaunchConfiguration} to find |
| * @param attributeName |
| * the name of the attribute to look-up |
| * @param oldValue |
| * the old value to match |
| * @param newValue |
| * the new value to set |
| */ |
| public static void updateLaunchConfigurations(final String type, |
| final String attributeName, final String oldValue, |
| final String newValue) { |
| final ILaunchConfigurationType configType = LaunchConfigurationUtils |
| .getLaunchConfigType(type); |
| final ILaunchManager manager = DebugPlugin.getDefault() |
| .getLaunchManager(); |
| try { |
| for (ILaunchConfiguration config : manager |
| .getLaunchConfigurations(configType)) { |
| try { |
| if (config.getAttribute(attributeName, "") //$NON-NLS-1$ |
| .equals(oldValue)) { |
| final ILaunchConfigurationWorkingCopy workingCopy = config |
| .getWorkingCopy(); |
| workingCopy.setAttribute(attributeName, newValue); |
| workingCopy.doSave(); |
| } |
| } catch (CoreException e) { |
| Activator.logErrorMessage(LaunchMessages.getFormattedString( |
| "UpdateLaunchConfiguration.named.error", //$NON-NLS-1$ |
| config.getName()), e); |
| } |
| } |
| } catch (CoreException e) { |
| Activator.logErrorMessage( |
| LaunchMessages.getString("UpdateLaunchConfiguration.error" //$NON-NLS-1$ |
| ), e); |
| Activator.logErrorMessage( |
| "Failed to retrieve launch configurations after connection name changed", |
| e); |
| } |
| } |
| |
| } |