Merge "jenkins.py cleanup"

This commit is contained in:
Jenkins 2012-07-24 19:35:35 +00:00 committed by Gerrit Code Review
commit f950b4a4a4
1 changed files with 57 additions and 49 deletions

View File

@ -16,18 +16,19 @@
# system module # system module
from __future__ import absolute_import from __future__ import absolute_import
import threading
from webob import Request
from paste import httpserver
from uuid import uuid1
import jenkins
import json import json
import logging
import pprint
import threading
import time
import urllib # for extending jenkins lib import urllib # for extending jenkins lib
import urllib2 # for extending jenkins lib import urllib2 # for extending jenkins lib
import urlparse import urlparse
import logging from uuid import uuid1
import pprint
import time import jenkins
from paste import httpserver
from webob import Request
from zuul.model import Build from zuul.model import Build
@ -61,8 +62,8 @@ class JenkinsCallback(threading.Thread):
def jenkins_endpoint(self, request): def jenkins_endpoint(self, request):
data = json.loads(request.body) data = json.loads(request.body)
if data: if data:
self.log.debug("Received data from Jenkins: \n%s" % ( self.log.debug("Received data from Jenkins: \n%s" %
pprint.pformat(data))) (pprint.pformat(data)))
build = data.get('build') build = data.get('build')
if build: if build:
phase = build.get('phase') phase = build.get('phase')
@ -72,9 +73,11 @@ class JenkinsCallback(threading.Thread):
params = build.get('parameters') params = build.get('parameters')
if params: if params:
uuid = params.get('UUID') uuid = params.get('UUID')
if (status and url and uuid and phase if (status and url and uuid and phase and
and phase == 'COMPLETED'): phase == 'COMPLETED'):
self.jenkins.onBuildCompleted(uuid, status, url, self.jenkins.onBuildCompleted(uuid,
status,
url,
number) number)
if (phase and phase == 'STARTED'): if (phase and phase == 'STARTED'):
self.jenkins.onBuildStarted(uuid, url, number) self.jenkins.onBuildStarted(uuid, url, number)
@ -127,7 +130,8 @@ class ExtendedJenkins(jenkins.Jenkins):
@param number: Jenkins build number for the job @param number: Jenkins build number for the job
@type number: int @type number: int
''' '''
self.jenkins_open(urllib2.Request(self.server + STOP_BUILD % locals())) request = urllib2.Request(self.server + STOP_BUILD % locals())
self.jenkins_open(request)
def cancel_queue(self, number): def cancel_queue(self, number):
''' '''
@ -138,9 +142,9 @@ class ExtendedJenkins(jenkins.Jenkins):
''' '''
# Jenkins returns a 302 from this URL, unless Referer is not set, # Jenkins returns a 302 from this URL, unless Referer is not set,
# then you get a 404. # then you get a 404.
self.jenkins_open(urllib2.Request(self.server + request = urllib2.Request(self.server + CANCEL_QUEUE % locals(),
CANCEL_QUEUE % locals(), headers={'Referer': self.server})
headers={'Referer': self.server})) self.jenkins_open(request)
def get_build_info(self, name, number): def get_build_info(self, name, number):
''' '''
@ -152,8 +156,8 @@ class ExtendedJenkins(jenkins.Jenkins):
@type number: int @type number: int
@return: dictionary @return: dictionary
''' '''
return json.loads(self.jenkins_open(urllib2.Request( request = urllib2.Request(self.server + BUILD_INFO % locals())
self.server + BUILD_INFO % locals()))) return json.loads(self.jenkins_open(request))
def set_build_description(self, name, number, description): def set_build_description(self, name, number, description):
''' '''
@ -167,9 +171,9 @@ class ExtendedJenkins(jenkins.Jenkins):
@type description: str @type description: str
''' '''
params = urllib.urlencode({'description': description}) params = urllib.urlencode({'description': description})
self.jenkins_open(urllib2.Request(self.server + request = urllib2.Request(self.server + BUILD_DESCRIPTION % locals(),
BUILD_DESCRIPTION % locals(), params)
params)) self.jenkins_open(request)
class Jenkins(object): class Jenkins(object):
@ -225,17 +229,17 @@ class Jenkins(object):
break break
except: except:
errored = True errored = True
self.log.exception( self.log.exception("Exception launching build %s for "
"Exception launching build %s for job %s for change %s\ "job %s for change %s (will retry):" %
(will retry):" % (build, job, change)) (build, job, change))
time.sleep(5) time.sleep(5)
if errored: if errored:
if launched: if launched:
self.log.error("Finally able to launch %s" % build) self.log.error("Finally able to launch %s" % build)
else: else:
self.log.error("Unable to launch %s, even after retrying,\ self.log.error("Unable to launch %s, even after retrying, "
declaring lost" % build) "declaring lost" % build)
# To keep the queue moving, declare this as a lost build # To keep the queue moving, declare this as a lost build
# so that the change will get dropped. # so that the change will get dropped.
self.onBuildCompleted(build.uuid, 'LOST', None, None) self.onBuildCompleted(build.uuid, 'LOST', None, None)
@ -269,17 +273,16 @@ declaring lost" % build)
self.log.debug("Looking for build %s in queue" % build) self.log.debug("Looking for build %s in queue" % build)
item = self.findBuildInQueue(build) item = self.findBuildInQueue(build)
if item: if item:
self.log.debug("Found queue item %s for build %s" % ( self.log.debug("Found queue item %s for build %s" %
item['id'], build)) (item['id'], build))
try: try:
self.jenkins.cancel_queue(item['id']) self.jenkins.cancel_queue(item['id'])
self.log.debug( self.log.debug("Canceled queue item %s for build %s" %
"Canceled queue item %s for build %s" % ( (item['id'], build))
item['id'], build))
return return
except: except:
self.log.exception("Exception canceling queue item %s \ self.log.exception("Exception canceling queue item %s "
for build %s" % (item['id'], build)) "for build %s" % (item['id'], build))
self.log.debug("Still unable to find build %s to cancel" % build) self.log.debug("Still unable to find build %s to cancel" % build)
if build.number: if build.number:
@ -287,9 +290,8 @@ for build %s" % (item['id'], build))
self.jenkins.stop_build(build.job.name, build.number) self.jenkins.stop_build(build.job.name, build.number)
self.log.debug("Canceled just running build %s" % build) self.log.debug("Canceled just running build %s" % build)
else: else:
self.log.error( self.log.error("Build %s has not started but "
"Build %s has not started but was not found in queue" % "was not found in queue" % build)
build)
def getBestBuildURL(self, url): def getBestBuildURL(self, url):
try: try:
@ -310,15 +312,16 @@ for build %s" % (item['id'], build))
if not build.number: if not build.number:
return return
try: try:
self.jenkins.set_build_description(build.job.name, build.number, self.jenkins.set_build_description(build.job.name,
build.number,
description) description)
except: except:
self.log.exception("Exception setting build description for %s" % self.log.exception("Exception setting build description for %s" %
build) build)
def onBuildCompleted(self, uuid, status, url, number): def onBuildCompleted(self, uuid, status, url, number):
self.log.info("Build %s #%s complete, status %s" % ( self.log.info("Build %s #%s complete, status %s" %
uuid, number, status)) (uuid, number, status))
build = self.builds.get(uuid) build = self.builds.get(uuid)
if build: if build:
self.log.debug("Found build %s" % build) self.log.debug("Found build %s" % build)
@ -365,16 +368,19 @@ for build %s" % (item['id'], build))
if hasattr(build, '_jenkins_missing_build_info'): if hasattr(build, '_jenkins_missing_build_info'):
missing_time = build._jenkins_missing_build_info missing_time = build._jenkins_missing_build_info
if time.time() - missing_time > JENKINS_GRACE_TIME: if time.time() - missing_time > JENKINS_GRACE_TIME:
self.log.debug("Lost build %s because it has \ self.log.debug("Lost build %s because "
started but the build URL is not working" % build) "it has started but "
"the build URL is not working" %
build)
lostbuilds.append(build) lostbuilds.append(build)
else: else:
build._jenkins_missing_build_info = time.time() build._jenkins_missing_build_info = time.time()
continue continue
if not info: if not info:
self.log.debug("Lost build %s because it started but \ self.log.debug("Lost build %s because "
info can not be retreived" % build) "it started but "
"info can not be retreived" % build)
lostbuilds.append(build) lostbuilds.append(build)
continue continue
if info['building']: if info['building']:
@ -382,8 +388,9 @@ info can not be retreived" % build)
continue continue
finish_time = (info['timestamp'] + info['duration']) / 1000 finish_time = (info['timestamp'] + info['duration']) / 1000
if time.time() - finish_time > JENKINS_GRACE_TIME: if time.time() - finish_time > JENKINS_GRACE_TIME:
self.log.debug("Lost build %s because it finished \ self.log.debug("Lost build %s because "
more than 5 minutes ago. Build info %s:" % (build, info)) "it finished more than 5 minutes ago. "
"Build info %s:" % (build, info))
lostbuilds.append(build) lostbuilds.append(build)
continue continue
# Give it more time # Give it more time
@ -404,8 +411,9 @@ more than 5 minutes ago. Build info %s:" % (build, info))
if hasattr(build, '_jenkins_missing_from_queue'): if hasattr(build, '_jenkins_missing_from_queue'):
missing_time = build._jenkins_missing_from_queue missing_time = build._jenkins_missing_from_queue
if time.time() - missing_time > JENKINS_GRACE_TIME: if time.time() - missing_time > JENKINS_GRACE_TIME:
self.log.debug("Lost build %s because it has not \ self.log.debug("Lost build %s because "
started and is not in the queue" % build) "it has not started and "
"is not in the queue" % build)
lostbuilds.append(build) lostbuilds.append(build)
continue continue
else: else: