11{-# LANGUAGE CPP, ConstraintKinds, DeriveDataTypeable, FlexibleContexts, MultiWayIf, NamedFieldPuns,
2- OverloadedStrings, RankNTypes, RecordWildCards, ScopedTypeVariables, TemplateHaskell ,
3- TupleSections #-}
2+ OverloadedStrings, PackageImports, RankNTypes, RecordWildCards, ScopedTypeVariables,
3+ TemplateHaskell, TupleSections #-}
44
55-- | Run commands in Docker containers
66module Stack.Docker
@@ -28,6 +28,7 @@ import Control.Monad.Logger (MonadLogger,logError,logInfo,logWarn)
2828import Control.Monad.Reader (MonadReader ,asks ,runReaderT )
2929import Control.Monad.Writer (execWriter ,runWriter ,tell )
3030import Control.Monad.Trans.Control (MonadBaseControl )
31+ import qualified "cryptohash" Crypto.Hash as Hash
3132import Data.Aeson.Extended (FromJSON (.. ),(.:) ,(.:?) ,(.!=) ,eitherDecode )
3233import Data.ByteString.Builder (stringUtf8 ,charUtf8 ,toLazyByteString )
3334import qualified Data.ByteString.Char8 as BS
@@ -56,7 +57,7 @@ import Path.Extra (toFilePathNoTrailingSep)
5657import Path.IO
5758import qualified Paths_stack as Meta
5859import Prelude -- Fix redundant import warnings
59- import Stack.Constants ( projectDockerSandboxDir , stackProgName , stackRootEnvVar , buildPlanDir )
60+ import Stack.Constants
6061import Stack.Docker.GlobalDB
6162import Stack.Types
6263import Stack.Types.Internal
@@ -272,62 +273,49 @@ runContainerAndExit getCmdArgs
272273 | otherwise -> throwM (NotPulledException image)
273274 let ImageConfig {.. } = iiConfig
274275 imageEnvVars = map (break (== ' =' )) icEnv
275- msandboxID = lookupImageEnv sandboxIDEnvVar imageEnvVars
276- sandboxID = fromMaybe " default" msandboxID
277- sandboxIDDir <- parseRelDir (sandboxID ++ " /" )
278- let stackRoot = configStackRoot config
276+ platformVariant = BS. unpack $ Hash. digestToHexByteString $ hashRepoName image
277+ stackRoot = configStackRoot config
279278 sandboxDir = projectDockerSandboxDir projectRoot
280- sandboxSandboxDir = sandboxDir </> $ (mkRelDir " _sandbox/" ) </> sandboxIDDir
281279 sandboxHomeDir = sandboxDir </> homeDirName
282- sandboxRepoDir = sandboxDir </> sandboxIDDir
283- sandboxSubdirs = map (\ d -> sandboxRepoDir </> d)
284- sandboxedHomeSubdirectories
285280 isTerm = not (dockerDetach docker) &&
286281 isStdinTerminal &&
287282 isStdoutTerminal &&
288283 isStderrTerminal
289284 keepStdinOpen = not (dockerDetach docker) &&
290285 -- Workaround for https://github.com/docker/docker/issues/12319
291- -- This seems be fixed in Docker 1.9.1, but will leave the workaround
286+ -- This is fixed in Docker 1.9.1, but will leave the workaround
292287 -- in place for now, for users who haven't upgraded yet.
293288 (isTerm || (isNothing bamboo && isNothing jenkins))
294289 newPathEnv = intercalate [Posix. searchPathSeparator] $
295290 nubOrd $
296- [toFilePathNoTrailingSep $ sandboxRepoDir </> $ (mkRelDir " .local/bin" )
297- ,toFilePathNoTrailingSep $ sandboxRepoDir </> $ (mkRelDir " .cabal/bin" )
298- ,toFilePathNoTrailingSep $ sandboxRepoDir </> $ (mkRelDir " bin" )
299- ,hostBinDir] ++
291+ [hostBinDir
292+ ,toFilePathNoTrailingSep $ sandboxHomeDir </> $ (mkRelDir " .local/bin" )] ++
300293 maybe [] Posix. splitSearchPath (lookupImageEnv " PATH" imageEnvVars)
301294 (cmnd,args,envVars,extraMount) <- getCmdArgs docker envOverride imageInfo isRemoteDocker
302295 pwd <- getWorkingDir
303296 liftIO
304297 (do updateDockerImageLastUsed config iiId (toFilePath projectRoot)
305- mapM_ createTree
306- ([sandboxHomeDir, sandboxSandboxDir, stackRoot] ++
307- sandboxSubdirs))
298+ mapM_ createTree ([sandboxHomeDir, stackRoot]))
308299 containerID <- (trim . decodeUtf8) <$> readDockerProcess
309300 envOverride
310301 (concat
311302 [[" create"
312303 ," --net=host"
313304 ," -e" ,inContainerEnvVar ++ " =1"
314305 ," -e" ,stackRootEnvVar ++ " =" ++ toFilePathNoTrailingSep stackRoot
315- ," -e" ," HOME=" ++ toFilePathNoTrailingSep sandboxRepoDir
306+ ," -e" ,platformVariantEnvVar ++ " =dk" ++ platformVariant
307+ ," -e" ," HOME=" ++ toFilePathNoTrailingSep sandboxHomeDir
316308 ," -e" ," PATH=" ++ newPathEnv
317309 ," -v" ,toFilePathNoTrailingSep stackRoot ++ " :" ++ toFilePathNoTrailingSep stackRoot
318310 ," -v" ,toFilePathNoTrailingSep projectRoot ++ " :" ++ toFilePathNoTrailingSep projectRoot
319- ," -v" ,toFilePathNoTrailingSep sandboxSandboxDir ++ " :" ++ toFilePathNoTrailingSep sandboxDir
320- ," -v" ,toFilePathNoTrailingSep sandboxHomeDir ++ " :" ++ toFilePathNoTrailingSep sandboxRepoDir
321- ," -v" ,toFilePathNoTrailingSep stackRoot ++ " :" ++
322- toFilePathNoTrailingSep (sandboxRepoDir </> $ (mkRelDir (" ." ++ stackProgName ++ " /" )))
311+ ," -v" ,toFilePathNoTrailingSep sandboxHomeDir ++ " :" ++ toFilePathNoTrailingSep sandboxHomeDir
323312 ," -w" ,toFilePathNoTrailingSep pwd]
324313 -- Disable the deprecated entrypoint in FP Complete-generated images
325314 ,[" --entrypoint=/usr/bin/env"
326- | isJust msandboxID &&
315+ | isJust (lookupImageEnv oldSandboxIdEnvVar imageEnvVars) &&
327316 (icEntrypoint == [" /usr/local/sbin/docker-entrypoint" ] ||
328317 icEntrypoint == [" /root/entrypoint.sh" ])]
329318 ,concatMap (\ (k,v) -> [" -e" , k ++ " =" ++ v]) envVars
330- ,concatMap sandboxSubdirArg sandboxSubdirs
331319 ,concatMap mountArg (extraMount ++ dockerMount docker)
332320 ,concatMap (\ nv -> [" -e" , nv]) (dockerEnv docker)
333321 ,case dockerContainerName docker of
@@ -369,12 +357,15 @@ runContainerAndExit getCmdArgs
369357 Right () -> do after
370358 liftIO exitSuccess
371359 where
360+ -- This is using a hash of the Docker repository (without tag or digest) to ensure
361+ -- binaries/libraries aren't shared between Docker and host (or incompatible Docker images)
362+ hashRepoName :: String -> Hash. Digest Hash. MD5
363+ hashRepoName = Hash. hash . BS. pack . takeWhile (\ c -> c /= ' :' && c /= ' @' )
372364 lookupImageEnv name vars =
373365 case lookup name vars of
374366 Just (' =' : val) -> Just val
375367 _ -> Nothing
376368 mountArg (Mount host container) = [" -v" ,host ++ " :" ++ container]
377- sandboxSubdirArg subdir = [" -v" ,toFilePathNoTrailingSep subdir++ " :" ++ toFilePathNoTrailingSep subdir]
378369 projectRoot = fromMaybeProjectRoot mprojectRoot
379370
380371-- | Clean-up old docker images and containers.
@@ -808,13 +799,6 @@ readDockerProcess
808799 => EnvOverride -> [String ] -> m BS. ByteString
809800readDockerProcess envOverride = readProcessStdout Nothing envOverride " docker"
810801
811- -- | Subdirectories of the home directory to sandbox between GHC/Stackage versions.
812- sandboxedHomeSubdirectories :: [Path Rel Dir ]
813- sandboxedHomeSubdirectories =
814- [$ (mkRelDir " .ghc/" )
815- ,$ (mkRelDir " .cabal/" )
816- ,$ (mkRelDir " .ghcjs/" )]
817-
818802-- | Name of home directory within docker sandbox.
819803homeDirName :: Path Rel Dir
820804homeDirName = $ (mkRelDir " _home/" )
@@ -835,13 +819,14 @@ concatT = T.pack . concat
835819fromMaybeProjectRoot :: Maybe (Path Abs Dir ) -> Path Abs Dir
836820fromMaybeProjectRoot = fromMaybe (throw CannotDetermineProjectRootException )
837821
838- -- | Environment variable that contains the sandbox ID.
839- sandboxIDEnvVar :: String
840- sandboxIDEnvVar = " DOCKER_SANDBOX_ID"
822+ -- | Environment variable that contained the old sandbox ID.
823+ -- | Use of this variable is deprecated, and only used to detect old images.
824+ oldSandboxIdEnvVar :: String
825+ oldSandboxIdEnvVar = " DOCKER_SANDBOX_ID"
841826
842827-- | Environment variable used to indicate stack is running in container.
843828inContainerEnvVar :: String
844- inContainerEnvVar = fmap toUpper stackProgName ++ " _IN_CONTAINER"
829+ inContainerEnvVar = stackProgNameUpper ++ " _IN_CONTAINER"
845830
846831-- | Command-line argument for "docker"
847832dockerCmdName :: String
0 commit comments