tinitial incomplete extraction of jenkins stuff from releasebot - devuan-releasebot - devuan's releasebot reimplemented (scorsh version) HTML git clone git://parazyd.org/devuan-releasebot.git DIR Log DIR Files DIR Refs DIR LICENSE --- DIR commit 28d1b5eacde356a98b00587b0f8efeb32776f817 HTML Author: parazyd <parazyd@dyne.org> Date: Mon, 24 Jul 2017 16:51:23 +0200 initial incomplete extraction of jenkins stuff from releasebot Diffstat: A build.py | 72 +++++++++++++++++++++++++++++++ A buildadd.py | 98 +++++++++++++++++++++++++++++++ A builddel.py | 56 +++++++++++++++++++++++++++++++ A buildmodify.py | 2 ++ A config.py | 40 +++++++++++++++++++++++++++++++ A funcs.py | 52 +++++++++++++++++++++++++++++++ A templates/binaries-config.xml | 134 +++++++++++++++++++++++++++++++ A templates/repos-config.xml | 112 +++++++++++++++++++++++++++++++ A templates/source-config.xml | 119 +++++++++++++++++++++++++++++++ 9 files changed, 685 insertions(+), 0 deletions(-) --- DIR diff --git a/build.py b/build.py t@@ -0,0 +1,72 @@ +#!/usr/bin/env python3 + +""" +Module to build Jenkins build jobs +""" + +import sys +from os import environ as env +from os.path import basename +from xml.etree import ElementTree as ET +import jenkins + +from config import dryrun, buildgroups, jobtypes, suites +from funcs import fill_template + + +def main(): + """ + Main function + """ + print('* Requested job build') + + # Used to differ whether we're adding or modifying + progname = basename(sys.argv[0]) + + print('- Connecting to Jenkins...') + jenk = jenkins.Jenkins(jenkins_host, jenkins_user, jenkins_pass) + + try: + jenk.get_whoami() + except jenkins.JenkinsException: + print('Error in request. Possible authentication fail.') + sys.exit(1) + + # XXX: is this check necessary? + if env['SCORSH_GROUP'] not in buildgroups: + print('Unauthorized for a jenkins build. Quitting.') + sys.exit(1) + + # the -4 cuts off '.git' from the path + pkgname = basename(env['SCORSH_REPO'])[:-4] + + for jobt in jobtypes: + jobname = '-'.join([pkgname, jobt]) + if not jenk.job_exists(jobname): + print('%s does not exist in Jenkins! Quitting.' % jobname) + sys.exit(1) + + # parse xml to find scm uri (line 274) + jobconfig = ET.fromstring(jenk.get_job_config(jobname)) + + jobrepo = "".join(jobconfig.find('scm').find('userRemoteConfigs').find( + 'hudson.plugins.git.UserRemoteConfig').find( + 'url').text.splitlines()) # dafuq!? + + build_for = [] # looks unnecessary in releasebot (line 292) + # perhaps we should just build everywhere we can? + # discuss + + build_for = suites + for build in build_for: + print('- Building for %s' % build) + if not dryrun: + jenk.build_job(jobname, {'codename': build}) + + +if __name__ == '__main__': + if len(sys.argv) > 1: + main() + else: + print('Error: not enough arguments') + sys.exit(1) DIR diff --git a/buildadd.py b/buildadd.py t@@ -0,0 +1,98 @@ +#!/usr/bin/env python3 + +""" +Module to add or modify Jenkins build jobs +""" + +import sys +from os import environ as env +from os.path import basename +import jenkins + +from config import (jenkins_user, jenkins_pass, jenkins_host, jobtypes, + arches_qemusys, architectures, dryrun) +from funcs import fill_template + + +def main(): + """ + Main function + """ + print('* Requested job creation/modification') + + # Used to differ whether we're adding or modifying + progname = basename(sys.argv[0]) + + print('- Connecting to Jenkins...') + jenk = jenkins.Jenkins(jenkins_host, jenkins_user, jenkins_pass) + + try: + jenk.get_whoami() + except jenkins.JenkinsException: + print('Error in request. Possible authentication fail.') + sys.exit(1) + + # the -4 cuts off '.git' from the path + pkgname = basename(env['SCORSH_REPO'])[:-4] + group = env['SCORSH_GROUP'] + + for jobt in jobtypes: + jobname = '-'.join([pkgname, jobt]) + + # TODO: here maybe correlate to config.buildgroups + # i.e.: if not group in buildgroups: exit + + print('* Trying to create %s job for %s/%s' % (jobt, group, pkgname)) + + if jenk.job_exists(jobname) and progname == 'buildadd.py': + print('* %s already exists') + continue + elif not jenk.job_exists(jobname) and progname == 'buildmodify.py': + print('* %s does not exist in Jenkins') + continue + + build_sequential = 'false' + arches = [] + qemusys = [] + jlabels = [] + for arg in sys.argv[1:]: + # XXX: What is build_sequential? + if arg == 'sequential': + build_sequential = 'true' + # XXX: What is pbuilder_network? + elif arg == 'pbuilder_network': + add_buildvar = 'export PBUILDER_USENETWORK=true' + elif arg in architectures: + arches.append(arg) + # XXX: What is qemusys? + elif arg in arches_qemusys: + qemusys.append(arg) + + # set is to remove dupes + jlabels = list(set(arches + qemusys)) + + # XXX: now there is some mention of description + # and puilder_network again. Wat do? + + # Here we use the XML template + pxml = fill_template(pkgname, jobt, arches, + git_uri=env['SCORSH_GITURL'], + buildvar=add_buildvar, + sequential=build_sequential, jlabels=jlabels) + + if pxml and progname == 'buildadd.py': + print('- Creating job') + if not dryrun: + jenk.create_job(jobname, pxml) + elif pxml and progname == 'buildmodify.py': + print('- Modifying job') + if not dryrun: + jenk.reconfig_job(jobname, pxml) + + +if __name__ == '__main__': + if len(sys.argv) > 1: + main() + else: + print('Error: not enough arguments') + sys.exit(1) DIR diff --git a/builddel.py b/builddel.py t@@ -0,0 +1,56 @@ +#!/usr/bin/env python3 + +""" +Module to delete Jenkins build jobs +""" + +import sys +from os import environ as env +from os.path import basename +import jenkins + +from config import (jenkins_user, jenkins_pass, jenkins_host, jobtypes, + dryrun) + + +def main(): + """ + Main function + """ + print('* Requested job deletion') + + print('- Connecting to Jenkins...') + jenk = jenkins.Jenkins(jenkins_host, jenkins_user, jenkins_pass) + + try: + jenk.get_whoami() + except jenkins.JenkinsException: + print('Error in request. Possible authentication fail.') + sys.exit(1) + + for jobt in jobtypes: + # the -4 cuts off '.git' from the path + pkgname = basename(env['SCORSH_REPO'])[:-4] + jobname = '-'.join([pkgname, jobt]) + + # TODO: here maybe correlate to config.buildgroups + # i.e.: if not group in buildgroups: exit + group = env['SCORSH_GROUP'] + + print('* Trying to delete %s job for %s/%s' % (jobt, group, pkgname)) + + if not jenk.job_exists(jobname): + print('* %s does not exist in Jenkins' % jobname) + continue + + print('- Deleting job') + if not dryrun: + jenk.delete_job(jobname) + + +if __name__ == '__main__': + if len(sys.argv) > 1: + main() + else: + print('Error: not enough arguments') + sys.exit(1) DIR diff --git a/buildmodify.py b/buildmodify.py t@@ -0,0 +1 @@ +buildadd.py +\ No newline at end of file DIR diff --git a/config.py b/config.py t@@ -0,0 +1,40 @@ +""" +Releasebot configuration file +""" + +dryrun = True +templatedir = './templates' + +jenkins_user = '' +jenkins_pass = '' +jenkins_host = 'https://ci.devuan.org' + +vcs_credentials = '' + +jobtypes = ['source', 'binaries', 'repos'] + +buildgroups = [ + 'devuan-packages', + 'maemo', +] + +suites = [ + 'jessie', + 'ascii', + 'unstable', +] + +architectures = [ + 'all' + 'amd64', + 'i386', + 'armel', + 'armhf', + 'arm64', +] + +arches_qemusys = [ + 'armel_qemusys', + 'armhf_qemusys', + 'arm64_qemusys', +] DIR diff --git a/funcs.py b/funcs.py t@@ -0,0 +1,52 @@ +""" +Common releasebot functions +""" + +from os.path import isfile, join + +from config import templatedir, vcs_credentials + +def read_template(jobtype): + """ + Reads a template file into memory + """ + fpath = join(templatedir, jobtype+'-config.xml') + if isfile(fpath): + return open(fpath).read() + + return None + + +def fill_template(pkgname, jobtype, arches=[], desc=None, git_uri=None, + buildvar='', sequential=None, jlabels=[]): + """ + Fills up blanks in the template + """ + tmpl = read_template(jobtype) + + + if tmpl: + if not git_uri: + git_uri = 'https://git.devuan.org/devuan-packages/%s.git' % pkgname + if not desc: + desc = 'Releasebot created Jenkins job for %s %s packaging' % \ + (pkgname, jobtype) + archlist = '' + for a in arches: + archlist += ' <string>%s</string>\n' % a + + jlablist = '' + for l in jlabels: + jlablist += ' <string>%s</string>\n' % l + + tmpl = tmpl.replace('[PKGNAME]', pkgname) + tmpl = tmpl.replace('[GIT_URI]', git_uri) + tmpl = tmpl.replace('[GIT_CREDENTIALS]', vcs_credentials) + tmpl = tmpl.replace('[DESCRIPTION]', desc) + tmpl = tmpl.replace('[ARCHITECTURES]', archlist) + tmpl = tmpl.replace('[LABELS]', jlablist) + tmpl = tmpl.replace('[BUILD_ADDVAR]', buildvar) + tmpl = tmpl.replace('[RUNSEQUENTIAL]', sequential) + return tmpl + + return None DIR diff --git a/templates/binaries-config.xml b/templates/binaries-config.xml t@@ -0,0 +1,134 @@ +<?xml version='1.0' encoding='UTF-8'?> +<matrix-project plugin="matrix-project@1.4"> + <actions/> + <description>[DESCRIPTION]</description> + <logRotator class="hudson.tasks.LogRotator"> + <daysToKeep>-1</daysToKeep> + <numToKeep>5</numToKeep> + <artifactDaysToKeep>-1</artifactDaysToKeep> + <artifactNumToKeep>-1</artifactNumToKeep> + </logRotator> + <keepDependencies>false</keepDependencies> + <properties> + <com.suryagaddipati.jenkins.SlaveUtilizationProperty plugin="slave-utilization-plugin@1.8"> + <needsExclusiveAccessToNode>false</needsExclusiveAccessToNode> + <singleInstancePerSlave>false</singleInstancePerSlave> + <slaveUtilizationPercentage>0</slaveUtilizationPercentage> + </com.suryagaddipati.jenkins.SlaveUtilizationProperty> + <hudson.model.ParametersDefinitionProperty> + <parameterDefinitions> + <hudson.model.TextParameterDefinition> + <name>codename</name> + <description></description> + <defaultValue>experimental</defaultValue> + </hudson.model.TextParameterDefinition> + </parameterDefinitions> + </hudson.model.ParametersDefinitionProperty> + </properties> + <scm class="hudson.scm.NullSCM"/> + <canRoam>true</canRoam> + <disabled>false</disabled> + <blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding> + <blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding> + <triggers/> + <concurrentBuild>false</concurrentBuild> + <axes> + <hudson.matrix.TextAxis> + <name>architecture</name> + <values> +[ARCHITECTURES] + </values> + </hudson.matrix.TextAxis> + <hudson.matrix.LabelAxis> + <name>label</name> + <values> +[LABELS] + </values> + </hudson.matrix.LabelAxis> + </axes> parazyd.org:70 /git/devuan-releasebot/commit/28d1b5eacde356a98b00587b0f8efeb32776f817.gph:409: line too long