External Resource Dispatcher

Skip to end of metadata
Go to start of metadata

Plugin Information

Plugin ID externalresource-dispatcher Changes In Latest Release
Since Latest Release
Latest Release
Latest Release Date
Required Core
Dependencies
1.1.0
Jun 25, 2013
1.424
metadata (version:1.0b)
build-flow-plugin (version:0.9)
maven-plugin (version:1.424)
Source Code
Issue Tracking
Maintainer(s)
GitHub
Open Issues
Robert Sandell (id: rsandell)
Tomas Westling (id: t_westling)
Usage Installations 2013-Apr 112
2013-May 110
2013-Jun 130
2013-Jul 134
2013-Aug 144
2013-Sep 143
2013-Oct 162
2013-Nov 172
2013-Dec 182
2014-Jan 179
2014-Feb 178
2014-Mar 183

This plugin adds support for external resources in Jenkins. An external resource is something external
attached to a Jenkins slave and can be locked by a build, which thus gets exclusive access to it, then released after the
build is done. Examples of external resources are phones, printers and USB christmas trees.

Note that even though the 'b' fell off in the latest release, this plugin is still considered to be in beta stage.

Quick usage guide

  • Connect an external resource of some kind to a Jenkins node.
  • Create Metadata on the node for the ExternalResource.
  • Create a project in Jenkins. Click the Resource Selection Criteria check box and add a name-value pair that matches your ExternalResource.
  • Start a build of the project. Note on the node page that the external resource is locked to your build.
  • Start another build using the same selection criteria. Note that this build will wait for the first one to finish, due to no free resource.

Adding ExternalResources to a node

Configure the node and click the Metadata check box. Add an ExternalResourceTreeNode with an ExternalResource as a child.
An ExternalResourceTreeNode is a collection of ExternalResource objects and the only Metadata type that can contain ExternalResource objects.
Fill in Name, Id and Description and add any amount of other Metadata for the resource.


The External Resource metadata for a node.

Selection criteria

In any project, selection criteria can be added using the check box named "Resource Selection Criteria".
When the project is built, the plugin tries to find a slave among the slaves to run on (selected as usual via a label)
that matches the selection criteria. It does this by matching metadata values on the external resource defined
on the slave. If the plugin finds a match, it locks the resource to the build and starts the build on the matched slave.
Once the build finishes, the resource is unlocked. Multiple selection criteria can be added, the current "Simple Selection"
adds an implicit "and" between the criteria, so that all the criteria must be matched. We plan to add a more advanced
resource selection in the future.

Currently, only one selector type exists, the StringResourceSelection. This is extendable, so plugin developers
can add their own. The String selection criteria tries to match a String value to a metadata value exactly.


Selection criteria.

Locked resource

For a build with a locked resource, we expose all the properties of the resource as environment variables, with the names:
MD_EXTERNAL_RESOURCES_LOCKED_NAME_OF_THE_PROPERTY_IN_CAPS. These can be used to refer to the locked resource from build steps.

Administrator settings

To add ExternalResources to a node, write permission to the node is needed. The same goes for adding resource selection
on a project, i.e. write permission to projects is needed.

On the configure system page in Jenkins, under External Resource Dispatcher Configuration, a couple of new settings are available:

  • Release Key - not used yet, will be used for a "Release All" feature where all resources on a node can be released by clicking a button.
  • Reservation Time - the number of seconds to reserve an ExternalResource. Since we use a QueueTaskDispatcher, we can't say for sure that
    a build will run on a particular machine, so we reserve the resource and then lock it once it starts to run.
  • External Resource Manager - described in detail further down, this sets the default manager for the Jenkins master.
  • Admin Notifier File - the path to a file in which to log problems with the resource handling.

Under the hood

Here we describe the different parts of the plugin in greater detail, with more focus on implementation details.

Dependency to Metadata plugin

This plugin has a dependency to the Metadata plugin and won't run without it. We use new Metadata types (ExternalResource and ExternalResourceTreeNode)
to describe the external resources on the nodes.

