aboutsummaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorPaul Sokolovsky <paul.sokolovsky@linaro.org>2013-08-26 23:08:19 +0300
committerPaul Sokolovsky <paul.sokolovsky@linaro.org>2013-08-26 23:08:19 +0300
commit384108fed2773576189998b4bb5cd620939570cd (patch)
tree7cf81583cf0af8554ac5497db70276e5211a3eaa /utils
parent9f53723660470edd7dd53ae7d49719e07f06cbd2 (diff)
Implement job creation.
Diffstat (limited to 'utils')
-rwxr-xr-xutils/cmdline-client/android-build-client138
1 files changed, 86 insertions, 52 deletions
diff --git a/utils/cmdline-client/android-build-client b/utils/cmdline-client/android-build-client
index 73faa47..1bd478c 100755
--- a/utils/cmdline-client/android-build-client
+++ b/utils/cmdline-client/android-build-client
@@ -20,54 +20,73 @@ import optparse
import getpass
from xml.dom import minidom
-from lxml.etree import fromstring, tostring
-
-
-auth_headers = None
-
-def jenkins_rest(jenkins_path, data=None, extra_headers=None):
- """Make an authenticated request to jenkins.
-
- @param jenkins_path: The path on the Jenkins instance to make the request
- to.
- @param data: Data to include in the request (if this is not None the
- request will be a POST).
- @param extra_headers: A dictionary of extra headers that will passed in
- addition to Authorization.
- @raises urllib2.HTTPError: If the response is not a HTTP 200.
- @returns: the body of the response.
- """
- headers = auth_headers.copy()
- if extra_headers:
- headers.update(extra_headers)
- url = options.url + jenkins_path
- print url
- req = urllib2.Request(
- url, data, headers)
- resp = urllib2.urlopen(req)
- return resp.read()
-
-def get_job_config(job_name):
- return jenkins_rest('job/' + job_name + '/config.xml')
-
-def set_job_config(url, configXml, extra_headers=None):
- headers = {'Content-Type': 'text/xml', }
- if extra_headers is not None:
- headers.update(extra_headers)
- _authJenkins(url, configXml, headers)
-
-def get_csrf_headers():
- try:
- crumb_data = _authJenkins('crumbIssuer/api/json')
- except urllib2.HTTPError:
- # Ignore errors in case CSRF protection is not enabled
- return {}
- data = json.loads(crumb_data)
- return {data['crumbRequestField']: data['crumb']}
+class Jenkins(object):
+
+ def __init__(self, base_url, username, passwd):
+ self.base = base_url
+ self.auth_headers = {
+ 'Authorization': 'Basic %s' % (
+ base64.b64encode('%s:%s' % (username, passwd)))}
+ self.csrf = None
+
+ def jenkins_rest(self, jenkins_path, data=None, extra_headers=None):
+ """Make an authenticated request to jenkins.
+
+ @param jenkins_path: The path on the Jenkins instance to make the request
+ to.
+ @param data: Data to include in the request (if this is not None the
+ request will be a POST).
+ @param extra_headers: A dictionary of extra headers that will passed in
+ addition to Authorization.
+ @raises urllib2.HTTPError: If the response is not a HTTP 200.
+ @returns: the body of the response.
+ """
+ headers = self.auth_headers.copy()
+ if extra_headers:
+ headers.update(extra_headers)
+ url = self.base + jenkins_path
+ print url
+ req = urllib2.Request(
+ url, data, headers)
+ resp = urllib2.urlopen(req)
+ return resp.read()
+
+ def get_csrf_headers(self):
+ if self.csrf is None:
+ try:
+ crumb_data = self.jenkins_rest('crumbIssuer/api/json')
+ data = json.loads(crumb_data)
+ self.csrf = {data['crumbRequestField']: data['crumb']}
+ except urllib2.HTTPError:
+ # Ignore errors in case CSRF protection is not enabled
+ self.csrf = {}
+ return self.csrf
+
+ def get_job_config(self, job_name):
+ return self.jenkins_rest('job/' + job_name + '/config.xml')
+
+ def _post_config(self, url, config_xml):
+ headers = self.get_csrf_headers()
+ headers['Content-Type'] = 'text/xml'
+ return self.jenkins_rest(url, config_xml, headers)
+
+ def set_job_config(self, job_name, config_xml):
+ return self._post_config('job/' + job_name + '/config.xml', config_xml)
+
+ def create_job(self, job_name, config_xml):
+ return self._post_config('createItem?name=' + job_name, config_xml)
+
+def job2user_group(job_group):
+ if job_group == "linaro-android":
+ return "linaro-android-builders"
+ return job_group
+
+def error(msg):
+ print msg
+ sys.exit(1)
def main():
- global auth_headers
global options
optparser = optparse.OptionParser(usage="%prog <cmd> <args>...")
optparser.add_option("--url", default="https://android-build.linaro.org/jenkins",
@@ -96,13 +115,28 @@ def main():
if options.url[-1] != '/':
options.url += '/'
- auth_headers = {
- 'Authorization': 'Basic %s' % (
- base64.encodestring('%s:%s' % (options.user, password))[:-1],),
- }
-
- job_group, job_subname = args[1].split("/")
- print get_job_config("template_" + job_group)
+ j = Jenkins(options.url, options.user, password)
+
+ if args[0] == "create":
+ if len(args) != 3:
+ optparser.error("Usage: create <job_name> <build_config_file>")
+ job_group, job_subname = args[1].split("/")
+ template = j.get_job_config("template_" + job2user_group(job_group))
+ dom = minidom.parseString(template)
+ nodes = dom.getElementsByTagName("hudson.model.StringParameterDefinition")
+ assert len(nodes) == 1
+ n = nodes[0].getElementsByTagName("defaultValue")[0]
+ build_config = open(args[2]).read()
+ n.childNodes[0].data = base64.encodestring(build_config)
+ job_conf = dom.toxml()
+ jenkins_job = args[1].replace("/", "_")
+ try:
+ j.create_job(jenkins_job, job_conf)
+ except urllib2.HTTPError, e:
+ error("Error creating job '%s' (job exists?)" % jenkins_job)
+ print "Job created successfully: %s/job/%s/" % (options.url, jenkins_job)
+ else:
+ optparser.error("Unknown command '%s'" % args[0])
if __name__ == "__main__":