Skip to content

Commit 1bd04e7

Browse files
committed
Docker: pass supplemantary groups and umask into container
1 parent c544438 commit 1bd04e7

File tree

3 files changed

+46
-18
lines changed

3 files changed

+46
-18
lines changed

ChangeLog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Other enhancements:
1414
[docs](http://docs.haskellstack.org/en/latest/yaml_configuration.html#image)
1515
- Specify which executables to include in images for `stack image container`
1616
[docs](http://docs.haskellstack.org/en/latest/yaml_configuration.html#image)
17+
- Docker: pass supplemantary groups and umask into container
1718

1819
Bug fixes:
1920

src/Stack/Docker.hs

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ import System.IO (stderr,stdin,stdout,hIsTerminalDevice)
7272
import System.IO.Error (isDoesNotExistError)
7373
import System.IO.Unsafe (unsafePerformIO)
7474
import qualified System.PosixCompat.User as User
75+
import qualified System.PosixCompat.Files as Files
7576
import System.Process.PagerEditor (editByteString)
7677
import System.Process.Read
7778
import System.Process.Run
@@ -82,6 +83,7 @@ import Text.Printf (printf)
8283
import Control.Concurrent (threadDelay)
8384
import Control.Monad.Trans.Control (liftBaseWith)
8485
import System.Posix.Signals
86+
import qualified System.Posix.User as PosixUser
8587
#endif
8688

8789
-- | If Docker is enabled, re-runs the currently running OS command in a Docker container.
@@ -104,10 +106,16 @@ reexecWithOptionalContainer mprojectRoot =
104106
where
105107
getCmdArgs docker envOverride imageInfo isRemoteDocker = do
106108
config <- asks getConfig
107-
deUidGid <-
109+
deUser <-
108110
if fromMaybe (not isRemoteDocker) (dockerSetUser docker)
109-
then liftIO $ Just <$>
110-
((,) <$> User.getEffectiveUserID <*> User.getEffectiveGroupID)
111+
then liftIO $ do
112+
duUid <- User.getEffectiveUserID
113+
duGid <- User.getEffectiveGroupID
114+
duGroups <- User.getGroups
115+
duUmask <- Files.setFileCreationMask 0o022
116+
-- Only way to get old umask seems to be to change it, so set it back afterward
117+
_ <- Files.setFileCreationMask duUmask
118+
return (Just DockerUser{..})
111119
else return Nothing
112120
args <-
113121
fmap
@@ -713,10 +721,10 @@ entrypoint config@Config{..} DockerEntrypoint{..} =
713721
estackUserEntry0 <- liftIO $ tryJust (guard . isDoesNotExistError) $
714722
User.getUserEntryForName stackUserName
715723
-- Switch UID/GID if needed, and update user's home directory
716-
case deUidGid of
724+
case deUser of
717725
Nothing -> return ()
718-
Just (0,_) -> return ()
719-
Just (uid,gid) -> updateOrCreateStackUser envOverride estackUserEntry0 homeDir uid gid
726+
Just (DockerUser 0 _ _ _) -> return ()
727+
Just du -> updateOrCreateStackUser envOverride estackUserEntry0 homeDir du
720728
case estackUserEntry0 of
721729
Left _ -> return ()
722730
Right ue -> do
@@ -751,35 +759,45 @@ entrypoint config@Config{..} DockerEntrypoint{..} =
751759
copyFile srcIndex destIndex
752760
return True
753761
where
754-
updateOrCreateStackUser envOverride estackUserEntry homeDir uid gid = do
762+
updateOrCreateStackUser envOverride estackUserEntry homeDir DockerUser{..} = do
755763
case estackUserEntry of
756764
Left _ -> do
757765
-- If no 'stack' user in image, create one with correct UID/GID and home directory
758766
readProcessNull Nothing envOverride "groupadd"
759767
["-o"
760-
,"--gid",show gid
768+
,"--gid",show duGid
761769
,stackUserName]
762770
readProcessNull Nothing envOverride "useradd"
763771
["-oN"
764-
,"--uid",show uid
765-
,"--gid",show gid
772+
,"--uid",show duUid
773+
,"--gid",show duGid
766774
,"--home",toFilePathNoTrailingSep homeDir
767775
,stackUserName]
768776
Right _ -> do
769-
-- If there is already a 'stack' user in thr image, adjust its UID/GID and home directory
777+
-- If there is already a 'stack' user in the image, adjust its UID/GID and home directory
770778
readProcessNull Nothing envOverride "usermod"
771779
["-o"
772-
,"--uid",show uid
780+
,"--uid",show duUid
773781
,"--home",toFilePathNoTrailingSep homeDir
774782
,stackUserName]
775783
readProcessNull Nothing envOverride "groupmod"
776784
["-o"
777-
,"--gid",show gid
785+
,"--gid",show duGid
778786
,stackUserName]
787+
forM_ duGroups $ \gid -> do
788+
readProcessNull Nothing envOverride "groupadd"
789+
["-o"
790+
,"--gid",show gid
791+
,"group" ++ show gid]
779792
-- 'setuid' to the wanted UID and GID
780793
liftIO $ do
781-
User.setGroupID gid
782-
User.setUserID uid
794+
User.setGroupID duGid
795+
#ifndef WINDOWS
796+
PosixUser.setGroups duGroups
797+
#endif
798+
User.setUserID duUid
799+
_ <- Files.setFileCreationMask duUmask
800+
return ()
783801
stackUserName = "stack"::String
784802

785803
-- | MVar used to ensure the Docker entrypoint is performed exactly once

src/Stack/Types/Config.hs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ module Stack.Types.Config
119119
,SetupInfoLocation(..)
120120
-- ** Docker entrypoint
121121
,DockerEntrypoint(..)
122+
,DockerUser(..)
122123
) where
123124

124125
import Control.Applicative
@@ -169,7 +170,7 @@ import Stack.Types.PackageIndex
169170
import Stack.Types.PackageName
170171
import Stack.Types.TemplateName
171172
import Stack.Types.Version
172-
import System.PosixCompat.Types (UserID, GroupID)
173+
import System.PosixCompat.Types (UserID, GroupID, FileMode)
173174
import System.Process.Read (EnvOverride)
174175
#ifdef mingw32_HOST_OS
175176
import qualified Crypto.Hash.SHA1 as SHA1
@@ -1613,6 +1614,14 @@ explicitSetupDeps name = do
16131614

16141615
-- | Data passed into Docker container for the Docker entrypoint's use
16151616
data DockerEntrypoint = DockerEntrypoint
1616-
{ deUidGid :: !(Maybe (UserID, GroupID))
1617-
-- ^ UID/GID of host user, if we wish to perform UID/GID switch in container
1617+
{ deUser :: !(Maybe DockerUser)
1618+
-- ^ UID/GID/etc of host user, if we wish to perform UID/GID switch in container
1619+
} deriving (Read,Show)
1620+
1621+
-- | Docker host user info
1622+
data DockerUser = DockerUser
1623+
{ duUid :: UserID -- ^ uid
1624+
, duGid :: GroupID -- ^ gid
1625+
, duGroups :: [GroupID] -- ^ Supplemantal groups
1626+
, duUmask :: FileMode -- ^ File creation mask }
16181627
} deriving (Read,Show)

0 commit comments

Comments
 (0)