Skip to content

Commit 6d7e7da

Browse files
authored
[grid][java] browser containers provisioned in dynamic grid can get hostconfig from node-docker (#13804)
* [grid][java] browser containers provisioned in dynamic grid uses node-docker hostConfig Signed-off-by: Viet Nguyen Duc <[email protected]> * update code as suggestions Signed-off-by: Viet Nguyen Duc <[email protected]> --------- Signed-off-by: Viet Nguyen Duc <[email protected]>
1 parent 61f507f commit 6d7e7da

File tree

6 files changed

+91
-5
lines changed

6 files changed

+91
-5
lines changed

java/src/org/openqa/selenium/docker/ContainerConfig.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import com.google.common.collect.ImmutableList;
2222
import com.google.common.collect.ImmutableMap;
2323
import com.google.common.collect.Multimap;
24+
import java.util.HashMap;
2425
import java.util.List;
2526
import java.util.Map;
2627
import java.util.stream.Collectors;
@@ -42,6 +43,7 @@ public class ContainerConfig {
4243
private final String networkName;
4344
private final boolean autoRemove;
4445
private final long shmSize;
46+
private final Map<String, Object> hostConfig;
4547

4648
public ContainerConfig(
4749
Image image,
@@ -51,6 +53,26 @@ public ContainerConfig(
5153
List<Device> devices,
5254
String networkName,
5355
long shmSize) {
56+
this(
57+
image,
58+
portBindings,
59+
envVars,
60+
volumeBinds,
61+
devices,
62+
networkName,
63+
shmSize,
64+
ImmutableMap.of());
65+
}
66+
67+
public ContainerConfig(
68+
Image image,
69+
Multimap<String, Map<String, Object>> portBindings,
70+
Map<String, String> envVars,
71+
Map<String, String> volumeBinds,
72+
List<Device> devices,
73+
String networkName,
74+
long shmSize,
75+
Map<String, Object> hostConfig) {
5476
this.image = image;
5577
this.portBindings = portBindings;
5678
this.envVars = envVars;
@@ -59,6 +81,7 @@ public ContainerConfig(
5981
this.networkName = networkName;
6082
this.autoRemove = true;
6183
this.shmSize = shmSize;
84+
this.hostConfig = hostConfig;
6285
}
6386

6487
public static ContainerConfig image(Image image) {
@@ -123,6 +146,17 @@ public ContainerConfig devices(List<Device> devices) {
123146
image, portBindings, envVars, volumeBinds, devices, networkName, shmSize);
124147
}
125148

149+
public ContainerConfig applyHostConfig(Map<String, Object> hostConfig, List<String> configKeys) {
150+
Map<String, Object> setHostConfig =
151+
configKeys.stream()
152+
.filter(hostConfig::containsKey)
153+
.filter(key -> hostConfig.get(key) != null)
154+
.collect(Collectors.toMap(key -> key, hostConfig::get));
155+
156+
return new ContainerConfig(
157+
image, portBindings, envVars, volumeBinds, devices, networkName, shmSize, setHostConfig);
158+
}
159+
126160
@Override
127161
public String toString() {
128162
return "ContainerConfig{"
@@ -142,6 +176,8 @@ public String toString() {
142176
+ autoRemove
143177
+ ", shmSize="
144178
+ shmSize
179+
+ ", hostConfig="
180+
+ hostConfig
145181
+ '}';
146182
}
147183

@@ -175,6 +211,12 @@ private Map<String, Object> toJson() {
175211
"Binds", volumeBinds,
176212
"Devices", devicesMapping);
177213

214+
if (!this.hostConfig.isEmpty()) {
215+
Map<String, Object> copyMap = new HashMap<>(hostConfig);
216+
copyMap.putAll(this.hostConfig);
217+
hostConfig = ImmutableMap.copyOf(copyMap);
218+
}
219+
178220
return ImmutableMap.of(
179221
"Image", image.getId(),
180222
"Env", envVars,

java/src/org/openqa/selenium/docker/ContainerInfo.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,19 @@ public class ContainerInfo {
2929
private final ContainerId id;
3030
private final List<Map<String, Object>> mountedVolumes;
3131
private final String networkName;
32+
private Map<String, Object> hostConfig;
3233

3334
public ContainerInfo(
34-
ContainerId id, String ip, List<Map<String, Object>> mountedVolumes, String networkName) {
35+
ContainerId id,
36+
String ip,
37+
List<Map<String, Object>> mountedVolumes,
38+
String networkName,
39+
Map<String, Object> hostConfig) {
3540
this.ip = Require.nonNull("Container ip address", ip);
3641
this.id = Require.nonNull("Container id", id);
3742
this.mountedVolumes = Require.nonNull("Mounted volumes", mountedVolumes);
3843
this.networkName = Require.nonNull("Network name", networkName);
44+
this.hostConfig = Require.nonNull("Host config", hostConfig);
3945
}
4046

4147
public String getIp() {
@@ -54,6 +60,10 @@ public String getNetworkName() {
5460
return networkName;
5561
}
5662

63+
public Map<String, Object> getHostConfig() {
64+
return this.hostConfig;
65+
}
66+
5767
@Override
5868
public String toString() {
5969
return "ContainerInfo{"

java/src/org/openqa/selenium/docker/v1_41/InspectContainer.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import static org.openqa.selenium.remote.http.HttpMethod.GET;
2424

2525
import java.util.ArrayList;
26+
import java.util.Collections;
2627
import java.util.List;
2728
import java.util.Map;
2829
import java.util.logging.Logger;
@@ -67,7 +68,9 @@ public ContainerInfo apply(ContainerId id) {
6768
ArrayList<Object> mounts = (ArrayList<Object>) rawInspectInfo.get("Mounts");
6869
List<Map<String, Object>> mountedVolumes =
6970
mounts.stream().map(mount -> (Map<String, Object>) mount).collect(Collectors.toList());
71+
Map<String, Object> hostConfig =
72+
(Map<String, Object>) rawInspectInfo.getOrDefault("HostConfig", Collections.emptyMap());
7073

71-
return new ContainerInfo(id, ip, mountedVolumes, networkName);
74+
return new ContainerInfo(id, ip, mountedVolumes, networkName, hostConfig);
7275
}
7376
}

java/src/org/openqa/selenium/grid/node/docker/DockerFlags.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,18 @@ public class DockerFlags implements HasRoles {
6969
"[\"selenium/standalone-firefox:latest\", \"{\\\"browserName\\\": \\\"firefox\\\"}\"]")
7070
private List<String> images2Capabilities;
7171

72+
@Parameter(
73+
names = {"--docker-host-config-keys"},
74+
description =
75+
"Specify which docker host configuration keys should be passed to browser containers."
76+
+ " Keys name can be found in the Docker API documentation, or by running `docker"
77+
+ " inspect` the node-docker container.")
78+
@ConfigValue(
79+
section = DockerOptions.DOCKER_SECTION,
80+
name = "host-config-keys",
81+
example = "[\"Dns\", \"DnsOptions\", \"DnsSearch\", \"ExtraHosts\", \"Binds\"]")
82+
private List<String> hostConfigKeys;
83+
7284
@Parameter(
7385
names = {"--docker-devices"},
7486
description =

java/src/org/openqa/selenium/grid/node/docker/DockerOptions.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,9 @@ public Map<Capabilities, Collection<SessionFactory>> getDockerSessionFactories(
129129
.getAll(DOCKER_SECTION, "configs")
130130
.orElseThrow(() -> new DockerException("Unable to find docker configs"));
131131

132+
List<String> hostConfigKeys =
133+
config.getAll(DOCKER_SECTION, "host-config-keys").orElseGet(Collections::emptyList);
134+
132135
Multimap<String, Capabilities> kinds = HashMultimap.create();
133136
for (int i = 0; i < allConfigs.size(); i++) {
134137
String imageName = allConfigs.get(i);
@@ -152,6 +155,7 @@ public Map<Capabilities, Collection<SessionFactory>> getDockerSessionFactories(
152155

153156
DockerAssetsPath assetsPath = getAssetsPath(info);
154157
String networkName = getDockerNetworkName(info);
158+
Map<String, Object> hostConfig = getDockerHostConfig(info);
155159

156160
loadImages(docker, kinds.keySet().toArray(new String[0]));
157161
Image videoImage = getVideoImage(docker);
@@ -182,7 +186,9 @@ public Map<Capabilities, Collection<SessionFactory>> getDockerSessionFactories(
182186
assetsPath,
183187
networkName,
184188
info.isPresent(),
185-
capabilities -> options.getSlotMatcher().matches(caps, capabilities)));
189+
capabilities -> options.getSlotMatcher().matches(caps, capabilities),
190+
hostConfig,
191+
hostConfigKeys));
186192
}
187193
LOG.info(
188194
String.format(
@@ -229,6 +235,11 @@ private String getDockerNetworkName(Optional<ContainerInfo> info) {
229235
return DEFAULT_DOCKER_NETWORK;
230236
}
231237

238+
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
239+
private Map<String, Object> getDockerHostConfig(Optional<ContainerInfo> info) {
240+
return info.map(ContainerInfo::getHostConfig).orElse(Collections.emptyMap());
241+
}
242+
232243
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
233244
private DockerAssetsPath getAssetsPath(Optional<ContainerInfo> info) {
234245
if (info.isPresent()) {

java/src/org/openqa/selenium/grid/node/docker/DockerSessionFactory.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ public class DockerSessionFactory implements SessionFactory {
101101
private final String networkName;
102102
private final boolean runningInDocker;
103103
private final Predicate<Capabilities> predicate;
104+
private final Map<String, Object> hostConfig;
105+
private final List<String> hostConfigKeys;
104106

105107
public DockerSessionFactory(
106108
Tracer tracer,
@@ -115,7 +117,9 @@ public DockerSessionFactory(
115117
DockerAssetsPath assetsPath,
116118
String networkName,
117119
boolean runningInDocker,
118-
Predicate<Capabilities> predicate) {
120+
Predicate<Capabilities> predicate,
121+
Map<String, Object> hostConfig,
122+
List<String> hostConfigKeys) {
119123
this.tracer = Require.nonNull("Tracer", tracer);
120124
this.clientFactory = Require.nonNull("HTTP client", clientFactory);
121125
this.sessionTimeout = Require.nonNull("Session timeout", sessionTimeout);
@@ -129,6 +133,8 @@ public DockerSessionFactory(
129133
this.assetsPath = assetsPath;
130134
this.runningInDocker = runningInDocker;
131135
this.predicate = Require.nonNull("Accepted capabilities predicate", predicate);
136+
this.hostConfig = Require.nonNull("Container host config", hostConfig);
137+
this.hostConfigKeys = Require.nonNull("Browser container host config keys", hostConfigKeys);
132138
}
133139

134140
@Override
@@ -285,10 +291,12 @@ private Container createBrowserContainer(int port, Capabilities sessionCapabilit
285291
.env(browserContainerEnvVars)
286292
.shmMemorySize(browserContainerShmMemorySize)
287293
.network(networkName)
288-
.devices(devices);
294+
.devices(devices)
295+
.applyHostConfig(hostConfig, hostConfigKeys);
289296
if (!runningInDocker) {
290297
containerConfig = containerConfig.map(Port.tcp(4444), Port.tcp(port));
291298
}
299+
LOG.fine("Container config: " + containerConfig);
292300
return docker.create(containerConfig);
293301
}
294302

0 commit comments

Comments
 (0)