diff --git a/src/main/java/com/spotify/docker/client/CompressedDirectory.java b/src/main/java/com/spotify/docker/client/CompressedDirectory.java index c64ee74df..7699ea0d6 100644 --- a/src/main/java/com/spotify/docker/client/CompressedDirectory.java +++ b/src/main/java/com/spotify/docker/client/CompressedDirectory.java @@ -161,7 +161,7 @@ private static String createPattern(String line) { if (pattern.startsWith("#")) { return null; } - if (OSUtils.isLinux()) { + if (OSUtils.isLinux() || OSUtils.isOsX()) { return pattern; } return pattern.replace("/", "\\\\"); diff --git a/src/main/java/com/spotify/docker/client/OSUtils.java b/src/main/java/com/spotify/docker/client/OSUtils.java index c1e559002..7d450be34 100644 --- a/src/main/java/com/spotify/docker/client/OSUtils.java +++ b/src/main/java/com/spotify/docker/client/OSUtils.java @@ -16,11 +16,15 @@ */ package com.spotify.docker.client; -import java.io.File; +import java.util.Locale; public class OSUtils { + public static boolean isOsX() { + return System.getProperty("os.name").toLowerCase(Locale.US).contains("os x"); + } + public static boolean isLinux() { - return File.separatorChar == '/'; + return System.getProperty("os.name").equalsIgnoreCase("linux"); } } diff --git a/src/main/java/com/spotify/docker/client/messages/HostConfig.java b/src/main/java/com/spotify/docker/client/messages/HostConfig.java index 17d2280a8..a50ad5e3f 100755 --- a/src/main/java/com/spotify/docker/client/messages/HostConfig.java +++ b/src/main/java/com/spotify/docker/client/messages/HostConfig.java @@ -101,6 +101,8 @@ public class HostConfig { private Integer oomScoreAdj; @JsonProperty("AutoRemove") private Boolean autoRemove; + @JsonProperty("PidsLimit") + private Integer pidsLimit; private HostConfig() { } @@ -138,6 +140,7 @@ private HostConfig(final Builder builder) { this.oomKillDisable = builder.oomKillDisable; this.oomScoreAdj = builder.oomScoreAdj; this.autoRemove = builder.autoRemove; + this.pidsLimit = builder.pidsLimit; } public List binds() { @@ -260,6 +263,14 @@ public Integer oomScoreAdj() { return oomScoreAdj; } + /** + * Tune container pids limit (set -1 for unlimited). + * Only works for kernels >= 4.3 + */ + public Integer pidsLimit() { + return pidsLimit; + } + public Boolean autoRemove() { return autoRemove; } @@ -304,7 +315,8 @@ public boolean equals(final Object o) { Objects.equals(this.ulimits, that.ulimits) && Objects.equals(this.oomKillDisable, that.oomKillDisable) && Objects.equals(this.oomScoreAdj, that.oomScoreAdj) && - Objects.equals(this.autoRemove, that.autoRemove); + Objects.equals(this.autoRemove, that.autoRemove) && + Objects.equals(this.pidsLimit, that.pidsLimit); } @Override @@ -314,7 +326,7 @@ public int hashCode() { capDrop, networkMode, securityOpt, devices, memory, memorySwap, memoryReservation, cpuShares, cpusetCpus, cpuQuota, cgroupParent, restartPolicy, logConfig, ipcMode, ulimits, pidMode, shmSize, - oomKillDisable, oomScoreAdj, autoRemove); + oomKillDisable, oomScoreAdj, autoRemove, pidsLimit); } @Override @@ -352,6 +364,7 @@ public String toString() { .add("oomKillDisable", oomKillDisable) .add("oomScoreAdj", oomScoreAdj) .add("autoRemove", autoRemove) + .add("pidsLimit", pidsLimit) .toString(); } @@ -511,6 +524,7 @@ public static class Builder { private Boolean oomKillDisable; private Integer oomScoreAdj; private Boolean autoRemove; + private Integer pidsLimit; private Builder() { } @@ -548,6 +562,7 @@ private Builder(final HostConfig hostConfig) { this.oomKillDisable = hostConfig.oomKillDisable; this.oomScoreAdj = hostConfig.oomScoreAdj; this.autoRemove = hostConfig.autoRemove; + this.pidsLimit = hostConfig.pidsLimit; } /** @@ -1065,6 +1080,15 @@ public Builder autoRemove(final Boolean autoRemove) { return this; } + public Builder pidsLimit(final Integer pidsLimit) { + this.pidsLimit = pidsLimit; + return this; + } + + public Integer pidsLimit() { + return pidsLimit; + } + public HostConfig build() { return new HostConfig(this); } diff --git a/src/test/java/com/spotify/docker/client/DefaultDockerClientTest.java b/src/test/java/com/spotify/docker/client/DefaultDockerClientTest.java index edb4be7a8..75547f48f 100755 --- a/src/test/java/com/spotify/docker/client/DefaultDockerClientTest.java +++ b/src/test/java/com/spotify/docker/client/DefaultDockerClientTest.java @@ -326,11 +326,11 @@ private void requireDockerApiVersionAtLeast(final String required, final String assumeTrue(msg, dockerApiVersionAtLeast(required)); } - private boolean dockerApiVersionAtLeast(String expected) throws Exception { + private boolean dockerApiVersionAtLeast(final String expected) throws Exception { return compareVersion(dockerApiVersion, expected) >= 0; } - private boolean dockerApiVersionLessThan(String expected) throws Exception { + private boolean dockerApiVersionLessThan(final String expected) throws Exception { return compareVersion(dockerApiVersion, expected) < 0; } @@ -3357,6 +3357,30 @@ public void testOomScoreAdj() throws Exception { assertThat(info.hostConfig().oomScoreAdj(), is(500)); } + + @Test + public void testPidsLimit() throws Exception { + if (OSUtils.isLinux()) { + assumeTrue("Linux kernel must be at least 4.3.", + compareVersion(System.getProperty("os.version"), "4.3") >= 0); + } + requireDockerApiVersionAtLeast("1.23", "PidsLimit"); + + // Pull image + sut.pull(BUSYBOX_LATEST); + + final ContainerConfig config = ContainerConfig.builder() + .image(BUSYBOX_LATEST) + .hostConfig(HostConfig.builder() + .pidsLimit(100) // Defaults to -1 + .build()) + .build(); + + final ContainerCreation container = sut.createContainer(config, randomName()); + final ContainerInfo info = sut.inspectContainer(container.id()); + + assertThat(info.hostConfig().pidsLimit(), is(100)); + } @Test(expected = ContainerNotFoundException.class) public void testAutoRemoveWhenSetToTrue() throws Exception { diff --git a/src/test/java/com/spotify/docker/client/messages/AuthConfigTest.java b/src/test/java/com/spotify/docker/client/messages/AuthConfigTest.java index fc07fb5c6..eb82f4841 100644 --- a/src/test/java/com/spotify/docker/client/messages/AuthConfigTest.java +++ b/src/test/java/com/spotify/docker/client/messages/AuthConfigTest.java @@ -145,7 +145,7 @@ public void testFromDockerConfig_MultiConfig() throws Exception { } private static Path getTestFilePath(final String path) { - if (OSUtils.isLinux()) { + if (OSUtils.isLinux() || OSUtils.isOsX()) { return getLinuxPath(path); } else { return getWindowsPath(path);