Repository: docker/docker-py

Issue:
Support for Restart Policy
Support for specifying restart policy through the remote API while creating containers. This will be very handy.

Support for Restart Policy
Support for specifying restart policy through the remote API while creating containers. This will be very handy.



Discussion:

Resolving patch:
diff --git a/docker/client.py b/docker/client.py
--- a/docker/client.py
+++ b/docker/client.py
@@ -806,7 +806,8 @@ def search(self, term):
 
     def start(self, container, binds=None, port_bindings=None, lxc_conf=None,
               publish_all_ports=False, links=None, privileged=False,
-              dns=None, dns_search=None, volumes_from=None, network_mode=None):
+              dns=None, dns_search=None, volumes_from=None, network_mode=None,
+              restart_policy=None):
         if isinstance(container, dict):
             container = container.get('Id')
 
@@ -859,13 +860,15 @@ def start(self, container, binds=None, port_bindings=None, lxc_conf=None,
             if volumes_from is not None:
                 warnings.warn(warning_message.format('volumes_from'),
                               DeprecationWarning)
-
         if dns_search:
             start_config['DnsSearch'] = dns_search
 
         if network_mode:
             start_config['NetworkMode'] = network_mode
 
+        if restart_policy:
+            start_config['RestartPolicy'] = restart_policy
+
         url = self._url("/containers/{0}/start".format(container))
         res = self._post_json(url, data=start_config)
         self._raise_for_status(res)


Test patch:
diff --git a/tests/integration_test.py b/tests/integration_test.py
--- a/tests/integration_test.py
+++ b/tests/integration_test.py
@@ -612,6 +612,23 @@ def runTest(self):
         self.assertIn('{0}_NAME='.format(link_env_prefix2), logs)
         self.assertIn('{0}_ENV_FOO=1'.format(link_env_prefix2), logs)
 
+
+class TestRestartingContainer(BaseTestCase):
+    def runTest(self):
+        container = self.client.create_container('busybox', ['false'])
+        id = container['Id']
+        self.client.start(id, restart_policy={
+            {
+                "Name": "on-failure",
+                "MaximumRetryCount": 1
+            }
+        })
+        self.client.wait(id)
+        self.client.remove_container(id)
+        containers = self.client.containers(all=True)
+        res = [x for x in containers if 'Id' in x and x['Id'].startswith(id)]
+        self.assertEqual(len(res), 0)
+
 #################
 #  LINKS TESTS  #
 #################
diff --git a/tests/test.py b/tests/test.py
--- a/tests/test.py
+++ b/tests/test.py
@@ -1,7 +1,7 @@
 # Copyright 2013 dotCloud inc.
 
-#    Licensed under the Apache License, Version 2.0 (the "License");
-#    you may not use this file except in compliance with the License.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
 #    You may obtain a copy of the License at
 
 #        http://www.apache.org/licenses/LICENSE-2.0
@@ -60,6 +60,7 @@ def fake_resp(url, data=None, **kwargs):
     status_code, content = fake_api.fake_responses[url]()
     return response(status_code=status_code, content=content)
 
+
 fake_request = mock.Mock(side_effect=fake_resp)
 url_prefix = 'http+unix://var/run/docker.sock/v{0}/'.format(
     docker.client.DEFAULT_DOCKER_API_VERSION)
@@ -616,7 +617,7 @@ def test_start_container_with_binds_rw(self):
             mount_origin = '/tmp'
             self.client.start(fake_api.FAKE_CONTAINER_ID,
                               binds={mount_origin: {
-                                     "bind": mount_dest, "ro": False}})
+                                  "bind": mount_dest, "ro": False}})
         except Exception as e:
             self.fail('Command should not raise exception: {0}'.format(e))
 
@@ -812,6 +813,34 @@ def test_start_container_with_dict_instead_of_id(self):
             docker.client.DEFAULT_TIMEOUT_SECONDS
         )
 
+    def test_start_container_with_restart_policy(self):
+        try:
+            self.client.start(fake_api.FAKE_CONTAINER_ID,
+                              restart_policy={
+                                  "Name": "always",
+                                  "MaximumRetryCount": 0
+                              })
+        except Exception as e:
+            self.fail('Command should not raise exception: {0}'.format(e))
+        args = fake_request.call_args
+        self.assertEqual(
+            args[0][0],
+            url_prefix + 'containers/3cc2351ab11b/start'
+        )
+        self.assertEqual(
+            json.loads(args[1]['data']),
+            {"PublishAllPorts": False, "Privileged": False,
+             "RestartPolicy": {"MaximumRetryCount": 0, "Name": "always"}}
+        )
+        self.assertEqual(
+            args[1]['headers'],
+            {'Content-Type': 'application/json'}
+        )
+        self.assertEqual(
+            args[1]['timeout'],
+            docker.client.DEFAULT_TIMEOUT_SECONDS
+        )
+
     def test_resize_container(self):
         try:
             self.client.resize(
@@ -1536,11 +1565,11 @@ def test_tar_with_excludes(self):
                     f.write("content")
 
         for exclude, names in (
-            (['*.py'], ['bar/a.txt', 'bar/other.png',
-                        'test/foo/a.txt', 'test/foo/other.png']),
-            (['*.png', 'bar'], ['test/foo/a.txt', 'test/foo/b.py']),
-            (['test/foo', 'a.txt'], ['bar/a.txt', 'bar/b.py',
-                                     'bar/other.png']),
+                (['*.py'], ['bar/a.txt', 'bar/other.png',
+                            'test/foo/a.txt', 'test/foo/other.png']),
+                (['*.png', 'bar'], ['test/foo/a.txt', 'test/foo/b.py']),
+                (['test/foo', 'a.txt'], ['bar/a.txt', 'bar/b.py',
+                                         'bar/other.png']),
         ):
             archive = docker.utils.tar(base, exclude=exclude)
             tar = tarfile.open(fileobj=archive)