Skip to content

Commit 0860f0b

Browse files
committed
Docker: move into StackT
1 parent 5918490 commit 0860f0b

File tree

2 files changed

+69
-60
lines changed

2 files changed

+69
-60
lines changed

src/Stack/Docker.hs

Lines changed: 49 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
{-# LANGUAGE CPP, DeriveDataTypeable, FlexibleContexts, MultiWayIf, NamedFieldPuns,
1+
{-# LANGUAGE CPP, ConstraintKinds, DeriveDataTypeable, FlexibleContexts, MultiWayIf, NamedFieldPuns,
22
OverloadedStrings, RankNTypes, RecordWildCards, TemplateHaskell, TupleSections #-}
33

44
-- | Run commands in Docker containers
@@ -22,9 +22,10 @@ module Stack.Docker
2222
import Control.Applicative
2323
import Control.Exception.Lifted
2424
import Control.Monad
25-
import Control.Monad.Catch (MonadThrow, throwM, MonadCatch)
25+
import Control.Monad.Catch (MonadThrow,throwM,MonadCatch)
2626
import Control.Monad.IO.Class (MonadIO,liftIO)
2727
import Control.Monad.Logger (MonadLogger,logError,logInfo,logWarn)
28+
import Control.Monad.Reader (MonadReader,asks)
2829
import Control.Monad.Writer (execWriter,runWriter,tell)
2930
import Control.Monad.Trans.Control (MonadBaseControl)
3031
import Data.Aeson.Extended (FromJSON(..),(.:),(.:?),(.!=),eitherDecode)
@@ -49,6 +50,7 @@ import Path
4950
import Path.IO (getWorkingDir,listDirectory)
5051
import Stack.Constants (projectDockerSandboxDir,stackProgName,stackDotYaml,stackRootEnvVar)
5152
import Stack.Types
53+
import Stack.Types.Internal
5254
import Stack.Docker.GlobalDB
5355
import System.Directory (createDirectoryIfMissing,removeDirectoryRecursive,removeFile)
5456
import System.Directory (doesDirectoryExist)
@@ -70,10 +72,12 @@ import System.Posix.Signals (installHandler,sigTERM,Handler(Catch))
7072
-- | If Docker is enabled, re-runs the currently running OS command in a Docker container.
7173
-- Otherwise, runs the inner action.
7274
rerunWithOptionalContainer
73-
:: (MonadLogger m, MonadIO m, MonadThrow m, MonadBaseControl IO m, MonadCatch m)
74-
=> Config -> Maybe (Path Abs Dir) -> IO () -> m ()
75-
rerunWithOptionalContainer config mprojectRoot =
76-
rerunCmdWithOptionalContainer config mprojectRoot getCmdArgs
75+
:: M env m
76+
=> Maybe (Path Abs Dir)
77+
-> IO ()
78+
-> m ()
79+
rerunWithOptionalContainer mprojectRoot =
80+
rerunCmdWithOptionalContainer mprojectRoot getCmdArgs
7781
where
7882
getCmdArgs =
7983
do args <- getArgs
@@ -82,41 +86,41 @@ rerunWithOptionalContainer config mprojectRoot =
8286
let mountPath = concat ["/opt/host/bin/",takeBaseName exePath]
8387
return (mountPath
8488
,args
85-
,config{configDocker=docker{dockerMount=Mount exePath mountPath :
86-
dockerMount docker}})
89+
,\c -> c{configDocker=(configDocker c)
90+
{dockerMount=Mount exePath mountPath :
91+
dockerMount (configDocker c)}})
8792
else do progName <- getProgName
88-
return (takeBaseName progName,args,config)
89-
docker = configDocker config
93+
return (takeBaseName progName,args,id)
9094

9195
-- | If Docker is enabled, re-runs the OS command returned by the second argument in a
9296
-- Docker container. Otherwise, runs the inner action.
9397
rerunCmdWithOptionalContainer
94-
:: (MonadLogger m,MonadIO m,MonadThrow m,MonadBaseControl IO m, MonadCatch m)
95-
=> Config
96-
-> Maybe (Path Abs Dir)
97-
-> IO (FilePath,[String],Config)
98+
:: M env m
99+
=> Maybe (Path Abs Dir)
100+
-> IO (FilePath,[String],Config -> Config)
98101
-> IO ()
99102
-> m ()
100-
rerunCmdWithOptionalContainer config mprojectRoot getCmdArgs inner =
101-
do inContainer <- getInContainer
103+
rerunCmdWithOptionalContainer mprojectRoot getCmdArgs inner =
104+
do config <- asks getConfig
105+
inContainer <- getInContainer
102106
if inContainer || not (dockerEnable (configDocker config))
103107
then liftIO inner
104-
else do (cmd_,args,config') <- liftIO getCmdArgs
105-
runContainerAndExit config' mprojectRoot cmd_ args [] (return ())
108+
else do (cmd_,args,modConfig) <- liftIO getCmdArgs
109+
runContainerAndExit modConfig mprojectRoot cmd_ args [] (return ())
106110

107111
-- | If Docker is enabled, re-runs the OS command returned by the second argument in a
108112
-- Docker container. Otherwise, runs the inner action.
109113
rerunCmdWithRequiredContainer
110-
:: (MonadLogger m,MonadIO m,MonadThrow m,MonadBaseControl IO m, MonadCatch m)
111-
=> Config
112-
-> Maybe (Path Abs Dir)
113-
-> IO (FilePath,[String],Config)
114+
:: M env m
115+
=> Maybe (Path Abs Dir)
116+
-> IO (FilePath,[String],Config -> Config)
114117
-> m ()
115-
rerunCmdWithRequiredContainer config mprojectRoot getCmdArgs =
116-
do when (not (dockerEnable (configDocker config)))
118+
rerunCmdWithRequiredContainer mprojectRoot getCmdArgs =
119+
do config <- asks getConfig
120+
when (not (dockerEnable (configDocker config)))
117121
(throwM DockerMustBeEnabledException)
118-
(cmd_,args,config') <- liftIO getCmdArgs
119-
runContainerAndExit config' mprojectRoot cmd_ args [] (return ())
122+
(cmd_,args,modConfig) <- liftIO getCmdArgs
123+
runContainerAndExit modConfig mprojectRoot cmd_ args [] (return ())
120124

121125
-- | Error if running in a container.
122126
preventInContainer :: (MonadIO m,MonadThrow m) => m () -> m ()
@@ -135,21 +139,23 @@ getInContainer =
135139
Just _ -> return True
136140

137141
-- | Run a command in a new Docker container, then exit the process.
138-
runContainerAndExit :: (MonadLogger m, MonadIO m, MonadThrow m, MonadBaseControl IO m, MonadCatch m)
139-
=> Config
142+
runContainerAndExit :: M env m
143+
=> (Config -> Config)
140144
-> Maybe (Path Abs Dir)
141145
-> FilePath
142146
-> [String]
143147
-> [(String, String)]
144148
-> IO ()
145149
-> m ()
146-
runContainerAndExit config
150+
runContainerAndExit modConfig
147151
mprojectRoot
148152
cmnd
149153
args
150154
envVars
151155
successPostAction =
152-
do envOverride <- getEnvOverride (configPlatform config)
156+
do config <- fmap modConfig (asks getConfig)
157+
let docker = configDocker config
158+
envOverride <- getEnvOverride (configPlatform config)
153159
checkDockerVersion envOverride
154160
uidOut <- readProcessStdout Nothing envOverride "id" ["-u"]
155161
gidOut <- readProcessStdout Nothing envOverride "id" ["-g"]
@@ -275,13 +281,13 @@ runContainerAndExit config
275281
sandboxSubdirArg subdir = ["-v",toFPNoTrailingSep subdir++ ":" ++ toFPNoTrailingSep subdir]
276282
toFPNoTrailingSep = dropTrailingPathSeparator . toFilePath
277283
projectRoot = fromMaybeProjectRoot mprojectRoot
278-
docker = configDocker config
279284

280285
-- | Clean-up old docker images and containers.
281-
cleanup :: (MonadLogger m, MonadIO m, MonadThrow m, MonadBaseControl IO m, MonadCatch m)
282-
=> Config -> CleanupOpts -> m ()
283-
cleanup config opts =
284-
do envOverride <- getEnvOverride (configPlatform config)
286+
cleanup :: M env m
287+
=> CleanupOpts -> m ()
288+
cleanup opts =
289+
do config <- asks getConfig
290+
envOverride <- getEnvOverride (configPlatform config)
285291
checkDockerVersion envOverride
286292
let runDocker = readDockerProcess envOverride
287293
imagesOut <- runDocker ["images","--no-trunc","-f","dangling=false"]
@@ -529,13 +535,13 @@ inspects envOverride images =
529535
Left e -> throwM e
530536

531537
-- | Pull latest version of configured Docker image from registry.
532-
pull :: (MonadLogger m, MonadIO m, MonadThrow m, MonadBaseControl IO m, MonadCatch m)
533-
=> Config -> m ()
534-
pull config =
535-
do envOverride <- getEnvOverride (configPlatform config)
538+
pull :: M env m => m ()
539+
pull =
540+
do config <- asks getConfig
541+
let docker = configDocker config
542+
envOverride <- getEnvOverride (configPlatform config)
536543
checkDockerVersion envOverride
537544
pullImage envOverride docker (dockerImage docker)
538-
where docker = configDocker config
539545

540546
-- | Pull Docker image from registry.
541547
pullImage :: (MonadLogger m,MonadIO m,MonadThrow m)
@@ -948,3 +954,6 @@ instance Show StackDockerException where
948954
"Cannot find 'docker' in PATH. Is Docker installed?"
949955
show (InvalidDatabasePathException ex) =
950956
concat ["Invalid database path: ",show ex]
957+
958+
type M env m = (MonadIO m,MonadReader env m,MonadLogger m,MonadBaseControl IO m,MonadCatch m
959+
,HasConfig env,HasTerminal env)

src/main/Main.hs

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -366,9 +366,8 @@ setupParser = SetupCmdOpts
366366
setupCmd :: SetupCmdOpts -> GlobalOpts -> IO ()
367367
setupCmd SetupCmdOpts{..} go@GlobalOpts{..} = do
368368
(manager,lc) <- loadConfigWithOpts go
369-
runStackLoggingT manager globalLogLevel globalTerminal $
369+
runStackT manager globalLogLevel (lcConfig lc) globalTerminal $
370370
Docker.rerunWithOptionalContainer
371-
(lcConfig lc)
372371
(lcProjectRoot lc)
373372
(runStackLoggingT manager globalLogLevel globalTerminal $ do
374373
(ghc, mstack) <-
@@ -399,8 +398,8 @@ withBuildConfig :: GlobalOpts
399398
-> IO ()
400399
withBuildConfig go@GlobalOpts{..} strat inner = do
401400
(manager, lc) <- loadConfigWithOpts go
402-
runStackLoggingT manager globalLogLevel globalTerminal $
403-
Docker.rerunWithOptionalContainer (lcConfig lc) (lcProjectRoot lc) $ do
401+
runStackT manager globalLogLevel (lcConfig lc) globalTerminal $
402+
Docker.rerunWithOptionalContainer (lcProjectRoot lc) $ do
404403
bconfig <- runStackLoggingT manager globalLogLevel globalTerminal $
405404
lcLoadBuildConfig lc globalResolver strat
406405
envConfig <-
@@ -460,8 +459,8 @@ installCmd opts go@GlobalOpts{..} = withBuildConfig go ExecStrategy $
460459
unpackCmd :: [String] -> GlobalOpts -> IO ()
461460
unpackCmd names go@GlobalOpts{..} = do
462461
(manager,lc) <- loadConfigWithOpts go
463-
runStackLoggingT manager globalLogLevel globalTerminal $
464-
Docker.rerunWithOptionalContainer (lcConfig lc) (lcProjectRoot lc) $
462+
runStackT manager globalLogLevel (lcConfig lc) globalTerminal $
463+
Docker.rerunWithOptionalContainer (lcProjectRoot lc) $
465464
runStackT manager globalLogLevel (lcConfig lc) globalTerminal $ do
466465
menv <- getMinimalEnvOverride
467466
Stack.Fetch.unpackPackages menv "." names
@@ -470,8 +469,8 @@ unpackCmd names go@GlobalOpts{..} = do
470469
updateCmd :: () -> GlobalOpts -> IO ()
471470
updateCmd () go@GlobalOpts{..} = do
472471
(manager,lc) <- loadConfigWithOpts go
473-
runStackLoggingT manager globalLogLevel globalTerminal $
474-
Docker.rerunWithOptionalContainer (lcConfig lc) (lcProjectRoot lc) $
472+
runStackT manager globalLogLevel (lcConfig lc) globalTerminal $
473+
Docker.rerunWithOptionalContainer (lcProjectRoot lc) $
475474
runStackT manager globalLogLevel (lcConfig lc) globalTerminal $
476475
getMinimalEnvOverride >>= Stack.PackageIndex.updateAllIndices
477476

@@ -506,8 +505,8 @@ replCmd (targets,args,path) go@GlobalOpts{..} = withBuildConfig go ExecStrategy
506505
dockerPullCmd :: () -> GlobalOpts -> IO ()
507506
dockerPullCmd _ go@GlobalOpts{..} = do
508507
(manager,lc) <- liftIO $ loadConfigWithOpts go
509-
runStackLoggingT manager globalLogLevel globalTerminal $ Docker.preventInContainer $
510-
Docker.pull (lcConfig lc)
508+
runStackT manager globalLogLevel (lcConfig lc) globalTerminal $
509+
Docker.preventInContainer Docker.pull
511510

512511
-- | Reset the Docker sandbox.
513512
dockerResetCmd :: Bool -> GlobalOpts -> IO ()
@@ -520,17 +519,18 @@ dockerResetCmd keepHome go@GlobalOpts{..} = do
520519
dockerCleanupCmd :: Docker.CleanupOpts -> GlobalOpts -> IO ()
521520
dockerCleanupCmd cleanupOpts go@GlobalOpts{..} = do
522521
(manager,lc) <- liftIO $ loadConfigWithOpts go
523-
runStackLoggingT manager globalLogLevel globalTerminal$ Docker.preventInContainer $
524-
Docker.cleanup (lcConfig lc) cleanupOpts
522+
runStackT manager globalLogLevel (lcConfig lc) globalTerminal $
523+
Docker.preventInContainer $
524+
Docker.cleanup cleanupOpts
525525

526526
-- | Execute a command
527527
dockerExecCmd :: (String, [String]) -> GlobalOpts -> IO ()
528528
dockerExecCmd (cmd,args) go@GlobalOpts{..} = do
529529
(manager,lc) <- liftIO $ loadConfigWithOpts go
530-
runStackLoggingT manager globalLogLevel globalTerminal$ Docker.preventInContainer $
531-
Docker.rerunCmdWithRequiredContainer (lcConfig lc)
532-
(lcProjectRoot lc)
533-
(return (cmd,args,lcConfig lc))
530+
runStackT manager globalLogLevel (lcConfig lc) globalTerminal $
531+
Docker.preventInContainer $
532+
Docker.rerunCmdWithRequiredContainer (lcProjectRoot lc)
533+
(return (cmd,args,id))
534534

535535
-- | Parser for build arguments.
536536
buildOpts :: Bool -> Parser BuildOpts
@@ -721,17 +721,17 @@ loadConfigWithOpts GlobalOpts{..} = do
721721
initCmd :: InitOpts -> GlobalOpts -> IO ()
722722
initCmd initOpts go@GlobalOpts{..} = do
723723
(manager,lc) <- loadConfigWithOpts go
724-
runStackLoggingT manager globalLogLevel globalTerminal $
725-
Docker.rerunWithOptionalContainer (lcConfig lc) (lcProjectRoot lc) $
724+
runStackT manager globalLogLevel (lcConfig lc) globalTerminal $
725+
Docker.rerunWithOptionalContainer (lcProjectRoot lc) $
726726
runStackT manager globalLogLevel (lcConfig lc) globalTerminal $
727727
initProject initOpts
728728

729729
-- | Project creation
730730
newCmd :: InitOpts -> GlobalOpts -> IO ()
731731
newCmd initOpts go@GlobalOpts{..} = do
732732
(manager,lc) <- loadConfigWithOpts go
733-
runStackLoggingT manager globalLogLevel globalTerminal $
734-
Docker.rerunWithOptionalContainer (lcConfig lc) (lcProjectRoot lc) $
733+
runStackT manager globalLogLevel (lcConfig lc) globalTerminal $
734+
Docker.rerunWithOptionalContainer (lcProjectRoot lc) $
735735
runStackT manager globalLogLevel (lcConfig lc) globalTerminal $ do
736736
newProject
737737
initProject initOpts

0 commit comments

Comments
 (0)