diff options
4 files changed, 210 insertions, 1 deletions
diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerVolume.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerVolume.java new file mode 100644 index 0000000000..572c358f36 --- /dev/null +++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerVolume.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2019 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.docker.core; + +import java.util.Map; + +/** + * @since 4.2 + */ +public interface IDockerVolume { + + /** + * @return the name of the volume + */ + String name(); + + /** + * @return the driver name of the volume + */ + String driver(); + + /** + * @return map of driver opts + */ + Map<String, String> driverOpts(); + + /** + * @return the options for the volume + */ + Map<String, String> options(); + + /** + * @return labels for the volume + */ + Map<String, String> labels(); + + /** + * @return the nount point of the volume + */ + String mountPoint(); + + /** + * @return the scope of the volume + */ + String scope(); + + /** + * @return the status of the volume + */ + Map<String, String> status(); + +} diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerConnection.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerConnection.java index fb37f6945f..36676ce772 100644 --- a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerConnection.java +++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerConnection.java @@ -85,6 +85,7 @@ import org.eclipse.linuxtools.docker.core.IDockerNetworkCreation; import org.eclipse.linuxtools.docker.core.IDockerPortBinding; import org.eclipse.linuxtools.docker.core.IDockerProgressHandler; import org.eclipse.linuxtools.docker.core.IDockerVersion; +import org.eclipse.linuxtools.docker.core.IDockerVolume; import org.eclipse.linuxtools.docker.core.ILogger; import org.eclipse.linuxtools.docker.core.IRegistryAccount; import org.eclipse.linuxtools.docker.core.Messages; @@ -124,6 +125,8 @@ import com.spotify.docker.client.messages.NetworkConfig; import com.spotify.docker.client.messages.PortBinding; import com.spotify.docker.client.messages.RegistryAuth; import com.spotify.docker.client.messages.Version; +import com.spotify.docker.client.messages.Volume; +import com.spotify.docker.client.messages.VolumeList; /** * A connection to a Docker daemon. The connection may rely on Unix Socket or TCP connection (using the REST API). @@ -516,6 +519,24 @@ public class DockerConnection } } + public List<IDockerVolume> getVolumes() throws DockerException { + List<IDockerVolume> volumeList = new ArrayList<>(); + try { + VolumeList list = client + .listVolumes(new DockerClient.ListVolumesParam[0]); + List<Volume> volumes = list.volumes(); + for (Volume volume : volumes) { + DockerVolume v = new DockerVolume(volume); + volumeList.add(v); + } + } catch (com.spotify.docker.client.exceptions.DockerException e) { + throw new DockerException(e.getMessage()); + } catch (InterruptedException e) { + return Collections.emptyList(); + } + return volumeList; + } + @Override public void addContainerListener(IDockerContainerListener listener) { if (containerListeners == null) diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerVolume.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerVolume.java new file mode 100644 index 0000000000..34d41443ac --- /dev/null +++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerVolume.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2019 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.core; + +import java.util.Map; + +import org.eclipse.linuxtools.docker.core.IDockerVolume; + +import com.spotify.docker.client.messages.Volume; + +public class DockerVolume implements IDockerVolume { + + private String name; + private String driver; + private Map<String, String> driverOpts; + private String mountPoint; + private String scope; + private Map<String, String> options; + private Map<String, String> labels; + private Map<String, String> status; + + public DockerVolume(final Volume volume) { + this.name = volume.name(); + this.driver = volume.driver(); + this.driverOpts = volume.driverOpts(); + this.mountPoint = volume.mountpoint(); + this.scope = volume.scope(); + this.options = volume.options(); + this.labels = volume.labels(); + this.status = volume.status(); + } + + + @Override + public String name() { + return name; + } + + @Override + public String driver() { + return driver; + } + + @Override + public Map<String, String> options() { + return options; + } + + @Override + public Map<String, String> labels() { + return labels; + } + + @Override + public String mountPoint() { + return mountPoint; + } + + @Override + public String scope() { + return scope; + } + + @Override + public Map<String, String> status() { + return status; + } + + @Override + public Map<String, String> driverOpts() { + return driverOpts; + } + +} diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/docker/ui/launch/ContainerLauncher.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/docker/ui/launch/ContainerLauncher.java index 9efeafd1ff..069e0b91dd 100644 --- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/docker/ui/launch/ContainerLauncher.java +++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/docker/ui/launch/ContainerLauncher.java @@ -60,6 +60,7 @@ import org.eclipse.linuxtools.docker.core.IDockerHostConfig; import org.eclipse.linuxtools.docker.core.IDockerImage; import org.eclipse.linuxtools.docker.core.IDockerImageInfo; import org.eclipse.linuxtools.docker.core.IDockerPortBinding; +import org.eclipse.linuxtools.docker.core.IDockerVolume; import org.eclipse.linuxtools.docker.ui.Activator; import org.eclipse.linuxtools.internal.docker.core.DockerConnection; import org.eclipse.linuxtools.internal.docker.core.DockerConsoleOutputStream; @@ -1611,7 +1612,48 @@ public class ContainerLauncher { remoteDataVolumes.put(p.toPortableString(), p.toPortableString()); } - builder = builder.volumes(remoteVolumes); + // Check volumes known by the connection to see if user has specified a + // volume_name:container_dir as an additional dir. In such a case, we + // don't need to copy data over and can simply bind to the volume. + try { + final List<String> volumes = new ArrayList<>(); + List<IDockerVolume> volumeList = ((DockerConnection) connection).getVolumes(); + for (IDockerVolume volume : volumeList) { + String name = volume.name(); + String containerDir = remoteDataVolumes.get(name); + if (containerDir != null) { + if (readOnlyVolumes.contains(name)) { + volumes.add(name + ":" + containerDir + ":Z,ro"); //$NON-NLS-1$ //$NON-NLS-2$ + readOnlyVolumes.remove(name); + } else { + volumes.add(name + ":" + containerDir + ":Z"); //$NON-NLS-1$ //$NON-NLS-2$ + } + remoteVolumes.remove(name); + remoteDataVolumes.remove(name); + IPath p = new Path(containerDir); + // if the working dir is a subdirectory of the volume mount, we don't need to + // copy it + // forward or back + if (workingDir != null) { + IPath working = new Path(workingDir); + if (p.isPrefixOf(working)) { + String s = working.removeTrailingSeparator().toPortableString(); + remoteVolumes.remove(s); + remoteDataVolumes.remove(s); + } + } + } + } + // bind any volumes we found above + if (!volumes.isEmpty()) { + hostBuilder = hostBuilder.binds(volumes); + } + } catch (DockerException e) { + Activator.log(e); + } + if (!remoteVolumes.isEmpty()) { + builder = builder.volumes(remoteVolumes); + } } else { // Running daemon on local host. // Add mounts for any directories we need to run the executable. |