def schedule_graph(task_graph, task_graph_id=None, dry_run=False): """ It schedules a TaskCluster graph and returns its id. :param task_graph: It is a TaskCluster graph as defined in here: http://docs.taskcluster.net/scheduler/api-docs/#createTaskGraph :type task_graph: json :param task_graph_id: TC graph id to which this task belongs to :type task_graph_id: str :param dry_run: It does not schedule the graph :type dry_run: bool :returns: task graph id. :rtype: int """ if not task_graph_id: task_graph_id = taskcluster_client.slugId() scheduler = taskcluster_client.Scheduler() LOG.info("Outputting the graph:") # We print to stdout instead of using the standard logging with dates and info levels # XXX: Use a different formatter for other tools to work better with this code print(json.dumps(task_graph, indent=4)) if dry_run: LOG.info("DRY-RUN: We have not scheduled the graph.") else: if not credentials_available(): return None try: result = scheduler.createTaskGraph(task_graph_id, task_graph) LOG.info("See the graph in %s%s" % (TC_TASK_GRAPH_INSPECTOR, task_graph_id)) return result except taskcluster_client.exceptions.TaskclusterAuthFailure as e: handle_auth_failure(e)
def __init__(self, options): cert = options["credentials"].get("certificate") if cert and not isinstance(cert, basestring): options["credentials"]["certificate"] = json.dumps(cert) self.queue = taskcluster.Queue(options) self.scheduler = taskcluster.Scheduler(options) log.debug("Dict of options: %s", options)
def main(): parser = argparse.ArgumentParser( description='Scrape and upload OS X system symbols') parser.add_argument('taskcluster_auth', help='Path to a file containing Taskcluster client' + ' ID and authentication token as a JSON file in the' + ' form {"clientId": "...", "accessToken": "..."}') args = parser.parse_args() tc_auth = read_tc_auth(args.taskcluster_auth) scheduler = taskcluster.Scheduler({'credentials': tc_auth}) graph_id = spawn_task_graph(scheduler) u = 'https://tools.taskcluster.net/task-graph-inspector/#{0}/'.format( graph_id) print(u)
def extend_task_graph(task_graph_id, task_graph, dry_run=False): """ From: http://docs.taskcluster.net/scheduler/api-docs/#extendTaskGraph Safety, it is only safe to call this API end-point while the task-graph being modified is still running. If the task-graph is finished or blocked, this method will leave the task-graph in this state. Hence, it is only truly safe to call this API end-point from within a task in the task-graph being modified. returns Task-Graph Status Response """ # XXX: handle the case when the task-graph is not running scheduler = taskcluster_client.Scheduler() if dry_run: LOG.info("DRY-RUN: We have not extended the graph.") else: LOG.debug("When extending a graph we don't need metadata and scopes.") del task_graph['metadata'] del task_graph['scopes'] print(json.dumps(task_graph, indent=4)) return scheduler.extendTaskGraph(task_graph_id, task_graph)
# reserved JWT claims, to be verified # Issued At iat = int(time.time()) # Expiration Time exp = iat + valid_for claims = { "iat": iat, "exp": exp, "taskId": task_id, "version": "1", } return jws.sign(claims, pvt_key, algorithm=algorithm) config = json.load(open("secrets.json")) config["credentials"]["certificate"] = json.dumps(config["credentials"]["certificate"]) scheduler = taskcluster.Scheduler(config) # funsize scheduler key pvt_key = open("id_rsa").read() template_vars = { "stableSlugId": stableSlugId(), "now": stringDate(datetime.datetime.utcnow()), "now_ms": time.time() * 1000, "fromNow": fromNow, "sign_task": partial(sign_task, pvt_key=pvt_key), ### TODO: change these "url": "http://people.mozilla.org/~raliiev/bouncer.apk", "filename": "bouncer.apk", "signign_format": "jar", "hash": "8f4210c62cf533322b09237a3741bc3e9bb52582b8d0b88c52a0d78a6eabe08e29b636d5c9668e8db721c9dead36736db643c53231e966c86dbc28d86b9eb699", }
def get_task_graph_status(task_graph_id): """ Returns state of a Task-Graph Status Response """ scheduler = taskcluster_client.Scheduler() response = scheduler.status(task_graph_id) return response['status']['state']
# -*- coding: utf-8 -*- import logging import taskcluster log = logging.getLogger(__name__) TC_QUEUE = taskcluster.Queue() TC_SCHEDULER = taskcluster.Scheduler() TASK_GRAPH_STATE_TO_STEP_STATE = { 'running': 'running', 'blocked': 'failed', 'finished': 'completed' } def get_taskcluster_tasks_state(task_group_id, scheduler_api=False): # TODO rather than poll taskcluster queue and scheduler for state # we should use pulse and listen in for status changes if scheduler_api: return get_scheduler_graph_state(task_graph_id=task_group_id) return get_queue_group_state(task_group_id) def get_scheduler_graph_state(task_graph_id): '''poll the scheduler for overall status. this request is relatively cheap. :returns state where state is of: running, blocked or finished''' try: return TASK_GRAPH_STATE_TO_STEP_STATE[TC_SCHEDULER.status(