diff --git a/README.md b/README.md index 992589e1..b80ddcba 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ Documentation Full documentation is available in the `/docs/` directory. + License ------- Docker is licensed under the Apache License, Version 2.0. See LICENSE for full license text diff --git a/docker/client.py b/docker/client.py index a586d5d8..c09b451a 100644 --- a/docker/client.py +++ b/docker/client.py @@ -753,6 +753,13 @@ class Client(requests.Session): logs=True ) + def pause(self, container): + if isinstance(container, dict): + container = container.get('Id') + url = self._url('/containers/{0}/pause'.format(container)) + res = self._post(url) + self._raise_for_status(res) + def ping(self): return self._result(self._get(self._url('/_ping'))) @@ -982,6 +989,13 @@ class Client(requests.Session): def version(self): return self._result(self._get(self._url("/version")), True) + def unpause(self, container): + if isinstance(container, dict): + container = container.get('Id') + url = self._url('/containers/{0}/unpause'.format(container)) + res = self._post(url) + self._raise_for_status(res) + def wait(self, container): if isinstance(container, dict): container = container.get('Id') diff --git a/docs/api.md b/docs/api.md index 613e2601..73fec4d2 100644 --- a/docs/api.md +++ b/docs/api.md @@ -400,6 +400,15 @@ output as it happens. **Returns** (generator or str): +## pause + +Pauses all processes within a container. + +**Params**: + +* container (str): The container to pause + + ## ping Hits the `/_ping` endpoint of the remote API and returns the result. An @@ -673,6 +682,14 @@ Display the running processes of a container 'Titles': ['PID', 'USER', 'COMMAND']} ``` +## unpause + +Unpauses all processes within a container. + +**Params**: + +* container (str): The container to unpause + ## version Nearly identical to the `docker version` command. diff --git a/tests/fake_api.py b/tests/fake_api.py index 252ea6bf..9d76ee37 100644 --- a/tests/fake_api.py +++ b/tests/fake_api.py @@ -251,6 +251,18 @@ def post_fake_kill_container(): return status_code, response +def post_fake_pause_container(): + status_code = 200 + response = {'Id': FAKE_CONTAINER_ID} + return status_code, response + + +def post_fake_unpause_container(): + status_code = 200 + response = {'Id': FAKE_CONTAINER_ID} + return status_code, response + + def post_fake_restart_container(): status_code = 200 response = {'Id': FAKE_CONTAINER_ID} @@ -352,6 +364,10 @@ fake_responses = { post_fake_stop_container, '{1}/{0}/containers/3cc2351ab11b/kill'.format(CURRENT_VERSION, prefix): post_fake_kill_container, + '{1}/{0}/containers/3cc2351ab11b/pause'.format(CURRENT_VERSION, prefix): + post_fake_pause_container, + '{1}/{0}/containers/3cc2351ab11b/unpause'.format(CURRENT_VERSION, prefix): + post_fake_unpause_container, '{1}/{0}/containers/3cc2351ab11b/json'.format(CURRENT_VERSION, prefix): get_fake_port, '{1}/{0}/containers/3cc2351ab11b/restart'.format(CURRENT_VERSION, prefix): diff --git a/tests/integration_test.py b/tests/integration_test.py index 4b773ead..8a39ce3b 100644 --- a/tests/integration_test.py +++ b/tests/integration_test.py @@ -670,6 +670,33 @@ class TestExecuteCommandStreaming(BaseTestCase): self.assertEqual(res, expected) +class TestPauseUnpauseContainer(BaseTestCase): + def runTest(self): + container = self.client.create_container('busybox', ['sleep', '9999']) + id = container['Id'] + self.client.pause(id) + container_info = self.client.inspect_container(id) + self.assertIn('State', container_info) + state = container_info['State'] + self.assertIn('ExitCode', state) + self.assertEqual(state['ExitCode'], 0) + self.assertIn('Running', state) + self.assertEqual(state['Running'], True) + self.assertIn('Paused', state) + self.assertEqual(state['Paused'], True) + + self.client.unpause(id) + container_info = self.client.inspect_container(id) + self.assertIn('State', container_info) + state = container_info['State'] + self.assertIn('ExitCode', state) + self.assertEqual(state['ExitCode'], 0) + self.assertIn('Running', state) + self.assertEqual(state['Running'], True) + self.assertIn('Paused', state) + self.assertEqual(state['Paused'], False) + + ################# # LINKS TESTS # ################# diff --git a/tests/test.py b/tests/test.py index 652af33f..598ccac5 100644 --- a/tests/test.py +++ b/tests/test.py @@ -1148,6 +1148,26 @@ class DockerClientTest(Cleanup, unittest.TestCase): self.assertEqual(args[1]['headers'], {'Content-Type': 'application/json'}) + def test_pause_container(self): + try: + self.client.pause(fake_api.FAKE_CONTAINER_ID) + except Exception as e: + self.fail('Command should not raise exception: {0}'.format(e)) + fake_request.assert_called_with( + url_prefix + 'containers/3cc2351ab11b/pause', + timeout=(docker.client.DEFAULT_TIMEOUT_SECONDS) + ) + + def test_unpause_container(self): + try: + self.client.unpause(fake_api.FAKE_CONTAINER_ID) + except Exception as e: + self.fail('Command should not raise exception: {0}'.format(e)) + fake_request.assert_called_with( + url_prefix + 'containers/3cc2351ab11b/unpause', + timeout=(docker.client.DEFAULT_TIMEOUT_SECONDS) + ) + def test_kill_container(self): try: self.client.kill(fake_api.FAKE_CONTAINER_ID)