From c166c000bcd05e2c24e636f34da2c4a796dba198 Mon Sep 17 00:00:00 2001 From: Aleksey Maksimov Date: Fri, 12 Jul 2013 16:21:59 +0800 Subject: [PATCH] Added Jobs() container (similar to Views()) --- jenkinsapi/jenkins.py | 73 ++++++++---------------- jenkinsapi/jobs.py | 125 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 147 insertions(+), 51 deletions(-) create mode 100644 jenkinsapi/jobs.py diff --git a/jenkinsapi/jenkins.py b/jenkinsapi/jenkins.py index 8c2b2aa..a6fddf1 100644 --- a/jenkinsapi/jenkins.py +++ b/jenkinsapi/jenkins.py @@ -4,6 +4,7 @@ import logging from jenkinsapi import config from jenkinsapi.job import Job +from jenkinsapi.jobs import Jobs from jenkinsapi.node import Node from jenkinsapi.view import View from jenkinsapi.nodes import Nodes @@ -12,12 +13,11 @@ from jenkinsapi.queue import Queue from jenkinsapi.fingerprint import Fingerprint from jenkinsapi.jenkinsbase import JenkinsBase from jenkinsapi.utils.requester import Requester -from jenkinsapi.exceptions import UnknownJob, JenkinsAPIException - - +from jenkinsapi.exceptions import UnknownJob log = logging.getLogger(__name__) + class Jenkins(JenkinsBase): """ Represents a jenkins environment. @@ -35,7 +35,8 @@ class Jenkins(JenkinsBase): JenkinsBase.__init__(self, baseurl) def _clone(self): - return Jenkins(self.baseurl, username=self.username, password=self.password, requester=self.requester) + return Jenkins(self.baseurl, username=self.username, + password=self.password, requester=self.requester) def base_server_url(self): if config.JENKINS_API in self.baseurl: @@ -75,12 +76,17 @@ class Jenkins(JenkinsBase): # This only ever needs to work on the base object return '%s/computer' % self.baseurl + @property + def jobs(self): + return Jobs(self) + def get_jobs(self): """ Fetch all the build-names on this Jenkins server. """ for info in self._data["jobs"]: - yield info["name"], Job(info["url"], info["name"], jenkins_obj=self) + yield info["name"],\ + Job(info["url"], info["name"], jenkins_obj=self) def get_jobs_info(self): """ @@ -96,7 +102,7 @@ class Jenkins(JenkinsBase): :param jobname: name of the job, str :return: Job obj """ - return self[jobname] + return self.jobs[jobname] def has_job(self, jobname): """ @@ -104,7 +110,7 @@ class Jenkins(JenkinsBase): :param jobname: string :return: boolean """ - return jobname in self + return jobname in self.jobs def create_job(self, jobname, config): """ @@ -113,35 +119,10 @@ class Jenkins(JenkinsBase): :param config: configuration of new job, xml :return: new Job obj """ - if self.has_job(jobname): - return self[jobname] - - params = {'name': jobname} - if isinstance(config, unicode): - config = str(config) - self.requester.post_xml_and_confirm_status(self.get_create_url(), data=config, params=params) - self.poll() - if not self.has_job(jobname): - raise JenkinsAPIException('Cannot create job %s' % jobname) - return self[jobname] + return self.jobs.create(jobname, config) def copy_job(self, jobname, newjobname): - """ - Copy a job - :param jobname: name of a exist job, str - :param newjobname: name of new job, str - :return: new Job obj - """ - params = { 'name': newjobname, - 'mode': 'copy', - 'from': jobname} - - self.requester.post_and_confirm_status( - self.get_create_url(), - params=params, - data='') - self.poll() - return self[newjobname] + return self.jobs.copy(jobname, newjobname) def build_job(self, jobname, params={}): """ @@ -150,7 +131,7 @@ class Jenkins(JenkinsBase): :param params: the job params, dict :return: none """ - self[jobname].invoke(build_params=params) + self.jobs.build(jobname, params=params) return def delete_job(self, jobname): @@ -159,13 +140,7 @@ class Jenkins(JenkinsBase): :param jobname: name of a exist job, str :return: new jenkins_obj """ - delete_job_url = self[jobname].get_delete_url() - self.requester.post_and_confirm_status( - delete_job_url, - data='some random bytes...' - ) - self.poll() - return self + del self.jobs[jobname] def rename_job(self, jobname, newjobname): """ @@ -174,12 +149,7 @@ class Jenkins(JenkinsBase): :param newjobname: name of new job, str :return: new Job obj """ - params = {'newName': newjobname} - rename_job_url = self[jobname].get_rename_url() - self.requester.post_and_confirm_status( - rename_job_url, params=params, data='') - self.poll() - return self[newjobname] + return self.jobs.rename(jobname, newjobname) def iterkeys(self): for info in self._data["jobs"]: @@ -187,7 +157,8 @@ class Jenkins(JenkinsBase): def iteritems(self): """ - :param return: An iterator of pairs. Each pair will be (job name, Job object) + :param return: An iterator of pairs. + Each pair will be (job name, Job object) """ return self.get_jobs() @@ -198,7 +169,7 @@ class Jenkins(JenkinsBase): return list(self.get_jobs()) def keys(self): - return [ a for a in self.iterkeys() ] + return [a for a in self.iterkeys()] # This is a function alias we retain for historical compatibility get_jobs_list = keys @@ -232,7 +203,7 @@ class Jenkins(JenkinsBase): :param jobname: string :return: boolean """ - return jobname in self.get_jobs_list() + return jobname in self.jobs def get_node(self, nodename): """Get a node object for a specific node""" diff --git a/jenkinsapi/jobs.py b/jenkinsapi/jobs.py new file mode 100644 index 0000000..7b984e8 --- /dev/null +++ b/jenkinsapi/jobs.py @@ -0,0 +1,125 @@ +import logging +from jenkinsapi.job import Job +from jenkinsapi.exceptions import JenkinsAPIException + +log = logging.getLogger(__name__) + + +class Jobs(object): + + def __init__(self, jenkins): + self.jenkins = jenkins + + def __len__(self): + return len(self.keys) + + def __delitem__(self, job_name): + """ + Delete a job by name + :param job_name: name of a exist job, str + """ + if job_name in self: + delete_job_url = self[job_name].get_delete_url() + self.jenkins.requester.post_and_confirm_status( + delete_job_url, + data='some random bytes...' + ) + self.jenkins.poll() + + def __getitem__(self, job_name): + for row in self.jenkins._data.get('jobs', []): + if row['name'] == job_name: + return Job( + row['url'], + row['name'], + self.jenkins) + else: + return None + + def iteritems(self): + """ + Get the names & objects for all jobs + """ + self.jenkins.poll() + for row in self.jenkins._data.get('jobs', []): + name = row['name'] + url = row['url'] + + yield name, Job(url, name, self.jenkins) + + def __contains__(self, job_name): + """ + True if job_name is the name of a defined job + """ + return job_name in self.keys() + + def iterkeys(self): + """ + Get the names of all available views + """ + for row in self.jenkins._data.get('jobs', []): + yield row['name'] + + def keys(self): + """ + Return a list of the names of all jobs + """ + return list(self.iterkeys()) + + def create(self, job_name, config): + """ + Create a job + :param jobname: name of new job, str + :param config: configuration of new job, xml + :return: new Job obj + """ + if job_name in self: + return self[job_name] + + params = {'name': job_name} + if isinstance(config, unicode): + config = str(config) + self.jenkins.requester.\ + post_xml_and_confirm_status(self.jenkins.get_create_url(), + data=config, params=params) + self.jenkins.poll() + if job_name not in self: + raise JenkinsAPIException('Cannot create job %s' % job_name) + + return self[job_name] + + def copy(self, job_name, new_job_name): + """ + Copy a job + :param job_name: name of a exist job, str + :param new_job_name: name of new job, str + :return: new Job obj + """ + params = {'name': new_job_name, + 'mode': 'copy', + 'from': job_name} + + self.requester.post_and_confirm_status( + self.jenkins.get_create_url(), + params=params, + data='') + self.jenkins.poll() + return self[new_job_name] + + def rename(self, job_name, new_job_name): + """ + Rename a job + :param job_name: name of a exist job, str + :param new_job_name: name of new job, str + :return: new Job obj + """ + params = {'newName': new_job_name} + rename_job_url = self[job_name].get_rename_url() + self.requester.post_and_confirm_status( + rename_job_url, params=params, data='') + self.jenkins.poll() + return self[new_job_name] + + def build(self, job_name, params): + assert(isinstance(params, dict)) + self[job_name].invoke(build_params=params) -- 2.34.1