浏览代码

Add a no-build option to fig up, to save time when services were already freshly built.

Signed-off-by: Daniel Nephin <[email protected]>
Daniel Nephin 11 年之前
父节点
当前提交
3056ae4be3
共有 5 个文件被更改,包括 63 次插入24 次删除
  1. 3 1
      fig/cli/main.py
  2. 15 3
      fig/project.py
  3. 14 6
      fig/service.py
  4. 14 14
      tests/integration/service_test.py
  5. 17 0
      tests/unit/service_test.py

+ 3 - 1
fig/cli/main.py

@@ -425,6 +425,7 @@ class TopLevelCommand(Command):
             --no-color            Produce monochrome output.
             --no-deps             Don't start linked services.
             --no-recreate         If containers already exist, don't recreate them.
+            --no-build            Don't build an image, even if it's missing
         """
         insecure_registry = options['--allow-insecure-ssl']
         detached = options['-d']
@@ -440,7 +441,8 @@ class TopLevelCommand(Command):
             start_links=start_links,
             recreate=recreate,
             insecure_registry=insecure_registry,
-            detach=options['-d']
+            detach=options['-d'],
+            do_build=not options['--no-build'],
         )
 
         to_attach = [c for s in project.get_services(service_names) for c in s.containers()]

+ 15 - 3
fig/project.py

@@ -167,14 +167,26 @@ class Project(object):
             else:
                 log.info('%s uses an image, skipping' % service.name)
 
-    def up(self, service_names=None, start_links=True, recreate=True, insecure_registry=False, detach=False):
+    def up(self,
+           service_names=None,
+           start_links=True,
+           recreate=True,
+           insecure_registry=False,
+           detach=False,
+           do_build=True):
         running_containers = []
         for service in self.get_services(service_names, include_links=start_links):
             if recreate:
-                for (_, container) in service.recreate_containers(insecure_registry=insecure_registry, detach=detach):
+                for (_, container) in service.recreate_containers(
+                        insecure_registry=insecure_registry,
+                        detach=detach,
+                        do_build=do_build):
                     running_containers.append(container)
             else:
-                for container in service.start_or_create_containers(insecure_registry=insecure_registry, detach=detach):
+                for container in service.start_or_create_containers(
+                        insecure_registry=insecure_registry,
+                        detach=detach,
+                        do_build=do_build):
                     running_containers.append(container)
 
         return running_containers

+ 14 - 6
fig/service.py

@@ -54,7 +54,7 @@ DOCKER_START_KEYS = [
     'cap_add',
     'cap_drop',
     'dns',
-    'dns_search', 
+    'dns_search',
     'env_file',
     'net',
     'privileged',
@@ -236,7 +236,7 @@ class Service(object):
                 return Container.create(self.client, **container_options)
             raise
 
-    def recreate_containers(self, insecure_registry=False, **override_options):
+    def recreate_containers(self, insecure_registry=False, do_build=True, **override_options):
         """
         If a container for this service doesn't exist, create and start one. If there are
         any, stop them, create+start new ones, and remove the old containers.
@@ -244,7 +244,10 @@ class Service(object):
         containers = self.containers(stopped=True)
         if not containers:
             log.info("Creating %s..." % self._next_container_name(containers))
-            container = self.create_container(insecure_registry=insecure_registry, **override_options)
+            container = self.create_container(
+                insecure_registry=insecure_registry,
+                do_build=do_build,
+                **override_options)
             self.start_container(container)
             return [(None, container)]
         else:
@@ -283,7 +286,7 @@ class Service(object):
         container.remove()
 
         options = dict(override_options)
-        new_container = self.create_container(**options)
+        new_container = self.create_container(do_build=False, **options)
         self.start_container(new_container, intermediate_container=intermediate_container)
 
         intermediate_container.remove()
@@ -330,14 +333,19 @@ class Service(object):
         )
         return container
 
-    def start_or_create_containers(self, insecure_registry=False, detach=False):
+    def start_or_create_containers(
+            self,
+            insecure_registry=False,
+            detach=False,
+            do_build=True):
         containers = self.containers(stopped=True)
 
         if not containers:
             log.info("Creating %s..." % self._next_container_name(containers))
             new_container = self.create_container(
                 insecure_registry=insecure_registry,
-                detach=detach
+                detach=detach,
+                do_build=do_build,
             )
             return [self.start_container(new_container)]
         else:

+ 14 - 14
tests/integration/service_test.py

