From 153fa6e2b1a1a871b305173e1dd8fdae111df948 Mon Sep 17 00:00:00 2001 From: "Brad P. Crochet" Date: Tue, 4 Mar 2014 11:55:07 -0500 Subject: [PATCH] Added support for Exclusion plugin This plugin allows the specification of critical blocks for builders. Once a set of builders is "wrapped" by a critical block start/critical block end pair, any resources (string) specified in the exclusion build wrapper will cause any jobs with those same resources to block and allow only one of those builds to proceed at a time. Change-Id: I0bf4ab003709917aa7fe6ad57b31200f466658da --- jenkins_jobs/modules/builders.py | 58 +++++++++++++++++++ jenkins_jobs/modules/wrappers.py | 28 +++++++++ setup.cfg | 3 + .../builders/fixtures/critical-block-end.xml | 6 ++ .../builders/fixtures/critical-block-end.yaml | 2 + .../fixtures/critical-block-start.xml | 6 ++ .../fixtures/critical-block-start.yaml | 2 + tests/builders/fixtures/critical-block.xml | 7 +++ tests/builders/fixtures/critical-block.yaml | 3 + tests/wrappers/fixtures/exclusion001.xml | 12 ++++ tests/wrappers/fixtures/exclusion001.yaml | 4 ++ tests/wrappers/fixtures/exclusion002.xml | 15 +++++ tests/wrappers/fixtures/exclusion002.yaml | 5 ++ tests/wrappers/fixtures/exclusion003.xml | 18 ++++++ tests/wrappers/fixtures/exclusion003.yaml | 6 ++ 15 files changed, 175 insertions(+) create mode 100644 tests/builders/fixtures/critical-block-end.xml create mode 100644 tests/builders/fixtures/critical-block-end.yaml create mode 100644 tests/builders/fixtures/critical-block-start.xml create mode 100644 tests/builders/fixtures/critical-block-start.yaml create mode 100644 tests/builders/fixtures/critical-block.xml create mode 100644 tests/builders/fixtures/critical-block.yaml create mode 100644 tests/wrappers/fixtures/exclusion001.xml create mode 100644 tests/wrappers/fixtures/exclusion001.yaml create mode 100644 tests/wrappers/fixtures/exclusion002.xml create mode 100644 tests/wrappers/fixtures/exclusion002.yaml create mode 100644 tests/wrappers/fixtures/exclusion003.xml create mode 100644 tests/wrappers/fixtures/exclusion003.yaml diff --git a/jenkins_jobs/modules/builders.py b/jenkins_jobs/modules/builders.py index 3a7f20393..51542567b 100644 --- a/jenkins_jobs/modules/builders.py +++ b/jenkins_jobs/modules/builders.py @@ -1048,6 +1048,64 @@ def sbt(parser, xml_parent, data): 'subdir-path', '') +def critical_block_start(parser, xml_parent, data): + """yaml: critical-block-start + Designate the start of a critical block. Must be used in conjuction with + critical-block-end. + + Must also add a build wrapper (exclusion), specifying the resources that + control the critical block. Otherwise, this will have no effect. + + Requires Jenkins `Exclusion Plugin. + `_ + + Example:: + + wrappers: + - exclusion: + resources: + myresource1 + builders: + - critical-block-start + - ... other builders + - critical-block-end + + """ + cbs = \ + XML.SubElement(xml_parent, + 'org.jvnet.hudson.plugins.exclusion.CriticalBlockStart') + cbs.set('plugin', 'Exclusion') + + +def critical_block_end(parser, xml_parent, data): + """yaml: critical-block-end + Designate the end of a critical block. Must be used in conjuction with + critical-block-start. + + Must also add a build wrapper (exclusion), specifying the resources that + control the critical block. Otherwise, this will have no effect. + + Requires Jenkins `Exclusion Plugin. + `_ + + Example:: + + wrappers: + - exclusion: + resources: + myresource1 + builders: + - critical-block-start + - ... other builders + - critical-block-end + + """ + cbs = \ + XML.SubElement(xml_parent, + 'org.jvnet.hudson.plugins.exclusion.CriticalBlockEnd') + cbs.set('plugin', 'Exclusion') + + class Builders(jenkins_jobs.modules.base.Base): sequence = 60 diff --git a/jenkins_jobs/modules/wrappers.py b/jenkins_jobs/modules/wrappers.py index c9b3db08c..46a70c2e4 100644 --- a/jenkins_jobs/modules/wrappers.py +++ b/jenkins_jobs/modules/wrappers.py @@ -969,6 +969,34 @@ def matrix_tie_parent(parser, xml_parent, data): XML.SubElement(mtp, 'labelName').text = data['node'] +def exclusion(parser, xml_parent, data): + """yaml: exclusion + Add a resource to use for critical sections to establish a mutex on. If + another job specifies the same resource, the second job will wait for the + blocked resource to become available. + + Requires the Jenkins `Exclusion Plugin. + `_ + + :arg list resources: List of resources to add for exclusion + + Example: + + .. literalinclude:: /../../tests/wrappers/fixtures/exclusion002.yaml + + """ + exl = XML.SubElement(xml_parent, + 'org.jvnet.hudson.plugins.exclusion.IdAllocator') + exl.set('plugin', 'Exclusion') + ids = XML.SubElement(exl, 'ids') + resources = data.get('resources', []) + for resource in resources: + dit = \ + XML.SubElement(ids, + 'org.jvnet.hudson.plugins.exclusion.DefaultIdType') + XML.SubElement(dit, 'name').text = str(resource).upper() + + class Wrappers(jenkins_jobs.modules.base.Base): sequence = 80 diff --git a/setup.cfg b/setup.cfg index 02c4fb866..a1db8ff02 100644 --- a/setup.cfg +++ b/setup.cfg @@ -41,6 +41,8 @@ jenkins_jobs.builders = builders-from=jenkins_jobs.modules.builders:builders_from conditional-step=jenkins_jobs.modules.builders:conditional_step copyartifact=jenkins_jobs.modules.builders:copyartifact + critical-block-start=jenkins_jobs.modules.builders:critical_block_start + critical-block-end=jenkins_jobs.modules.builders:critical_block_end gradle=jenkins_jobs.modules.builders:gradle grails=jenkins_jobs.modules.builders:grails inject=jenkins_jobs.modules.builders:inject @@ -174,6 +176,7 @@ jenkins_jobs.wrappers = copy-to-slave=jenkins_jobs.modules.wrappers:copy_to_slave delivery-pipeline=jenkins_jobs.modules.wrappers:delivery_pipeline env-file=jenkins_jobs.modules.wrappers:env_file + exclusion=jenkins_jobs.modules.wrappers:exclusion inject-passwords=jenkins_jobs.modules.wrappers:inject_passwords inject=jenkins_jobs.modules.wrappers:inject jclouds=jenkins_jobs.modules.wrappers:jclouds diff --git a/tests/builders/fixtures/critical-block-end.xml b/tests/builders/fixtures/critical-block-end.xml new file mode 100644 index 000000000..018594b19 --- /dev/null +++ b/tests/builders/fixtures/critical-block-end.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/tests/builders/fixtures/critical-block-end.yaml b/tests/builders/fixtures/critical-block-end.yaml new file mode 100644 index 000000000..3e87c3714 --- /dev/null +++ b/tests/builders/fixtures/critical-block-end.yaml @@ -0,0 +1,2 @@ +builders: + - critical-block-end \ No newline at end of file diff --git a/tests/builders/fixtures/critical-block-start.xml b/tests/builders/fixtures/critical-block-start.xml new file mode 100644 index 000000000..facd70892 --- /dev/null +++ b/tests/builders/fixtures/critical-block-start.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/tests/builders/fixtures/critical-block-start.yaml b/tests/builders/fixtures/critical-block-start.yaml new file mode 100644 index 000000000..1dbbd5c41 --- /dev/null +++ b/tests/builders/fixtures/critical-block-start.yaml @@ -0,0 +1,2 @@ +builders: + - critical-block-start diff --git a/tests/builders/fixtures/critical-block.xml b/tests/builders/fixtures/critical-block.xml new file mode 100644 index 000000000..cacfb596b --- /dev/null +++ b/tests/builders/fixtures/critical-block.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/tests/builders/fixtures/critical-block.yaml b/tests/builders/fixtures/critical-block.yaml new file mode 100644 index 000000000..04ca4206d --- /dev/null +++ b/tests/builders/fixtures/critical-block.yaml @@ -0,0 +1,3 @@ +builders: + - critical-block-start + - critical-block-end \ No newline at end of file diff --git a/tests/wrappers/fixtures/exclusion001.xml b/tests/wrappers/fixtures/exclusion001.xml new file mode 100644 index 000000000..b0fdcb01e --- /dev/null +++ b/tests/wrappers/fixtures/exclusion001.xml @@ -0,0 +1,12 @@ + + + + + + + MYRESOURCE + + + + + \ No newline at end of file diff --git a/tests/wrappers/fixtures/exclusion001.yaml b/tests/wrappers/fixtures/exclusion001.yaml new file mode 100644 index 000000000..ee6fbf5f7 --- /dev/null +++ b/tests/wrappers/fixtures/exclusion001.yaml @@ -0,0 +1,4 @@ +wrappers: + - exclusion: + resources: + - myresource diff --git a/tests/wrappers/fixtures/exclusion002.xml b/tests/wrappers/fixtures/exclusion002.xml new file mode 100644 index 000000000..57b4eb007 --- /dev/null +++ b/tests/wrappers/fixtures/exclusion002.xml @@ -0,0 +1,15 @@ + + + + + + + MYRESOURCE1 + + + MYRESOURCE2 + + + + + \ No newline at end of file diff --git a/tests/wrappers/fixtures/exclusion002.yaml b/tests/wrappers/fixtures/exclusion002.yaml new file mode 100644 index 000000000..9554fa7d1 --- /dev/null +++ b/tests/wrappers/fixtures/exclusion002.yaml @@ -0,0 +1,5 @@ +wrappers: + - exclusion: + resources: + - myresource1 + - myresource2 diff --git a/tests/wrappers/fixtures/exclusion003.xml b/tests/wrappers/fixtures/exclusion003.xml new file mode 100644 index 000000000..39960b8a0 --- /dev/null +++ b/tests/wrappers/fixtures/exclusion003.xml @@ -0,0 +1,18 @@ + + + + + + + MYRESOURCE1 + + + MYRESOURCE2 + + + MYRESOURCE3 + + + + + \ No newline at end of file diff --git a/tests/wrappers/fixtures/exclusion003.yaml b/tests/wrappers/fixtures/exclusion003.yaml new file mode 100644 index 000000000..d9b2c0a66 --- /dev/null +++ b/tests/wrappers/fixtures/exclusion003.yaml @@ -0,0 +1,6 @@ +wrappers: + - exclusion: + resources: + - myResource1 + - MyresoUrce2 + - myReSoUrCe3