From 41a94174fd4773c12cdcdb7dad54273a3c0b2ff8 Mon Sep 17 00:00:00 2001 From: Joffrey F Date: Tue, 10 Feb 2015 12:11:55 -0800 Subject: [PATCH 1/3] Added rename method --- docker/client.py | 26 +++++++++++++++++--------- docker/unixconn/unixconn.py | 4 ++-- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/docker/client.py b/docker/client.py index 179e9d3fd4..664082e3bf 100644 --- a/docker/client.py +++ b/docker/client.py @@ -892,6 +892,23 @@ def remove_image(self, image, force=False, noprune=False): res = self._delete(self._url("/images/" + image), params=params) self._raise_for_status(res) + def rename(self, container, name): + if isinstance(container, dict): + container = container.get('Id') + url = self._url("/containers/{0}/rename".format(container)) + params = {'name': name} + res = self._post(url, None, params=params) + self._raise_for_status(res) + + def resize(self, container, height, width): + if isinstance(container, dict): + container = container.get('Id') + + params = {'h': height, 'w': width} + url = self._url("/containers/{0}/resize".format(container)) + res = self._post(url, params=params) + self._raise_for_status(res) + def restart(self, container, timeout=10): if isinstance(container, dict): container = container.get('Id') @@ -939,15 +956,6 @@ def start(self, container, binds=None, port_bindings=None, lxc_conf=None, res = self._post_json(url, data=start_config) self._raise_for_status(res) - def resize(self, container, height, width): - if isinstance(container, dict): - container = container.get('Id') - - params = {'h': height, 'w': width} - url = self._url("/containers/{0}/resize".format(container)) - res = self._post(url, params=params) - self._raise_for_status(res) - def stop(self, container, timeout=10): if isinstance(container, dict): container = container.get('Id') diff --git a/docker/unixconn/unixconn.py b/docker/unixconn/unixconn.py index 1f18060a15..460f753e78 100644 --- a/docker/unixconn/unixconn.py +++ b/docker/unixconn/unixconn.py @@ -12,13 +12,13 @@ # See the License for the specific language governing permissions and # limitations under the License. import six +import requests.adapters +import socket if six.PY3: import http.client as httplib else: import httplib -import requests.adapters -import socket try: import requests.packages.urllib3 as urllib3 From 35c4cbd9c49d70922802aa19cb57c302c9bc9d8b Mon Sep 17 00:00:00 2001 From: Joffrey F Date: Tue, 10 Feb 2015 12:43:33 -0800 Subject: [PATCH 2/3] Bumped default API version, fixed rename() --- docker/client.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/docker/client.py b/docker/client.py index 664082e3bf..dcfcef5095 100644 --- a/docker/client.py +++ b/docker/client.py @@ -33,7 +33,7 @@ if not six.PY3: import websocket -DEFAULT_DOCKER_API_VERSION = '1.16' +DEFAULT_DOCKER_API_VERSION = '1.17' DEFAULT_TIMEOUT_SECONDS = 60 STREAM_HEADER_SIZE_BYTES = 8 @@ -374,8 +374,12 @@ def stream_result(): sep = bytes() if six.PY3 else str() - return stream and self._multiplexed_response_stream_helper(response) or \ - sep.join([x for x in self._multiplexed_buffer_helper(response)]) + if stream: + return self._multiplexed_response_stream_helper(response) + else: + return sep.join( + [x for x in self._multiplexed_buffer_helper(response)] + ) def attach_socket(self, container, params=None, ws=False): if params is None: @@ -893,11 +897,15 @@ def remove_image(self, image, force=False, noprune=False): self._raise_for_status(res) def rename(self, container, name): + if utils.compare_version('1.17', self._version) < 0: + raise errors.InvalidVersion( + 'rename was only introduced in API version 1.17' + ) if isinstance(container, dict): container = container.get('Id') url = self._url("/containers/{0}/rename".format(container)) params = {'name': name} - res = self._post(url, None, params=params) + res = self._post(url, params=params) self._raise_for_status(res) def resize(self, container, height, width): From a7f7fbb0fdd1ad247c413170c354d08deb43dd32 Mon Sep 17 00:00:00 2001 From: Joffrey F Date: Tue, 10 Feb 2015 12:43:56 -0800 Subject: [PATCH 3/3] rename() tests and docs --- docs/api.md | 9 +++++++++ tests/fake_api.py | 9 ++++++++- tests/integration_test.py | 12 ++++++++++++ tests/test.py | 15 +++++++++++++++ 4 files changed, 44 insertions(+), 1 deletion(-) diff --git a/docs/api.md b/docs/api.md index dba4cde688..1d162e9f6a 100644 --- a/docs/api.md +++ b/docs/api.md @@ -526,6 +526,15 @@ Remove an image. Similar to the `docker rmi` command. * force (bool): Force removal of the image * noprune (bool): Do not delete untagged parents +## rename + +Rename a container. Similar to the `docker rename` command. + +**Params**: + +* container (str): ID of the container to rename +* name (str): New name for the container + ## restart Restart a container. Similar to the `docker restart` command. diff --git a/tests/fake_api.py b/tests/fake_api.py index c0b323bc05..d311fc1104 100644 --- a/tests/fake_api.py +++ b/tests/fake_api.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -CURRENT_VERSION = 'v1.16' +CURRENT_VERSION = 'v1.17' FAKE_CONTAINER_ID = '3cc2351ab11b' FAKE_IMAGE_ID = 'e9aa60c60128' @@ -271,6 +271,11 @@ def post_fake_restart_container(): return status_code, response +def post_fake_rename_container(): + status_code = 204 + return status_code, None + + def delete_fake_remove_container(): status_code = 200 response = {'Id': FAKE_CONTAINER_ID} @@ -348,6 +353,8 @@ def post_fake_tag_image(): post_fake_resize_container, '{1}/{0}/containers/3cc2351ab11b/json'.format(CURRENT_VERSION, prefix): get_fake_inspect_container, + '{1}/{0}/containers/3cc2351ab11b/rename'.format(CURRENT_VERSION, prefix): + post_fake_rename_container, '{1}/{0}/images/e9aa60c60128/tag'.format(CURRENT_VERSION, prefix): post_fake_tag_image, '{1}/{0}/containers/3cc2351ab11b/wait'.format(CURRENT_VERSION, prefix): diff --git a/tests/integration_test.py b/tests/integration_test.py index 32f32a0051..46b630ec82 100644 --- a/tests/integration_test.py +++ b/tests/integration_test.py @@ -322,6 +322,18 @@ def runTest(self): self.assertEqual('/foobar', inspect['Name']) +class TestRenameContainer(BaseTestCase): + def runTest(self): + name = 'hong_meiling' + res = self.client.create_container('busybox', 'true') + self.assertIn('Id', res) + self.tmp_containers.append(res['Id']) + self.client.rename(res, name) + inspect = self.client.inspect_container(res['Id']) + self.assertIn('Name', inspect) + self.assertEqual(name, inspect['Name']) + + class TestStartContainer(BaseTestCase): def runTest(self): res = self.client.create_container('busybox', 'true') diff --git a/tests/test.py b/tests/test.py index 7ada2a92d7..5c8f6ea1da 100644 --- a/tests/test.py +++ b/tests/test.py @@ -1256,6 +1256,21 @@ def test_resize_container(self): timeout=docker.client.DEFAULT_TIMEOUT_SECONDS ) + def test_rename_container(self): + try: + self.client.rename( + {'Id': fake_api.FAKE_CONTAINER_ID}, + name='foobar' + ) + except Exception as e: + self.fail('Command shold not raise exception: {0}'.format(e)) + + fake_request.assert_called_with( + url_prefix + 'containers/3cc2351ab11b/rename', + params={'name': 'foobar'}, + timeout=docker.client.DEFAULT_TIMEOUT_SECONDS + ) + def test_wait(self): try: self.client.wait(fake_api.FAKE_CONTAINER_ID)