@@ -391,34 +391,34 @@ class ServiceTest(DockerClientTestCase):
 
     def test_restart_always_value(self):
         service = self.create_service('web', restart='always')
-        container = service.start_container().inspect()
-        self.assertEqual(container['HostConfig']['RestartPolicy']['Name'], 'always')
+        container = create_and_start_container(service)
+        self.assertEqual(container.get('HostConfig.RestartPolicy.Name'), 'always')
 
     def test_restart_on_failure_value(self):
         service = self.create_service('web', restart='on-failure:5')
-        container = service.start_container().inspect()
-        self.assertEqual(container['HostConfig']['RestartPolicy']['Name'], 'on-failure')
-        self.assertEqual(container['HostConfig']['RestartPolicy']['MaximumRetryCount'], 5)
+        container = create_and_start_container(service)
+        self.assertEqual(container.get('HostConfig.RestartPolicy.Name'), 'on-failure')
+        self.assertEqual(container.get('HostConfig.RestartPolicy.MaximumRetryCount'), 5)
 
     def test_cap_add_list(self):
         service = self.create_service('web', cap_add=['SYS_ADMIN', 'NET_ADMIN'])
-        container = service.start_container().inspect()
-        self.assertEqual(container['HostConfig']['CapAdd'], ['SYS_ADMIN', 'NET_ADMIN'])
+        container = create_and_start_container(service)
+        self.assertEqual(container.get('HostConfig.CapAdd'), ['SYS_ADMIN', 'NET_ADMIN'])
 
     def test_cap_drop_list(self):
         service = self.create_service('web', cap_drop=['SYS_ADMIN', 'NET_ADMIN'])
-        container = service.start_container().inspect()
-        self.assertEqual(container['HostConfig']['CapDrop'], ['SYS_ADMIN', 'NET_ADMIN'])
+        container = create_and_start_container(service)
+        self.assertEqual(container.get('HostConfig.CapDrop'), ['SYS_ADMIN', 'NET_ADMIN'])
 
     def test_dns_search_single_value(self):
         service = self.create_service('web', dns_search='example.com')
-        container = service.start_container().inspect()
-        self.assertEqual(container['HostConfig']['DnsSearch'], ['example.com'])
+        container = create_and_start_container(service)
+        self.assertEqual(container.get('HostConfig.DnsSearch'), ['example.com'])
 
     def test_dns_search_list(self):
         service = self.create_service('web', dns_search=['dc1.example.com', 'dc2.example.com'])
-        container = service.start_container().inspect()
-        self.assertEqual(container['HostConfig']['DnsSearch'], ['dc1.example.com', 'dc2.example.com'])
+        container = create_and_start_container(service)
+        self.assertEqual(container.get('HostConfig.DnsSearch'), ['dc1.example.com', 'dc2.example.com'])
 
     def test_working_dir_param(self):
         service = self.create_service('container', working_dir='/working/dir/sample')
@@ -433,7 +433,7 @@ class ServiceTest(DockerClientTestCase):
 
     def test_env_from_file_combined_with_env(self):
         service = self.create_service('web', environment=['ONE=1', 'TWO=2', 'THREE=3'], env_file=['tests/fixtures/env/one.env', 'tests/fixtures/env/two.env'])
-        env = service.start_container().environment
+        env = create_and_start_container(service).environment
         for k,v in {'ONE': '1', 'TWO': '2', 'THREE': '3', 'FOO': 'baz', 'DOO': 'dah'}.iteritems():
             self.assertEqual(env[k], v)
 

+ 17 - 0
tests/unit/service_test.py

@@ -228,6 +228,23 @@ class ServiceTest(unittest.TestCase):
         service.create_container()
         self.assertEqual(Container.create.call_args[1]['image'], 'someimage:latest')
 
+    def test_create_container_with_build(self):
+        self.mock_client.images.return_value = []
+        service = Service('foo', client=self.mock_client, build='.')
+        service.build = mock.create_autospec(service.build)
+        service.create_container(do_build=True)
+
+        self.mock_client.images.assert_called_once_with(name=service.full_name)
+        service.build.assert_called_once_with()
+
+    def test_create_container_no_build(self):
+        self.mock_client.images.return_value = []
+        service = Service('foo', client=self.mock_client, build='.')
+        service.create_container(do_build=False)
+
+        self.assertFalse(self.mock_client.images.called)
+        self.assertFalse(self.mock_client.build.called)
+
 
 class ServiceVolumesTest(unittest.TestCase):