aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/remote
diff options
context:
space:
mode:
authorGravatar olaola <olaola@google.com>2017-04-19 19:01:43 +0200
committerGravatar Klaus Aehlig <aehlig@google.com>2017-04-20 11:06:47 +0200
commit3ffc6a7b47bf2da1fa723343f0e88962d308ee63 (patch)
tree463ff9fe772e7c31ea567a6a8e32a90695a682a3 /src/main/java/com/google/devtools/build/lib/remote
parentdfcd5da86e2acfd42ca09c7f65e012465ab3e382 (diff)
OnePlatform auth support for Bazel, in preparation for next version of the API.
TESTED: local server RELNOTES: n/a PiperOrigin-RevId: 153599636
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/remote')
-rw-r--r--src/main/java/com/google/devtools/build/lib/remote/BUILD8
-rw-r--r--src/main/java/com/google/devtools/build/lib/remote/ChannelOptions.java112
-rw-r--r--src/main/java/com/google/devtools/build/lib/remote/GrpcActionCache.java19
-rw-r--r--src/main/java/com/google/devtools/build/lib/remote/GrpcInterfaces.java40
-rw-r--r--src/main/java/com/google/devtools/build/lib/remote/GrpcRemoteExecutor.java11
-rw-r--r--src/main/java/com/google/devtools/build/lib/remote/RemoteOptions.java72
-rw-r--r--src/main/java/com/google/devtools/build/lib/remote/RemoteSpawnRunner.java19
-rw-r--r--src/main/java/com/google/devtools/build/lib/remote/RemoteSpawnStrategy.java33
-rw-r--r--src/main/java/com/google/devtools/build/lib/remote/RemoteUtils.java32
9 files changed, 250 insertions, 96 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/remote/BUILD b/src/main/java/com/google/devtools/build/lib/remote/BUILD
index 98ca68dec1..a1c2c190fd 100644
--- a/src/main/java/com/google/devtools/build/lib/remote/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/remote/BUILD
@@ -6,6 +6,10 @@ java_library(
name = "remote",
srcs = glob(["*.java"]),
tags = ["bazel"],
+ runtime_deps = [
+ # This is required for client TLS.
+ "//third_party:netty_tcnative",
+ ],
deps = [
"//src/main/java/com/google/devtools/build/lib:build-base",
"//src/main/java/com/google/devtools/build/lib:concurrent",
@@ -13,20 +17,20 @@ java_library(
"//src/main/java/com/google/devtools/build/lib:io",
"//src/main/java/com/google/devtools/build/lib:packages-internal",
"//src/main/java/com/google/devtools/build/lib:runtime",
- "//src/main/java/com/google/devtools/build/lib:shell",
"//src/main/java/com/google/devtools/build/lib:util",
"//src/main/java/com/google/devtools/build/lib:vfs",
"//src/main/java/com/google/devtools/build/lib/actions",
- "//src/main/java/com/google/devtools/build/lib/exec/local",
"//src/main/java/com/google/devtools/build/lib/standalone",
"//src/main/java/com/google/devtools/common/options",
"//src/main/protobuf:remote_protocol_java_proto",
"//third_party:apache_httpclient",
"//third_party:apache_httpcore",
+ "//third_party:auth",
"//third_party:gson",
"//third_party:guava",
"//third_party:hazelcast",
"//third_party:jsr305",
+ "//third_party:netty",
"//third_party/grpc:grpc-jar",
"//third_party/protobuf:protobuf_java",
],
diff --git a/src/main/java/com/google/devtools/build/lib/remote/ChannelOptions.java b/src/main/java/com/google/devtools/build/lib/remote/ChannelOptions.java
new file mode 100644
index 0000000000..45d76fc832
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/remote/ChannelOptions.java
@@ -0,0 +1,112 @@
+// Copyright 2017 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.devtools.build.lib.remote;
+
+import com.google.auth.oauth2.GoogleCredentials;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.ImmutableList;
+import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe;
+import io.grpc.CallCredentials;
+import io.grpc.auth.MoreCallCredentials;
+import io.grpc.netty.GrpcSslContexts;
+import io.netty.handler.ssl.SslContext;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import javax.annotation.Nullable;
+import javax.net.ssl.SSLException;
+
+/** Instantiate all authentication helpers from build options. */
+@ThreadSafe
+public final class ChannelOptions {
+ private final boolean tlsEnabled;
+ private final SslContext sslContext;
+ private final String tlsAuthorityOverride;
+ private final CallCredentials credentials;
+
+ private ChannelOptions(
+ boolean tlsEnabled,
+ SslContext sslContext,
+ String tlsAuthorityOverride,
+ CallCredentials credentials) {
+ this.tlsEnabled = tlsEnabled;
+ this.sslContext = sslContext;
+ this.tlsAuthorityOverride = tlsAuthorityOverride;
+ this.credentials = credentials;
+ }
+
+ public boolean tlsEnabled() {
+ return tlsEnabled;
+ }
+
+ public CallCredentials getCallCredentials() {
+ return credentials;
+ }
+
+ public String getTlsAuthorityOverride() {
+ return tlsAuthorityOverride;
+ }
+
+ public SslContext getSslContext() {
+ return sslContext;
+ }
+
+ public static ChannelOptions create(RemoteOptions options) {
+ try {
+ return create(
+ options,
+ options.authCredentialsJson != null
+ ? new FileInputStream(options.authCredentialsJson)
+ : null);
+ } catch (IOException e) {
+ throw new IllegalArgumentException(
+ "Failed initializing auth credentials for remote cache/execution " + e);
+ }
+ }
+
+ @VisibleForTesting
+ public static ChannelOptions create(
+ RemoteOptions options, @Nullable InputStream credentialsInputStream) {
+ boolean tlsEnabled = options.tlsEnabled;
+ SslContext sslContext = null;
+ String tlsAuthorityOverride = options.tlsAuthorityOverride;
+ CallCredentials credentials = null;
+ if (options.tlsEnabled && options.tlsCert != null) {
+ try {
+ sslContext = GrpcSslContexts.forClient().trustManager(new File(options.tlsCert)).build();
+ } catch (SSLException e) {
+ throw new IllegalArgumentException(
+ "SSL error initializing cert " + options.tlsCert + " : " + e);
+ }
+ }
+ if (options.authEnabled) {
+ try {
+ GoogleCredentials creds =
+ credentialsInputStream == null
+ ? GoogleCredentials.getApplicationDefault()
+ : GoogleCredentials.fromStream(credentialsInputStream);
+ if (options.authScope != null) {
+ creds = creds.createScoped(ImmutableList.of(options.authScope));
+ }
+ credentials = MoreCallCredentials.from(creds);
+ } catch (IOException e) {
+ throw new IllegalArgumentException(
+ "Failed initializing auth credentials for remote cache/execution " + e);
+ }
+ }
+ return new ChannelOptions(tlsEnabled, sslContext, tlsAuthorityOverride, credentials);
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/remote/GrpcActionCache.java b/src/main/java/com/google/devtools/build/lib/remote/GrpcActionCache.java
index 56d4fa2e18..67b04a969a 100644
--- a/src/main/java/com/google/devtools/build/lib/remote/GrpcActionCache.java
+++ b/src/main/java/com/google/devtools/build/lib/remote/GrpcActionCache.java
@@ -19,7 +19,6 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.actions.ActionInput;
import com.google.devtools.build.lib.actions.ActionInputFileCache;
-import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe;
import com.google.devtools.build.lib.remote.ContentDigests.ActionKey;
import com.google.devtools.build.lib.remote.RemoteProtocol.ActionResult;
@@ -48,7 +47,7 @@ import com.google.devtools.build.lib.util.Preconditions;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.Path;
import com.google.protobuf.ByteString;
-import io.grpc.ManagedChannel;
+import io.grpc.Channel;
import io.grpc.Status;
import io.grpc.StatusRuntimeException;
import io.grpc.stub.StreamObserver;
@@ -84,14 +83,17 @@ public class GrpcActionCache implements RemoteActionCache {
}
@VisibleForTesting
- public GrpcActionCache(ManagedChannel channel, RemoteOptions options) {
+ public GrpcActionCache(
+ Channel channel, RemoteOptions options, ChannelOptions channelOptions) {
this.options = options;
- this.casIface = GrpcInterfaces.casInterface(options.grpcTimeoutSeconds, channel);
- this.iface = GrpcInterfaces.executionCacheInterface(options.grpcTimeoutSeconds, channel);
+ this.casIface =
+ GrpcInterfaces.casInterface(options.grpcTimeoutSeconds, channel, channelOptions);
+ this.iface =
+ GrpcInterfaces.executionCacheInterface(options.grpcTimeoutSeconds, channel, channelOptions);
}
- public GrpcActionCache(RemoteOptions options) throws InvalidConfigurationException {
- this(RemoteUtils.createChannelLegacy(options.remoteCache), options);
+ public GrpcActionCache(RemoteOptions options, ChannelOptions channelOptions) {
+ this(RemoteUtils.createChannel(options.remoteCache, channelOptions), options, channelOptions);
}
public static boolean isRemoteCacheOptions(RemoteOptions options) {
@@ -340,8 +342,7 @@ public class GrpcActionCache implements RemoteActionCache {
}
}
- private void uploadChunks(int numItems, Chunker blobs)
- throws InterruptedException, IOException {
+ private void uploadChunks(int numItems, Chunker blobs) throws InterruptedException, IOException {
CountDownLatch finishLatch = new CountDownLatch(numItems); // Maximal number of batches.
AtomicReference<RuntimeException> exception = new AtomicReference<>(null);
UploadBlobReplyStreamObserver responseObserver = null;
diff --git a/src/main/java/com/google/devtools/build/lib/remote/GrpcInterfaces.java b/src/main/java/com/google/devtools/build/lib/remote/GrpcInterfaces.java
index 73ab0372d2..6e100ae1d0 100644
--- a/src/main/java/com/google/devtools/build/lib/remote/GrpcInterfaces.java
+++ b/src/main/java/com/google/devtools/build/lib/remote/GrpcInterfaces.java
@@ -33,28 +33,28 @@ import com.google.devtools.build.lib.remote.RemoteProtocol.ExecutionCacheReply;
import com.google.devtools.build.lib.remote.RemoteProtocol.ExecutionCacheRequest;
import com.google.devtools.build.lib.remote.RemoteProtocol.ExecutionCacheSetReply;
import com.google.devtools.build.lib.remote.RemoteProtocol.ExecutionCacheSetRequest;
-import io.grpc.ManagedChannel;
+import io.grpc.Channel;
import io.grpc.stub.StreamObserver;
import java.util.Iterator;
import java.util.concurrent.TimeUnit;
-/**
- * Implementations of the gRPC interfaces that actually talk to gRPC.
- */
+/** Implementations of the gRPC interfaces that actually talk to gRPC. */
public class GrpcInterfaces {
- /**
- * Create a {@link GrpcCasInterface} instance that actually talks to gRPC.
- */
+ /** Create a {@link GrpcCasInterface} instance that actually talks to gRPC. */
public static GrpcCasInterface casInterface(
- final int grpcTimeoutSeconds, final ManagedChannel channel) {
+ final int grpcTimeoutSeconds,
+ final Channel channel,
+ final ChannelOptions channelOptions) {
return new GrpcCasInterface() {
private CasServiceBlockingStub getCasServiceBlockingStub() {
return CasServiceGrpc.newBlockingStub(channel)
+ .withCallCredentials(channelOptions.getCallCredentials())
.withDeadlineAfter(grpcTimeoutSeconds, TimeUnit.SECONDS);
}
private CasServiceStub getCasServiceStub() {
return CasServiceGrpc.newStub(channel)
+ .withCallCredentials(channelOptions.getCallCredentials())
.withDeadlineAfter(grpcTimeoutSeconds, TimeUnit.SECONDS);
}
@@ -87,14 +87,15 @@ public class GrpcInterfaces {
};
}
- /**
- * Create a {@link GrpcCasInterface} instance that actually talks to gRPC.
- */
+ /** Create a {@link GrpcCasInterface} instance that actually talks to gRPC. */
public static GrpcExecutionCacheInterface executionCacheInterface(
- final int grpcTimeoutSeconds, final ManagedChannel channel) {
+ final int grpcTimeoutSeconds,
+ final Channel channel,
+ final ChannelOptions channelOptions) {
return new GrpcExecutionCacheInterface() {
private ExecutionCacheServiceBlockingStub getExecutionCacheServiceBlockingStub() {
- return ExecutionCacheServiceGrpc.newBlockingStub(channel)
+ return ExecutionCacheServiceGrpc.newBlockingStub(channel)
+ .withCallCredentials(channelOptions.getCallCredentials())
.withDeadlineAfter(grpcTimeoutSeconds, TimeUnit.SECONDS);
}
@@ -110,18 +111,19 @@ public class GrpcInterfaces {
};
}
- /**
- * Create a {@link GrpcExecutionInterface} instance that actually talks to gRPC.
- */
+ /** Create a {@link GrpcExecutionInterface} instance that actually talks to gRPC. */
public static GrpcExecutionInterface executionInterface(
- final int grpcTimeoutSeconds, final ManagedChannel channel) {
+ final int grpcTimeoutSeconds,
+ final Channel channel,
+ final ChannelOptions channelOptions) {
return new GrpcExecutionInterface() {
@Override
public Iterator<ExecuteReply> execute(ExecuteRequest request) {
ExecuteServiceBlockingStub stub =
ExecuteServiceGrpc.newBlockingStub(channel)
- .withDeadlineAfter(
- grpcTimeoutSeconds + request.getTimeoutMillis() / 1000, TimeUnit.SECONDS);
+ .withCallCredentials(channelOptions.getCallCredentials())
+ .withDeadlineAfter(
+ grpcTimeoutSeconds + request.getTimeoutMillis() / 1000, TimeUnit.SECONDS);
return stub.execute(request);
}
};
diff --git a/src/main/java/com/google/devtools/build/lib/remote/GrpcRemoteExecutor.java b/src/main/java/com/google/devtools/build/lib/remote/GrpcRemoteExecutor.java
index d3f8cbbfe7..1812d8f4f0 100644
--- a/src/main/java/com/google/devtools/build/lib/remote/GrpcRemoteExecutor.java
+++ b/src/main/java/com/google/devtools/build/lib/remote/GrpcRemoteExecutor.java
@@ -39,12 +39,15 @@ public class GrpcRemoteExecutor extends GrpcActionCache {
this.executionIface = executionIface;
}
- public GrpcRemoteExecutor(ManagedChannel channel, RemoteOptions options) {
+ public GrpcRemoteExecutor(
+ ManagedChannel channel, ChannelOptions channelOptions, RemoteOptions options) {
super(
options,
- GrpcInterfaces.casInterface(options.grpcTimeoutSeconds, channel),
- GrpcInterfaces.executionCacheInterface(options.grpcTimeoutSeconds, channel));
- this.executionIface = GrpcInterfaces.executionInterface(options.grpcTimeoutSeconds, channel);
+ GrpcInterfaces.casInterface(options.grpcTimeoutSeconds, channel, channelOptions),
+ GrpcInterfaces.executionCacheInterface(
+ options.grpcTimeoutSeconds, channel, channelOptions));
+ this.executionIface =
+ GrpcInterfaces.executionInterface(options.grpcTimeoutSeconds, channel, channelOptions);
}
public ExecuteReply executeRemotely(ExecuteRequest request) {
diff --git a/src/main/java/com/google/devtools/build/lib/remote/RemoteOptions.java b/src/main/java/com/google/devtools/build/lib/remote/RemoteOptions.java
index 561c55ea08..fa3647aba0 100644
--- a/src/main/java/com/google/devtools/build/lib/remote/RemoteOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/remote/RemoteOptions.java
@@ -33,7 +33,7 @@ public final class RemoteOptions extends OptionsBase {
name = "hazelcast_node",
defaultValue = "null",
category = "remote",
- help = "A comma separated list of hostnames of hazelcast nodes. For client mode only."
+ help = "A comma separated list of hostnames of hazelcast nodes."
)
public String hazelcastNode;
@@ -41,7 +41,7 @@ public final class RemoteOptions extends OptionsBase {
name = "hazelcast_client_config",
defaultValue = "null",
category = "remote",
- help = "A file path to a hazelcast client config XML file. For client mode only."
+ help = "A file path to a hazelcast client config XML file."
)
public String hazelcastClientConfig;
@@ -59,9 +59,7 @@ public final class RemoteOptions extends OptionsBase {
name = "remote_worker",
defaultValue = "null",
category = "remote",
- help =
- "Hostname and port number of remote worker in the form of host:port. "
- + "For client mode only."
+ help = "Hostname and port number of remote worker in the form of host:port. "
)
public String remoteWorker;
@@ -69,9 +67,7 @@ public final class RemoteOptions extends OptionsBase {
name = "remote_cache",
defaultValue = "null",
category = "remote",
- help =
- "Hostname and port number of remote gRPC cache in the form of host:port. "
- + "For client mode only."
+ help = "Hostname and port number of remote gRPC cache in the form of host:port. "
)
public String remoteCache;
@@ -79,7 +75,7 @@ public final class RemoteOptions extends OptionsBase {
name = "grpc_max_chunk_size_bytes",
defaultValue = "400000", // <4MB. Bounded by the gRPC size limit on the overall message.
category = "remote",
- help = "The maximal number of bytes to be sent in a single message. For client mode only."
+ help = "The maximal number of bytes to be sent in a single message."
)
public int grpcMaxChunkSizeBytes;
@@ -87,7 +83,7 @@ public final class RemoteOptions extends OptionsBase {
name = "grpc_max_batch_inputs",
defaultValue = "100",
category = "remote",
- help = "The maximal number of input file to be sent in a single batch. For client mode only."
+ help = "The maximal number of input file to be sent in a single batch."
)
public int grpcMaxBatchInputs;
@@ -95,7 +91,7 @@ public final class RemoteOptions extends OptionsBase {
name = "grpc_max_batch_size_bytes",
defaultValue = "10485760", // 10MB
category = "remote",
- help = "The maximal number of input bytes to be sent in a single batch. For client mode only."
+ help = "The maximal number of input bytes to be sent in a single batch."
)
public int grpcMaxBatchSizeBytes;
@@ -103,7 +99,7 @@ public final class RemoteOptions extends OptionsBase {
name = "grpc_timeout_seconds",
defaultValue = "60",
category = "remote",
- help = "The maximal number of seconds to wait for remote calls. For client mode only."
+ help = "The maximal number of seconds to wait for remote calls."
)
public int grpcTimeoutSeconds;
@@ -138,4 +134,56 @@ public final class RemoteOptions extends OptionsBase {
help = "Temporary, for testing only. Manually set a Platform to pass to remote execution."
)
public String experimentalRemotePlatformOverride;
+
+ @Option(
+ name = "auth_enabled",
+ defaultValue = "false",
+ category = "remote",
+ help = "Whether to enable API key authentication."
+ )
+ public boolean authEnabled;
+
+ @Option(
+ name = "auth_scope",
+ defaultValue = "null",
+ category = "remote",
+ help = "If server authentication requires a scope, provide it here."
+ )
+ public String authScope;
+
+ @Option(
+ name = "auth_credentials_json",
+ defaultValue = "null",
+ category = "remote",
+ help = "Location of credentials JSON file."
+ )
+ public String authCredentialsJson;
+
+ @Option(
+ name = "tls_enabled",
+ defaultValue = "false",
+ category = "remote",
+ help =
+ "If set to true, Bazel uses TLS encryption for all connections to remote cache and "
+ + "execution servers."
+ )
+ public boolean tlsEnabled;
+
+ @Option(
+ name = "tls_cert",
+ defaultValue = "null",
+ category = "remote",
+ help = "TLS certificate file to use."
+ )
+ public String tlsCert;
+
+ @Option(
+ name = "tls_authority_override",
+ defaultValue = "null",
+ category = "remote",
+ help =
+ "If present, consider the value of the flag a valid TLS authority. This is useful for "
+ + "using self-signed test TLS certificates. For testing only."
+ )
+ public String tlsAuthorityOverride;
}
diff --git a/src/main/java/com/google/devtools/build/lib/remote/RemoteSpawnRunner.java b/src/main/java/com/google/devtools/build/lib/remote/RemoteSpawnRunner.java
index 7484dafae9..e7025beee8 100644
--- a/src/main/java/com/google/devtools/build/lib/remote/RemoteSpawnRunner.java
+++ b/src/main/java/com/google/devtools/build/lib/remote/RemoteSpawnRunner.java
@@ -41,10 +41,8 @@ import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.protobuf.TextFormat;
import com.google.protobuf.TextFormat.ParseException;
-import io.grpc.ManagedChannel;
import io.grpc.StatusRuntimeException;
import java.io.IOException;
-import java.net.URISyntaxException;
import java.util.Collection;
import java.util.List;
import java.util.SortedMap;
@@ -90,19 +88,14 @@ final class RemoteSpawnRunner implements SpawnRunner {
private static GrpcRemoteExecutor connect(RemoteOptions options) {
Preconditions.checkArgument(GrpcRemoteExecutor.isRemoteExecutionOptions(options));
- ManagedChannel channel;
- try {
- channel = RemoteUtils.createChannel(options.remoteWorker);
- } catch (URISyntaxException e) {
- throw new RuntimeException(e);
- }
- return new GrpcRemoteExecutor(channel, options);
+ ChannelOptions channelOptions = ChannelOptions.create(options);
+ return new GrpcRemoteExecutor(
+ RemoteUtils.createChannel(options.remoteWorker, channelOptions), channelOptions, options);
}
@Override
- public SpawnResult exec(
- Spawn spawn,
- SpawnExecutionPolicy policy) throws InterruptedException, IOException {
+ public SpawnResult exec(Spawn spawn, SpawnExecutionPolicy policy)
+ throws InterruptedException, IOException {
ActionExecutionMetadata owner = spawn.getResourceOwner();
if (owner.getOwner() != null) {
policy.report(ProgressStatus.EXECUTING);
@@ -193,7 +186,7 @@ final class RemoteSpawnRunner implements SpawnRunner {
private static void passRemoteOutErr(
RemoteActionCache cache, ActionResult result, FileOutErr outErr)
- throws CacheNotFoundException {
+ throws CacheNotFoundException {
ImmutableList<byte[]> streams =
cache.downloadBlobs(ImmutableList.of(result.getStdoutDigest(), result.getStderrDigest()));
outErr.printOut(new String(streams.get(0), UTF_8));
diff --git a/src/main/java/com/google/devtools/build/lib/remote/RemoteSpawnStrategy.java b/src/main/java/com/google/devtools/build/lib/remote/RemoteSpawnStrategy.java
index 05c9b92d8c..f67a01f2d8 100644
--- a/src/main/java/com/google/devtools/build/lib/remote/RemoteSpawnStrategy.java
+++ b/src/main/java/com/google/devtools/build/lib/remote/RemoteSpawnStrategy.java
@@ -30,7 +30,6 @@ import com.google.devtools.build.lib.actions.Spawn;
import com.google.devtools.build.lib.actions.SpawnActionContext;
import com.google.devtools.build.lib.actions.Spawns;
import com.google.devtools.build.lib.actions.UserExecException;
-import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.exec.SpawnInputExpander;
@@ -75,7 +74,8 @@ final class RemoteSpawnStrategy implements SpawnActionContext {
private final RemoteOptions options;
// TODO(olaola): This will be set on a per-action basis instead.
private final Platform platform;
- private final SpawnInputExpander spawnInputExpander = new SpawnInputExpander(/*strict=*/false);
+ private final ChannelOptions channelOptions;
+ private final SpawnInputExpander spawnInputExpander = new SpawnInputExpander(/*strict=*/ false);
RemoteSpawnStrategy(
Map<String, String> clientEnv,
@@ -87,12 +87,14 @@ final class RemoteSpawnStrategy implements SpawnActionContext {
this.standaloneStrategy = new StandaloneSpawnStrategy(execRoot, verboseFailures, productName);
this.verboseFailures = verboseFailures;
this.options = options;
+ channelOptions = ChannelOptions.create(options);
if (options.experimentalRemotePlatformOverride != null) {
Platform.Builder platformBuilder = Platform.newBuilder();
try {
TextFormat.getParser().merge(options.experimentalRemotePlatformOverride, platformBuilder);
} catch (ParseException e) {
- throw new RuntimeException("Failed to parse --experimental_remote_platform_override", e);
+ throw new IllegalArgumentException(
+ "Failed to parse --experimental_remote_platform_override", e);
}
platform = platformBuilder.build();
} else {
@@ -212,20 +214,19 @@ final class RemoteSpawnStrategy implements SpawnActionContext {
if (spawn.isRemotable()) {
// Initialize remote cache and execution handlers. We use separate handlers for every
// action to enable server-side parallelism (need a different gRPC channel per action).
- try {
- if (SimpleBlobStoreFactory.isRemoteCacheOptions(options)) {
- actionCache = new SimpleBlobStoreActionCache(SimpleBlobStoreFactory.create(options));
- } else if (GrpcActionCache.isRemoteCacheOptions(options)) {
- actionCache = new GrpcActionCache(options);
- }
- // Otherwise actionCache remains null and remote caching/execution are disabled.
+ if (SimpleBlobStoreFactory.isRemoteCacheOptions(options)) {
+ actionCache = new SimpleBlobStoreActionCache(SimpleBlobStoreFactory.create(options));
+ } else if (GrpcActionCache.isRemoteCacheOptions(options)) {
+ actionCache = new GrpcActionCache(options, channelOptions);
+ }
+ // Otherwise actionCache remains null and remote caching/execution are disabled.
- if (actionCache != null && GrpcRemoteExecutor.isRemoteExecutionOptions(options)) {
- workExecutor = new GrpcRemoteExecutor(
- RemoteUtils.createChannelLegacy(options.remoteWorker), options);
- }
- } catch (InvalidConfigurationException e) {
- eventHandler.handle(Event.warn(e.toString()));
+ if (actionCache != null && GrpcRemoteExecutor.isRemoteExecutionOptions(options)) {
+ workExecutor =
+ new GrpcRemoteExecutor(
+ RemoteUtils.createChannel(options.remoteWorker, channelOptions),
+ channelOptions,
+ options);
}
}
if (!spawn.isRemotable() || actionCache == null) {
diff --git a/src/main/java/com/google/devtools/build/lib/remote/RemoteUtils.java b/src/main/java/com/google/devtools/build/lib/remote/RemoteUtils.java
index 89ecf43b2e..d890829142 100644
--- a/src/main/java/com/google/devtools/build/lib/remote/RemoteUtils.java
+++ b/src/main/java/com/google/devtools/build/lib/remote/RemoteUtils.java
@@ -14,34 +14,24 @@
package com.google.devtools.build.lib.remote;
-import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe;
import io.grpc.ManagedChannel;
+import io.grpc.netty.NegotiationType;
import io.grpc.netty.NettyChannelBuilder;
-import java.net.URI;
-import java.net.URISyntaxException;
/** Helper methods for gRPC calls */
@ThreadSafe
public final class RemoteUtils {
- public static ManagedChannel createChannelLegacy(String hostAndPort)
- throws InvalidConfigurationException {
- try {
- return createChannel(hostAndPort);
- } catch (URISyntaxException e) {
- throw new InvalidConfigurationException(
- "Invalid argument for the address of remote cache server: " + hostAndPort);
+ public static ManagedChannel createChannel(String target, ChannelOptions channelOptions) {
+ NettyChannelBuilder builder = NettyChannelBuilder.forTarget(target);
+ builder.negotiationType(
+ channelOptions.tlsEnabled() ? NegotiationType.TLS : NegotiationType.PLAINTEXT);
+ if (channelOptions.getSslContext() != null) {
+ builder.sslContext(channelOptions.getSslContext());
+ if (channelOptions.getTlsAuthorityOverride() != null) {
+ builder.overrideAuthority(channelOptions.getTlsAuthorityOverride());
+ }
}
- }
-
- public static ManagedChannel createChannel(String hostAndPort)
- throws URISyntaxException {
- URI uri = new URI("dummy://" + hostAndPort);
- if (uri.getHost() == null || uri.getPort() == -1) {
- throw new URISyntaxException("Invalid host or port.", "");
- }
- return NettyChannelBuilder.forAddress(uri.getHost(), uri.getPort())
- .usePlaintext(true)
- .build();
+ return builder.build();
}
}