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:
parent
6fe4626518
commit
8a63d7a2a0
@ -24,11 +24,16 @@ Wrappers can alter the way the build is run as well as the build output.
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
import xml.etree.ElementTree as XML
|
import xml.etree.ElementTree as XML
|
||||||
|
import pkg_resources
|
||||||
import jenkins_jobs.modules.base
|
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.builders import create_builders
|
||||||
from jenkins_jobs.modules.helpers import config_file_provider_builder
|
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):
|
def ci_skip(parser, xml_parent, data):
|
||||||
"""yaml: ci-skip
|
"""yaml: ci-skip
|
||||||
@ -129,50 +134,153 @@ def timeout(parser, xml_parent, data):
|
|||||||
<Build-timeout+Plugin>`.
|
<Build-timeout+Plugin>`.
|
||||||
|
|
||||||
:arg bool fail: Mark the build as failed (default false)
|
: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
|
:arg bool write-description: Write a message in the description
|
||||||
(default false)
|
(default false)
|
||||||
:arg int timeout: Abort the build after this number of minutes (default 3)
|
:arg int timeout: Abort the build after this number of minutes (default 3)
|
||||||
:arg str timeout-var: Export an environment variable to reference the
|
:arg str timeout-var: Export an environment variable to reference the
|
||||||
timeout value (optional)
|
timeout value (optional)
|
||||||
:arg str type: Timeout type to use (default absolute)
|
: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:
|
:type values:
|
||||||
* **likely-stuck**
|
* **likely-stuck**
|
||||||
* **elastic**
|
* **no-activity**
|
||||||
* **absolute**
|
* **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,
|
prefix = 'hudson.plugins.build__timeout.'
|
||||||
'hudson.plugins.build__timeout.'
|
twrapper = XML.SubElement(xml_parent, prefix + 'BuildTimeoutWrapper')
|
||||||
'BuildTimeoutWrapper')
|
|
||||||
XML.SubElement(twrapper, 'timeoutMinutes').text = str(
|
plugin_info = parser.registry.get_plugin_info(
|
||||||
data.get('timeout', 3))
|
"Jenkins build timeout plugin")
|
||||||
timeout_env_var = data.get('timeout-var')
|
version = pkg_resources.parse_version(plugin_info.get("version", "0"))
|
||||||
if timeout_env_var:
|
|
||||||
XML.SubElement(twrapper, 'timeoutEnvVar').text = str(timeout_env_var)
|
valid_strategies = ['absolute', 'no-activity', 'likely-stuck', 'elastic']
|
||||||
XML.SubElement(twrapper, 'failBuild').text = str(
|
|
||||||
data.get('fail', 'false')).lower()
|
if version >= pkg_resources.parse_version("1.14"):
|
||||||
XML.SubElement(twrapper, 'writingDescription').text = str(
|
strategy = data.get('type', 'absolute')
|
||||||
data.get('write-description', 'false')).lower()
|
if strategy not in valid_strategies:
|
||||||
XML.SubElement(twrapper, 'timeoutPercentage').text = str(
|
InvalidAttributeError('type', strategy, valid_strategies)
|
||||||
data.get('elastic-percentage', 0))
|
|
||||||
XML.SubElement(twrapper, 'timeoutMinutesElasticDefault').text = str(
|
if strategy == "absolute":
|
||||||
data.get('elastic-default-timeout', 3))
|
strategy_element = XML.SubElement(
|
||||||
tout_type = str(data.get('type', 'absolute')).lower()
|
twrapper, 'strategy',
|
||||||
if tout_type == 'likely-stuck':
|
{'class': "hudson.plugins.build_timeout."
|
||||||
tout_type = 'likelyStuck'
|
"impl.AbsoluteTimeOutStrategy"})
|
||||||
XML.SubElement(twrapper, 'timeoutType').text = tout_type
|
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):
|
def timestamps(parser, xml_parent, data):
|
||||||
|
@ -11,4 +11,4 @@
|
|||||||
<timeoutType>absolute</timeoutType>
|
<timeoutType>absolute</timeoutType>
|
||||||
</hudson.plugins.build__timeout.BuildTimeoutWrapper>
|
</hudson.plugins.build__timeout.BuildTimeoutWrapper>
|
||||||
</buildWrappers>
|
</buildWrappers>
|
||||||
</project>
|
</project>
|
@ -11,4 +11,4 @@
|
|||||||
<timeoutType>elastic</timeoutType>
|
<timeoutType>elastic</timeoutType>
|
||||||
</hudson.plugins.build__timeout.BuildTimeoutWrapper>
|
</hudson.plugins.build__timeout.BuildTimeoutWrapper>
|
||||||
</buildWrappers>
|
</buildWrappers>
|
||||||
</project>
|
</project>
|
@ -0,0 +1 @@
|
|||||||
|
plugins_info.yaml
|
14
tests/wrappers/fixtures/timeout/version-1.14/absolute001.xml
Normal file
14
tests/wrappers/fixtures/timeout/version-1.14/absolute001.xml
Normal 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>
|
@ -0,0 +1,6 @@
|
|||||||
|
wrappers:
|
||||||
|
- timeout:
|
||||||
|
timeout: 90
|
||||||
|
timeout-var: 'BUILD_TIMEOUT'
|
||||||
|
fail: true
|
||||||
|
type: absolute
|
@ -0,0 +1 @@
|
|||||||
|
plugins_info.yaml
|
16
tests/wrappers/fixtures/timeout/version-1.14/elastic001.xml
Normal file
16
tests/wrappers/fixtures/timeout/version-1.14/elastic001.xml
Normal 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>
|
@ -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
|
@ -0,0 +1 @@
|
|||||||
|
plugins_info.yaml
|
@ -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>
|
@ -0,0 +1,6 @@
|
|||||||
|
wrappers:
|
||||||
|
- timeout:
|
||||||
|
timeout: 90
|
||||||
|
timeout-var: 'BUILD_TIMEOUT'
|
||||||
|
abort: true
|
||||||
|
type: likely-stuck
|
@ -0,0 +1 @@
|
|||||||
|
plugins_info.yaml
|
@ -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>
|
@ -0,0 +1,5 @@
|
|||||||
|
wrappers:
|
||||||
|
- timeout:
|
||||||
|
timeout: 90
|
||||||
|
timeout-var: 'BUILD_TIMEOUT'
|
||||||
|
type: absolute
|
@ -0,0 +1 @@
|
|||||||
|
plugins_info.yaml
|
@ -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>
|
@ -0,0 +1,7 @@
|
|||||||
|
wrappers:
|
||||||
|
- timeout:
|
||||||
|
timeout: 5
|
||||||
|
timeout-var: 'BUILD_TIMEOUT'
|
||||||
|
type: no-activity
|
||||||
|
abort: true
|
||||||
|
write-description: "Blah Blah Blah"
|
@ -0,0 +1,3 @@
|
|||||||
|
- longName: 'Jenkins build timeout plugin'
|
||||||
|
shortName: 'build-timeout'
|
||||||
|
version: "1.14"
|
Loading…
Reference in New Issue
Block a user