1 # 2 # Copyright (C) 2017 The Android Open Source Project 3 # 4 # Licensed under the Apache License, Version 2.0 (the "License"); 5 # you may not use this file except in compliance with the License. 6 # You may obtain a copy of the License at 7 # 8 # http://www.apache.org/licenses/LICENSE-2.0 9 # 10 # Unless required by applicable law or agreed to in writing, software 11 # distributed under the License is distributed on an "AS IS" BASIS, 12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 # See the License for the specific language governing permissions and 14 # limitations under the License. 15 # 16 17 import logging 18 import os 19 import re 20 import zipfile 21 22 from host_controller.build import build_provider 23 from vts.utils.python.common import cmd_utils 24 25 _GCLOUD_AUTH_ENV_KEY = "run_gcs_key" 26 27 28 class BuildProviderGCS(build_provider.BuildProvider): 29 """A build provider for GCS (Google Cloud Storage).""" 30 31 def __init__(self): 32 super(BuildProviderGCS, self).__init__() 33 if _GCLOUD_AUTH_ENV_KEY in os.environ: 34 gcloud_path = BuildProviderGCS.GetGcloudPath() 35 if gcloud_path is not None: 36 auth_cmd = "%s auth activate-service-account --key-file=%s" % ( 37 gcloud_path, os.environ[_GCLOUD_AUTH_ENV_KEY]) 38 _, stderr, ret_code = cmd_utils.ExecuteOneShellCommand( 39 auth_cmd) 40 if ret_code == 0: 41 logging.info(stderr) 42 else: 43 print(stderr) 44 logging.error(stderr) 45 46 @staticmethod 47 def GetGcloudPath(): 48 """Returns the gcloud file path if found; None otherwise.""" 49 sh_stdout, _, ret_code = cmd_utils.ExecuteOneShellCommand( 50 "which gcloud") 51 if ret_code == 0: 52 return sh_stdout.strip() 53 else: 54 logging.error("`gcloud` doesn't exist on the host; " 55 "please install Google Cloud SDK before retrying.") 56 return None 57 58 @staticmethod 59 def GetGsutilPath(): 60 """Returns the gsutil file path if found; None otherwise.""" 61 sh_stdout, sh_stderr, ret_code = cmd_utils.ExecuteOneShellCommand( 62 "which gsutil") 63 if ret_code == 0: 64 return sh_stdout.strip() 65 else: 66 logging.fatal("`gsutil` doesn't exist on the host; " 67 "please install Google Cloud SDK before retrying.") 68 return None 69 70 @staticmethod 71 def IsGcsFile(gsutil_path, gs_path): 72 """Checks whether a given path is for a GCS file. 73 74 Args: 75 gsutil_path: string, the path of a gsutil binary. 76 gs_path: string, the GCS file path (e.g., gs://<bucket>/<file>. 77 78 Returns: 79 True if gs_path is a file, False otherwise. 80 """ 81 check_command = "%s stat %s" % (gsutil_path, gs_path) 82 _, _, ret_code = cmd_utils.ExecuteOneShellCommand(check_command) 83 return ret_code == 0 84 85 def Fetch(self, path): 86 """Fetches Android device artifact file(s) from GCS. 87 88 Args: 89 path: string, the path of a directory which keeps artifacts. 90 91 Returns: 92 a dict containing the device image info. 93 a dict containing the test suite package info. 94 a dict containing the info about custom tool files. 95 """ 96 if not path.startswith("gs://"): 97 path = "gs://" + re.sub("^/*", "", path) 98 path = re.sub("/*$", "", path) 99 # make sure gsutil is available. Instead of a Python library, 100 # gsutil binary is used that is to avoid packaging GCS PIP package 101 # as part of VTS HC (Host Controller). 102 gsutil_path = BuildProviderGCS.GetGsutilPath() 103 if gsutil_path: 104 temp_dir_path = self.CreateNewTmpDir() 105 # IsGcsFile returns False if path is directory or doesn't exist. 106 # cp command returns non-zero if path doesn't exist. 107 if not BuildProviderGCS.IsGcsFile(gsutil_path, path): 108 dest_path = temp_dir_path 109 copy_command = "%s cp -r %s/* %s" % (gsutil_path, path, 110 temp_dir_path) 111 else: 112 dest_path = os.path.join(temp_dir_path, os.path.basename(path)) 113 copy_command = "%s cp %s %s" % (gsutil_path, path, 114 temp_dir_path) 115 116 _, _, ret_code = cmd_utils.ExecuteOneShellCommand(copy_command) 117 if ret_code == 0: 118 self.SetFetchedFile(dest_path, temp_dir_path) 119 else: 120 logging.error("Error in copy file from GCS (code %s)." % 121 ret_code) 122 return (self.GetDeviceImage(), 123 self.GetTestSuitePackage(), 124 self.GetAdditionalFile()) 125