From 3b9f526111d81a11b43f87d3579eddccb6c9658f Mon Sep 17 00:00:00 2001 From: Aleksey Maksimov Date: Thu, 10 Jul 2014 21:50:48 +0800 Subject: Fix for issue #291 Methods will re-try POST if GET fails --- jenkinsapi/custom_exceptions.py | 7 +++++++ jenkinsapi/jenkins.py | 8 ++++++-- jenkinsapi/node.py | 7 ++++++- jenkinsapi/utils/requester.py | 9 ++++++--- 4 files changed, 25 insertions(+), 6 deletions(-) (limited to 'jenkinsapi') diff --git a/jenkinsapi/custom_exceptions.py b/jenkinsapi/custom_exceptions.py index 2dde269..46c3b9d 100644 --- a/jenkinsapi/custom_exceptions.py +++ b/jenkinsapi/custom_exceptions.py @@ -126,3 +126,10 @@ class NotInQueue(JenkinsAPIException): It's a job that is not in the queue """ pass + + +class PostRequired(JenkinsAPIException): + """ + Method requires POST and not GET + """ + pass diff --git a/jenkinsapi/jenkins.py b/jenkinsapi/jenkins.py index ac16160..6d25c74 100644 --- a/jenkinsapi/jenkins.py +++ b/jenkinsapi/jenkins.py @@ -28,7 +28,7 @@ from jenkinsapi.queue import Queue from jenkinsapi.fingerprint import Fingerprint from jenkinsapi.jenkinsbase import JenkinsBase from jenkinsapi.utils.requester import Requester -from jenkinsapi.custom_exceptions import UnknownJob +from jenkinsapi.custom_exceptions import UnknownJob, PostRequired log = logging.getLogger(__name__) @@ -286,7 +286,11 @@ class Jenkins(JenkinsBase): assert self.has_node(nodename), "This node: %s is not registered as a slave" % nodename assert nodename != "master", "you cannot delete the master node" url = "%s/doDelete" % self.get_node_url(nodename) - self.requester.get_and_confirm_status(url) + try: + self.requester.get_and_confirm_status(url) + except PostRequired: + # Latest Jenkins requires POST here. GET kept for compatibility + self.requester.post_and_confirm_status(url, data={}) def create_node(self, name, num_executors=2, node_description=None, remote_fs='/var/lib/jenkins', labels=None, exclusive=False): diff --git a/jenkinsapi/node.py b/jenkinsapi/node.py index 7039e38..27ddd51 100644 --- a/jenkinsapi/node.py +++ b/jenkinsapi/node.py @@ -3,6 +3,7 @@ Module for jenkinsapi Node class """ from jenkinsapi.jenkinsbase import JenkinsBase +from jenkinsapi.custom_exceptions import PostRequired import logging try: @@ -94,7 +95,11 @@ class Node(JenkinsBase): """ initial_state = self.is_temporarily_offline() url = self.baseurl + "/toggleOffline?offlineMessage=" + urlquote(message) - html_result = self.jenkins.requester.get_and_confirm_status(url) + try: + html_result = self.jenkins.requester.get_and_confirm_status(url) + except PostRequired: + html_result = self.jenkins.requester.post_and_confirm_status(url, data={}) + self.poll() log.debug(html_result) state = self.is_temporarily_offline() diff --git a/jenkinsapi/utils/requester.py b/jenkinsapi/utils/requester.py index 2116c91..d7a994f 100644 --- a/jenkinsapi/utils/requester.py +++ b/jenkinsapi/utils/requester.py @@ -10,7 +10,7 @@ except ImportError: # Python3 import urllib.parse as urlparse -from jenkinsapi.custom_exceptions import JenkinsAPIException +from jenkinsapi.custom_exceptions import JenkinsAPIException, PostRequired # import logging # # these two lines enable debugging at httplib level (requests->urllib3->httplib) @@ -121,6 +121,9 @@ class Requester(object): valid = valid or self.VALID_STATUS_CODES response = self.get_url(url, params, headers) if not response.status_code in valid: - raise JenkinsAPIException('Operation failed. url={0}, headers={1}, status={2}, text={3}'.format( - response.url, headers, response.status_code, response.text.encode('UTF-8'))) + if response.status_code == 405: # POST required + raise PostRequired('POST required for url {0}'.format(url)) + else: + raise JenkinsAPIException('Operation failed. url={0}, headers={1}, status={2}, text={3}'.format( + response.url, headers, response.status_code, response.text.encode('UTF-8'))) return response -- cgit v1.2.3