Add function to get running builds
It can be useful to get a list of running builds from jenkins. This is particularly useful when you need to take an action on a specific built or if you need to know when the jenkins master has finished running all builds (say after quieting down). Add a function to return this list. Change-Id: I5c7dac8076250f94cd2b358c5b153d9410f53aee
This commit is contained in:
parent
f763f5c703
commit
f80e54b4bc
@ -22,6 +22,7 @@ the things you can use it for:
|
||||
* Get information on nodes
|
||||
* Create/delete/reconfig views
|
||||
* Put server in shutdown mode (quiet down)
|
||||
* List running builds
|
||||
* and many more..
|
||||
|
||||
To install::
|
||||
|
@ -57,7 +57,7 @@ import six
|
||||
from six.moves.http_client import BadStatusLine
|
||||
from six.moves.urllib.error import HTTPError
|
||||
from six.moves.urllib.error import URLError
|
||||
from six.moves.urllib.parse import quote, urlencode, urljoin
|
||||
from six.moves.urllib.parse import quote, urlencode, urljoin, urlparse
|
||||
from six.moves.urllib.request import Request, urlopen
|
||||
|
||||
if sys.version_info < (2, 7, 0):
|
||||
@ -726,6 +726,46 @@ class Jenkins(object):
|
||||
self.jenkins_open(Request(
|
||||
self._build_url(STOP_BUILD, locals()), b''))
|
||||
|
||||
def get_running_builds(self):
|
||||
'''Return list of running builds.
|
||||
|
||||
Each build is a dict with keys 'name', 'number', 'url', 'node',
|
||||
and 'executor'.
|
||||
|
||||
:returns: List of builds,
|
||||
``[ { str: str, str: int, str:str, str: str, str: int} ]``
|
||||
|
||||
Example::
|
||||
>>> builds = server.get_running_builds()
|
||||
>>> print(builds)
|
||||
[{'node': 'foo-slave', 'url': 'https://localhost/job/test/15/',
|
||||
'executor': 0, 'name': 'test', 'number': 15}]
|
||||
'''
|
||||
builds = []
|
||||
nodes = self.get_nodes()
|
||||
for node in nodes:
|
||||
# the name returned is not the name to lookup when
|
||||
# dealing with master :/
|
||||
if node['name'] == 'master':
|
||||
node_name = '(master)'
|
||||
else:
|
||||
node_name = node['name']
|
||||
info = self.get_node_info(node_name, depth=2)
|
||||
for executor in info['executors']:
|
||||
executable = executor['currentExecutable']
|
||||
if executable:
|
||||
executor_number = executor['number']
|
||||
build_number = executable['number']
|
||||
url = executable['url']
|
||||
m = re.match(r'/job/([^/]+)/.*', urlparse(url).path)
|
||||
job_name = m.group(1)
|
||||
builds.append({'name': job_name,
|
||||
'number': build_number,
|
||||
'url': url,
|
||||
'node': node_name,
|
||||
'executor': executor_number})
|
||||
return builds
|
||||
|
||||
def get_nodes(self):
|
||||
'''Get a list of nodes connected to the Master
|
||||
|
||||
|
@ -127,3 +127,186 @@ class JenkinsStopBuildTest(JenkinsTestBase):
|
||||
jenkins_mock.call_args[0][0].get_full_url(),
|
||||
u'http://example.com/job/Test%20Job/52/stop')
|
||||
self._check_requests(jenkins_mock.call_args_list)
|
||||
|
||||
|
||||
class JenkinsListRunningBuildsTest(JenkinsTestBase):
|
||||
@patch.object(jenkins.Jenkins, 'get_node_info')
|
||||
@patch.object(jenkins.Jenkins, 'get_nodes')
|
||||
def test_with_builds_master(self, nodes_mock, node_info_mock):
|
||||
nodes_to_return = [{
|
||||
'name': "master", 'offline': False
|
||||
}]
|
||||
nodes_mock.return_value = nodes_to_return
|
||||
build = {
|
||||
"actions": [
|
||||
{
|
||||
"parameters": [
|
||||
{
|
||||
"name": "FOO",
|
||||
"value": "foo"
|
||||
},
|
||||
{
|
||||
"name": "BAR",
|
||||
"value": "bar"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"causes": [
|
||||
{
|
||||
"shortDescription": "Started by user foo",
|
||||
"userId": "foo",
|
||||
"userName": "Foo Bar"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"artifacts": [],
|
||||
"building": True,
|
||||
"description": None,
|
||||
"duration": 0,
|
||||
"estimatedDuration": 20148,
|
||||
"executor": {},
|
||||
"fullDisplayName": "test #1",
|
||||
"id": "2015-09-14_20-25-42",
|
||||
"keepLog": False,
|
||||
"number": 1,
|
||||
"result": None,
|
||||
"timestamp": 1442262342729,
|
||||
"url": "https://localhost/job/test/1/",
|
||||
"builtOn": "",
|
||||
"changeSet": {
|
||||
"items": [],
|
||||
"kind": None
|
||||
},
|
||||
"culprits": []
|
||||
}
|
||||
node_info_to_return = {
|
||||
"executors": [
|
||||
{
|
||||
"currentExecutable": None,
|
||||
"currentWorkUnit": None,
|
||||
"idle": True,
|
||||
"likelyStuck": False,
|
||||
"number": 0,
|
||||
"progress": -1
|
||||
},
|
||||
{
|
||||
"currentExecutable": build,
|
||||
"currentWorkUnit": {},
|
||||
"idle": False,
|
||||
"likelyStuck": False,
|
||||
"number": 1,
|
||||
"progress": 14
|
||||
}
|
||||
],
|
||||
}
|
||||
node_info_mock.return_value = node_info_to_return
|
||||
builds = self.j.get_running_builds()
|
||||
self.assertEqual([{'name': 'test',
|
||||
'number': 1,
|
||||
'node': '(master)',
|
||||
'executor': 1,
|
||||
'url': 'https://localhost/job/test/1/'}], builds)
|
||||
|
||||
@patch.object(jenkins.Jenkins, 'get_node_info')
|
||||
@patch.object(jenkins.Jenkins, 'get_nodes')
|
||||
def test_with_builds_non_master(self, nodes_mock, node_info_mock):
|
||||
nodes_to_return = [{
|
||||
'name': "foo-slave", 'offline': False
|
||||
}]
|
||||
nodes_mock.return_value = nodes_to_return
|
||||
build = {
|
||||
"actions": [
|
||||
{
|
||||
"parameters": [
|
||||
{
|
||||
"name": "FOO",
|
||||
"value": "foo"
|
||||
},
|
||||
{
|
||||
"name": "BAR",
|
||||
"value": "bar"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"causes": [
|
||||
{
|
||||
"shortDescription": "Started by user foo",
|
||||
"userId": "foo",
|
||||
"userName": "Foo Bar"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"artifacts": [],
|
||||
"building": True,
|
||||
"description": None,
|
||||
"duration": 0,
|
||||
"estimatedDuration": 20148,
|
||||
"executor": {},
|
||||
"fullDisplayName": "test #1",
|
||||
"id": "2015-09-14_20-25-42",
|
||||
"keepLog": False,
|
||||
"number": 15,
|
||||
"result": None,
|
||||
"timestamp": 1442262342729,
|
||||
"url": "https://localhost/job/test/15/",
|
||||
"builtOn": "",
|
||||
"changeSet": {
|
||||
"items": [],
|
||||
"kind": None
|
||||
},
|
||||
"culprits": []
|
||||
}
|
||||
node_info_to_return = {
|
||||
"executors": [
|
||||
{
|
||||
"currentExecutable": None,
|
||||
"currentWorkUnit": None,
|
||||
"idle": True,
|
||||
"likelyStuck": False,
|
||||
"number": 1,
|
||||
"progress": -1
|
||||
},
|
||||
{
|
||||
"currentExecutable": build,
|
||||
"currentWorkUnit": {},
|
||||
"idle": False,
|
||||
"likelyStuck": False,
|
||||
"number": 0,
|
||||
"progress": 14
|
||||
}
|
||||
],
|
||||
}
|
||||
node_info_mock.return_value = node_info_to_return
|
||||
builds = self.j.get_running_builds()
|
||||
self.assertEqual([{'name': 'test',
|
||||
'number': 15,
|
||||
'node': 'foo-slave',
|
||||
'executor': 0,
|
||||
'url': 'https://localhost/job/test/15/'}], builds)
|
||||
|
||||
@patch.object(jenkins.Jenkins, 'get_node_info')
|
||||
@patch.object(jenkins.Jenkins, 'get_nodes')
|
||||
def test_with_no_builds(self, nodes_mock, node_info_mock):
|
||||
nodes_to_return = [{
|
||||
'name': "master", 'offline': False
|
||||
}]
|
||||
nodes_mock.return_value = nodes_to_return
|
||||
node_info_to_return = {
|
||||
"executors": [
|
||||
{
|
||||
"currentExecutable": None,
|
||||
"currentWorkUnit": None,
|
||||
"idle": True,
|
||||
"likelyStuck": False,
|
||||
"number": 0,
|
||||
"progress": -1
|
||||
}
|
||||
]
|
||||
}
|
||||
node_info_mock.return_value = node_info_to_return
|
||||
builds = self.j.get_running_builds()
|
||||
self.assertEqual([], builds)
|
||||
|
Loading…
Reference in New Issue
Block a user