1# Copyright 2015 The Chromium Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5"""Encapsulates a simplistic interface to the buildbucket service.""" 6 7import json 8 9from apiclient import discovery 10import httplib2 11 12from dashboard import utils 13 14_DISCOVERY_URL = ( 15 'https://cr-buildbucket.appspot.com' 16 '/_ah/api/discovery/v1/apis/{api}/{apiVersion}/rest') 17 18# Default Buildbucket bucket name. 19_BUCKET_NAME = 'master.tryserver.chromium.perf' 20 21 22def _DiscoverService(): 23 return discovery.build('buildbucket', 'v1', 24 discoveryServiceUrl=_DISCOVERY_URL) 25 26 27class _AuthenticatedHttp(object): 28 """Provides access via its constructor to a singleton authenticated http.""" 29 30 _singleton = None 31 _singleton_credentials = None 32 33 def __new__(cls, credentials): 34 if credentials and credentials != cls._singleton_credentials: 35 cls._singleton_credentials = credentials 36 cls._MakeSingleton(credentials) 37 if not cls._singleton: 38 cls._MakeSingleton() 39 assert cls._singleton 40 return cls._singleton 41 42 @classmethod 43 def _MakeSingleton(cls, override_credentials=None): 44 """Instantiates the singleton.""" 45 # Uses rietveld credentials to authorize an http client. Note this same 46 # account is authorized for buildbucket. 47 cls._singleton = httplib2.Http() 48 if override_credentials: 49 credentials = override_credentials 50 else: 51 credentials = utils.ServiceAccountCredentials() 52 53 # If we cannot pull the credentials from ndb we simply use the unauthorized 54 # client. This useful when running a local dev server. 55 if credentials: 56 credentials.authorize(cls._singleton) 57 58 59def PutJob(job, bucket=_BUCKET_NAME, credentials=None): 60 """Creates a job via buildbucket's API.""" 61 parameters = job.GetBuildParameters() 62 service = _DiscoverService() 63 request = service.put( 64 body={ 65 'bucket': bucket, 66 'parameters_json': json.dumps(parameters), 67 }) 68 response_content = request.execute(http=_AuthenticatedHttp(credentials)) 69 job.response_fields = response_content.get('build') 70 return job.response_fields.get('id') 71 72 73def GetJobStatus(job_id, credentials=None): 74 """Gets the details of a job via buildbucket's API.""" 75 service = _DiscoverService() 76 request = service.get(id=job_id) 77 response_content = request.execute(http=_AuthenticatedHttp(credentials)) 78 return response_content 79 80# TODO(robertocn): Implement CancelJobByID 81