Skip to content

Commit

Permalink
[docker] Support unix domain sockets on the default URLs for a platform
Browse files Browse the repository at this point in the history
  • Loading branch information
shs96c committed Mar 12, 2020
1 parent 63b9bfb commit d9f7cef
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import com.google.common.io.ByteStreams;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBufInputStream;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
Expand All @@ -44,7 +45,6 @@
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpHeaderValues;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpObject;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpVersion;
import org.openqa.selenium.remote.http.ClientConfig;
Expand All @@ -67,7 +67,6 @@
import java.util.Objects;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

import static java.net.HttpURLConnection.HTTP_INTERNAL_ERROR;
Expand Down Expand Up @@ -118,13 +117,17 @@ public HttpResponse execute(HttpRequest req) throws UncheckedIOException {
Joiner.on('&').appendTo(uri, queryPairs);
}

byte[] bytes = Contents.bytes(req.getContent());

DefaultFullHttpRequest fullRequest = new DefaultFullHttpRequest(
HttpVersion.HTTP_1_1,
HttpMethod.valueOf(req.getMethod().toString()),
uri.toString());
uri.toString(),
Unpooled.wrappedBuffer(bytes));
req.getHeaderNames().forEach(name -> req.getHeaders(name).forEach(value -> fullRequest.headers().add(name, value)));
fullRequest.headers().set(HttpHeaderNames.HOST, "localhost");
fullRequest.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.CLOSE);
fullRequest.headers().set(HttpHeaderNames.CONTENT_LENGTH, bytes.length);

ChannelFuture future = channel.writeAndFlush(fullRequest);

Expand Down
9 changes: 9 additions & 0 deletions java/server/src/org/openqa/selenium/docker/Image.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package org.openqa.selenium.docker;

import org.openqa.selenium.docker.internal.ImageSummary;
import org.openqa.selenium.json.Json;

import java.util.Objects;
import java.util.Set;
Expand All @@ -43,4 +44,12 @@ public ImageId getId() {
public Set<String> getTags() {
return summary.getRepoTags();
}

@Override
public String toString() {
new Json().toJson(summary);
return "Image{" +
"summary=" + summary +
'}';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import org.openqa.selenium.docker.Image;
import org.openqa.selenium.docker.internal.Reference;
import org.openqa.selenium.remote.http.HttpHandler;
import org.openqa.selenium.remote.http.HttpRequest;

import java.time.Duration;
import java.util.Objects;
Expand Down
11 changes: 0 additions & 11 deletions java/server/src/org/openqa/selenium/grid/docker/DockerFlags.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,8 @@
package org.openqa.selenium.grid.docker;

import com.beust.jcommander.Parameter;

import org.openqa.selenium.grid.config.ConfigValue;

import java.io.UncheckedIOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;

Expand All @@ -42,12 +39,4 @@ public class DockerFlags {
variableArity = true)
@ConfigValue(section = "docker", name = "configs")
private List<String> images2Capabilities;

public DockerFlags() {
try {
dockerUrl = new URL("http://localhost:2375");
} catch (MalformedURLException e) {
throw new UncheckedIOException(e);
}
}
}
67 changes: 40 additions & 27 deletions java/server/src/org/openqa/selenium/grid/docker/DockerOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,30 +21,30 @@
import com.google.common.collect.Multimap;
import io.opentelemetry.trace.Tracer;
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.Platform;
import org.openqa.selenium.docker.Docker;
import org.openqa.selenium.docker.DockerException;
import org.openqa.selenium.docker.Image;
import org.openqa.selenium.grid.config.Config;
import org.openqa.selenium.grid.config.ConfigException;
import org.openqa.selenium.grid.node.local.LocalNode;
import org.openqa.selenium.json.Json;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.remote.http.HttpClient;
import org.openqa.selenium.remote.http.HttpRequest;
import org.openqa.selenium.remote.http.HttpResponse;

import java.io.IOException;
import java.io.UncheckedIOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.logging.Logger;

import static java.util.logging.Level.WARNING;
import static org.openqa.selenium.remote.http.HttpMethod.GET;
import static org.openqa.selenium.Platform.WINDOWS;

public class DockerOptions {

Expand All @@ -56,13 +56,37 @@ public DockerOptions(Config config) {
this.config = Objects.requireNonNull(config);
}

private URL getDockerUrl() {
private URI getDockerUri() {
try {
String raw = config.get("docker", "url")
.orElseThrow(() -> new ConfigException("No docker url configured"));
return new URL(raw);
} catch (MalformedURLException e) {
throw new UncheckedIOException(e);
Optional<String> possibleUri = config.get("docker", "url");
if (possibleUri.isPresent()) {
return new URI(possibleUri.get());
}

Optional<String> possibleHost = config.get("docker", "host");
if (possibleHost.isPresent()) {
String host = possibleHost.get();
if (!(host.startsWith("tcp:") || host.startsWith("http:") || host.startsWith("https"))) {
host = "http://" + host;
}
URI uri = new URI(host);
return new URI(
"http",
uri.getUserInfo(),
uri.getHost(),
uri.getPort(),
uri.getPath(),
null,
null);
}

// Default for the system we're running on.
if (Platform.getCurrent().is(WINDOWS)) {
return new URI("http://localhost:2376");
}
return new URI("unix:/var/run/docker.sock");
} catch (URISyntaxException e) {
throw new ConfigException("Unable to determine docker url", e);
}
}

Expand All @@ -72,21 +96,10 @@ private boolean isEnabled(HttpClient.Factory clientFactory) {
}

// Is the daemon up and running?
URL url = getDockerUrl();
HttpClient client = clientFactory.createClient(url);
URI uri = getDockerUri();
HttpClient client = clientFactory.createClient(ClientConfig.defaultConfig().baseUri(uri));

try {
HttpResponse response = client.execute(new HttpRequest(GET, "/_ping"));
if (response.getStatus() != 200) {
LOG.warning(String.format("Docker config enabled, but daemon unreachable: %s", url));
return false;
}

return true;
} catch (UncheckedIOException e) {
LOG.log(WARNING, "Unable to ping docker daemon. Docker disabled: " + e.getMessage());
return false;
}
return new Docker(client).isSupported();
}

public void configure(Tracer tracer, HttpClient.Factory clientFactory, LocalNode.Builder node)
Expand All @@ -110,7 +123,7 @@ public void configure(Tracer tracer, HttpClient.Factory clientFactory, LocalNode
kinds.put(imageName, stereotype);
}

HttpClient client = clientFactory.createClient(new URL("http://localhost:2375"));
HttpClient client = clientFactory.createClient(ClientConfig.defaultConfig().baseUri(getDockerUri()));
Docker docker = new Docker(client);

loadImages(docker, kinds.keySet().toArray(new String[0]));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.openqa.selenium.remote.http.WebSocket;

import java.io.UncheckedIOException;
import java.net.URI;
import java.net.URL;
import java.util.Objects;

Expand All @@ -45,9 +46,9 @@ public RoutableHttpClientFactory(URL self, CombinedHandler handler, HttpClient.F
public HttpClient createClient(ClientConfig config) {
Objects.requireNonNull(config, "Client config to use must be set.");

URL url = config.baseUrl();
URI url = config.baseUri();

if (self.getProtocol().equals(url.getProtocol()) &&
if (self.getProtocol().equals(url.getScheme()) &&
self.getHost().equals(url.getHost()) &&
self.getPort() == url.getPort()) {

Expand Down

0 comments on commit d9f7cef

Please sign in to comment.