Skip to content

Commit

Permalink
[grid] Starting containers with the correct network
Browse files Browse the repository at this point in the history
This will help us to run containers when
the user starts everything in a custom
network or in docker-compose.
  • Loading branch information
diemol committed Mar 19, 2021
1 parent a625b1e commit c8e2a79
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 28 deletions.
29 changes: 22 additions & 7 deletions java/server/src/org/openqa/selenium/grid/docker/DockerOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@

package org.openqa.selenium.grid.docker;

import static org.openqa.selenium.Platform.WINDOWS;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Multimap;
Expand Down Expand Up @@ -51,12 +49,15 @@
import java.util.concurrent.ExecutionException;
import java.util.logging.Logger;

import static org.openqa.selenium.Platform.WINDOWS;

public class DockerOptions {

static final String DOCKER_SECTION = "docker";
static final String DEFAULT_ASSETS_PATH = "/opt/selenium/assets";
static final String DEFAULT_DOCKER_URL = "unix:/var/run/docker.sock";
static final String DEFAULT_VIDEO_IMAGE = "selenium/video:latest";
private static final String DEFAULT_DOCKER_NETWORK = "bridge";
private static final Logger LOG = Logger.getLogger(DockerOptions.class.getName());
private static final Json JSON = new Json();
private final Config config;
Expand Down Expand Up @@ -143,6 +144,7 @@ public Map<Capabilities, Collection<SessionFactory>> getDockerSessionFactories(
loadImages(docker, kinds.keySet().toArray(new String[0]));
Image videoImage = getVideoImage(docker);
loadImages(docker, videoImage.getName());
String networkName = getDockerNetworkName(docker);

int maxContainerCount = Runtime.getRuntime().availableProcessors();
ImmutableMultimap.Builder<Capabilities, SessionFactory> factories = ImmutableMultimap.builder();
Expand All @@ -159,13 +161,14 @@ public Map<Capabilities, Collection<SessionFactory>> getDockerSessionFactories(
image,
caps,
videoImage,
assetsPath));
assetsPath,
networkName));
}
LOG.info(String.format(
"Mapping %s to docker image %s %d times",
caps,
name,
maxContainerCount));
"Mapping %s to docker image %s %d times",
caps,
name,
maxContainerCount));
});
return factories.build().asMap();
}
Expand All @@ -175,6 +178,18 @@ private Image getVideoImage(Docker docker) {
return docker.getImage(videoImage);
}

private String getDockerNetworkName(Docker docker) {
// Selenium Server is running inside a Docker container, we will inspect that container
// to get the mounted volume and use that. If no volume was mounted, no assets will be saved.
// Since Docker 1.12, the env var HOSTNAME has the container id (unless the user overwrites it)
String hostname = HostIdentifier.getHostName();
Optional<ContainerInfo> info = docker.inspect(new ContainerId(hostname));
if (info.isPresent()) {
return info.get().getNetworkName();
}
return DEFAULT_DOCKER_NETWORK;
}

