-
Notifications
You must be signed in to change notification settings - Fork 105
fix: check Compute Engine environment for DirectPath #1250
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
needs tests
gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java
Outdated
Show resolved
Hide resolved
gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java
Outdated
Show resolved
Hide resolved
gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java
Show resolved
Hide resolved
gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java
Show resolved
Hide resolved
gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java
Outdated
Show resolved
Hide resolved
gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java
Outdated
Show resolved
Hide resolved
resultOutStream.write(bs, 0, num); | ||
} | ||
String result = new String(resultOutStream.toByteArray()); | ||
return result.contains("01/01/2011") && result.contains("Google"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why this date?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As this is open source code, can this be made with a reference to a public doc?
Also this needs a comment in the source code explaining it, and possibly a named constant for the date.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry I could not find a public doc, so I just removed the link in the code. Two constants are added though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
per doc, Virtual machines started after August 2016 have access to a more reliable "product name" string which is equal to "Google Compute Engine".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Google Compute Engine" is for /sys/class/dmi/id/product_name, but for now we are checking /sys/class/dmi/id/bios_date and /sys/class/dmi/id/bios_vendor in the code. Do you think we also need to check /sys/class/dmi/id/product_name?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm just going by the doc you cited. I read it as saying one should use product name instead of bios id and vendor
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, yeah, thanks, product name is used now.
Codecov Report
@@ Coverage Diff @@
## master #1250 +/- ##
============================================
- Coverage 79.32% 78.98% -0.35%
Complexity 1226 1226
============================================
Files 209 209
Lines 5344 5357 +13
Branches 442 446 +4
============================================
- Hits 4239 4231 -8
- Misses 931 948 +17
- Partials 174 178 +4
Continue to review full report at Codecov.
|
resultOutStream.write(bs, 0, num); | ||
} | ||
String result = new String(resultOutStream.toByteArray()); | ||
return result.contains("01/01/2011") && result.contains("Google"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
per doc, Virtual machines started after August 2016 have access to a more reliable "product name" string which is equal to "Google Compute Engine".
Process process = Runtime.getRuntime().exec(new String[] {"/bin/sh", "-c", cmd}); | ||
process.waitFor(); | ||
String result = CharStreams.toString(new InputStreamReader(process.getInputStream())); | ||
return result.contains(GCE_BIOS_DATE) && result.contains(GCE_BIOS_VENDOR); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
per doc, "Virtual machines started after August 2016 have access to a more reliable "product name" string which is equal to "Google Compute Engine"."
try { | ||
Process process = Runtime.getRuntime().exec(new String[] {"/bin/sh", "-c", cmd}); | ||
process.waitFor(); | ||
String result = CharStreams.toString(new InputStreamReader(process.getInputStream())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs an explicit encoding, probably UTF-8
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
UTF-8 encoding added. Thanks!
@@ -234,6 +238,26 @@ private boolean isDirectPathEnabled(String serviceAddress) { | |||
return false; | |||
} | |||
|
|||
// DirectPath should only be used on Compute Engine. | |||
// Notice Windows is supported for now. | |||
public static boolean isOnComputeEngine() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this need to be public? If it's just for testing we can make it default visibility.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a good point. public has been removed. Thanks!
if ("Linux".equals(osName)) { | ||
String cmd = "cat /sys/class/dmi/id/product_name"; | ||
try { | ||
Process process = Runtime.getRuntime().exec(new String[] {"/bin/sh", "-c", cmd}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is going on here? Why is this forking a process, to call a shell to then run the cat command to read a file? That seems unnecessary on two levels. Why not use a FileInputStream
? Is there something I'm missing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey Eric, yes FileInputStream
can definitely work. Sorry I am not a java expert and I directly follow the doc to use a shall command. Do you want me to make the change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not a gax-java maintaner, so "I have no power here." But it seems like a good idea to fix it, as it reduces the chances of something going wrong and makes it easier to debug. For example, if there's permission problems the error will be more obvious.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I will have another PR for this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should fix this. Process/exec on "bin/sh" seems completely unnecessary
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please file an issue
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done #1323
String result = | ||
CharStreams.toString(new InputStreamReader(process.getInputStream(), "UTF-8")); | ||
return result.contains(GCE_PRODUCTION_NAME_PRIOR_2016) | ||
|| result.contains(GCE_PRODUCTION_NAME_AFTER_2016); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So couple of comments:
-
if the result contains something like Google App Engine then this will return true because GCE_PRODUCTION_NAME_PRIOR_2016 = "Google" even though this is App Engine and not GCE.
-
Secondly I did a test on a pod in GKE and
cat /sys/class/dmi/id/product_name
Google Compute Engine
So even on GKE it returns "Google Compute Engine" so it is quite possible even on GAE it returns the same string.
Add Compute Engine environment check since DirectPath can only be used on Compute Engine. This doc is used for checking: https://docs.google.com/document/d/1xQXE27x9wTvwPsgiX9Hn0o8mcq5z3SKi-1jwscQsCAk/edit#. Relevant issue and PR: grpc/grpc-java#7604 and googleapis/java-bigtable#520.