External Resource Metadata

We have added two new Metadata types, ExternalResource and ExternalResourceTreeNode. Only an ExternalResourceTreeNode can contain ExternalResources.

ExternalResource

An external resource is based on a TreeNodeMetadataValue, so it can contain other MetadataValues as children.
Other than those, it should always contain the following properties:

  • Name - the name of the resource.
  • Id - a unique identifier for the resource.
  • Description - text describing the resource.
  • Enabled - true if the resource is up and running, ready to be used, false if not.

ExternalResourceTreeNode

This is also based on TreeNodeMetadataValue, but can only contain ExternalResources as children.
It is also the only type of node that can contain ExternalResources. The reason for this is the resource handling.
In addition to its children, an ExternalResourceTreeNode contains an ExternalResourceManager. All the children of the ExternalResourceTreeNode will use the same manager.

ExternalResourceManagers

An ExternalResourceManager is what takes care of the resource handling. It is responsible for locking and releasing the
resources. Currently, two manager types exist, NoopExternalResourceManager and ResourceMonitorExternalResourceManager.
Plugin developers can add their own managers.

NoopExternalResourceManager

The easiest way of getting up and running with the External Resource Dispatcher. The NoopExternalResourceManager takes
care of the resource handling all from within Jenkins. If other systems outside of Jenkins are using the same External
Resources, this manager should not be chosen since the locking/releasing of resources will not look outside Jenkins.

ResourceMonitorExternalResourceManager

The difference between the NoopExternalResourceManager and this one is that the ResourceMonitor expects something external to Jenkins
to take care of the resources, and communicates with the plugin through CLI or http requests. At Sony, we have a service running on the slave machines
that can communicate with the ResourceMonitorExternalResourceManager which handles the locking and releasing of our Android phones.
When a phone is connected via usb to a slave computer, it also automatically adds it to Jenkins via http.
The service will hopefully soon be released as open source as well.

Command Line Interface (CLI) and HTTP

There are some CLI and HTTP commands intended primarily to be used by an ExternalResourceManager but can be used by a human or other system as well.
Most of the commands give a response in JSON format for example

{type: "OK", errorCode: 0, message: "OK"}

for an ok response.
All HTTP commands are placed under http://yourjenkins/external-resource-httpcli
Below is a brief description of each command, you can look in the Jenkins CLI help for information about their parameters.

disable-external-resource

HTTP name: /disable
Disables a resource on the slave. The resource can no longer be booked by jobs until it is enabled again.
Requires that the user has the EnableDisable permission set for the node that the resource is on.

enable-external-resource

HTTP name: /enable
Enables a previously disabled resource.
Requires that the user has the EnableDisable permission set for the node that the resource is on.

expire-external-resource

HTTP name: /expireReservation
Expires the lease of a reserved resource making it available again to be used by a build. The build that reserved it in the first place will probably fail when it starts and tries to lock the resource.

lock-external-resource

HTTP name: /lockResource
Adds the lock information to the resource so that no build can use it untill it is released. This is to inform Jenkins that another external process has locked it instead of a Jenkins build.
Requires that the user has the LockRelease permission set for the node that the resource is on.

reserve-external-resource

HTTP name: /reserveResource
Similar to the lock but for the reserve info instead.
Requires that the user has the LockRelease permission set for the node that the resource is on.

release-external-resource

HTTP name: /releaseResource
Removes any lock and reservation from the resource making it available again for builds to grab.
Requires that the user has the LockRelease permission set for the node that the resource is on.

Integration with the Build Flow Plugin

There is an extension point for Build Flow Plugin that can be used for easy access to the resource manager from within the build flow script like:

def manager = extension.'externalresource-dispatcher'
manager.lock(...)

Change Log

Version 1.0b (released Nov 22, 2012)

Initial beta release

Labels

