Explorar o código

Scaling down removes containers

Squashed version of #162.
Closes #121.
sebastianneubauer %!s(int64=11) %!d(string=hai) anos
pai
achega
352ad7a38c
Modificáronse 4 ficheiros con 60 adicións e 8 borrados
  1. 1 8
      fig/cli/main.py
  2. 11 0
      fig/project.py
  3. 10 0
      fig/service.py
  4. 38 0
      tests/project_test.py

+ 1 - 8
fig/cli/main.py

@@ -298,20 +298,13 @@ class TopLevelCommand(Command):
         """
         detached = options['-d']
 
-        (old, new) = self.project.recreate_containers(service_names=options['SERVICE'])
+        new = self.project.up(service_names=options['SERVICE'])
 
         if not detached:
             to_attach = [c for (s, c) in new]
             print("Attaching to", list_containers(to_attach))
             log_printer = LogPrinter(to_attach, attach_params={"logs": True})
 
-        for (service, container) in new:
-            service.start_container(container)
-
-        for (service, container) in old:
-            container.remove()
-
-        if not detached:
             try:
                 log_printer.run()
             finally:

+ 11 - 0
fig/project.py

@@ -137,6 +137,17 @@ class Project(object):
             else:
                 log.info('%s uses an image, skipping' % service.name)
 
+    def up(self, service_names=None):
+        (old, new) = self.recreate_containers(service_names=service_names)
+
+        for (service, container) in new:
+            service.start_container(container)
+
+        for (service, container) in old:
+            container.remove()
+
+        return new
+
     def remove_stopped(self, service_names=None, **options):
         for service in self.get_services(service_names):
             service.remove_stopped(**options)

+ 10 - 0
fig/service.py

@@ -85,6 +85,14 @@ class Service(object):
             c.kill(**options)
 
     def scale(self, desired_num):
+        """
+        Adjusts the number of containers to the specified number and ensures they are running.
+
+        - creates containers until there are at least `desired_num`
+        - stops containers until there are at most `desired_num` running
+        - starts containers until there are at least `desired_num` running
+        - removes all stopped containers
+        """
         if not self.can_be_scaled():
             raise CannotBeScaledError()
 
@@ -117,6 +125,8 @@ class Service(object):
             self.start_container(c)
             running_containers.append(c)
 
+        self.remove_stopped()
+
 
     def remove_stopped(self, **options):
         for c in self.containers(stopped=True):

+ 38 - 0
tests/project_test.py

@@ -118,3 +118,41 @@ class ProjectTest(DockerClientTestCase):
 
         project.remove_stopped()
         self.assertEqual(len(project.containers(stopped=True)), 0)
+
+    def test_project_up(self):
+        web = self.create_service('web')
+        db = self.create_service('db')
+        project = Project('figtest', [web, db], self.client)
+        project.start()
+        self.assertEqual(len(project.containers()), 0)
+        project.up()
+        self.assertEqual(len(project.containers()), 2)
+        project.kill()
+        project.remove_stopped()
+
+    def test_unscale_after_restart(self):
+        web = self.create_service('web')
+        project = Project('figtest', [web], self.client)
+
+        project.start()
+
+        service = project.get_service('web')
+        service.scale(1)
+        self.assertEqual(len(service.containers()), 1)
+        service.scale(3)
+        self.assertEqual(len(service.containers()), 3)
+        project.up()
+        service = project.get_service('web')
+        self.assertEqual(len(service.containers()), 3)
+        service.scale(1)
+        self.assertEqual(len(service.containers()), 1)
+        project.up()
+        service = project.get_service('web')
+        self.assertEqual(len(service.containers()), 1)
+        # does scale=0 ,makes any sense? after recreating at least 1 container is running
+        service.scale(0)
+        project.up()
+        service = project.get_service('web')
+        self.assertEqual(len(service.containers()), 1)
+        project.kill()
+        project.remove_stopped()