浏览代码

Fix service recreate when image changes to build.

Signed-off-by: Daniel Nephin <[email protected]>
Daniel Nephin 10 年之前
父节点
当前提交
8ff960afd1
共有 3 个文件被更改,包括 46 次插入34 次删除
  1. 8 5
      compose/service.py
  2. 36 29
      tests/integration/state_test.py
  3. 2 0
      tests/unit/config/config_test.py

+ 8 - 5
compose/service.py

@@ -414,6 +414,7 @@ class Service(object):
             return [
                 self.recreate_container(
                     container,
+                    do_build=do_build,
                     timeout=timeout,
                     attach_logs=should_attach_logs
                 )
@@ -435,10 +436,12 @@ class Service(object):
         else:
             raise Exception("Invalid action: {}".format(action))
 
-    def recreate_container(self,
-                           container,
-                           timeout=DEFAULT_TIMEOUT,
-                           attach_logs=False):
+    def recreate_container(
+            self,
+            container,
+            do_build=False,
+            timeout=DEFAULT_TIMEOUT,
+            attach_logs=False):
         """Recreate a container.
 
         The original container is renamed to a temporary name so that data
@@ -450,7 +453,7 @@ class Service(object):
         container.stop(timeout=timeout)
         container.rename_to_tmp_name()
         new_container = self.create_container(
-            do_build=False,
+            do_build=do_build,
             previous_container=container,
             number=container.labels.get(LABEL_CONTAINER_NUMBER),
             quiet=True,

+ 36 - 29
tests/integration/state_test.py

@@ -4,9 +4,7 @@ by `docker-compose up`.
 """
 from __future__ import unicode_literals
 
-import os
-import shutil
-import tempfile
+import py
 
 from .testcases import DockerClientTestCase
 from compose.config import config
@@ -232,40 +230,49 @@ class ServiceStateTest(DockerClientTestCase):
 
         image_id = self.client.images(name='busybox')[0]['Id']
         self.client.tag(image_id, repository=repo, tag=tag)
+        self.addCleanup(self.client.remove_image, image)
 
-        try:
-            web = self.create_service('web', image=image)
-            container = web.create_container()
-
-            # update the image
-            c = self.client.create_container(image, ['touch', '/hello.txt'])
-            self.client.commit(c, repository=repo, tag=tag)
-            self.client.remove_container(c)
+        web = self.create_service('web', image=image)
+        container = web.create_container()
 
-            web = self.create_service('web', image=image)
-            self.assertEqual(('recreate', [container]), web.convergence_plan())
+        # update the image
+        c = self.client.create_container(image, ['touch', '/hello.txt'])
+        self.client.commit(c, repository=repo, tag=tag)
+        self.client.remove_container(c)
 
-        finally:
-            self.client.remove_image(image)
+        web = self.create_service('web', image=image)
+        self.assertEqual(('recreate', [container]), web.convergence_plan())
 
     def test_trigger_recreate_with_build(self):
-        context = tempfile.mkdtemp()
+        context = py.test.ensuretemp('test_trigger_recreate_with_build')
+        self.addCleanup(context.remove)
+
         base_image = "FROM busybox\nLABEL com.docker.compose.test_image=true\n"
+        dockerfile = context.join('Dockerfile')
+        dockerfile.write(base_image)
 
-        try:
-            dockerfile = os.path.join(context, 'Dockerfile')
+        web = self.create_service('web', build=str(context))
+        container = web.create_container()
+
+        dockerfile.write(base_image + 'CMD echo hello world\n')
+        web.build()
 
-            with open(dockerfile, 'w') as f:
-                f.write(base_image)
+        web = self.create_service('web', build=str(context))
+        self.assertEqual(('recreate', [container]), web.convergence_plan())
 
-            web = self.create_service('web', build=context)
-            container = web.create_container()
+    def test_image_changed_to_build(self):
+        context = py.test.ensuretemp('test_image_changed_to_build')
+        self.addCleanup(context.remove)
+        context.join('Dockerfile').write("""
+            FROM busybox
+            LABEL com.docker.compose.test_image=true
+        """)
 
-            with open(dockerfile, 'w') as f:
-                f.write(base_image + 'CMD echo hello world\n')
-            web.build()
+        web = self.create_service('web', image='busybox')
+        container = web.create_container()
 
-            web = self.create_service('web', build=context)
-            self.assertEqual(('recreate', [container]), web.convergence_plan())
-        finally:
-            shutil.rmtree(context)
+        web = self.create_service('web', build=str(context))
+        plan = web.convergence_plan()
+        self.assertEqual(('recreate', [container]), plan)
+        containers = web.execute_convergence_plan(plan)
+        self.assertEqual(len(containers), 1)

+ 2 - 0
tests/unit/config/config_test.py

@@ -177,6 +177,7 @@ class ConfigTest(unittest.TestCase):
         details = config.ConfigDetails('.', [base_file, override_file])
 
         tmpdir = py.test.ensuretemp('config_test')
+        self.addCleanup(tmpdir.remove)
         tmpdir.join('common.yml').write("""
             base:
               labels: ['label=one']
@@ -412,6 +413,7 @@ class ConfigTest(unittest.TestCase):
 
     def test_load_yaml_with_yaml_error(self):
         tmpdir = py.test.ensuretemp('invalid_yaml_test')
+        self.addCleanup(tmpdir.remove)
         invalid_yaml_file = tmpdir.join('docker-compose.yml')
         invalid_yaml_file.write("""
             web: