fix(docker): use Floci's address on the configured docker network #1
+23
-5
@@ -5,6 +5,7 @@ import com.github.dockerjava.api.command.InspectContainerResponse;
|
||||
import com.github.dockerjava.api.model.ContainerNetwork;
|
||||
import com.github.dockerjava.api.model.ExposedPort;
|
||||
import com.github.dockerjava.api.model.Ports;
|
||||
import io.github.hectorvent.floci.config.EmulatorConfig;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.inject.Inject;
|
||||
import org.jboss.logging.Logger;
|
||||
@@ -32,14 +33,21 @@ public class CurrentContainerNetworkResolver {
|
||||
|
||||
private final DockerClient dockerClient;
|
||||
private final ContainerDetector containerDetector;
|
||||
private final EmulatorConfig config;
|
||||
private final Map<Integer, Integer> cachedPublishedPorts = new ConcurrentHashMap<>();
|
||||
|
||||
private volatile Optional<CurrentContainerNetwork> cachedNetwork;
|
||||
|
||||
@Inject
|
||||
public CurrentContainerNetworkResolver(DockerClient dockerClient, ContainerDetector containerDetector) {
|
||||
public CurrentContainerNetworkResolver(DockerClient dockerClient, ContainerDetector containerDetector,
|
||||
EmulatorConfig config) {
|
||||
this.dockerClient = dockerClient;
|
||||
this.containerDetector = containerDetector;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
public CurrentContainerNetworkResolver(DockerClient dockerClient, ContainerDetector containerDetector) {
|
||||
this(dockerClient, containerDetector, null);
|
||||
}
|
||||
|
||||
public Optional<String> resolveNetworkName() {
|
||||
@@ -148,11 +156,21 @@ public class CurrentContainerNetworkResolver {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Spawned containers join services.docker-network when it is set, so Floci's address on that
|
||||
* network is the one they can reach. Floci can be attached to other networks too (for example
|
||||
* the emulated VPC networks), whose addresses spawned containers cannot route to.
|
||||
*/
|
||||
private Optional<CurrentContainerNetwork> selectNetwork(Map<String, ContainerNetwork> networks) {
|
||||
return networks.entrySet().stream()
|
||||
.filter(entry -> isUsable(entry.getValue()))
|
||||
.filter(entry -> isUserDefinedNetwork(entry.getKey()))
|
||||
.findFirst()
|
||||
Optional<String> configured = config == null ? Optional.empty()
|
||||
: config.services().dockerNetwork().filter(name -> !name.isBlank());
|
||||
return configured
|
||||
.filter(name -> isUsable(networks.get(name)))
|
||||
.map(name -> Map.entry(name, networks.get(name)))
|
||||
.or(() -> networks.entrySet().stream()
|
||||
.filter(entry -> isUsable(entry.getValue()))
|
||||
.filter(entry -> isUserDefinedNetwork(entry.getKey()))
|
||||
.findFirst())
|
||||
.or(() -> networks.entrySet().stream()
|
||||
.filter(entry -> isUsable(entry.getValue()))
|
||||
.findFirst())
|
||||
|
||||
+56
-1
@@ -6,6 +6,7 @@ import com.github.dockerjava.api.command.InspectContainerResponse;
|
||||
import com.github.dockerjava.api.model.ContainerNetwork;
|
||||
import com.github.dockerjava.api.model.ExposedPort;
|
||||
import com.github.dockerjava.api.model.Ports;
|
||||
import io.github.hectorvent.floci.config.EmulatorConfig;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
@@ -43,6 +44,55 @@ class CurrentContainerNetworkResolverTest {
|
||||
assertEquals(Optional.of("172.24.0.2"), resolver.resolveContainerIp());
|
||||
}
|
||||
|
||||
@Test
|
||||
void resolveNetworkName_prefersConfiguredDockerNetworkOverOtherAttachedNetworks() {
|
||||
DockerClient dockerClient = mock(DockerClient.class);
|
||||
ContainerDetector containerDetector = mock(ContainerDetector.class);
|
||||
when(containerDetector.isRunningInContainer()).thenReturn(true);
|
||||
|
||||
InspectContainerCmd inspectCmd = mock(InspectContainerCmd.class);
|
||||
InspectContainerResponse inspect = mock(InspectContainerResponse.class, RETURNS_DEEP_STUBS);
|
||||
Map<String, ContainerNetwork> networks = networks(
|
||||
"floci-vpc-4566-us-east-1-vpc-default-us-east-1", "172.31.0.3",
|
||||
"floci_default", "172.22.0.4");
|
||||
when(dockerClient.inspectContainerCmd("floci-container")).thenReturn(inspectCmd);
|
||||
when(inspectCmd.exec()).thenReturn(inspect);
|
||||
when(inspect.getNetworkSettings().getNetworks()).thenReturn(networks);
|
||||
|
||||
EmulatorConfig config = mock(EmulatorConfig.class, RETURNS_DEEP_STUBS);
|
||||
when(config.services().dockerNetwork()).thenReturn(Optional.of("floci_default"));
|
||||
|
||||
CurrentContainerNetworkResolver resolver =
|
||||
new TestResolver(dockerClient, containerDetector, config, "floci-container");
|
||||
|
||||
assertEquals(Optional.of("floci_default"), resolver.resolveNetworkName());
|
||||
assertEquals(Optional.of("172.22.0.4"), resolver.resolveContainerIp());
|
||||
}
|
||||
|
||||
@Test
|
||||
void resolveNetworkName_fallsBackWhenConfiguredNetworkIsNotAttached() {
|
||||
DockerClient dockerClient = mock(DockerClient.class);
|
||||
ContainerDetector containerDetector = mock(ContainerDetector.class);
|
||||
when(containerDetector.isRunningInContainer()).thenReturn(true);
|
||||
|
||||
InspectContainerCmd inspectCmd = mock(InspectContainerCmd.class);
|
||||
InspectContainerResponse inspect = mock(InspectContainerResponse.class, RETURNS_DEEP_STUBS);
|
||||
Map<String, ContainerNetwork> networks = networks(
|
||||
"bridge", "172.17.0.2",
|
||||
"avoxx-network", "172.24.0.2");
|
||||
when(dockerClient.inspectContainerCmd("floci-container")).thenReturn(inspectCmd);
|
||||
when(inspectCmd.exec()).thenReturn(inspect);
|
||||
when(inspect.getNetworkSettings().getNetworks()).thenReturn(networks);
|
||||
|
||||
EmulatorConfig config = mock(EmulatorConfig.class, RETURNS_DEEP_STUBS);
|
||||
when(config.services().dockerNetwork()).thenReturn(Optional.of("floci_default"));
|
||||
|
||||
CurrentContainerNetworkResolver resolver =
|
||||
new TestResolver(dockerClient, containerDetector, config, "floci-container");
|
||||
|
||||
assertEquals(Optional.of("avoxx-network"), resolver.resolveNetworkName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void resolveNetworkName_returnsEmptyOutsideContainer() {
|
||||
DockerClient dockerClient = mock(DockerClient.class);
|
||||
@@ -126,7 +176,12 @@ class CurrentContainerNetworkResolverTest {
|
||||
private final String containerId;
|
||||
|
||||
TestResolver(DockerClient dockerClient, ContainerDetector containerDetector, String containerId) {
|
||||
super(dockerClient, containerDetector);
|
||||
this(dockerClient, containerDetector, null, containerId);
|
||||
}
|
||||
|
||||
TestResolver(DockerClient dockerClient, ContainerDetector containerDetector, EmulatorConfig config,
|
||||
String containerId) {
|
||||
super(dockerClient, containerDetector, config);
|
||||
this.containerId = containerId;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user