Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trivial support for ipv6 #73

Merged
merged 4 commits into from
Jan 26, 2024
Merged
Show file tree
Hide file tree
Changes from 3 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
Original file line number Diff line number Diff line change
Expand Up @@ -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 ipv6Enabled() ? out.substring(1,out.lastIndexOf(":") - 1) : out.split(":")[0];
jglick marked this conversation as resolved.
Show resolved Hide resolved
} catch (IOException | InterruptedException e) {
throw new AssertionError("Failed to figure out port map " + n, e);
}
Expand All @@ -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 ipv6Enabled() ? out.substring(1,out.lastIndexOf(":") -1) : out.split(":")[0];
jglick marked this conversation as resolved.
Show resolved Hide resolved
} catch (IOException | InterruptedException e) {
throw new AssertionError("Failed to figure out udp port map " + n, e);
}
Expand All @@ -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.split(":")[ipv6Enabled() ? 3 : 1]);
jglick marked this conversation as resolved.
Show resolved Hide resolved
} catch (IOException | InterruptedException e) {
throw new AssertionError("Failed to figure out port map " + n, e);
}
Expand All @@ -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.split(":")[ipv6Enabled() ? 3 : 1]);
jglick marked this conversation as resolved.
Show resolved Hide resolved
} catch (IOException | InterruptedException e) {
throw new AssertionError("Failed to figure out udp port map " + n, e);
}
Expand Down Expand Up @@ -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
Expand All @@ -233,4 +235,12 @@ public String toString() {
public boolean sharingHostDockerService() {
return Boolean.valueOf(System.getenv("SHARED_DOCKER_SERVICE"));
}

public static boolean ipv6Enabled() {
return Boolean.getBoolean("java.net.preferIPv6Addresses");
}

public static String encloseInBrackets(String toEnclose) {
jglick marked this conversation as resolved.
Show resolved Hide resolved
return String.format("[%s]", toEnclose);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down Expand Up @@ -248,16 +248,21 @@ public Starter(Class<T> 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("[")) ? DockerContainer.encloseInBrackets(ipAddress) : ipAddress;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand Down