From 67b1e0b1cb4bf41f37c2d9f5d9add34034fa3c9f Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Thu, 15 Sep 2011 19:22:26 +0300 Subject: Move mangle tool and snippets into own directory. --- control/job-mangle/mangle-jobs | 125 +++++++++++++++++++++++++++++ control/job-mangle/reset-cron.mangle | 7 ++ control/job-mangle/test.mangle | 6 ++ control/job-mangle/update-artifacts.mangle | 5 ++ control/job-mangle/update-jobs.mangle | 9 +++ control/mangle-jobs | 125 ----------------------------- control/reset-cron.mangle | 7 -- control/test.mangle | 6 -- control/update-artifacts.mangle | 5 -- control/update-jobs.mangle | 9 --- 10 files changed, 152 insertions(+), 152 deletions(-) create mode 100755 control/job-mangle/mangle-jobs create mode 100644 control/job-mangle/reset-cron.mangle create mode 100644 control/job-mangle/test.mangle create mode 100644 control/job-mangle/update-artifacts.mangle create mode 100644 control/job-mangle/update-jobs.mangle delete mode 100755 control/mangle-jobs delete mode 100644 control/reset-cron.mangle delete mode 100644 control/test.mangle delete mode 100644 control/update-artifacts.mangle delete mode 100644 control/update-jobs.mangle (limited to 'control') diff --git a/control/job-mangle/mangle-jobs b/control/job-mangle/mangle-jobs new file mode 100755 index 0000000..ee220fb --- /dev/null +++ b/control/job-mangle/mangle-jobs @@ -0,0 +1,125 @@ +#!/usr/bin/python +"""Helper to mass-edit jobs in jenkins. + +""" + +############################################################################### +# Copyright (c) 2011 Linaro +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +############################################################################### + +import base64 +from contextlib import nested +import json +import os +import sys +from tempfile import NamedTemporaryFile +import urllib2 +import optparse + +from lxml.etree import fromstring, tostring + + +optparser = optparse.OptionParser(usage="%prog ") +optparser.add_option("--user", + help="Jenkins username") +optparser.add_option("--passwd-file", metavar="FILE", + help="File holding Jenkins password") +optparser.add_option("--really", action="store_true", + help="Actually perform changes") +optparser.add_option("--limit", type="int", default=-1, + help="Change at most LIMIT jobs") +optparser.add_option("--file", + help="Process a file instead of all jobs on a remote server") + +options, args = optparser.parse_args(sys.argv[1:]) +if len(args) != 1: + optparser.error("Wrong number of arguments") + +d = {} +execfile(args[0], d, d) +mangler = d['mangle'] + +password = None +if options.passwd_file: + password = open(options.passwd_file).read().strip() +auth_headers = { + 'Authorization': 'Basic %s' % ( + base64.encodestring('%s:%s' % (options.user, password))[:-1],), + } + +def _authJenkins(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) + req = urllib2.Request( + 'http://localhost:9090/jenkins/' + jenkins_path, data, headers) + resp = urllib2.urlopen(req) + return resp.read() + +def getJobConfig(job_name): + return _authJenkins('job/' + job_name + '/config.xml') + +def postConfig(url, configXml): + _authJenkins(url, configXml, {'Content-Type': 'text/xml'}) + +def render_xml(tree): + text = tostring(tree, xml_declaration=True, encoding='UTF-8') + line1, rest = text.split("\n", 1) + line1 = line1.replace("'", '"') + return line1 + rest + +def show_diff(old, new): + with nested(NamedTemporaryFile(), NamedTemporaryFile()) as (a, b): + a.write(old) + b.write(new) + a.flush(); b.flush() + os.system('diff -u %s %s' % (a.name, b.name)) + print + +def process_remote_jenkins(): + jobs = json.load(urllib2.urlopen('http://localhost:9090/jenkins/api/json?tree=jobs[name]')) + names = [job['name'] for job in jobs['jobs']] + names = [name for name in names if name == 'blank' or '_' in name] + limit = options.limit + for name in names: + if limit == 0: + break + limit -= 1 + print "Processing:" + name + sys.stdout.flush() + text = getJobConfig(name) + tree = fromstring(text) + mangler(tree) + new_text = render_xml(tree) + if not options.really: + show_diff(text, new_text) + else: + postConfig('job/' + name + '/config.xml', new_text) + +def main(): + if options.file: + text = open(options.file).read() + tree = fromstring(text) + mangler(tree) + new_text = render_xml(tree) + show_diff(text, new_text) + else: + process_remote_jenkins() + +if __name__ == "__main__": + main() diff --git a/control/job-mangle/reset-cron.mangle b/control/job-mangle/reset-cron.mangle new file mode 100644 index 0000000..771c773 --- /dev/null +++ b/control/job-mangle/reset-cron.mangle @@ -0,0 +1,7 @@ +# Reset any triggers of a job, cron triggers in particular (but not limited) + +def mangle(tree): + tag = tree.xpath('//triggers')[0] + for t in tag: + tag.remove(t) + tag.text = None diff --git a/control/job-mangle/test.mangle b/control/job-mangle/test.mangle new file mode 100644 index 0000000..9fbcaa2 --- /dev/null +++ b/control/job-mangle/test.mangle @@ -0,0 +1,6 @@ + +def mangle(tree): + tags = tree.xpath('/project/description') + if not tags: return + tag = tags[0] + tag.text = 'Excitingly created.' diff --git a/control/job-mangle/update-artifacts.mangle b/control/job-mangle/update-artifacts.mangle new file mode 100644 index 0000000..ec6df43 --- /dev/null +++ b/control/job-mangle/update-artifacts.mangle @@ -0,0 +1,5 @@ +new_value = "build/out/target/*/*/*.img,build/out/target/*/*/*.tar.bz2,build/out/*.tar.bz2,build/out/*.xml,build/out/lava-job-info" + +def mangle(tree): + tags = tree.xpath('/project/publishers/hudson.tasks.ArtifactArchiver/artifacts') + tags[0].text = new_value diff --git a/control/job-mangle/update-jobs.mangle b/control/job-mangle/update-jobs.mangle new file mode 100644 index 0000000..a83d815 --- /dev/null +++ b/control/job-mangle/update-jobs.mangle @@ -0,0 +1,9 @@ +new_cmd = '''\ +rm -rf build-tools +bzr get http://bazaar.launchpad.net/~linaro-infrastructure/linaro-android-build-tools/trunk build-tools +build-tools/node/build us-east-1.ec2-git-mirror.linaro.org "$CONFIG" +''' + +def mangle(tree): + tags = tree.xpath('/project/builders/hudson.tasks.Shell/command') + tags[0].text = new_cmd diff --git a/control/mangle-jobs b/control/mangle-jobs deleted file mode 100755 index ee220fb..0000000 --- a/control/mangle-jobs +++ /dev/null @@ -1,125 +0,0 @@ -#!/usr/bin/python -"""Helper to mass-edit jobs in jenkins. - -""" - -############################################################################### -# Copyright (c) 2011 Linaro -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# which accompanies this distribution, and is available at -# http://www.eclipse.org/legal/epl-v10.html -############################################################################### - -import base64 -from contextlib import nested -import json -import os -import sys -from tempfile import NamedTemporaryFile -import urllib2 -import optparse - -from lxml.etree import fromstring, tostring - - -optparser = optparse.OptionParser(usage="%prog ") -optparser.add_option("--user", - help="Jenkins username") -optparser.add_option("--passwd-file", metavar="FILE", - help="File holding Jenkins password") -optparser.add_option("--really", action="store_true", - help="Actually perform changes") -optparser.add_option("--limit", type="int", default=-1, - help="Change at most LIMIT jobs") -optparser.add_option("--file", - help="Process a file instead of all jobs on a remote server") - -options, args = optparser.parse_args(sys.argv[1:]) -if len(args) != 1: - optparser.error("Wrong number of arguments") - -d = {} -execfile(args[0], d, d) -mangler = d['mangle'] - -password = None -if options.passwd_file: - password = open(options.passwd_file).read().strip() -auth_headers = { - 'Authorization': 'Basic %s' % ( - base64.encodestring('%s:%s' % (options.user, password))[:-1],), - } - -def _authJenkins(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) - req = urllib2.Request( - 'http://localhost:9090/jenkins/' + jenkins_path, data, headers) - resp = urllib2.urlopen(req) - return resp.read() - -def getJobConfig(job_name): - return _authJenkins('job/' + job_name + '/config.xml') - -def postConfig(url, configXml): - _authJenkins(url, configXml, {'Content-Type': 'text/xml'}) - -def render_xml(tree): - text = tostring(tree, xml_declaration=True, encoding='UTF-8') - line1, rest = text.split("\n", 1) - line1 = line1.replace("'", '"') - return line1 + rest - -def show_diff(old, new): - with nested(NamedTemporaryFile(), NamedTemporaryFile()) as (a, b): - a.write(old) - b.write(new) - a.flush(); b.flush() - os.system('diff -u %s %s' % (a.name, b.name)) - print - -def process_remote_jenkins(): - jobs = json.load(urllib2.urlopen('http://localhost:9090/jenkins/api/json?tree=jobs[name]')) - names = [job['name'] for job in jobs['jobs']] - names = [name for name in names if name == 'blank' or '_' in name] - limit = options.limit - for name in names: - if limit == 0: - break - limit -= 1 - print "Processing:" + name - sys.stdout.flush() - text = getJobConfig(name) - tree = fromstring(text) - mangler(tree) - new_text = render_xml(tree) - if not options.really: - show_diff(text, new_text) - else: - postConfig('job/' + name + '/config.xml', new_text) - -def main(): - if options.file: - text = open(options.file).read() - tree = fromstring(text) - mangler(tree) - new_text = render_xml(tree) - show_diff(text, new_text) - else: - process_remote_jenkins() - -if __name__ == "__main__": - main() diff --git a/control/reset-cron.mangle b/control/reset-cron.mangle deleted file mode 100644 index 771c773..0000000 --- a/control/reset-cron.mangle +++ /dev/null @@ -1,7 +0,0 @@ -# Reset any triggers of a job, cron triggers in particular (but not limited) - -def mangle(tree): - tag = tree.xpath('//triggers')[0] - for t in tag: - tag.remove(t) - tag.text = None diff --git a/control/test.mangle b/control/test.mangle deleted file mode 100644 index 9fbcaa2..0000000 --- a/control/test.mangle +++ /dev/null @@ -1,6 +0,0 @@ - -def mangle(tree): - tags = tree.xpath('/project/description') - if not tags: return - tag = tags[0] - tag.text = 'Excitingly created.' diff --git a/control/update-artifacts.mangle b/control/update-artifacts.mangle deleted file mode 100644 index ec6df43..0000000 --- a/control/update-artifacts.mangle +++ /dev/null @@ -1,5 +0,0 @@ -new_value = "build/out/target/*/*/*.img,build/out/target/*/*/*.tar.bz2,build/out/*.tar.bz2,build/out/*.xml,build/out/lava-job-info" - -def mangle(tree): - tags = tree.xpath('/project/publishers/hudson.tasks.ArtifactArchiver/artifacts') - tags[0].text = new_value diff --git a/control/update-jobs.mangle b/control/update-jobs.mangle deleted file mode 100644 index a83d815..0000000 --- a/control/update-jobs.mangle +++ /dev/null @@ -1,9 +0,0 @@ -new_cmd = '''\ -rm -rf build-tools -bzr get http://bazaar.launchpad.net/~linaro-infrastructure/linaro-android-build-tools/trunk build-tools -build-tools/node/build us-east-1.ec2-git-mirror.linaro.org "$CONFIG" -''' - -def mangle(tree): - tags = tree.xpath('/project/builders/hudson.tasks.Shell/command') - tags[0].text = new_cmd -- cgit v1.2.3