Added globbed parameters to the job specification
Now you can specify a globbed parameter when updating or deleting a job, it will parse the yaml files and select those jobs that match to be updated/deleted For example: jenkins-jobs --config ~/jenkins.ini update myjobs/ \*only_those\* Will only update the jobs that have 'only_those' on their name. For the delete subcommand the option '-p' lets you specify the path where to load the job list from, so you can use globs for the jobs in that list (it does not allow you to use globs with non-managed jobs) Change-Id: I5bb1074845fb143c7c3120c138a6b138d3548305 Signed-off-by: David Caro <dcaroest@redhat.com>
This commit is contained in:
parent
72d32db155
commit
4dd267ee0d
@ -27,6 +27,7 @@ import pkg_resources
|
||||
import logging
|
||||
import copy
|
||||
import itertools
|
||||
import fnmatch
|
||||
from jenkins_jobs.errors import JenkinsJobsException
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@ -61,6 +62,19 @@ def deep_format(obj, paramdict):
|
||||
return ret
|
||||
|
||||
|
||||
def matches(what, where):
|
||||
"""
|
||||
Checks if the given string matches against the given list of glob patterns
|
||||
|
||||
:arg str what: String that we want to test if matches
|
||||
:arg list where: list of glob patters to match
|
||||
"""
|
||||
for pattern in where:
|
||||
if re.match(fnmatch.translate(pattern), what):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class YamlParser(object):
|
||||
def __init__(self, config=None):
|
||||
self.registry = ModuleRegistry(config)
|
||||
@ -120,7 +134,8 @@ class YamlParser(object):
|
||||
changed = True
|
||||
|
||||
for job in self.data.get('job', {}).values():
|
||||
if jobs_filter and job['name'] not in jobs_filter:
|
||||
if jobs_filter and not matches(job['name'], jobs_filter):
|
||||
logger.debug("Ignoring job {}".format(job['name']))
|
||||
continue
|
||||
logger.debug("XMLifying job '{0}'".format(job['name']))
|
||||
job = self.applyDefaults(job)
|
||||
@ -205,7 +220,7 @@ class YamlParser(object):
|
||||
# We also want to skip XML generation whenever the user did
|
||||
# not ask for that job.
|
||||
job_name = expanded.get('name')
|
||||
if jobs_filter and job_name not in jobs_filter:
|
||||
if jobs_filter and not matches(job_name, jobs_filter):
|
||||
continue
|
||||
|
||||
logger.debug("Generating XML for template job {0}"
|
||||
@ -432,10 +447,17 @@ class Builder(object):
|
||||
self.global_config = config
|
||||
self.ignore_cache = ignore_cache
|
||||
|
||||
def delete_job(self, name):
|
||||
self.jenkins.delete_job(name)
|
||||
if(self.cache.is_cached(name)):
|
||||
self.cache.set(name, '')
|
||||
def load_files(self, fn):
|
||||
if os.path.isdir(fn):
|
||||
files_to_process = [os.path.join(fn, f)
|
||||
for f in os.listdir(fn)
|
||||
if (f.endswith('.yml') or f.endswith('.yaml'))]
|
||||
else:
|
||||
files_to_process = [fn]
|
||||
self.parser = YamlParser(self.global_config)
|
||||
for in_file in files_to_process:
|
||||
logger.debug("Parsing YAML file {0}".format(in_file))
|
||||
self.parser.parse(in_file)
|
||||
|
||||
def delete_old_managed(self, keep):
|
||||
jobs = self.jenkins.get_jobs()
|
||||
@ -446,30 +468,33 @@ class Builder(object):
|
||||
.format(job['name']))
|
||||
self.delete_job(job['name'])
|
||||
|
||||
def delete_job(self, glob_name, fn=None):
|
||||
if fn:
|
||||
self.load_files(fn)
|
||||
self.parser.generateXML(glob_name)
|
||||
jobs = [j.name
|
||||
for j in self.parser.jobs
|
||||
if matches(j.name, [glob_name])]
|
||||
else:
|
||||
jobs = [glob_name]
|
||||
for job in jobs:
|
||||
self.jenkins.delete_job(job)
|
||||
if(self.cache.is_cached(job)):
|
||||
self.cache.set(job, '')
|
||||
|
||||
def delete_all_jobs(self):
|
||||
jobs = self.jenkins.get_jobs()
|
||||
for job in jobs:
|
||||
self.delete_job(job['name'])
|
||||
|
||||
def update_job(self, fn, names=None, output_dir=None):
|
||||
if os.path.isdir(fn):
|
||||
files_to_process = [os.path.join(fn, f)
|
||||
for f in os.listdir(fn)
|
||||
if (f.endswith('.yml') or f.endswith('.yaml'))]
|
||||
else:
|
||||
files_to_process = [fn]
|
||||
parser = YamlParser(self.global_config)
|
||||
for in_file in files_to_process:
|
||||
logger.debug("Parsing YAML file {0}".format(in_file))
|
||||
parser.parse(in_file)
|
||||
if names:
|
||||
logger.debug("Will filter out jobs not in %s" % names)
|
||||
parser.generateXML(names)
|
||||
self.load_files(fn)
|
||||
self.parser.generateXML(names)
|
||||
|
||||
parser.jobs.sort(lambda a, b: cmp(a.name, b.name))
|
||||
self.parser.jobs.sort(lambda a, b: cmp(a.name, b.name))
|
||||
|
||||
for job in parser.jobs:
|
||||
if names and job.name not in names:
|
||||
for job in self.parser.jobs:
|
||||
if names and not matches(job.name, names):
|
||||
continue
|
||||
if output_dir:
|
||||
if names:
|
||||
@ -492,4 +517,4 @@ class Builder(object):
|
||||
self.cache.set(job.name, md5)
|
||||
else:
|
||||
logger.debug("'{0}' has not changed".format(job.name))
|
||||
return parser.jobs
|
||||
return self.parser.jobs
|
||||
|
@ -45,6 +45,8 @@ def main():
|
||||
parser_test.add_argument('name', help='name(s) of job(s)', nargs='*')
|
||||
parser_delete = subparser.add_parser('delete')
|
||||
parser_delete.add_argument('name', help='name of job', nargs='+')
|
||||
parser_delete.add_argument('-p', '--path', default=None,
|
||||
help='Path to YAML file or directory')
|
||||
subparser.add_parser('delete-all',
|
||||
help='Delete *ALL* jobs from Jenkins server, '
|
||||
'including those not managed by Jenkins Job '
|
||||
@ -99,8 +101,8 @@ def main():
|
||||
|
||||
if options.command == 'delete':
|
||||
for job in options.name:
|
||||
logger.info("Deleting job {0}".format(job))
|
||||
builder.delete_job(job)
|
||||
logger.info("Deleting jobs in [{0}]".format(job))
|
||||
builder.delete_job(job, options.path)
|
||||
elif options.command == 'delete-all':
|
||||
confirm('Sure you want to delete *ALL* jobs from Jenkins server?\n'
|
||||
'(including those not managed by Jenkins Job Builder)')
|
||||
|
Loading…
Reference in New Issue
Block a user