# jobconfig.py -- create Jenkins job config.xml files # # Copyright 2012 Lars Wirzenius # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import StringIO from xml.etree import ElementTree as ET empty = '''\ false true false false false false ''' class JobConfig(object): '''Create a Jenkins job configuration XML file. This does not try to be complete, and only tries to do the minimal things I need for my automated job creation needs. ''' def __init__(self): self._project = ET.fromstring(empty) self._tree = ET.ElementTree(self._project) self._param_dicts = [] def set_job_suffix(self, suffix): self._suffix = suffix def add_param_dict(self, prefix, param_dict): self._param_dicts.append((prefix, param_dict)) def _get_params(self): unified = {} for prefix, param_dict in self._param_dicts: for key in param_dict: unified['%s.%s' % (prefix, key)] = param_dict[key] return unified def job_id(self): '''Create a unique job id from constituent parts. Escape characters that Jenkins gets upset by, such as '@'. ''' def esc(s): s = '.'.join(s.split('@')) return s s = '%(project.name)s_%(host.name)s_' + self._suffix return esc(s % self._get_params()) def tostring(self): f = StringIO.StringIO() self._tree.write( f, xml_declaration=True, method='xml', encoding='UTF-8') return f.getvalue() def set_description(self, new_description): description = self._tree.find('description') description.clear() description.text = new_description % self._get_params() def set_name(self, new_name): displayName = self._tree.find('displayName') if displayName is not None: displayName.clear() else: displayName = ET.SubElement(self._project, 'displayName') displayName.text = new_name % self._get_params() def add_shell_command(self, shell_text): builders = self._project.find('builders') shell = ET.SubElement(builders, 'hudson.tasks.Shell') shell_text = 'set -eux\n' + shell_text ET.SubElement(shell, 'command').text = shell_text % self._get_params() def add_ssh_command(self, shell_text): prefix = '''\ ssh "%(host.ssh-target)s" sh <<\\END set -eux mkdir -p "%(host.directory)s" cd "%(host.directory)s" ''' suffix = '\nEND' self.add_shell_command(prefix + shell_text + suffix) def set_bzr(self, url): scm = self._project.find('scm') scm.clear() scm.set('class', 'hudson.plugins.bazaar.BazaarSCM') ET.SubElement(scm, 'source').text = url ET.SubElement(scm, 'clean').text = 'false' ET.SubElement(scm, 'checkout').text = 'false' def set_git(self, url): scm = self._project.find('scm') scm.clear() scm.set('class', 'hudson.plugins.git.GitSCM') ET.SubElement(scm, 'configVersion').text = '2' remotes = ET.SubElement(scm, 'userRemoteConfigs') urc = ET.SubElement(remotes, 'hudson.plugins.git.UserRemoteConfig') ET.SubElement(urc, 'name').text = '' ET.SubElement(urc, 'refspec').text = '' ET.SubElement(urc, 'url').text = url branches = ET.SubElement(scm, 'branches') spec = ET.SubElement(branches, 'hudson.plugins.git.BranchSpec') ET.SubElement(spec, 'name').text = '**' ET.SubElement(scm, 'disableSubmodules').text = 'false' ET.SubElement(scm, 'recursiveSubmodules').text = 'false' ET.SubElement(scm, 'doGenerateSubmoduleConfigurations').text = 'false' ET.SubElement(scm, 'authorOrCommitter').text = 'false' ET.SubElement(scm, 'clean').text = 'false' ET.SubElement(scm, 'wipeOutWorkspace').text = 'false' ET.SubElement(scm, 'pruneBranches').text = 'false' ET.SubElement(scm, 'remotePoll').text = 'false' ET.SubElement(scm, 'ignoreNotifyCommit').text = 'false' chooser = ET.SubElement(scm, 'buildChooser') chooser.set('class', 'hudson.plugins.git.util.DefaultBuildChooser') ET.SubElement(scm, 'gitTool').text = 'Default' ET.SubElement(scm, 'submoduleCfg').set('class', 'list') ET.SubElement(scm, 'relativeTargetDir').text = '' ET.SubElement(scm, 'reference').text = '' ET.SubElement(scm, 'excludedRegions').text = '' ET.SubElement(scm, 'excludedUsers').text = '' ET.SubElement(scm, 'gitConfigName').text = '' ET.SubElement(scm, 'gitConfigEmail').text = '' ET.SubElement(scm, 'skipTag').text = 'true' ET.SubElement(scm, 'includedRegions').text = '' ET.SubElement(scm, 'scmName').text = ''