isolate_android_sdk: Find or download isolate binary, fix infra path

BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2016353003

Review-Url: https://codereview.chromium.org/2016353003
diff --git a/.gitignore b/.gitignore
index 34f6f27..9fb5a30d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,6 +15,9 @@
 bower_components
 common
 gyp/build
+infra/bots/tools/luci-go/linux64/isolate
+infra/bots/tools/luci-go/mac64/isolate
+infra/bots/tools/luci-go/win64/isolate.exe
 out
 platform_tools/android/apps/build
 platform_tools/android/apps/*.properties
diff --git a/infra/bots/isolate_android_sdk.py b/infra/bots/isolate_android_sdk.py
index 456670b..1cb0acc 100644
--- a/infra/bots/isolate_android_sdk.py
+++ b/infra/bots/isolate_android_sdk.py
@@ -18,15 +18,68 @@
 import utils
 
 
+INFRA_BOTS_DIR = os.path.realpath(os.path.dirname(os.path.abspath(__file__)))
 ISOLATE_FILE_NAME = 'android_sdk.isolate'
 REPO_SKIA = 'https://skia.googlesource.com/skia.git'
 SDK_DIR_NAME = 'android-sdk'
 
 
+def get_isolate_binary():
+  """Find or, if necessary, obtain the isolate binary."""
+  # Try to find isolate locally.
+  platform = 'linux64'
+  if sys.platform == 'win32':
+    platform = 'win64'
+  elif sys.platform == 'darwin':
+    platform = 'mac64'
+  repo_isolate = os.path.join(INFRA_BOTS_DIR,
+                              'tools', 'luci-go', platform)
+  path = os.pathsep.join((repo_isolate, os.environ['PATH']))
+  try:
+    output = subprocess.check_output(
+        ['which', 'isolate'],
+        env={'PATH':path}).rstrip()
+    print 'Found isolate binary: %s' % output
+    return output
+  except subprocess.CalledProcessError:
+    pass
+
+  # Download isolate from GS.
+  print 'Unable to find isolate binary; attempting to download...'
+  try:
+    subprocess.check_call(
+        ['download_from_google_storage',
+         '--bucket', 'chromium-luci',
+         '-d', repo_isolate])
+  except OSError as e:
+    raise Exception('Failed to download isolate binary. '
+                    'Is depot_tools in PATH?  Error: %s' % e)
+  except subprocess.CalledProcessError as e:
+    raise Exception('Failed to download isolate binary. '
+                    'Are you authenticated to Google Storage?  Error: %s' % e)
+
+  output = subprocess.check_output(
+      ['which', 'isolate'],
+      env={'PATH':path}).rstrip()
+  return output
+
+
+def check_isolate_auth(isolate):
+  """Ensure that we're authenticated to the isolate server."""
+  not_logged_in = 'Not logged in'
+  try:
+    output = subprocess.check_output([isolate, 'whoami'])
+    
+  except subprocess.CalledProcessError:
+    output = not_logged_in
+  if output == not_logged_in:
+    raise Exception('Not authenticated to isolate server. You probably need to '
+                    'run:\n$ %s login' % isolate)
+
+
 def isolate_android_sdk(android_sdk_root):
   """Isolate the Android SDK and return the isolated hash."""
-  repo_isolate_file = os.path.join(os.path.dirname(os.path.realpath(__file__)),
-                                   ISOLATE_FILE_NAME)
+  repo_isolate_file = os.path.join(INFRA_BOTS_DIR, ISOLATE_FILE_NAME)
   with utils.tmp_dir():
     # Copy the SDK dir contents into a directory with a known name.
     sdk_dir = os.path.join(os.getcwd(), SDK_DIR_NAME)
@@ -35,7 +88,8 @@
     shutil.copyfile(repo_isolate_file, isolate_file)
 
     # Isolate the SDK.
-    isolate = 'isolate'  # TODO(borenet): Don't assume this is in PATH.
+    isolate = get_isolate_binary()
+    check_isolate_auth(isolate)
     android_sdk_relpath = os.path.relpath(
         sdk_dir, os.path.dirname(isolate_file))
     isolate_cmd = [isolate, 'archive', '--quiet',
@@ -47,7 +101,6 @@
     return shlex.split(isolate_out)[0]
 
 
-
 def update_sdk_file(skia_path, isolated_hash):
   """Edit the android_sdk_hash file, upload a CL."""
   with utils.chdir(skia_path):
@@ -64,8 +117,8 @@
   parser = argparse.ArgumentParser()
   parser.add_argument('--android_sdk_root', required=True)
   args = parser.parse_args()
-  skia_path = os.path.join(os.path.dirname(os.path.realpath(__file__)),
-                           os.pardir, os.pardir)
+  skia_path = os.path.abspath(os.path.join(INFRA_BOTS_DIR,
+                                           os.pardir, os.pardir))
 
   with utils.print_timings():
     isolated_hash = isolate_android_sdk(args.android_sdk_root)