1
0
Эх сурвалжийг харах

Add COMPOSE_IGNORE_ORPHANS

Signed-off-by: John Harris <[email protected]>
John Harris 7 жил өмнө
parent
commit
963b004749

+ 19 - 1
compose/cli/main.py

@@ -377,9 +377,20 @@ class TopLevelCommand(object):
             -t, --timeout TIMEOUT   Specify a shutdown timeout in seconds.
                                     (default: 10)
         """
+        environment = Environment.from_env_file(self.project_dir)
+        ignore_orphans = environment.get_boolean('COMPOSE_IGNORE_ORPHANS')
+
+        if ignore_orphans and options['--remove-orphans']:
+            raise UserError("COMPOSE_IGNORE_ORPHANS and --remove-orphans cannot be combined.")
+
         image_type = image_type_from_opt('--rmi', options['--rmi'])
         timeout = timeout_from_opts(options)
-        self.project.down(image_type, options['--volumes'], options['--remove-orphans'], timeout=timeout)
+        self.project.down(
+            image_type,
+            options['--volumes'],
+            options['--remove-orphans'],
+            timeout=timeout,
+            ignore_orphans=ignore_orphans)
 
     def events(self, options):
         """
@@ -941,6 +952,12 @@ class TopLevelCommand(object):
         if detached and timeout:
             raise UserError("-d and --timeout cannot be combined.")
 
+        environment = Environment.from_env_file(self.project_dir)
+        ignore_orphans = environment.get_boolean('COMPOSE_IGNORE_ORPHANS')
+
+        if ignore_orphans and remove_orphans:
+            raise UserError("COMPOSE_IGNORE_ORPHANS and --remove-orphans cannot be combined.")
+
         if no_start:
             for excluded in ['-d', '--abort-on-container-exit', '--exit-code-from']:
                 if options.get(excluded):
@@ -955,6 +972,7 @@ class TopLevelCommand(object):
                 timeout=timeout,
                 detached=detached,
                 remove_orphans=remove_orphans,
+                ignore_orphans=ignore_orphans,
                 scale_override=parse_scale_args(options['--scale']),
                 start=not no_start
             )

+ 12 - 3
compose/project.py

@@ -330,9 +330,16 @@ class Project(object):
             service_names, stopped=True, one_off=one_off
         ), options)
 
-    def down(self, remove_image_type, include_volumes, remove_orphans=False, timeout=None):
+    def down(
+            self,
+            remove_image_type,
+            include_volumes,
+            remove_orphans=False,
+            timeout=None,
+            ignore_orphans=False):
         self.stop(one_off=OneOffFilter.include, timeout=timeout)
-        self.find_orphan_containers(remove_orphans)
+        if not ignore_orphans:
+            self.find_orphan_containers(remove_orphans)
         self.remove_stopped(v=include_volumes, one_off=OneOffFilter.include)
 
         self.networks.remove()
@@ -432,6 +439,7 @@ class Project(object):
            timeout=None,
            detached=False,
            remove_orphans=False,
+           ignore_orphans=False,
            scale_override=None,
            rescale=True,
            start=True):
@@ -439,7 +447,8 @@ class Project(object):
         warn_for_swarm_mode(self.client)
 
         self.initialize()
-        self.find_orphan_containers(remove_orphans)
+        if not ignore_orphans:
+            self.find_orphan_containers(remove_orphans)
 
         if scale_override is None:
             scale_override = {}

+ 6 - 0
tests/acceptance/cli_test.py

@@ -1337,6 +1337,12 @@ class CLITestCase(DockerClientTestCase):
         result = self.dispatch(['up', '-d', '-t', '1'], returncode=1)
         assert "-d and --timeout cannot be combined." in result.stderr
 
+    @mock.patch.dict(os.environ)
+    def test_up_with_ignore_remove_orphans(self):
+        os.environ["COMPOSE_IGNORE_ORPHANS"] = "True"
+        result = self.dispatch(['up', '-d', '--remove-orphans'], returncode=1)
+        assert "COMPOSE_IGNORE_ORPHANS and --remove-orphans cannot be combined." in result.stderr
+
     def test_up_handles_sigint(self):
         proc = start_process(self.base_dir, ['up', '-t', '2'])
         wait_on_condition(ContainerCountCondition(self.project, 2))

+ 25 - 0
tests/integration/project_test.py

@@ -1633,6 +1633,31 @@ class ProjectTest(DockerClientTestCase):
             if ctnr.labels.get(LABEL_SERVICE) == 'service1'
         ]) == 0
 
+    def test_project_up_ignore_orphans(self):
+        config_dict = {
+            'service1': {
+                'image': 'busybox:latest',
+                'command': 'top',
+            }
+        }
+
+        config_data = load_config(config_dict)
+        project = Project.from_config(
+            name='composetest', config_data=config_data, client=self.client
+        )
+        project.up()
+        config_dict['service2'] = config_dict['service1']
+        del config_dict['service1']
+
+        config_data = load_config(config_dict)
+        project = Project.from_config(
+            name='composetest', config_data=config_data, client=self.client
+        )
+        with mock.patch('compose.project.log') as mock_log:
+            project.up(ignore_orphans=True)
+
+        mock_log.warning.assert_not_called()
+
     @v2_1_only()
     def test_project_up_healthy_dependency(self):
         config_dict = {