Skip to content
This repository was archived by the owner on Feb 9, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,23 +51,23 @@ For secure tls (https) communication:
DOCKER_CERT_PATH=/Users/marcus/.docker/machine/machines/docker-1.11.2

### Latest release version
Supports a subset of the Docker Remote API [v1.23](https://github.com/docker/docker/blob/master/docs/reference/api/docker_remote_api_v1.23.md), Docker Server version 1.11.x
Supports a subset of the Docker Remote API [v1.23](https://github.com/docker/docker/blob/master/docs/api/v1.23.md), Docker Server version 1.11.x

<dependency>
<groupId>com.github.docker-java</groupId>
<artifactId>docker-java</artifactId>
<version>3.0.3</version>
<version>3.0.6</version>
</dependency>

### Latest development version
Supports a subset of the Docker Remote API [v1.23](https://github.com/docker/docker/blob/master/docs/reference/api/docker_remote_api_v1.23.md), Docker Server version 1.11.x
Supports a subset of the Docker Remote API [v1.23](https://github.com/docker/docker/blob/master/docs/api/v1.23.md), Docker Server version 1.11.x

You can find the latest development version including javadoc and source files on [Sonatypes OSS repository](https://oss.sonatype.org/content/groups/public/com/github/docker-java/docker-java/).

<dependency>
<groupId>com.github.docker-java</groupId>
<artifactId>docker-java</artifactId>
<version>3.0.4-SNAPSHOT</version>
<version>3.0.7-SNAPSHOT</version>
</dependency>


Expand Down
54 changes: 51 additions & 3 deletions src/main/java/com/github/dockerjava/api/model/Bind.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,48 @@ public class Bind implements Serializable {

private AccessMode accessMode;

/**
* @since {@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_23}
*/
private Boolean noCopy;

/**
* @since {@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_17}
*/
private SELContext secMode;

/**
* @since {@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_22}
*/
private PropagationMode propagationMode;

public Bind(String path, Volume volume) {
this(path, volume, AccessMode.DEFAULT, SELContext.DEFAULT);
}

public Bind(String path, Volume volume, Boolean noCopy) {
this(path, volume, AccessMode.DEFAULT, SELContext.DEFAULT, noCopy);
}

public Bind(String path, Volume volume, AccessMode accessMode) {
this(path, volume, accessMode, SELContext.DEFAULT);
}

public Bind(String path, Volume volume, AccessMode accessMode, SELContext secMode) {
this(path, volume, accessMode, secMode, null);
}

public Bind(String path, Volume volume, AccessMode accessMode, SELContext secMode, Boolean noCopy) {
this(path, volume, accessMode, secMode, noCopy, PropagationMode.DEFAULT_MODE);
}

public Bind(String path, Volume volume, AccessMode accessMode, SELContext secMode, Boolean noCopy, PropagationMode propagationMode) {
this.path = path;
this.volume = volume;
this.accessMode = accessMode;
this.secMode = secMode;
this.noCopy = noCopy;
this.propagationMode = propagationMode;
}

public String getPath() {
Expand All @@ -54,6 +78,14 @@ public SELContext getSecMode() {
return secMode;
}

public Boolean getNoCopy() {
return noCopy;
}

public PropagationMode getPropagationMode() {
return propagationMode;
}

/**
* Parses a bind mount specification to a {@link Bind}.
*
Expand All @@ -74,15 +106,25 @@ public static Bind parse(String serialized) {
String[] flags = parts[2].split(",");
AccessMode accessMode = AccessMode.DEFAULT;
SELContext seMode = SELContext.DEFAULT;
Boolean nocopy = null;
PropagationMode propagationMode = PropagationMode.DEFAULT_MODE;
for (String p : flags) {
if (p.length() == 2) {
accessMode = AccessMode.valueOf(p.toLowerCase());
} else if ("nocopy".equals(p)) {
nocopy = true;
} else if (PropagationMode.SHARED.toString().equals(p)) {
propagationMode = PropagationMode.SHARED;
} else if (PropagationMode.SLAVE.toString().equals(p)) {
propagationMode = PropagationMode.SLAVE;
} else if (PropagationMode.PRIVATE.toString().equals(p)) {
propagationMode = PropagationMode.PRIVATE;
} else {
seMode = SELContext.fromString(p);
}
}

return new Bind(parts[0], new Volume(parts[1]), accessMode, seMode);
return new Bind(parts[0], new Volume(parts[1]), accessMode, seMode, nocopy, propagationMode);
}
default: {
throw new IllegalArgumentException();
Expand All @@ -102,6 +144,8 @@ public boolean equals(Object obj) {
.append(volume, other.getVolume())
.append(accessMode, other.getAccessMode())
.append(secMode, other.getSecMode())
.append(noCopy, other.getNoCopy())
.append(propagationMode, other.getPropagationMode())
.isEquals();
} else {
return super.equals(obj);
Expand All @@ -115,6 +159,8 @@ public int hashCode() {
.append(volume)
.append(accessMode)
.append(secMode)
.append(noCopy)
.append(propagationMode)
.toHashCode();
}

Expand All @@ -127,10 +173,12 @@ public int hashCode() {
*/
@Override
public String toString() {
return String.format("%s:%s:%s%s",
return String.format("%s:%s:%s%s%s%s",
path,
volume.getPath(),
accessMode.toString(),
secMode != SELContext.none ? "," + secMode.toString() : "");
secMode != SELContext.none ? "," + secMode.toString() : "",
noCopy != null ? ",nocopy" : "",
propagationMode != PropagationMode.DEFAULT_MODE ? "," + propagationMode.toString() : "");
}
}
50 changes: 50 additions & 0 deletions src/main/java/com/github/dockerjava/api/model/PropagationMode.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.github.dockerjava.api.model;

/**
* The propagation mode of a file system or file: <code>shared</code>, <code>slave</code> or <code>private</code>.
*
* @see https://github.com/docker/docker/pull/17034
* @since 1.22
*/
public enum PropagationMode {
/** default */
DEFAULT(""),

/** shared */
SHARED("shared"),

/** slave */
SLAVE("slave"),

/** private */
PRIVATE("private");

/**
* The default {@link PropagationMode}: {@link #DEFAULT}
*/
public static final PropagationMode DEFAULT_MODE = DEFAULT;

private String value;

PropagationMode(String v) {
value = v;
}

@Override
public String toString() {
return value;
}

public static PropagationMode fromString(String v) {
switch (v) {
case "shared":
return SHARED;
case "slave":
return SLAVE;
case "private":
return PRIVATE;
default:
return DEFAULT;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@
import com.github.dockerjava.netty.exec.RenameContainerCmdExec;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelConfig;
import io.netty.channel.ChannelFactory;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.epoll.EpollDomainSocketChannel;
Expand Down Expand Up @@ -178,6 +181,8 @@ public DuplexChannel getChannel() {
}
};

private Integer connectTimeout = null;

@Override
public void init(DockerClientConfig dockerClientConfig) {
checkNotNull(dockerClientConfig, "config was not specified");
Expand Down Expand Up @@ -218,7 +223,15 @@ private class UnixDomainSocketInitializer implements NettyInitializer {
@Override
public EventLoopGroup init(Bootstrap bootstrap, DockerClientConfig dockerClientConfig) {
EventLoopGroup epollEventLoopGroup = new EpollEventLoopGroup(0, new DefaultThreadFactory(threadPrefix));
bootstrap.group(epollEventLoopGroup).channel(EpollDomainSocketChannel.class)

ChannelFactory<EpollDomainSocketChannel> factory = new ChannelFactory<EpollDomainSocketChannel>() {
@Override
public EpollDomainSocketChannel newChannel() {
return configure(new EpollDomainSocketChannel());
}
};

bootstrap.group(epollEventLoopGroup).channelFactory(factory)
.handler(new ChannelInitializer<UnixChannel>() {
@Override
protected void initChannel(final UnixChannel channel) throws Exception {
Expand All @@ -245,7 +258,14 @@ public EventLoopGroup init(Bootstrap bootstrap, final DockerClientConfig dockerC

Security.addProvider(new BouncyCastleProvider());

bootstrap.group(nioEventLoopGroup).channel(NioSocketChannel.class)
ChannelFactory<NioSocketChannel> factory = new ChannelFactory<NioSocketChannel>() {
@Override
public NioSocketChannel newChannel() {
return configure(new NioSocketChannel());
}
};

bootstrap.group(nioEventLoopGroup).channelFactory(factory)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(final SocketChannel channel) throws Exception {
Expand Down Expand Up @@ -580,6 +600,24 @@ public void close() throws IOException {
eventLoopGroup.shutdownGracefully();
}

/**
* Configure connection timeout in milliseconds
*/
public NettyDockerCmdExecFactory withConnectTimeout(Integer connectTimeout) {
this.connectTimeout = connectTimeout;
return this;
}

private <T extends Channel> T configure(T channel) {
ChannelConfig channelConfig = channel.config();

if (connectTimeout != null) {
channelConfig.setConnectTimeoutMillis(connectTimeout);
}

return channel;
}

private WebTarget getBaseResource() {
return new WebTarget(channelProvider);
}
Expand Down
Loading