Update 'timeout' wrapper module

Add support specifically for BuildTimeoutWrapper plugin version 1.14 and later;
leave module behavior intact for previous versions.

Change-Id: I6e9459271172540eda4fdb576d788fa2ae6f4d68
This commit is contained in:
Wayne 2015-01-31 12:27:51 -08:00
parent 6fe4626518
commit 8a63d7a2a0
23 changed files with 258 additions and 35 deletions

View File

@ -24,11 +24,16 @@ Wrappers can alter the way the build is run as well as the build output.
import logging
import xml.etree.ElementTree as XML
import pkg_resources
import jenkins_jobs.modules.base
from jenkins_jobs.errors import JenkinsJobsException
from jenkins_jobs.errors import (JenkinsJobsException, InvalidAttributeError)
from jenkins_jobs.modules.builders import create_builders
from jenkins_jobs.modules.helpers import config_file_provider_builder
logger = logging.getLogger(__name__)
MIN_TO_SEC = 60
def ci_skip(parser, xml_parent, data):
"""yaml: ci-skip
@ -129,50 +134,153 @@ def timeout(parser, xml_parent, data):
<Build-timeout+Plugin>`.
:arg bool fail: Mark the build as failed (default false)
:arg bool abort: Mark the build as aborted (default false)
:arg bool write-description: Write a message in the description
(default false)
:arg int timeout: Abort the build after this number of minutes (default 3)
:arg str timeout-var: Export an environment variable to reference the
timeout value (optional)
:arg str type: Timeout type to use (default absolute)
:arg int elastic-percentage: Percentage of the three most recent builds
where to declare a timeout (default 0)
:arg int elastic-default-timeout: Timeout to use if there were no previous
builds (default 3)
:type values:
* **likely-stuck**
* **elastic**
* **absolute**
* **likely-stuck**
* **no-activity**
* **elastic**
* **absolute**
Example:
:arg int elastic-percentage: Percentage of the three most recent builds
where to declare a timeout, only applies to **elastic** type.
(default 0)
:arg int elastic-number-builds: Number of builds to consider computing
average duration, only applies to **elastic** type. (default 3)
:arg int elastic-default-timeout: Timeout to use if there were no previous
builds, only applies to **elastic** type. (default 3)
.. literalinclude:: /../../tests/wrappers/fixtures/timeout001.yaml
Example (Version < 1.14):
.. literalinclude:: /../../tests/wrappers/fixtures/timeout002.yaml
.. literalinclude:: /../../tests/wrappers/fixtures/timeout/timeout001.yaml
.. literalinclude:: /../../tests/wrappers/fixtures/timeout/timeout002.yaml
.. literalinclude:: /../../tests/wrappers/fixtures/timeout/timeout003.yaml
Example (Version >= 1.14):
.. literalinclude::
/../../tests/wrappers/fixtures/timeout/version-1.14/absolute001.yaml
.. literalinclude::
/../../tests/wrappers/fixtures/timeout/version-1.14/no-activity001.yaml
.. literalinclude::
/../../tests/wrappers/fixtures/timeout/version-1.14/likely-stuck001.yaml
.. literalinclude::
/../../tests/wrappers/fixtures/timeout/version-1.14/elastic001.yaml
.. literalinclude:: /../../tests/wrappers/fixtures/timeout003.yaml
"""
twrapper = XML.SubElement(xml_parent,
'hudson.plugins.build__timeout.'
'BuildTimeoutWrapper')
XML.SubElement(twrapper, 'timeoutMinutes').text = str(
data.get('timeout', 3))
timeout_env_var = data.get('timeout-var')
if timeout_env_var:
XML.SubElement(twrapper, 'timeoutEnvVar').text = str(timeout_env_var)
XML.SubElement(twrapper, 'failBuild').text = str(
data.get('fail', 'false')).lower()
XML.SubElement(twrapper, 'writingDescription').text = str(
data.get('write-description', 'false')).lower()
XML.SubElement(twrapper, 'timeoutPercentage').text = str(
data.get('elastic-percentage', 0))
XML.SubElement(twrapper, 'timeoutMinutesElasticDefault').text = str(
data.get('elastic-default-timeout', 3))
tout_type = str(data.get('type', 'absolute')).lower()
if tout_type == 'likely-stuck':
tout_type = 'likelyStuck'
XML.SubElement(twrapper, 'timeoutType').text = tout_type
prefix = 'hudson.plugins.build__timeout.'
twrapper = XML.SubElement(xml_parent, prefix + 'BuildTimeoutWrapper')
plugin_info = parser.registry.get_plugin_info(
"Jenkins build timeout plugin")
version = pkg_resources.parse_version(plugin_info.get("version", "0"))
valid_strategies = ['absolute', 'no-activity', 'likely-stuck', 'elastic']
if version >= pkg_resources.parse_version("1.14"):
strategy = data.get('type', 'absolute')
if strategy not in valid_strategies:
InvalidAttributeError('type', strategy, valid_strategies)
if strategy == "absolute":
strategy_element = XML.SubElement(
twrapper, 'strategy',
{'class': "hudson.plugins.build_timeout."
"impl.AbsoluteTimeOutStrategy"})
XML.SubElement(strategy_element, 'timeoutMinutes'
).text = str(data.get('timeout', 3))
elif strategy == "no-activity":
strategy_element = XML.SubElement(
twrapper, 'strategy',
{'class': "hudson.plugins.build_timeout."
"impl.NoActivityTimeOutStrategy"})
timeout_sec = int(data.get('timeout', 3)) * MIN_TO_SEC
XML.SubElement(strategy_element,
'timeoutSecondsString').text = str(timeout_sec)
elif strategy == "likely-stuck":
strategy_element = XML.SubElement(
twrapper, 'strategy',
{'class': "hudson.plugins.build_timeout."
"impl.LikelyStuckTimeOutStrategy"})
XML.SubElement(strategy_element,
'timeoutMinutes').text = str(data.get('timeout', 3))
elif strategy == "elastic":
strategy_element = XML.SubElement(
twrapper, 'strategy',
{'class': "hudson.plugins.build_timeout."
"impl.ElasticTimeOutStrategy"})
XML.SubElement(strategy_element, 'timeoutPercentage'
).text = str(data.get('elastic-percentage', 0))
XML.SubElement(strategy_element, 'numberOfBuilds'
).text = str(data.get('elastic-number-builds', 0))
XML.SubElement(strategy_element, 'timeoutMinutesElasticDefault'
).text = str(data.get('elastic-default-timeout', 3))
actions = []
for action in ['fail', 'abort']:
if str(data.get(action, 'false')).lower() == 'true':
actions.append(action)
# Set the default action to "abort"
if len(actions) == 0:
actions.append("abort")
description = data.get('write-description', None)
if description is not None:
actions.append('write-description')
operation_list = XML.SubElement(twrapper, 'operationList')
for action in actions:
fmt_str = prefix + "operations.{0}Operation"
if action == "abort":
XML.SubElement(operation_list, fmt_str.format("Abort"))
elif action == "fail":
XML.SubElement(operation_list, fmt_str.format("Fail"))
elif action == "write-description":
write_description = XML.SubElement(
operation_list, fmt_str.format("WriteDescription"))
XML.SubElement(write_description, "description"
).text = description
else:
raise JenkinsJobsException("Unsupported BuiltTimeoutWrapper "
"plugin action: {0}".format(action))
timeout_env_var = data.get('timeout-var')
if timeout_env_var:
XML.SubElement(twrapper,
'timeoutEnvVar').text = str(timeout_env_var)
else:
XML.SubElement(twrapper,
'timeoutMinutes').text = str(data.get('timeout', 3))
timeout_env_var = data.get('timeout-var')
if timeout_env_var:
XML.SubElement(twrapper,
'timeoutEnvVar').text = str(timeout_env_var)
XML.SubElement(twrapper, 'failBuild'
).text = str(data.get('fail', 'false')).lower()
XML.SubElement(twrapper, 'writingDescription'
).text = str(data.get('write-description', 'false')
).lower()
XML.SubElement(twrapper, 'timeoutPercentage'
).text = str(data.get('elastic-percentage', 0))
XML.SubElement(twrapper, 'timeoutMinutesElasticDefault'
).text = str(data.get('elastic-default-timeout', 3))
tout_type = str(data.get('type', 'absolute')).lower()
if tout_type == 'likely-stuck':
tout_type = 'likelyStuck'
XML.SubElement(twrapper, 'timeoutType').text = tout_type
def timestamps(parser, xml_parent, data):