plugin-slaves plugin-slaves Delete
plugin-cli plugin-cli Delete
plugin-android plugin-android Delete
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.
  1. Dec 03, 2012

    Jan Fagerström says:

    Is it possible to use a variable as input to the Resource Selection Criteri...

    Is it possible to use a variable as input to the Resource Selection Criteria, for example: using 

    ${SIZE}
    

    instead of 7 in your example above for screen.size?

    1. Dec 10, 2012

      Robert Sandell says:

      Nope, but it is a feature we are planning to add.

      Nope, but it is a feature we are planning to add.

      1. Mar 11, 2013

        jude vais says:

        This would be a KILLER feature. its essentially make or break for the implementa...

        This would be a KILLER feature. its essentially make or break for the implementation i'm eyeing. is there a timeline for its inclusion?

  2. Dec 10, 2012

    Magnus Jacobsson says:

    I would like to add the resource selection criteria within a matrix job. i.e. to...

    I would like to add the resource selection criteria within a matrix job. i.e. to be able to use different external resources for each iteration in the configuration matrix. This would be like the Exclusion-Plugin works. Any ideas to support this?

    1. Dec 10, 2012

      Robert Sandell says:

      That is something we have on the todo list, as well as being able to specify the...

      That is something we have on the todo list, as well as being able to specify the criteria as a parameter.

  3. Jan 18, 2013

    Massimo Rossello says:

    I have a master and a slave both with 4 executors and a similar resource configu...

    I have a master and a slave both with 4 executors and a similar resource configured like:

    - External Resource TreeNode

    --- External Resource

    ------ deviceClass (String)

    ------ deviceVersion (String)

    my jobs look for deviceClass. With the master, only one job takes the resource. On the slave, up to three jobs succeed to lock and go into execution. Therefore, I am forced to have just one executor on the slave.

    How can I debug this situation?

    1. Jan 21, 2013

      Robert Sandell says:

      That sounds like a serious bug, It could be a race condition in the QueueTaskDi...

      That sounds like a serious bug,

      It could be a race condition in the QueueTaskDispatcher/surrounding classes, or a miss in whatever ResourceManager you have chosen.

      1. Jan 21, 2013

        Massimo Rossello says:

        I chose the Default Manager. Other meaningful info I can provide: I tried to...

        I chose the Default Manager.

        Other meaningful info I can provide:

        1. I tried to configure a Node folding the two strings as documented above, therefore accessing the lock through a dotted sequence like "device.deviceClass", but it did not help
        2. a similar race condition happened at the master too when deleting the old resource definition (which was disabled, while the new one was enabled), while there were enqueued jobs waiting. But after aborting all jobs, and enqueuing others, the master worked fine while the slave kept failing
        3. could be that job that can "execute concurrent build if necessary" can cause damage at least more easily?
  4. Jul 04, 2013

    Martin Axelsson says:

    How to get the environment variables to work? I have created a string under a No...

    How to get the environment variables to work? I have created a string under a Node and want to access the value of that string in Execute shell in my Jenkins job.

    String

    Name: HW_SETUP

    Value: 8

    How to get the value of HW_SETUP in my job?

    1. Aug 05, 2013

      Tomas Ljunggren says:

      "For a build with a locked resource, we expose all the properties of the resourc...

      "For a build with a locked resource, we expose all the properties of the resource as environment variables, with the names:
      MD_EXTERNAL_RESOURCES_LOCKED_NAME_OF_THE_PROPERTY_IN_CAPS. These can be used to refer to the locked resource from build steps."

      Try with MD_EXTERNAL_RESOURCES_LOCKED_HW_SETUP

  5. Aug 14, 2013

    Roman G says:

    Hi, the plugin looks fine. Is it any possibility to lock resources without conne...

    Hi,
    the plugin looks fine.
    Is it any possibility to lock resources without connection to node?

    1. Aug 15, 2013

      Robert Sandell says:

      That depends on what you mean by connection to a node, you could model your reso...

      That depends on what you mean by connection to a node, you could model your resources to be attached to the master node.

      But the intention of the plugin is to make sure that builds are running on nodes where there is a free resource available that fulfills the spec of the job.

      I guess none node specific resources could be added as a feature, but it is nothing that we have on the todo list at the moment.