TaskCluster Client 
A taskcluster client library for node.js.
This client library is generated from the auto-generated API reference.
You can create a Client class from a JSON reference object at runtime using
taskcluster.createClient(reference)
. But there is also a set of builtin
references from which Client classes are already constructed.
Calling API End-Points
To invoke an API end-point instantiate a taskcluster Client class, these are
classes can be created from a JSON reference object, but a number of them are
also built-in to this library. In the following example we instantiate an
instance of the Queue
Client class and use to to create a task.
var taskcluster = require('taskcluster-client');
var queue = new taskcluster.Queue({
credentials: {
clientId: '...',
accessToken: '...'
}
});
var taskId = '...';
queue.createTask(taskId, task).then(function(result) {
console.log(result.status);
});
The payload
parameter is always a JSON object as documented by the REST API
documentation. The methods always returns a promise for the response JSON
object as documented in the REST API documentation.
Listening for Events
Many TaskCluster components publishes messages about current events over AMQP.
The JSON reference object also contains meta-data about declared AMQP topic
exchanges and their routing key construction. This is designed to make it easy
to construct routing key patterns and parse routing keys from incoming messages.
The following example create a listener
and instantiate an instance of
the Client class QueueEvents
which we use to find the exchange and create
a routing pattern to listen for completion of a specific task. The
taskCompleted
method will construct a routing key pattern by using *
or #
for missing entries, pending on whether or not they are single word or
multi-key entries.
var taskcluster = require('taskcluster-client');
var listener = new taskcluster.Listener({
connectionString: 'amqp://...'
});
var queueEvents = new taskcluster.QueueEvents();
listener.bind(queueEvents.taskCompleted({taskId: '<myTaskId>'}));
listener.on('message', function(message) {
message.exchange
message.payload
message.routingKey
message.routing.taskId
message.routing.runId
message.redelivered
message.routes
return new Promise(...);
});
listener.resume().then(function() {
});
To bind to a custom routing-key like the task-specific routes that messages
from the queue is CC'ed to, just provide the desired routing key to the
method for exchange. See example below.
var RawRoutingPattern = 'route.task.specific.routing.key';
listener.bind(queueEvents.taskCompleted(RawRoutingPattern);
Advanced Listening
For advanced queue usage the connect
method can be used to
create and bind the queue and return an associated
amqplib channel:
var taskcluster = require('taskcluster-client');
var listener = new taskcluster.Listener({
connectionString: 'amqp://...'
});
var channel = listener.connect().then(function(channel) {
return channel.consume(function(msg) {
channel.ack(msg);
});
});
The listener creates a AMQP queue, on the server side and subscribes to messages
on the queue. It's possible to use named queues, see details below. For details
on routing key entries refer to documentation on
docs.taskcluster.net.
Remark, API end-points and AMQP exchanges are typically documented in
separate reference files. For this reason they also have separate Client
classes, even if they are from the same component.
Documentation
The set of API entries listed below is generated from the builtin references.
Detailed documentation with description, payload and result format details is
available on docs.taskcluster.net.
On the documentation site entries often have a
signature, you'll find that it matches the signatures below. Notice that all
the methods returns a promise. A method with : void
also returns a promise,
that either resolves without giving a value or rejects with an error.
Methods in taskcluster.Auth
var auth = new taskcluster.Auth(options);
auth.inspect(clientId) : result
auth.getCredentials(clientId) : result
Methods in taskcluster.Queue
var queue = new taskcluster.Queue(options);
queue.createTask(taskId, payload) : result
queue.getTask(taskId) : result
queue.defineTask(taskId, payload) : result
queue.scheduleTask(taskId) : result
queue.status(taskId) : result
queue.claimTask(taskId, runId, payload) : result
queue.reclaimTask(taskId, runId) : result
queue.claimWork(provisionerId, workerType, payload) : result
queue.reportCompleted(taskId, runId, payload) : result
queue.rerunTask(taskId) : result
queue.createArtifact(taskId, runId, name, payload) : result
queue.getArtifact(taskId, runId, name) : void
queue.getLastestArtifact(taskId, name) : void
queue.listArtifacts(taskId, runId) : result
queue.listLatestArtifacts(taskId) : result
queue.getPendingTasks(provisionerId) : void
queue.getAMQPConnectionString() : result
queue.ping() : void
Methods in taskcluster.Scheduler
var scheduler = new taskcluster.Scheduler(options);
scheduler.createTaskGraph(taskGraphId, payload) : result
scheduler.extendTaskGraph(taskGraphId, payload) : result
scheduler.status(taskGraphId) : result
scheduler.info(taskGraphId) : result
scheduler.inspect(taskGraphId) : result
scheduler.ping() : void
Methods in taskcluster.index
var index = new taskcluster.index(options);
index.find(namespace) : result
index.listNamespaces(namespace, payload) : result
index.listTasks(namespace, payload) : result
index.insert(namespace, payload) : result
index.ping() : void
Exchanges in taskcluster.QueueEvents
var queueEvents = new taskcluster.QueueEvents(options);
queueEvents.taskDefined(routingKeyPattern) : binding-info
queueEvents.taskPending(routingKeyPattern) : binding-info
queueEvents.taskRunning(routingKeyPattern) : binding-info
queueEvents.artifactCreated(routingKeyPattern) : binding-info
queueEvents.taskCompleted(routingKeyPattern) : binding-info
queueEvents.taskFailed(routingKeyPattern) : binding-info
Exchanges in taskcluster.SchedulerEvents
var schedulerEvents = new taskcluster.SchedulerEvents(options);
schedulerEvents.taskGraphRunning(routingKeyPattern) : binding-info
schedulerEvents.taskGraphExtended(routingKeyPattern) : binding-info
schedulerEvents.taskGraphBlocked(routingKeyPattern) : binding-info
schedulerEvents.taskGraphFinished(routingKeyPattern) : binding-info
Construct Urls
You can build a url for any request, but this feature is mostly useful for
request that doesn't require any authentication. If you need authentication
take a look at the section on building signed urls, which is possible for all
GET
requests. To construct a url for a request use the buildUrl
method, as
illustrated in the following example:
var queue = new taskcluster.Queue(...);
var url = queue.buildUrl(
queue.getTask,
taskId
);
Please, note that the payload
parameter cannot be encoded in urls. And must be
sent when using a constructed urls. Again, this is not a problem as most methods
that takes a payload
also requires authentication.
Construct Signed Urls
It's possible to build both signed urls for all GET
requests. A signed url
contains a query-string parameter called bewit
, this parameter holds
expiration time, signature and scope restrictions (if applied). The signature
covers the following parameters:
- Expiration time,
- Url and query-string, and
- scope restrictions (if applied)
These signed urls is very convenient if you want to grant somebody access to
specific resource without proxying the request or sharing your credentials.
For example it's fairly safe to provide someone with a signed url for a
specific artifact that is protected by a scope. See example below.
var queue = new taskcluster.Queue(...);
var signedUrl = queue.buildSignedUrl(
queue.getArtifactFromRun,
taskId,
runId,
artifactName,
{
expiration: 60 * 10
});
Please, note that the payload
parameter cannot be encoded in the signed url
and must be sent as request payload. This should work fine, just remember that
it's only possible to make signed urls for GET
requests, which in most cases
don't take a payload.
Also please consider using a relatively limited expiration time, as it's not
possible to retract a signed url without revoking your credentials.
For more technical details on signed urls, see bewit urls in
hawk.
Create Client Class Dynamically
You can create a Client class from a reference JSON object as illustrated
below:
var reference = {...};
var MyClient = taskcluster.createClient(reference);
var myClient = new MyClient(options);
myClient.myMethod(arg1, arg2, payload).then(function(result) {
});
Configuration of API Invocations
There is a number of configuration options for Client which affects invocation
of API end-points. These are useful if using a non-default server, for example
when setting up a staging area or testing locally.
Configuring API BaseUrls
If you use the builtin API Client classes documented above you can configure
the baseUrl
when creating an instance of the client. As illustrated below:
var auth = new taskcluster.Auth({
credentials: {...},
baseUrl: "http://localhost:4040"
});
Configuring Credentials
When creating an instance of a Client class the credentials can be provided
in options. For example:
var auth = new taskcluster.Auth({
credentials: {
clientId: '...',
accessToken: '...'
}
});
You can also configure default options globally using
taskcluster.config(options)
, as follows:
taskcluster.config({
credentials: {
clientId: '...',
accessToken: '...'
}
});
var auth = new taskcluster.Auth();
If the clientId
and accessToken
are left empty we also check the
TASKCLUSTER_CLIENT_ID
and TASKCLUSTER_ACCESS_TOKEN
environment variables
to use as defaults (similar to how AWS, Azure, etc. handle authentication).
Restricting Authorized Scopes
If you wish to perform requests on behalf of a third-party that has small set of
scopes than you do. You can specify which scopes your request should be allowed
to use, in the key authorizedScopes
. This is useful when the scheduler
performs a request on behalf of a task-graph, or when authentication takes
place in a trusted proxy. See example below:
var queue = new taskcluster.Queue({
credentials: {
clientId: '...',
accessToken: '...'
},
authorizedScopes: ['queue:post:define-task/my-provisioner/my-worker-type']
});
queue.defineTask(taskId taskDefinition).then(function(result) {
});
Configuration of Exchange Bindings
When a taskcluster Client class is instantiated the option exchangePrefix
may
be given. This will replace the default exchangePrefix
. This can be useful if
deploying a staging area or similar. See example below:
var queueEvents = new taskcluster.QueueEvents({
exchangePrefix: 'staging-queue/v1/'
});
listener.bind(queueEvents.taskCompleted({taskId: '<myTaskId>'}));
Using the Listener
TaskCluster relies on AMQP for exchanges of messages. You'll need an AMQP
connection string for using the taskcluster AMQP listener.
An outline of how to create an instance and use is given below. Note, you
must call resume()
before message starts arriving.
var listener = new taskcluster.Listener({
prefetch: 5,
connectionString: 'amqp://...',
queueName: 'my-queue',
maxLength: 0,
});
listener.connect().then(...);
listener.resume().then(...);
listener.pause().then(...);
listener.deleteQueue();
listener.close();
Using Connection
, instead of giving a connectionString
it is also
possible to give the Listener
the key connection
which must then be a
taskcluster.Connection
object. Using a Connection
object it's possible
to have multiple listeners using the same AMQP TCP connection, which is the
recommended way of using AMQP. Notice, that the Connection
will not be
closed with the Listener
s, so you must close()
it manually.
var connection = new taskcluster.Connection({
connectionString: 'amqp://...',
});
var listener = new taskcluster.Listener({
connection: connection,
});
connection.close();
Using taskcluster-client
in a Browser
Running the script utils/browserify.js
will generate taskcluster-client.js
using browserify. This does not contain any listener, but all the API logic
and references is present. To get AMQP events in the browser use
events.taskcluster.net.
Updating Builtin APIs
When releasing a new version of the taskcluster-client
library, we should
always update the builtin references using utils/update-apis.js
this
maintenance script can be used to list, show, add, remove and update builtin
API definitions.
When apis.json
is updated, please run utils/generate-docs.js
to update
the documentation in this file.
##License
The taskcluster client library is released on MPL 2.0.