summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoffrey F <f.joffrey@gmail.com>2016-12-07 15:37:17 -0800
committerGitHub <noreply@github.com>2016-12-07 15:37:17 -0800
commitd024b1bd78808faafb9d1ccc57d7520e4d04a5f6 (patch)
treebd3db75bdc2e4be54b3975a6f294bd623798c497
parent281b5558b543b0eb09ceeb1c98b49987b87fa135 (diff)
parentc239e4050425394b20970998d3c33776621a90a7 (diff)
downloaddocker-py-d024b1bd78808faafb9d1ccc57d7520e4d04a5f6.tar.gz
Merge pull request #1338 from docker/remove_node
Implement swarm node removal
-rw-r--r--docker/api/swarm.py28
-rw-r--r--docker/models/nodes.py19
-rw-r--r--tests/integration/api_swarm_test.py17
3 files changed, 64 insertions, 0 deletions
diff --git a/docker/api/swarm.py b/docker/api/swarm.py
index edc206f..3ada538 100644
--- a/docker/api/swarm.py
+++ b/docker/api/swarm.py
@@ -228,6 +228,33 @@ class SwarmApiMixin(object):
return self._result(self._get(url, params=params), True)
+ @utils.check_resource
+ @utils.minimum_version('1.24')
+ def remove_node(self, node_id, force=False):
+ """
+ Remove a node from the swarm.
+
+ Args:
+ node_id (string): ID of the node to be removed.
+ force (bool): Force remove an active node. Default: `False`
+
+ Raises:
+ :py:class:`docker.errors.NotFound`
+ If the node referenced doesn't exist in the swarm.
+
+ :py:class:`docker.errors.APIError`
+ If the server returns an error.
+ Returns:
+ `True` if the request was successful.
+ """
+ url = self._url('/nodes/{0}', node_id)
+ params = {
+ 'force': force
+ }
+ res = self._delete(url, params=params)
+ self._raise_for_status(res)
+ return True
+
@utils.minimum_version('1.24')
def update_node(self, node_id, version, node_spec=None):
"""
@@ -235,6 +262,7 @@ class SwarmApiMixin(object):
Args:
+ node_id (string): ID of the node to be updated.
version (int): The version number of the node object being
updated. This is required to avoid conflicting writes.
node_spec (dict): Configuration settings to update. Any values
diff --git a/docker/models/nodes.py b/docker/models/nodes.py
index 0887f99..8dd9350 100644
--- a/docker/models/nodes.py
+++ b/docker/models/nodes.py
@@ -41,6 +41,25 @@ class Node(Model):
"""
return self.client.api.update_node(self.id, self.version, node_spec)
+ def remove(self, force=False):
+ """
+ Remove this node from the swarm.
+
+ Args:
+ force (bool): Force remove an active node. Default: `False`
+
+ Returns:
+ `True` if the request was successful.
+
+ Raises:
+ :py:class:`docker.errors.NotFound`
+ If the node doesn't exist in the swarm.
+
+ :py:class:`docker.errors.APIError`
+ If the server returns an error.
+ """
+ return self.client.api.remove_node(self.id, force=force)
+
class NodeCollection(Collection):
"""Nodes on the Docker server."""
diff --git a/tests/integration/api_swarm_test.py b/tests/integration/api_swarm_test.py
index 24c566f..a10437b 100644
--- a/tests/integration/api_swarm_test.py
+++ b/tests/integration/api_swarm_test.py
@@ -159,3 +159,20 @@ class SwarmTest(BaseAPIIntegrationTest):
node_spec=orig_spec)
reverted_node = self.client.inspect_node(node['ID'])
assert orig_spec == reverted_node['Spec']
+
+ @requires_api_version('1.24')
+ def test_remove_main_node(self):
+ assert self.client.init_swarm('eth0')
+ nodes_list = self.client.nodes()
+ node_id = nodes_list[0]['ID']
+ with pytest.raises(docker.errors.NotFound):
+ self.client.remove_node('foobar01')
+ with pytest.raises(docker.errors.APIError) as e:
+ self.client.remove_node(node_id)
+
+ assert e.value.response.status_code == 500
+
+ with pytest.raises(docker.errors.APIError) as e:
+ self.client.remove_node(node_id, True)
+
+ assert e.value.response.status_code == 500