From 9d839d576491b807c53dd97112e403c8af1d1801 Mon Sep 17 00:00:00 2001 From: mohanli-ml Date: Wed, 9 Dec 2020 06:05:23 +0000 Subject: [PATCH 1/2] fix: check Compute Engine environment for DirectPath --- transport/grpc/dial.go | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/transport/grpc/dial.go b/transport/grpc/dial.go index f8a6ca29981..20d547b4064 100644 --- a/transport/grpc/dial.go +++ b/transport/grpc/dial.go @@ -11,7 +11,9 @@ import ( "context" "crypto/tls" "errors" + "io/ioutil" "log" + "runtime" "strings" "go.opencensus.io/plugin/ocgrpc" @@ -28,6 +30,11 @@ import ( _ "google.golang.org/grpc/balancer/grpclb" ) +const ( + GCEProductionNamePrior2016 = "Google" + GCEProductionNameAfter2016 = "Google Compute Engine" +) + // Set at init time by dial_appengine.go. If nil, we're not on App Engine. var appengineDialerHook func(context.Context) grpc.DialOption @@ -137,7 +144,7 @@ func dial(ctx context.Context, insecure bool, o *internal.DialSettings) (*grpc.C // * The endpoint is a host:port (or dns:///host:port). // * Credentials are obtained via GCE metadata server, using the default // service account. - if o.EnableDirectPath && checkDirectPathEndPoint(endpoint) && isTokenSourceDirectPathCompatible(creds.TokenSource) { + if o.EnableDirectPath && checkDirectPathEndPoint(endpoint) && isTokenSourceDirectPathCompatible(creds.TokenSource) && isOnComputeEngine() { if !strings.HasPrefix(endpoint, "dns:///") { endpoint = "dns:///" + endpoint } @@ -186,7 +193,7 @@ func dial(ctx context.Context, insecure bool, o *internal.DialSettings) (*grpc.C // point when isDirectPathEnabled will default to true, we guard it by // the Directpath env var for now once we can introspect user defined // dialer (https://github.com/grpc/grpc-go/issues/2795). - if timeoutDialerOption != nil && o.EnableDirectPath && checkDirectPathEndPoint(endpoint) { + if timeoutDialerOption != nil && o.EnableDirectPath && checkDirectPathEndPoint(endpoint) && isOnComputeEngine() { grpcOpts = append(grpcOpts, timeoutDialerOption) } @@ -247,6 +254,20 @@ func isTokenSourceDirectPathCompatible(ts oauth2.TokenSource) bool { return true } +func isOnComputeEngine() bool { + // DirectPath should only be used on Compute Engine. + // Notice Windows is not supported for now. + if runtime.GOOS == "linux" { + file, err := ioutil.ReadFile("/sys/class/dmi/id/product_name") + if err != nil { + log.Print("Fail to check Compute Engine, and DirectPath will not be used.") + return false + } + return strings.Contains(string(file), GCEProductionNamePrior2016) || strings.Contains(string(file), GCEProductionNameAfter2016) + } + return false +} + func checkDirectPathEndPoint(endpoint string) bool { // Only [dns:///]host[:port] is supported, not other schemes (e.g., "tcp://" or "unix://"). // Also don't try direct path if the user has chosen an alternate name resolver From ff4397992b0483f2e03e905ae67f54113dd8b024 Mon Sep 17 00:00:00 2001 From: mohanli-ml Date: Wed, 9 Dec 2020 18:58:01 +0000 Subject: [PATCH 2/2] fix(transport/grpc): check Compute Engine environment for DirectPath --- transport/grpc/dial.go | 26 +++----------------------- 1 file changed, 3 insertions(+), 23 deletions(-) diff --git a/transport/grpc/dial.go b/transport/grpc/dial.go index 20d547b4064..727a5beff1b 100644 --- a/transport/grpc/dial.go +++ b/transport/grpc/dial.go @@ -11,11 +11,10 @@ import ( "context" "crypto/tls" "errors" - "io/ioutil" "log" - "runtime" "strings" + "cloud.google.com/go/compute/metadata" "go.opencensus.io/plugin/ocgrpc" "golang.org/x/oauth2" "google.golang.org/api/internal" @@ -30,11 +29,6 @@ import ( _ "google.golang.org/grpc/balancer/grpclb" ) -const ( - GCEProductionNamePrior2016 = "Google" - GCEProductionNameAfter2016 = "Google Compute Engine" -) - // Set at init time by dial_appengine.go. If nil, we're not on App Engine. var appengineDialerHook func(context.Context) grpc.DialOption @@ -144,7 +138,7 @@ func dial(ctx context.Context, insecure bool, o *internal.DialSettings) (*grpc.C // * The endpoint is a host:port (or dns:///host:port). // * Credentials are obtained via GCE metadata server, using the default // service account. - if o.EnableDirectPath && checkDirectPathEndPoint(endpoint) && isTokenSourceDirectPathCompatible(creds.TokenSource) && isOnComputeEngine() { + if o.EnableDirectPath && checkDirectPathEndPoint(endpoint) && isTokenSourceDirectPathCompatible(creds.TokenSource) && metadata.OnGCE() { if !strings.HasPrefix(endpoint, "dns:///") { endpoint = "dns:///" + endpoint } @@ -193,7 +187,7 @@ func dial(ctx context.Context, insecure bool, o *internal.DialSettings) (*grpc.C // point when isDirectPathEnabled will default to true, we guard it by // the Directpath env var for now once we can introspect user defined // dialer (https://github.com/grpc/grpc-go/issues/2795). - if timeoutDialerOption != nil && o.EnableDirectPath && checkDirectPathEndPoint(endpoint) && isOnComputeEngine() { + if timeoutDialerOption != nil && o.EnableDirectPath && checkDirectPathEndPoint(endpoint) && metadata.OnGCE() { grpcOpts = append(grpcOpts, timeoutDialerOption) } @@ -254,20 +248,6 @@ func isTokenSourceDirectPathCompatible(ts oauth2.TokenSource) bool { return true } -func isOnComputeEngine() bool { - // DirectPath should only be used on Compute Engine. - // Notice Windows is not supported for now. - if runtime.GOOS == "linux" { - file, err := ioutil.ReadFile("/sys/class/dmi/id/product_name") - if err != nil { - log.Print("Fail to check Compute Engine, and DirectPath will not be used.") - return false - } - return strings.Contains(string(file), GCEProductionNamePrior2016) || strings.Contains(string(file), GCEProductionNameAfter2016) - } - return false -} - func checkDirectPathEndPoint(endpoint string) bool { // Only [dns:///]host[:port] is supported, not other schemes (e.g., "tcp://" or "unix://"). // Also don't try direct path if the user has chosen an alternate name resolver