diff --git a/schemas/resultset-action-message.json b/schemas/resultset-action-message.json index 20b6004b9..277e97e58 100644 --- a/schemas/resultset-action-message.json +++ b/schemas/resultset-action-message.json @@ -2,7 +2,7 @@ "id": "https://treeherder.mozilla.org/schemas/v1/resultset-action-message.json#", "$schema": "http://json-schema.org/draft-04/schema#", "title": "Notification of triggering jobs in a resultset", - "description": "Event is dispatched when user/service issues a trigger_missing_jobs on a resultset", + "description": "Event is dispatched when user/service issues a (trigger_missing_jobs, trigger_all_talos_jobs) action on a resultset", "type": "object", "properties": { "version": { @@ -19,10 +19,15 @@ "description": "Project unique identifier for a resultset", "type": "string" }, + "times": { + "title": "Times", + "description": "Number of times to execute the command for a resultset.", + "type": "number" + }, "action": { "title": "Action", "description": "Type of action issued on task", - "enum": ["trigger_missing_jobs"], + "enum": ["trigger_missing_jobs", "trigger_all_talos_jobs"], "type": "string" }, "requester": { diff --git a/treeherder/model/derived/jobs.py b/treeherder/model/derived/jobs.py index 99a449bc6..15eb676ce 100644 --- a/treeherder/model/derived/jobs.py +++ b/treeherder/model/derived/jobs.py @@ -309,6 +309,12 @@ class JobsModel(TreeherderModelBase): routing_key='publish_to_pulse' ) + def trigger_all_talos_jobs(self, requester, resultset_id, project, times): + publish_resultset_action.apply_async( + args=[self.project, "trigger_all_talos_jobs", resultset_id, requester, times], + routing_key='publish_to_pulse' + ) + def _job_action_event(self, job, action, requester): """ Helper for issuing an 'action' for a given job (such as diff --git a/treeherder/model/tasks.py b/treeherder/model/tasks.py index 6766b841d..d73aa2f58 100644 --- a/treeherder/model/tasks.py +++ b/treeherder/model/tasks.py @@ -132,7 +132,7 @@ def publish_job_action(project, action, job_id, requester): @task(name='publish-resultset-action') -def publish_resultset_action(project, action, resultset_id, requester): +def publish_resultset_action(project, action, resultset_id, requester, times=1): publisher = pulse_connection.get_publisher() if not publisher: return @@ -142,7 +142,8 @@ def publish_resultset_action(project, action, resultset_id, requester): project=project, action=action, requester=requester, - resultset_id=resultset_id + resultset_id=resultset_id, + times=times ) diff --git a/treeherder/webapp/api/resultset.py b/treeherder/webapp/api/resultset.py index df161a549..ab6f42b26 100644 --- a/treeherder/webapp/api/resultset.py +++ b/treeherder/webapp/api/resultset.py @@ -6,6 +6,7 @@ from rest_framework import viewsets from rest_framework.response import Response from rest_framework.decorators import detail_route from rest_framework.reverse import reverse +from rest_framework.exceptions import ParseError from rest_framework.permissions import IsAuthenticated from treeherder.webapp.api.permissions import IsStaffOrReadOnly from treeherder.model.derived import DatasetNotFoundError @@ -150,6 +151,26 @@ class ResultSetViewSet(viewsets.ViewSet): except Exception as ex: return Response("Exception: {0}".format(ex), 404) + @detail_route(methods=['post'], permission_classes=[IsStaffOrReadOnly]) + @with_jobs + def trigger_all_talos_jobs(self, request, project, jm, pk=None): + """ + Trigger all the talos jobs in a resultset. + """ + if not pk: + return Response({"message": "resultset id required"}, status=400) + + times = int(request.QUERY_PARAMS.get('times', None)) + if not times: + raise ParseError(detail="The 'times' parameter is mandatory for this endpoint") + + try: + jm.trigger_all_talos_jobs(request.user.email, pk, project, times) + return Response({"message": "Talos jobs triggered for push '{0}'".format(pk)}) + + except Exception as ex: + return Response("Exception: {0}".format(ex), 404) + @with_jobs @oauth_required def create(self, request, project, jm): diff --git a/ui/js/controllers/jobs.js b/ui/js/controllers/jobs.js index 6f4c95bf2..5daea6b1c 100644 --- a/ui/js/controllers/jobs.js +++ b/ui/js/controllers/jobs.js @@ -199,6 +199,26 @@ treeherderApp.controller('ResultSetCtrl', [ }); }; + $scope.triggerAllTalosJobs = function(revision) { + if (!window.confirm('This will trigger all talos jobs for revision ' + revision + '!\n\nDo you want to proceed?')) { + return; + } + + var times = parseInt(window.prompt("Enter number of instances to have for each talos job", 6)); + while (times < 1 || times > 6 || isNaN(times)) { + times = window.prompt("We only allow instances of each talos job to be between 1 to 6 times. Enter again", 6); + } + + ThResultSetModel.triggerAllTalosJobs($scope.resultset.id, $scope.repoName, times).then(function() { + thNotify.send("Request sent to trigger all talos jobs " + times + " time(s)", "success"); + }, function(e) { + thNotify.send( + ThModelErrors.format(e, "The action 'trigger all talos jobs' failed"), + 'danger', true + ); + }); + }; + $scope.revisionResultsetFilterUrl = $scope.urlBasePath + "?repo=" + $scope.repoName + "&revision=" + $scope.resultset.revision; diff --git a/ui/js/models/resultset.js b/ui/js/models/resultset.js index 8d0e9c7f3..e8807dd2c 100644 --- a/ui/js/models/resultset.js +++ b/ui/js/models/resultset.js @@ -198,6 +198,11 @@ treeherder.factory( triggerMissingJobs: function(resultset_id, repoName) { var uri = resultset_id + '/trigger_missing_jobs/'; return $http.post(thUrl.getProjectUrl("/resultset/", repoName) + uri); + }, + + triggerAllTalosJobs: function(resultset_id, repoName, times) { + var uri = resultset_id + '/trigger_all_talos_jobs/?times=' + times; + return $http.post(thUrl.getProjectUrl("/resultset/", repoName) + uri); } }; }]); diff --git a/ui/partials/main/thActionButton.html b/ui/partials/main/thActionButton.html index 37e70bef8..e03128be7 100644 --- a/ui/partials/main/thActionButton.html +++ b/ui/partials/main/thActionButton.html @@ -17,6 +17,10 @@ href="" prevent-default-on-left-click ng-show="user.is_staff" ng-click="triggerMissingJobs(resultset.revision)">Trigger Missing Jobs +
  • Trigger All Talos Jobs
  • Revision URL List