View File

@ -11,4 +11,4 @@
<timeoutType>absolute</timeoutType>
</hudson.plugins.build__timeout.BuildTimeoutWrapper>
</buildWrappers>
</project>
</project>

View File

@ -11,4 +11,4 @@
<timeoutType>elastic</timeoutType>
</hudson.plugins.build__timeout.BuildTimeoutWrapper>
</buildWrappers>
</project>
</project>

View File

@ -0,0 +1 @@
plugins_info.yaml

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<project>
<buildWrappers>
<hudson.plugins.build__timeout.BuildTimeoutWrapper>
<strategy class="hudson.plugins.build_timeout.impl.AbsoluteTimeOutStrategy">
<timeoutMinutes>90</timeoutMinutes>
</strategy>
<operationList>
<hudson.plugins.build__timeout.operations.FailOperation/>
</operationList>
<timeoutEnvVar>BUILD_TIMEOUT</timeoutEnvVar>
</hudson.plugins.build__timeout.BuildTimeoutWrapper>
</buildWrappers>
</project>

View File

@ -0,0 +1,6 @@
wrappers:
- timeout:
timeout: 90
timeout-var: 'BUILD_TIMEOUT'
fail: true
type: absolute

View File

@ -0,0 +1 @@
plugins_info.yaml

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<project>
<buildWrappers>
<hudson.plugins.build__timeout.BuildTimeoutWrapper>
<strategy class="hudson.plugins.build_timeout.impl.ElasticTimeOutStrategy">
<timeoutPercentage>150</timeoutPercentage>
<numberOfBuilds>14</numberOfBuilds>
<timeoutMinutesElasticDefault>3</timeoutMinutesElasticDefault>
</strategy>
<operationList>
<hudson.plugins.build__timeout.operations.AbortOperation/>
</operationList>
<timeoutEnvVar>BUILD_TIMEOUT</timeoutEnvVar>
</hudson.plugins.build__timeout.BuildTimeoutWrapper>
</buildWrappers>
</project>

