Fix for issue #291
authorAleksey Maksimov <ctpeko3a@gmail.com>
Thu, 10 Jul 2014 13:50:48 +0000 (21:50 +0800)
committerAleksey Maksimov <ctpeko3a@gmail.com>
Thu, 10 Jul 2014 13:50:48 +0000 (21:50 +0800)
Methods will re-try POST if GET fails

jenkinsapi/custom_exceptions.py
jenkinsapi/jenkins.py
jenkinsapi/node.py
jenkinsapi/utils/requester.py

index 2dde2696117aa6b35ced1f27fd48e5bad86349ee..46c3b9dbca6f02f3d2f20aeca589fd4fafd3fef8 100644 (file)
@@ -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
index ac1616001ea561703d5ad9aa4d8de9eb54cb4dca..6d25c74a3810a0e9ff3a797db2918f6eab8b160d 100644 (file)
@@ -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):
index 7039e383b2ac595c0b3902692c7044dc66d0aead..27ddd51d18051e0ff5d98344246a5be838e1433b 100644 (file)
@@ -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()
index 2116c91cd7affe01fea2284e99e190e253cc71f4..d7a994fcbe04b10dbd92742d84d8de2a00c0dcc2 100644 (file)
@@ -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