Bug 1470621 - actionPerm is the cb_name, not name; r?tomprince draft
authorDustin J. Mitchell <dustin@mozilla.com>
Thu, 28 Jun 2018 17:34:50 +0000
changeset 812175 794647d9847acfa3959cc286ed81fd43294c4fac
parent 812151 abf6d7c53e5ac6fc84e82f6926e0d8a3e6ce6540
push id114474
push userdmitchell@mozilla.com
push dateThu, 28 Jun 2018 17:55:07 +0000
Bug 1470621 - actionPerm is the cb_name, not name; r?tomprince The actionPerm is for access control, so it must limit access to a specific callback function, not a name (which can apply to mulitple functions). To make things nicer, we allow functions to specify their cb_name, rather than assuming it matches the Python function name. MozReview-Commit-ID: 2oiuXrrw7DE
--- a/taskcluster/taskgraph/actions/cancel_all.py
+++ b/taskcluster/taskgraph/actions/cancel_all.py
@@ -36,16 +36,17 @@ def list_group(task_group_id, session):
     title='Cancel All',
+    cb_name='cancel-all',
         'Cancel all running and pending tasks created by the decision task '
         'this action task is associated with.'
--- a/taskcluster/taskgraph/actions/purge_caches.py
+++ b/taskcluster/taskgraph/actions/purge_caches.py
@@ -14,16 +14,17 @@ from .registry import register_callback_
 logger = logging.getLogger(__name__)
     title='Purge Caches',
+    cb_name='purge-caches',
         'Purge any caches associated with this task '
         'across all workers of the same workertype as the task.'
     context=[{'worker-implementation': 'docker-worker'}]
--- a/taskcluster/taskgraph/actions/registry.py
+++ b/taskcluster/taskgraph/actions/registry.py
@@ -47,17 +47,17 @@ def hash_taskcluster_yml(filename):
     of the sha256 of the file's content, and is used by administrative scripts
     to create a hook based on this content.
     return hash.hash_path(filename)[:10]
 def register_callback_action(name, title, symbol, description, order=10000,
                              context=[], available=lambda parameters: True,
-                             schema=None, kind='task', generic=True):
+                             schema=None, kind='task', generic=True, cb_name=None):
     Register an action callback that can be triggered from supporting
     user interfaces, such as Treeherder.
     This function is to be used as a decorator for a callback that takes
     parameters as follows:
@@ -105,48 +105,55 @@ def register_callback_action(name, title
     schema : dict
         JSON schema specifying input accepted by the action.
         This is optional and can be left ``null`` if no input is taken.
     kind : string
         The action kind to define - must be one of `task` or `hook`.  Only for
         transitional purposes.
     generic : boolean
         For kind=hook, whether this is a generic action or has its own permissions.
+    cb_name : string
+        The name under which this function should be registered, defaulting to the
+        function name. This is used to generation actionPerm for non-generic hook
+        actions, and thus appears in ci-configuration and various role and hook names.
+        This must be unique among all registered callbacks.
         To be used as decorator for the callback function.
     mem = {"registered": False}  # workaround nonlocal missing in 2.x
     assert isinstance(title, basestring), 'title must be a string'
     assert isinstance(description, basestring), 'description must be a string'
     title = title.strip()
     description = description.strip()
-    def register_callback(cb):
+    def register_callback(cb, cb_name=cb_name):
         assert isinstance(name, basestring), 'name must be a string'
         assert isinstance(order, int), 'order must be an integer'
         assert kind in ('task', 'hook'), 'kind must be task or hook'
         assert callable(schema) or is_json(schema), 'schema must be a JSON compatible object'
         assert isinstance(cb, FunctionType), 'callback must be a function'
         # Allow for json-e > 25 chars in the symbol.
         if '$' not in symbol:
             assert 1 <= len(symbol) <= 25, 'symbol must be between 1 and 25 characters'
         assert isinstance(symbol, basestring), 'symbol must be a string'
         assert not mem['registered'], 'register_callback_action must be used as decorator'
-        assert cb.__name__ not in callbacks, 'callback name {} is not unique'.format(cb.__name__)
+        if not cb_name:
+            cb_name = cb.__name__
+        assert cb_name not in callbacks, 'callback name {} is not unique'.format(cb_name)
         def action_builder(parameters, graph_config):
             if not available(parameters):
                 return None
-            actionPerm = 'generic' if generic else name
+            actionPerm = 'generic' if generic else cb_name
             # gather up the common decision-task-supplied data for this action
             repo_param = '{}head_repository'.format(graph_config['project-repo-param-prefix'])
             repository = {
                 'url': parameters[repo_param],
                 'project': parameters['project'],
                 'level': parameters['level'],
@@ -162,17 +169,17 @@ def register_callback_action(name, title
             match = re.match(r'https://(hg.mozilla.org)/(.*?)/?$', parameters[repo_param])
             if not match:
                 raise Exception('Unrecognized {}'.format(repo_param))
             action = {
                 'name': name,
                 'title': title,
                 'description': description,
                 'taskGroupId': task_group_id,
-                'cb_name': cb.__name__,
+                'cb_name': cb_name,
                 'symbol': symbol,
             rv = {
                 'name': name,
                 'title': title,
                 'description': description,
                 'context': context,
@@ -247,17 +254,17 @@ def register_callback_action(name, title
             return rv
         actions.append(Action(order, action_builder))
         mem['registered'] = True
-        callbacks[cb.__name__] = cb
+        callbacks[cb_name] = cb
     return register_callback
 def render_actions_json(parameters, graph_config):
     Render JSON object for the ``public/actions.json`` artifact.