How to prevent certain Jenkins jobs from running s

2019-01-11 12:29发布

问题:

I have a couple of jobs that use a shared resource (database), which sometimes can cause builds to fail in the (rare) event that the jobs happen to get triggered simultaneously.

Given jobs A through E, for example, is there any way to specify that A and C should never be run concurrently?

Other than the aforementioned resource, the builds are independent of each other (not e.g. in a upstream/downstream relation).

A "brute-force" way would be limiting number of executors to one, but that obviously is less than ideal if most jobs could well be executed concurrently and there's no lack of computing resources on the build server.

回答1:

There are currently 2 ways of doing this:

  • Use the Throttle Concurrent Builds plugin.
  • Set up those jobs to run on a slave having only 1 executor.


回答2:

The Locks and Latches plugin here should help.

This question is probably a dupe of How do I ensure that only one of a certain category of job runs at once in Hudson?



回答3:

Have a look at the External Resource Dispatcher Jenkins plugin, which was first published in November 2012. This (relatively) new plugin seems to exactly cover this use case.



回答4:

That's an old question, but the topic can still be relevant, especially when running application tests on Jenkins.

The Lockable Resources Plugin allows you to define lockable resources that can be used by builds. If your build requires an resource, it takes the lock. If a second build requires the same resource (which then is already locked), it will be queued for the resource to be free.

Although the docs use computers or printers as examples for lockable resources, the database example from above should work as well.

In opposite to the Locks and Latches Plugin mentioned in answers from 2012, this package seems to be currently maintained (currently ~2016).



回答5:

N.B. you don't need physical or virtual hardware for a slave/node, you can set up "slaves" that run on the master server.

Manage Jenkins > Manage Nodes > New node

and make a "dumb slaves" each with its own root directory.

Create a few slaves, execute them when the server boots, and then you have essentially created pools of executors.

You might have, say...

db - only one executor in your case. compile - limit according to hardware or # of CPUs. scripts - have many executors for all those little jobs that Jenkins is good at doing.



回答6:

Old question, and whether this will work for your application I can't be sure as you didn't mention details of your application. However, I wanted to add the way that I handled this in our Rails application test suite.

Our application's database configuration (database.yml) isn't in the source repository. Instead, it lives in /var/lib/configs/uniquing_database.yml on the VM which runs our Jenkins instance.

One of the steps of our build process involves copying this config file to the project workspace:

cp /var/lib/jenkins/configs/myapp_unique_database.yml config/database.yml

and that config takes workspace and build number information exposed to the environment by Jenkins into account in order to create a uniquely named database for that job and it's specific execution:

test:
  adapter: postgresql
  encoding: unicode
  host: 127.0.0.1
  port: 5432
  database: myapp_test<%= ENV['JOB_NAME'].split('/').last %><%= ENV['BUILD_NUMBER'] %>

The rest of our build proceeds without any knowledge or care that it's running in a distinct database. Finally, at the end of our build, we make sure to drop that database so we don't have a bunch of test databases polluting the file system:

RAILS_ENV=test bundle exec rake db:drop