18cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet#!/usr/bin/env python 28cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet 38cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet 48cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet""" Trigger a Cluster Telemetry job with the given Lua script. """ 58cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet 68cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet 78cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenetimport argparse 88cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenetimport base64 98cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenetimport getpass 108cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenetimport httplib2 118cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenetimport json 128cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenetimport subprocess 138cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenetimport urllib 148cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet 158cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet 168cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenetCT_URL = 'https://skia-tree-status.appspot.com/skia-telemetry/' 178cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenetCT_ADD_LUA_TASK_URL = CT_URL + 'add_lua_task' 188cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenetCT_GET_SKP_REPOS_URL = CT_URL + 'get_skp_repos' 198cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenetCT_PENDING_TASKS_URL = CT_URL + 'pending_tasks' 208cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenetPOST_DATA = ('username=%s' 218cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet '&password=%s' 228cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet '&description=%s' 238cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet '&lua_script=%s' 248cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet '&pagesets_type_and_chromium_build=%s') 258cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet 268cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet 278cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenetdef trigger_ct_run(user, password, description, script, skp_repo, 288cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet aggregator=None): 298cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet """Trigger a Cluster Telemetry run of the given script.""" 308cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet with open(script) as f: 318cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet script_contents = urllib.quote(base64.b64encode(f.read())) 328cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet 338cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet body = POST_DATA % (user, password, description, script_contents, skp_repo) 348cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet 358cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet if aggregator: 368cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet with open(aggregator) as f: 378cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet body += '&lua_aggregator=%s' % urllib.quote(base64.b64encode(f.read())) 388cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet 398cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet resp, content = httplib2.Http().request( 408cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet CT_ADD_LUA_TASK_URL, 'POST', body=body) 418cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet if resp['status'] != '200': 428cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet raise Exception( 438cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet 'Failed to trigger Cluster Telemetry job: (%s): %s' % ( 448cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet resp['status'], content)) 458cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet 468cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet 478cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenetdef parse_args(): 488cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet """Parse command-line flags and obtain any additional information.""" 498cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet parser = argparse.ArgumentParser( 508cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet description='Trigger a Cluster Telemetry job with the given Lua script.') 518cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet parser.add_argument('--script', help='Lua script to run', required=True) 528cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet parser.add_argument('--aggregator', help='Aggregator script') 538cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet parser.add_argument('--description', help='Description of the job.') 548cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet parser.add_argument('--email', 558cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet help=('Email address to send results. If not specified, ' 568cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet 'the value of `git config user.email` is used.')) 578cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet parser.add_argument('--password_file', 588cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet help=('File in which the CT password is stored. Will ' 598cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet 'prompt for password if not specified.')) 608cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet parser.add_argument('--skp_repo', default='10k', 618cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet help='Which set of SKPs to use, eg. "10k", "All"') 628cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet args = parser.parse_args() 638cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet 648cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet # If the user provided their email address, use that. Otherwise obtain it 658cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet # from the Git config. 668cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet user = args.email 678cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet if not user: 688cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet user = subprocess.check_output(['git', 'config', 'user.email']).rstrip() 698cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet 708cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet # Read the password from the password file, if provided, otherwise prompt. 718cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet if args.password_file: 728cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet with open(args.password_file) as f: 738cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet password = f.read().rstrip() 748cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet else: 758cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet password = getpass.getpass( 768cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet 'Enter the skia_status_password ' 778cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet '(on https://valentine.corp.google.com/): ') 788cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet 798cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet # Find an SKP repo to use. 808cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet resp, content = httplib2.Http().request(CT_GET_SKP_REPOS_URL, "GET") 818cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet if resp['status'] != '200': 828cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet raise Exception('Failed to obtain SKP repos from %s' % CT_GET_SKP_REPOS_URL) 838cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet skp_repos = json.loads(content) 848cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet chosen_skp_repo = skp_repos.get(args.skp_repo)[0] 858cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet if not chosen_skp_repo: 868cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet raise Exception('No generated SKPs exist for "%s"' % args.skp_repo) 878cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet skp_repo = '-'.join((args.skp_repo, 888cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet chosen_skp_repo[0], 898cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet chosen_skp_repo[1])) 908cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet 918cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet return (user, password, args.description, args.script, skp_repo, 928cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet args.aggregator) 938cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet 948cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet 958cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenetdef main(): 968cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet user, password, description, script, skp_repo, aggregator = parse_args() 978cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet trigger_ct_run(user, password, description, script, skp_repo, aggregator) 988cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet print ('Successfully triggered Cluster Telemetry job. View the queue at %s' % 998cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet CT_PENDING_TASKS_URL) 1008cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet 1018cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet 1028cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenetif __name__ == '__main__': 1038cd8f9429a8a7d5c09c48f7cc9ab34073e01d945borenet main() 104