diff --git a/src/main/java/org/jenkinsci/test/acceptance/docker/DockerContainer.java b/src/main/java/org/jenkinsci/test/acceptance/docker/DockerContainer.java index 6b9bd8a..a6438ab 100644 --- a/src/main/java/org/jenkinsci/test/acceptance/docker/DockerContainer.java +++ b/src/main/java/org/jenkinsci/test/acceptance/docker/DockerContainer.java @@ -90,9 +90,10 @@ public String ipBound(int n) { return getIpAddress(); } String out = Docker.cmd("port").add(cid, n).popen().verifyOrDieWith("docker port command failed").trim(); - if (out.isEmpty()) // expected to return single line like "0.0.0.0:55326" + if (out.isEmpty()) // expected to return single line like "0.0.0.0:55326" or [::]:55326 throw new IllegalStateException(format("Port %d is not mapped for container %s", n, cid)); - return out.split(":")[0]; + // assumes it is published only in ipv6 or only in ipv4 + return out.substring(0,out.lastIndexOf(":")).replaceAll("[\\[\\]]",""); } catch (IOException | InterruptedException e) { throw new AssertionError("Failed to figure out port map " + n, e); } @@ -108,9 +109,9 @@ public String ipUdpBound(int n) { return getIpAddress(); } String out = Docker.cmd("port").add(cid, n + "/udp").popen().verifyOrDieWith("docker port command failed").trim(); - if (out.isEmpty()) // expected to return single line like "0.0.0.0:55326" + if (out.isEmpty()) // expected to return single line like "0.0.0.0:55326" or [::]:55326 throw new IllegalStateException(format("Udp port %d is not mapped for container %s", n, cid)); - return out.split(":")[0]; + return out.substring(0,out.lastIndexOf(":")).replaceAll("[\\[\\]]",""); } catch (IOException | InterruptedException e) { throw new AssertionError("Failed to figure out udp port map " + n, e); } @@ -126,10 +127,10 @@ public int port(int n) { return n; } String out = Docker.cmd("port").add(cid, n).popen().verifyOrDieWith("docker port command failed").trim(); - if (out.isEmpty()) // expected to return single line like "0.0.0.0:55326" + if (out.isEmpty()) // expected to return single line like "0.0.0.0:55326" or [::]:55326 throw new IllegalStateException(format("Port %d is not mapped for container %s", n, cid)); - return Integer.parseInt(out.split(":")[1]); + return Integer.parseInt(out.substring(out.lastIndexOf(":") + 1, out.length())); } catch (IOException | InterruptedException e) { throw new AssertionError("Failed to figure out port map " + n, e); } @@ -145,10 +146,10 @@ public int udpPort(int n) { return n; } String out = Docker.cmd("port").add(cid, n + "/udp").popen().verifyOrDieWith("docker port command failed").trim(); - if (out.isEmpty()) // expected to return single line like "0.0.0.0:55326" + if (out.isEmpty()) // expected to return single line like "0.0.0.0:55326" or [::]:55326 throw new IllegalStateException(format("Udp port %d is not mapped for container %s", n, cid)); - return Integer.parseInt(out.split(":")[1]); + return Integer.parseInt(out.substring(out.lastIndexOf(":") + 1, out.length())); } catch (IOException | InterruptedException e) { throw new AssertionError("Failed to figure out udp port map " + n, e); } @@ -214,10 +215,11 @@ public JsonNode inspect() throws IOException { * IP address of this container reachable through the bridge. */ public String getIpAddress() throws IOException { + String ipLabel = ipv6Enabled() ? "GlobalIPv6Address" : "IPAddress"; if (System.getenv("DOCKER_FIXTURES_NETWORK") != null) { - return inspect().get("NetworkSettings").get("Networks").get(System.getenv("DOCKER_FIXTURES_NETWORK")).get("IPAddress").asText(); + return inspect().get("NetworkSettings").get("Networks").get(System.getenv("DOCKER_FIXTURES_NETWORK")).get(ipLabel).asText(); } - return inspect().get("NetworkSettings").get("IPAddress").asText(); + return inspect().get("NetworkSettings").get(ipLabel).asText(); } @Override @@ -233,4 +235,9 @@ public String toString() { public boolean sharingHostDockerService() { return Boolean.valueOf(System.getenv("SHARED_DOCKER_SERVICE")); } + + public static boolean ipv6Enabled() { + return Boolean.getBoolean("java.net.preferIPv6Addresses"); + } + } diff --git a/src/main/java/org/jenkinsci/test/acceptance/docker/DockerImage.java b/src/main/java/org/jenkinsci/test/acceptance/docker/DockerImage.java index 6faecba..d79688b 100644 --- a/src/main/java/org/jenkinsci/test/acceptance/docker/DockerImage.java +++ b/src/main/java/org/jenkinsci/test/acceptance/docker/DockerImage.java @@ -16,7 +16,7 @@ */ public class DockerImage { - public static final String DEFAULT_DOCKER_HOST = "127.0.0.1"; + public static final String DEFAULT_DOCKER_HOST = InetAddress.getLoopbackAddress().getHostAddress(); public final String tag; static DockerHostResolver dockerHostResolver = new DockerHostResolver(); @@ -248,16 +248,21 @@ public Starter(Class type, DockerImage image) { } private String getPortMapping(int port) { + // docker command needs ipv6 addresses in brackets return portOffset == null - ? ipAddress + "::" + port - : ipAddress + ":" + (portOffset + port) + ":" + port + ? addBracketsIfNeeded(ipAddress) + "::" + port + : addBracketsIfNeeded(ipAddress) + ":" + (portOffset + port) + ":" + port ; } private String getUdpPortMapping(int udpPort) { return portOffset == null - ? ipAddress + "::" + udpPort + "/udp" - : ipAddress + ":" + (portOffset + udpPort) + ":" + udpPort + "/udp"; + ? addBracketsIfNeeded(ipAddress) + "::" + udpPort + "/udp" + : addBracketsIfNeeded(ipAddress) + ":" + (portOffset + udpPort) + ":" + udpPort + "/udp"; + } + + private static String addBracketsIfNeeded(String ipAddress) { + return DockerContainer.ipv6Enabled() && !ipAddress.contains("[") ? String.format("[%s]", ipAddress) : ipAddress; } } } diff --git a/src/test/java/org/jenkinsci/test/acceptance/docker/DockerImageTest.java b/src/test/java/org/jenkinsci/test/acceptance/docker/DockerImageTest.java index ac2e5d0..e3fab7c 100644 --- a/src/test/java/org/jenkinsci/test/acceptance/docker/DockerImageTest.java +++ b/src/test/java/org/jenkinsci/test/acceptance/docker/DockerImageTest.java @@ -10,13 +10,15 @@ import org.mockito.Mockito; import org.mockito.junit.MockitoJUnitRunner; +import java.net.InetAddress; + @RunWith(MockitoJUnitRunner.class) public class DockerImageTest { private static final String DOCKER_HOST_IP= "42.42.42.42"; private static final String DOCKER_HOST_SOCKET= "unix:///var/run/foo.sock"; private static final String DOCKER_HOST_INVALID= "hfdsdfah"; - private static final String DOCKER_HOST_LOCALHOST= "127.0.0.1"; + private static final String DOCKER_HOST_LOCALHOST= InetAddress.getLoopbackAddress().getHostAddress(); @Mock DockerImage.DockerHostResolver dockerHostResolver; @@ -40,7 +42,7 @@ public void shouldReturnLocalhostIfDockerHostEnvironmentNotSet() { DockerImage dockerImage = new DockerImage("a"); dockerImage.dockerHostResolver = dockerHostResolver; - Assert.assertThat(dockerImage.getDockerHost(), CoreMatchers.is("127.0.0.1")); + Assert.assertThat(dockerImage.getDockerHost(), CoreMatchers.is(DOCKER_HOST_LOCALHOST)); } @Test