private DockerAssetsPath getAssetsPath(Docker docker) {
Optional<String> assetsPath = config.get(DOCKER_SECTION, "assets-path");
if (assetsPath.isPresent()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,6 @@

package org.openqa.selenium.grid.docker;

import static java.util.Optional.ofNullable;
import static org.openqa.selenium.docker.ContainerConfig.image;
import static org.openqa.selenium.remote.Dialect.W3C;
import static org.openqa.selenium.remote.http.Contents.string;
import static org.openqa.selenium.remote.http.HttpMethod.GET;
import static org.openqa.selenium.remote.tracing.Tags.EXCEPTION;

import org.openqa.selenium.Capabilities;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.ImmutableCapabilities;
Expand Down Expand Up @@ -81,6 +74,13 @@
import java.util.logging.Level;
import java.util.logging.Logger;

import static java.util.Optional.ofNullable;
import static org.openqa.selenium.docker.ContainerConfig.image;
import static org.openqa.selenium.remote.Dialect.W3C;
import static org.openqa.selenium.remote.http.Contents.string;
import static org.openqa.selenium.remote.http.HttpMethod.GET;
import static org.openqa.selenium.remote.tracing.Tags.EXCEPTION;

public class DockerSessionFactory implements SessionFactory {

private static final Logger LOG = Logger.getLogger(DockerSessionFactory.class.getName());
Expand All @@ -93,6 +93,7 @@ public class DockerSessionFactory implements SessionFactory {
private final Capabilities stereotype;
private final Image videoImage;
private final DockerAssetsPath assetsPath;
private final String networkName;

public DockerSessionFactory(
Tracer tracer,
Expand All @@ -102,12 +103,14 @@ public DockerSessionFactory(
Image browserImage,
Capabilities stereotype,
Image videoImage,
DockerAssetsPath assetsPath) {
DockerAssetsPath assetsPath,
String networkName) {
this.tracer = Require.nonNull("Tracer", tracer);
this.clientFactory = Require.nonNull("HTTP client", clientFactory);
this.docker = Require.nonNull("Docker command", docker);
this.dockerUri = Require.nonNull("Docker URI", dockerUri);
this.browserImage = Require.nonNull("Docker browser image", browserImage);
this.networkName = Require.nonNull("Docker network name", networkName);
this.stereotype = ImmutableCapabilities.copyOf(
Require.nonNull("Stereotype", stereotype));
this.videoImage = videoImage;
Expand Down Expand Up @@ -176,9 +179,8 @@ public Either<WebDriverException, ActiveSession> apply(CreateSessionRequest sess
try {
result = new ProtocolHandshake().createSession(client, command);
response = result.createResponse();
attributeMap.put(
AttributeKey.DRIVER_RESPONSE.getKey(),
EventAttribute.setValue(response.toString()));
attributeMap.put(AttributeKey.DRIVER_RESPONSE.getKey(),
EventAttribute.setValue(response.toString()));
} catch (IOException | RuntimeException e) {
span.setAttribute("error", true);
span.setStatus(Status.CANCELLED);
Expand Down Expand Up @@ -242,15 +244,13 @@ public Either<WebDriverException, ActiveSession> apply(CreateSessionRequest sess
}

private Container createBrowserContainer(int port, Capabilities sessionCapabilities) {
Map<String, String> browserContainerEnvVars =
getBrowserContainerEnvVars(sessionCapabilities);
Map<String, String> devShmMount =
Collections.singletonMap("/dev/shm", "/dev/shm");
return docker.create(
image(browserImage)
.env(browserContainerEnvVars)
.bind(devShmMount)
.map(Port.tcp(4444), Port.tcp(port)));
Map<String, String> browserContainerEnvVars = getBrowserContainerEnvVars(sessionCapabilities);
Map<String, String> devShmMount = Collections.singletonMap("/dev/shm", "/dev/shm");
return docker.create(image(browserImage)
.env(browserContainerEnvVars)
.bind(devShmMount)
.map(Port.tcp(4444), Port.tcp(port))
.network(networkName));
}

private Map<String, String> getBrowserContainerEnvVars(Capabilities sessionRequestCapabilities) {
Expand All @@ -275,7 +275,10 @@ private Container startVideoContainer(Capabilities sessionCapabilities,
sessionCapabilities,
browserContainerIp);
Map<String, String> volumeBinds = Collections.singletonMap(hostPath, "/videos");
Container videoContainer = docker.create(image(videoImage).env(envVars).bind(volumeBinds));
Container videoContainer = docker.create(image(videoImage)
.env(envVars)
.bind(volumeBinds)
.network(networkName));
videoContainer.start();
LOG.info(String.format("Video container started (id: %s)", videoContainer.getId()));
return videoContainer;
Expand Down

0 comments on commit c8e2a79

Please sign in to comment.