浏览代码

Terminate containers on SIGHUP (fixes #4909)

Signed-off-by: Guillermo Arribas <[email protected]>
Guillermo Arribas 8 年之前
父节点
当前提交
da32c44bce
共有 3 个文件被更改,包括 30 次插入2 次删除
  1. 3 2
      compose/cli/main.py
  2. 14 0
      compose/cli/signals.py
  3. 13 0
      tests/acceptance/cli_test.py

+ 3 - 2
compose/cli/main.py

@@ -1178,6 +1178,7 @@ def run_one_off_container(container_options, project, service, options):
             project.client.remove_container(container.id, force=True, v=True)
 
     signals.set_signal_handler_to_shutdown()
+    signals.set_signal_handler_to_hang_up()
     try:
         try:
             if IS_WINDOWS_PLATFORM:
@@ -1195,10 +1196,10 @@ def run_one_off_container(container_options, project, service, options):
                 service.start_container(container)
                 pty.start(sockets)
                 exit_code = container.wait()
-        except signals.ShutdownException:
+        except (signals.ShutdownException, signals.HangUpException):
             project.client.stop(container.id)
             exit_code = 1
-    except signals.ShutdownException:
+    except (signals.ShutdownException, signals.HangUpException):
         project.client.kill(container.id)
         remove_container(force=True)
         sys.exit(2)

+ 14 - 0
compose/cli/signals.py

@@ -10,6 +10,10 @@ class ShutdownException(Exception):
     pass
 
 
+class HangUpException(Exception):
+    pass
+
+
 def shutdown(signal, frame):
     raise ShutdownException()
 
@@ -23,6 +27,16 @@ def set_signal_handler_to_shutdown():
     set_signal_handler(shutdown)
 
 
+def hang_up(signal, frame):
+    raise HangUpException()
+
+
+def set_signal_handler_to_hang_up():
+    # on Windows a ValueError will be raised if trying to set signal handler for SIGHUP
+    if not IS_WINDOWS_PLATFORM:
+        signal.signal(signal.SIGHUP, hang_up)
+
+
 def ignore_sigpipe():
     # Restore default behavior for SIGPIPE instead of raising
     # an exception when encountered.

+ 13 - 0
tests/acceptance/cli_test.py

@@ -1795,6 +1795,19 @@ class CLITestCase(DockerClientTestCase):
             'simplecomposefile_simple_run_1',
             'exited'))
 
+    def test_run_handles_sighup(self):
+        proc = start_process(self.base_dir, ['run', '-T', 'simple', 'top'])
+        wait_on_condition(ContainerStateCondition(
+            self.project.client,
+            'simplecomposefile_simple_run_1',
+            'running'))
+
+        os.kill(proc.pid, signal.SIGHUP)
+        wait_on_condition(ContainerStateCondition(
+            self.project.client,
+            'simplecomposefile_simple_run_1',
+            'exited'))
+
     @mock.patch.dict(os.environ)
     def test_run_unicode_env_values_from_system(self):
         value = 'ą, ć, ę, ł, ń, ó, ś, ź, ż'