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