Jelajahi Sumber

Spike: Re-use existing containers for `fig run`

Signed-off-by: Chris Corbyn <[email protected]>
d11wtq 11 tahun lalu
induk
melakukan
3d8ce448b8
3 mengubah file dengan 25 tambahan dan 12 penghapusan
  1. 12 3
      fig/cli/main.py
  2. 2 5
      fig/project.py
  3. 11 4
      fig/service.py

+ 12 - 3
fig/cli/main.py

@@ -222,7 +222,8 @@ class TopLevelCommand(Command):
         if not options['--no-links']:
             self.project.up(
                 service_names=service.get_linked_names(),
-                start_links=True
+                start_links=True,
+                keep_old=True
             )
 
         tty = True
@@ -301,7 +302,9 @@ class TopLevelCommand(Command):
 
         If there are existing containers for a service, `fig up` will stop
         and recreate them (preserving mounted volumes with volumes-from),
-        so that changes in `fig.yml` are picked up.
+        so that changes in `fig.yml` are picked up. If you do not want existing
+        containers to be recreated, `fig up --keep-old` will re-use existing
+        containers.
 
         Usage: up [options] [SERVICE...]
 
@@ -309,13 +312,19 @@ class TopLevelCommand(Command):
             -d          Detached mode: Run containers in the background, print
                         new container names.
             --no-links  Don't start linked services.
+            --keep-old  If containers already exist, don't recreate them.
         """
         detached = options['-d']
 
         start_links = not options['--no-links']
+        keep_old = options['--keep-old']
         service_names = options['SERVICE']
 
-        to_attach = self.project.up(service_names=service_names, start_links=start_links)
+        to_attach = self.project.up(
+            service_names=service_names,
+            start_links=start_links,
+            keep_old=keep_old
+        )
 
         if not detached:
             print("Attaching to", list_containers(to_attach))

+ 2 - 5
fig/project.py

@@ -138,11 +138,11 @@ class Project(object):
             else:
                 log.info('%s uses an image, skipping' % service.name)
 
-    def up(self, service_names=None, start_links=True):
+    def up(self, service_names=None, start_links=True, keep_old=False):
         new_containers = []
 
         for service in self.get_services(service_names, include_links=start_links):
-            for (_, new) in service.recreate_containers():
+            for (_, new) in service.recreate_containers(keep_old):
                 new_containers.append(new)
 
         return new_containers
@@ -159,9 +159,6 @@ class Project(object):
         return l
 
     def _prepend_with_links(self, acc, service):
-        if service in acc:
-            return acc
-
         linked_names = service.get_linked_names()
 
         if len(linked_names) > 0:

+ 11 - 4
fig/service.py

@@ -76,9 +76,7 @@ class Service(object):
 
     def start(self, **options):
         for c in self.containers(stopped=True):
-            if not c.is_running:
-                log.info("Starting %s..." % c.name)
-                self.start_container(c, **options)
+            self.start_container_if_stopped(c, **options)
 
     def stop(self, **options):
         for c in self.containers():
@@ -156,7 +154,7 @@ class Service(object):
                 return Container.create(self.client, **container_options)
             raise
 
-    def recreate_containers(self, **override_options):
+    def recreate_containers(self, keep_old=False, **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.
@@ -168,6 +166,8 @@ class Service(object):
             container = self.create_container(**override_options)
             self.start_container(container)
             return [(None, container)]
+        elif keep_old:
+            return [(None, self.start_container_if_stopped(c)) for c in containers]
         else:
             tuples = []
 
@@ -201,6 +201,13 @@ class Service(object):
 
         return (intermediate_container, new_container)
 
+    def start_container_if_stopped(self, container, **options):
+        if container.is_running:
+            return container
+        else:
+            log.info("Starting %s..." % container.name)
+            return self.start_container(container, **options)
+
     def start_container(self, container=None, volumes_from=None, **override_options):
         if container is None:
             container = self.create_container(**override_options)