Bug 1593820 - [try] Create a ./mach try --pernosco flag to opt-in to the Pernosco debugging service, r=jmaher
authorAndrew Halberstadt <ahalberstadt@mozilla.com>
Wed, 13 Nov 2019 14:23:55 +0000
changeset 501743 be6ff7053ebe1e620a8a57af13bb6b6c11aab4a0
parent 501742 e333a13aa5f6f658c334e4553664b8df4adb5b7a
child 501744 70738ac7ba9b76a586cedc22ca11e02ebf659f16
push id114172
push userdluca@mozilla.com
push dateTue, 19 Nov 2019 11:31:10 +0000
treeherdermozilla-inbound@b5c5ba07d3db [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjmaher
bugs1593820
milestone72.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1593820 - [try] Create a ./mach try --pernosco flag to opt-in to the Pernosco debugging service, r=jmaher This gives developers the ability to request analysis from the Pernosco service. When this flag is set, Pernosco will examine the push for relevant failures, analyze them and then send a link to the generated report. Previously developers needed to request access to a whitelist whereupon all their try pushes were analyzed. Developers currently on this whitelist who would like to opt-out can run |mach try --no-persnosco| to do so. Differential Revision: https://phabricator.services.mozilla.com/D52419
tools/tryselect/selectors/chooser/__init__.py
tools/tryselect/selectors/fuzzy.py
tools/tryselect/templates.py
--- a/tools/tryselect/selectors/chooser/__init__.py
+++ b/tools/tryselect/selectors/chooser/__init__.py
@@ -22,16 +22,17 @@ class ChooserParser(BaseTryParser):
     templates = [
         'artifact',
         'browsertime',
         'chemspill-prio',
         'disable-pgo',
         'env',
         'gecko-profile',
         'path',
+        'pernosco',
         'rebuild',
         'visual-metrics-jobs',
     ]
 
 
 def run(update=False, query=None, try_config=None, full=False, parameters=None,
         save=False, preset=None, mod_presets=False, push=True, message='{msg}',
         closed_tree=False):
--- a/tools/tryselect/selectors/fuzzy.py
+++ b/tools/tryselect/selectors/fuzzy.py
@@ -244,16 +244,17 @@ class FuzzyParser(BaseTryParser):
         'artifact',
         'browsertime',
         'chemspill-prio',
         'debian-buster',
         'disable-pgo',
         'env',
         'gecko-profile',
         'path',
+        'pernosco',
         'rebuild',
         'visual-metrics-jobs',
     ]
 
 
 def run_cmd(cmd, cwd=None):
     is_win = platform.system() == 'Windows'
     return subprocess.call(cmd, cwd=cwd, shell=True if is_win else False)
--- a/tools/tryselect/templates.py
+++ b/tools/tryselect/templates.py
@@ -6,16 +6,17 @@
 Templates provide a way of modifying the task definition of selected
 tasks. They live under taskcluster/taskgraph/templates.
 """
 
 from __future__ import absolute_import, print_function, unicode_literals
 
 import json
 import os
+import subprocess
 import sys
 from abc import ABCMeta, abstractmethod, abstractproperty
 from argparse import Action, SUPPRESS
 from textwrap import dedent
 
 import mozpack.path as mozpath
 import voluptuous
 from taskgraph.decision import visual_metrics_jobs_schema
@@ -88,16 +89,73 @@ class Artifact(Template):
                 print("Artifact builds enabled, pass --no-artifact to disable")
                 return {
                     'artifact': {'enabled': '1'}
                 }
         except BuildEnvironmentNotFoundException:
             pass
 
 
+class Pernosco(Template):
+    arguments = [
+        [['--pernosco'],
+         {'action': 'store_true',
+          'default': None,
+          'help': 'Opt-in to analysis by the Pernosco debugging service.',
+          }],
+        [['--no-pernosco'],
+         {'dest': 'pernosco',
+          'action': 'store_false',
+          'default': None,
+          'help': 'Opt-out of the Pernosco debugging service (if you are on the whitelist).',
+          }],
+    ]
+
+    def add_arguments(self, parser):
+        group = parser.add_mutually_exclusive_group()
+        return super(Pernosco, self).add_arguments(group)
+
+    def context(self, pernosco, **kwargs):
+        if pernosco is None:
+            return
+
+        # The Pernosco service currently requires a Mozilla e-mail address to
+        # log in. Prevent people with non-Mozilla addresses from using this
+        # flag so they don't end up consuming time and resources only to
+        # realize they can't actually log in and see the reports.
+        if pernosco:
+            try:
+                output = subprocess.check_output(['ssh', '-G', 'hg.mozilla.org']).splitlines()
+                address = [l.rsplit(' ', 1)[-1] for l in output if l.startswith('user')][0]
+                if not address.endswith('@mozilla.com'):
+                    print(dedent("""\
+                        Pernosco requires a Mozilla e-mail address to view its reports. Please
+                        push to try with an @mozilla.com address to use --pernosco.
+
+                            Current user: {}
+                    """.format(address)))
+                    sys.exit(1)
+
+            except (subprocess.CalledProcessError, IndexError):
+                print("warning: failed to detect current user for 'hg.mozilla.org'")
+                print("Pernosco requires a Mozilla e-mail address to view its reports.")
+                while True:
+                    answer = raw_input("Do you have an @mozilla.com address? [Y/n]: ").lower()
+                    if answer == 'n':
+                        sys.exit(1)
+                    elif answer == 'y':
+                        break
+
+        return {
+            'env': {
+                'PERNOSCO': str(int(pernosco)),
+            }
+        }
+
+
 class Path(Template):
 
     arguments = [
         [['paths'],
          {'nargs': '*',
           'default': [],
           'help': 'Run tasks containing tests under the specified path(s).',
           }],
@@ -330,12 +388,13 @@ class DebianTests(TryConfig):
 all_templates = {
     'artifact': Artifact,
     'browsertime': Browsertime,
     'chemspill-prio': ChemspillPrio,
     'disable-pgo': DisablePgo,
     'env': Environment,
     'gecko-profile': GeckoProfile,
     'path': Path,
+    'pernosco': Pernosco,
     'rebuild': Rebuild,
     'debian-buster': DebianTests,
     'visual-metrics-jobs': VisualMetricsJobs,
 }