blob: b1e8d5f9173bcb70ce067060bfff4731656fd688 [file] [log] [blame]
import apiclient
import httplib2
import oauth2client.client
import os
import pprint
# Location of the credentials file for the android build API,
# relative to the User's Home Directory.
HOMEDIR_JSON_CREDENTIALS_PATH = '.ab_credentials.json'
# Scope URL on which we need authorization.
DEFAULT_SCOPE_URL = 'https://www.googleapis.com/auth/androidbuild.internal'
# Default Service name and version to connect to.
DEFAULT_API_SERVICE_NAME = 'androidbuildinternal'
DEFAULT_API_VERSION = 'v2beta1'
def LoadCredentials(json_credentials_path=None, scope_url=None):
'''Load the credentials from a local file.
Returns a scoped credentials object which can be used to .authorize() a
httlib2.Http() instance used by an apiclient.
This method works with both service accounts (JSON generated from pantheon's
API manager under Credentials section), or with authenticated users (using a
scheme scimiliar to the one used by 'gcloud auth login'.)
Args:
json_credentials_path: Path to a JSON file with credentials for a service
account or for authenticated user. Defaults to looking for one using
FindCredentialsFile().
scope_url: URL in which the credentials should be scoped.
Returns:
A scoped oauth2client.client.Credentials object that can be used to
authorize an Http instance used by an apiclient object.
'''
if json_credentials_path is None:
user_homedir = os.path.expanduser('~')
if not user_homedir:
raise Exception('Could not locate user home directory.')
json_credentials_path = os.path.join(user_homedir, HOMEDIR_JSON_CREDENTIALS_PATH)
if not os.path.exists(json_credentials_path):
raise Exception('Could not find JSON credentials file at: %s' %
(json_credentials_path))
# This is the way to support both service account credentials (JSON generated
# from Pantheon) or authenticated users (similiar to 'gcloud auth login').
google_creds = oauth2client.client.GoogleCredentials.from_stream(
json_credentials_path)
if scope_url is None:
scope_url = DEFAULT_SCOPE_URL
# We need to rescope the credentials which are currently unscoped.
scoped_creds = google_creds.create_scoped(scope_url)
return scoped_creds
def getApiClient(creds, api_service_name=None, api_version=None):
'''Build an API client for androidbuild and authorize it.
Args:
creds: The scoped oauth2client.client.Credentials to use for authorization.
api_service_name: Optional override for the API service name.
api_version: Optional override for the API version.
Returns:
An apiclient.discovery.Resource that supports the androidbuild API methods.
'''
if api_service_name is None:
api_service_name = DEFAULT_API_SERVICE_NAME
if api_version is None:
api_version = DEFAULT_API_VERSION
base_http_client = httplib2.Http()
auth_http_client = creds.authorize(base_http_client)
ab_client = apiclient.discovery.build(api_service_name, api_version,
http=auth_http_client)
return ab_client
def generate_git_information(poller):
'''Return the proper git branch and target for the input.
Args:
poller: The poller that found the change (example: 'sys_image_mnc_poller').
Returns:
The git branch and git target for the passed in poller to query AB with.
'''
if 'emulator_linux_poller' in poller or 'emulator_windows_poller' in poller:
return 'aosp-emu-master-dev', 'sdk_tools_linux'
elif 'emulator_mac_poller' in poller:
return 'aosp-emu-master-dev', 'sdk_tools_mac'
elif 'sys_image_mnc_poller' in poller:
return 'git_mnc-emu-dev', 'sdk_google_phone_x86-sdk_addon'
elif 'sys_image_gb_poller' in poller:
return 'git_gb-emu-dev', 'sdk_x86-sdk'
elif 'sys_image_ics-mr1_poller' in poller:
return 'git_ics-mr1-emu-dev', 'sdk_x86-sdk'
elif 'sys_image_jb_poller' in poller:
return 'git_jb-emu-dev', 'sdk_x86-sdk'
elif 'sys_image_jb-mr1.1_poller' in poller:
return 'git_jb-mr1.1-emu-dev', 'sdk_x86-sdk'
elif 'sys_image_jb-mr2_poller' in poller:
return 'git_jb-mr2-emu-dev', 'sdk_x86-sdk'
elif 'sys_image_lmp_mr1_poller' in poller:
return 'git_lmp-mr1-emu-dev', 'sdk_google_phone_x86-sdk_addon'
elif 'sys_image_nyc_dev_poller' in poller:
return 'git_nyc-emu-dev', 'sdk_google_phone_x86-sdk_addon'
elif 'sys_image_nyc_mr1_dev_poller' in poller:
return 'git_nyc-mr1-emu-dev', 'sdk_google_phone_x86-sdk'
elif 'sys_image_klp_poller' in poller:
return 'git_klp-emu-dev', 'google_sdk_x86-sdk_addon'
elif 'sys_image_lmp_poller' in poller:
return 'git_lmp-emu-dev', 'sdk_google_phone_x86-sdk_addon'
elif 'sys_image_master_poller' in poller:
return 'git_master', 'sdk_gphone_x86-sdk_addon'
elif 'emulator_2.3_linux_poller' in poller or 'emulator_2.3_windows_poller' in poller:
return 'aosp-emu-2.3-release', 'sdk_tools_linux'
elif 'emulator_2.3_mac_poller' in poller:
return 'aosp-emu-2.3-release', 'sdk_tools_mac'
else:
raise NotImplementedError('The passed in poller: %s, does not have a '
'implementation.' % (poller))
def query_ab(poller, prevRevision, currRevision):
'''Entry function for master from gs_multi_poller.py to create changes.
Args:
poller: The poller (such as 'emulator_linux_poller') that initiated the change.
prevRevision: The previous revision (last built revision) for this poller.
currRevision: The current revision (that triggered poller) for this poller.
Returns:
A python list of all of the changes associated with this build (all changes
between the prevRevision (exclusive) and the currRevision (inclusive).
'''
git_branch, git_target = generate_git_information(poller)
creds = LoadCredentials()
ab_client = getApiClient(creds)
req = ab_client.build().list(branch=git_branch,
buildType='submitted',
target=git_target,
startBuildId=currRevision,
endBuildId=prevRevision,
extraFields='changeInfo')
resp = req.execute()
if 'builds' not in resp:
raise ValueError('Failed to retrieve data from AndroidBuild API')
changeSets = []
for build in resp['builds']:
for changes in build['changes']:
if 'changeNumber' not in changes: # We sometimes get merged changes with no actual number. Ignore them.
continue
changeSet = {}
changeSet['buildId'] = build['buildId']
changeSet['email'] = changes['revisions'][0]['commit']['author']['email']
changeSet['changeNumber'] = changes['changeNumber']
changeSet['subject'] = changes['revisions'][0]['commit']['subject']
changeSet['branch'] = changes['branch']
changeSets.append(changeSet)
return changeSets
if __name__ == '__main__':
creds = LoadCredentials()
ab_client = getApiClient(creds)
req = ab_client.build().list(branch='aosp-emu-master-dev',
buildType='submitted',
target='sdk_tools_linux',
startBuildId=3578761,
endBuildId=3566000,
extraFields='changeInfo')
resp = req.execute()
pprint.pprint(resp)