Skip to content

Commit 52944d2

Browse files
committed
Docker: improved posix signal proxying
fixes #547
1 parent 159c10a commit 52944d2

File tree

2 files changed

+21
-13
lines changed

2 files changed

+21
-13
lines changed

src/Stack/Docker.hs

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ module Stack.Docker
1919
) where
2020

2121
import Control.Applicative
22+
import Control.Concurrent (threadDelay)
2223
import Control.Concurrent.MVar.Lifted (MVar,modifyMVar_,newMVar)
2324
import Control.Exception.Lifted
2425
import Control.Monad
@@ -330,10 +331,14 @@ runContainerAndExit getCmdArgs
330331
before
331332
#ifndef WINDOWS
332333
runInBase <- liftBaseWith $ \run -> return (void . run)
333-
oldHandlers <- forM ([sigINT | not keepStdinOpen] ++ [sigTERM]) $ \sig -> do
334-
let sigHandler = do
335-
runInBase (readProcessNull Nothing envOverride "docker"
336-
["kill","--signal=" ++ show sig,containerID])
334+
oldHandlers <- forM ([sigINT,sigABRT,sigHUP,sigPIPE,sigTERM,sigUSR1,sigUSR2]) $ \sig -> do
335+
let sigHandler = runInBase $ do
336+
readProcessNull Nothing envOverride "docker"
337+
["kill","--signal=" ++ show sig,containerID]
338+
when (sig `elem` [sigTERM,sigABRT]) $ do
339+
-- Give the container 30 seconds to exit gracefully, then send a sigKILL to force it
340+
liftIO $ threadDelay 30000000
341+
readProcessNull Nothing envOverride "docker" ["kill",containerID]
337342
oldHandler <- liftIO $ installHandler sig (Catch sigHandler) Nothing
338343
return (sig, oldHandler)
339344
#endif
@@ -344,16 +349,19 @@ runContainerAndExit getCmdArgs
344349
,["-a" | not (dockerDetach docker)]
345350
,["-i" | keepStdinOpen]
346351
,[containerID]])
347-
e <- try (callProcess'
348-
(if keepStdinOpen then id else (\cp -> cp { delegate_ctlc = False }))
349-
cmd
350-
)
352+
e <- finally
353+
(try $ callProcess'
354+
(\cp -> cp { delegate_ctlc = False })
355+
cmd)
356+
(do unless (dockerPersist docker || dockerDetach docker) $
357+
catch
358+
(readProcessNull Nothing envOverride "docker" ["rm","-f",containerID])
359+
(\(_::ReadProcessException) -> return ())
351360
#ifndef WINDOWS
352-
forM_ oldHandlers $ \(sig,oldHandler) ->
353-
liftIO $ installHandler sig oldHandler Nothing
361+
forM_ oldHandlers $ \(sig,oldHandler) ->
362+
liftIO $ installHandler sig oldHandler Nothing
354363
#endif
355-
unless (dockerPersist docker || dockerDetach docker)
356-
(readProcessNull Nothing envOverride "docker" ["rm","-f",containerID])
364+
)
357365
case e of
358366
Left (ProcessExitedUnsuccessfully _ ec) -> liftIO (exitWith ec)
359367
Right () -> do after

src/System/Process/Read.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ tryProcessStdout wd menv name args =
179179

180180
-- | Produce a strict 'S.ByteString' from the stdout of a process.
181181
--
182-
-- Throws a 'ProcessExitedUnsuccessfully' exception if the process fails.
182+
-- Throws a 'ReadProcessException' exception if the process fails.
183183
readProcessStdout :: (MonadIO m, MonadLogger m, MonadBaseControl IO m, MonadCatch m)
184184
=> Maybe (Path Abs Dir) -- ^ Optional directory to run in
185185
-> EnvOverride

0 commit comments

Comments
 (0)