View File

@ -0,0 +1,8 @@
wrappers:
- timeout:
elastic-percentage: 150
elastic-default-timeout: 3
elastic-number-builds: 14
timeout-var: 'BUILD_TIMEOUT'
abort: true
type: elastic

View File

@ -0,0 +1 @@
plugins_info.yaml

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<project>
<buildWrappers>
<hudson.plugins.build__timeout.BuildTimeoutWrapper>
<strategy class="hudson.plugins.build_timeout.impl.LikelyStuckTimeOutStrategy">
<timeoutMinutes>90</timeoutMinutes>
</strategy>
<operationList>
<hudson.plugins.build__timeout.operations.AbortOperation/>
</operationList>
<timeoutEnvVar>BUILD_TIMEOUT</timeoutEnvVar>
</hudson.plugins.build__timeout.BuildTimeoutWrapper>
</buildWrappers>
</project>

View File

@ -0,0 +1,6 @@
wrappers:
- timeout:
timeout: 90
timeout-var: 'BUILD_TIMEOUT'
abort: true
type: likely-stuck

View File

@ -0,0 +1 @@
plugins_info.yaml

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<project>
<buildWrappers>
<hudson.plugins.build__timeout.BuildTimeoutWrapper>
<strategy class="hudson.plugins.build_timeout.impl.AbsoluteTimeOutStrategy">
<timeoutMinutes>90</timeoutMinutes>
</strategy>
<operationList>
<hudson.plugins.build__timeout.operations.AbortOperation/>
</operationList>
<timeoutEnvVar>BUILD_TIMEOUT</timeoutEnvVar>
</hudson.plugins.build__timeout.BuildTimeoutWrapper>
</buildWrappers>
</project>

View File

@ -0,0 +1,5 @@
wrappers:
- timeout:
timeout: 90
timeout-var: 'BUILD_TIMEOUT'
type: absolute

View File

@ -0,0 +1 @@
plugins_info.yaml

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<project>
<buildWrappers>
<hudson.plugins.build__timeout.BuildTimeoutWrapper>
<strategy class="hudson.plugins.build_timeout.impl.NoActivityTimeOutStrategy">
<timeoutSecondsString>300</timeoutSecondsString>
</strategy>
<operationList>
<hudson.plugins.build__timeout.operations.AbortOperation/>
<hudson.plugins.build__timeout.operations.WriteDescriptionOperation>
<description>Blah Blah Blah</description>
</hudson.plugins.build__timeout.operations.WriteDescriptionOperation>
</operationList>
<timeoutEnvVar>BUILD_TIMEOUT</timeoutEnvVar>
</hudson.plugins.build__timeout.BuildTimeoutWrapper>
</buildWrappers>
</project>

View File

@ -0,0 +1,7 @@
wrappers:
- timeout:
timeout: 5
timeout-var: 'BUILD_TIMEOUT'
type: no-activity
abort: true
write-description: "Blah Blah Blah"

View File

@ -0,0 +1,3 @@
- longName: 'Jenkins build timeout plugin'
shortName: 'build-timeout'
version: "1.14"