Merge "jenkins.py cleanup"
This commit is contained in:
commit
f950b4a4a4
|
@ -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:
|
||||||
|
|
Loading…
Reference in New Issue