Add JSON status endpoint.

Can be used for nifty ajax-style status pages.

Add optional description field to pipeline.

Change-Id: If5db3f6945f65f038833cbf9c783de5ffef63b49
Reviewed-on: https://review.openstack.org/18579
Reviewed-by: Jeremy Stanley <fungi@yuggoth.org>
Approved: James E. Blair <corvus@inaugust.com>
Tested-by: Jenkins
This commit is contained in:
James E. Blair 2012-12-22 10:55:10 -08:00 committed by Jenkins
parent 6aea36dd35
commit 8dbd56aff0
4 changed files with 81 additions and 1 deletions

View File

@ -166,6 +166,10 @@ explanation of each of the parameters::
This is used later in the project definition to indicate what jobs
should be run for events in the pipeline.
**description**
This is an optional field that may be used to provide a textual
description of the pipeline.
**manager**
There are currently two schemes for managing pipelines:

View File

@ -49,9 +49,9 @@ class JenkinsCallback(threading.Thread):
def app(self, environ, start_response):
request = Request(environ)
start_response('200 OK', [('content-type', 'text/html')])
if request.path == '/jenkins_endpoint':
self.jenkins_endpoint(request)
start_response('200 OK', [('content-type', 'text/html')])
return ['Zuul good.']
elif request.path == '/status':
try:
@ -59,8 +59,19 @@ class JenkinsCallback(threading.Thread):
except:
self.log.exception("Exception formatting status:")
raise
start_response('200 OK', [('content-type', 'text/html')])
return [ret]
elif request.path == '/status.json':
try:
ret = self.jenkins.sched.formatStatusJSON()
except:
self.log.exception("Exception formatting status:")
raise
start_response('200 OK', [('content-type', 'application/json'),
('Access-Control-Allow-Origin', '*')])
return [ret]
else:
start_response('200 OK', [('content-type', 'text/html')])
return ['Zuul good.']
def jenkins_endpoint(self, request):

View File

@ -27,6 +27,7 @@ class Pipeline(object):
"""A top-level pipeline such as check, gate, post, etc."""
def __init__(self, name):
self.name = name
self.description = None
self.job_trees = {} # project -> JobTree
self.manager = None
self.queues = []
@ -186,6 +187,24 @@ class Pipeline(object):
ret += self.formatStatus(head, html=True)
return ret
def formatStatusJSON(self):
j_pipeline = dict(name=self.name,
description=self.description)
j_queues = []
j_pipeline['change_queues'] = j_queues
for queue in self.queues:
j_queue = dict(name=queue.name)
j_queues.append(j_queue)
j_queue['heads'] = []
for head in queue.getHeads():
j_changes = []
c = head
while c:
j_changes.append(self.formatChangeJSON(c))
c = c.change_behind
j_queue['heads'].append(j_changes)
return j_pipeline
def formatStatus(self, changeish, indent=0, html=False):
indent_str = ' ' * indent
ret = ''
@ -224,6 +243,29 @@ class Pipeline(object):
ret += self.formatStatus(changeish.change_behind, indent + 2, html)
return ret
def formatChangeJSON(self, changeish):
ret = {}
if hasattr(changeish, 'url') and changeish.url is not None:
ret['url'] = changeish.url
ret['id'] = changeish._id()
ret['project'] = changeish.project.name
ret['jobs'] = []
for job in self.getJobs(changeish):
build = changeish.current_build_set.getBuild(job.name)
if build:
result = build.result
url = build.url
else:
result = None
url = None
ret['jobs'].append(
dict(
name=job.name,
url=url,
result=result,
voting=job.voting))
return ret
class ChangeQueue(object):
"""DependentPipelines have multiple parallel queues shared by

View File

@ -12,6 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.
import json
import logging
import os
import pickle
@ -82,6 +83,7 @@ class Scheduler(threading.Thread):
for conf_pipeline in data.get('pipelines', []):
pipeline = Pipeline(conf_pipeline['name'])
pipeline.description = conf_pipeline.get('description')
manager = globals()[conf_pipeline['manager']](self, pipeline)
pipeline.setManager(manager)
@ -407,6 +409,27 @@ class Scheduler(threading.Thread):
ret += '</pre></html>'
return ret
def formatStatusJSON(self):
data = {}
if self._pause:
ret = '<p><b>Queue only mode:</b> preparing to '
if self._reconfigure:
ret += 'reconfigure'
if self._exit:
ret += 'exit'
ret += ', queue length: %s' % self.trigger_event_queue.qsize()
ret += '</p>'
data['message'] = ret
pipelines = []
data['pipelines'] = pipelines
keys = self.pipelines.keys()
keys.sort()
for key in keys:
pipeline = self.pipelines[key]
pipelines.append(pipeline.formatStatusJSON())
return json.dumps(data)
class BasePipelineManager(object):
log = logging.getLogger("zuul.BasePipelineManager")