another try at unmounting /proc for systemd-nspawn

This commit is contained in:
Joey Hess 2015-06-01 18:14:47 -04:00
parent 0bcbffad98
commit ef1307652e
2 changed files with 22 additions and 26 deletions

View File

@ -16,10 +16,10 @@ import Propellor
import Propellor.Types.CmdLine import Propellor.Types.CmdLine
import Propellor.Types.Chroot import Propellor.Types.Chroot
import Propellor.Property.Chroot.Util import Propellor.Property.Chroot.Util
import Propellor.Property.Mount
import qualified Propellor.Property.Debootstrap as Debootstrap import qualified Propellor.Property.Debootstrap as Debootstrap
import qualified Propellor.Property.Systemd.Core as Systemd import qualified Propellor.Property.Systemd.Core as Systemd
import qualified Propellor.Shim as Shim import qualified Propellor.Shim as Shim
import Propellor.Property.Mount
import qualified Data.Map as M import qualified Data.Map as M
import Data.List.Utils import Data.List.Utils
@ -70,7 +70,7 @@ provisioned' propigator c@(Chroot loc system builderconf _) systemdonly =
where where
go desc a = propertyList (chrootDesc c desc) [a] go desc a = propertyList (chrootDesc c desc) [a]
setup = propellChroot c (inChrootProcess c) systemdonly setup = propellChroot c (inChrootProcess (not systemdonly) c) systemdonly
`requires` toProp built `requires` toProp built
built = case (system, builderconf) of built = case (system, builderconf) of
@ -95,7 +95,7 @@ chrootInfo (Chroot loc _ _ h) =
mempty { _chrootinfo = mempty { _chroots = M.singleton loc h } } mempty { _chrootinfo = mempty { _chroots = M.singleton loc h } }
-- | Propellor is run inside the chroot to provision it. -- | Propellor is run inside the chroot to provision it.
propellChroot :: Chroot -> ([String] -> IO CreateProcess) -> Bool -> Property NoInfo propellChroot :: Chroot -> ([String] -> IO (CreateProcess, IO ())) -> Bool -> Property NoInfo
propellChroot c@(Chroot loc _ _ _) mkproc systemdonly = property (chrootDesc c "provisioned") $ do propellChroot c@(Chroot loc _ _ _) mkproc systemdonly = property (chrootDesc c "provisioned") $ do
let d = localdir </> shimdir c let d = localdir </> shimdir c
let me = localdir </> "propellor" let me = localdir </> "propellor"
@ -123,14 +123,16 @@ propellChroot c@(Chroot loc _ _ _) mkproc systemdonly = property (chrootDesc c "
parenthost <- asks hostName parenthost <- asks hostName
cmd <- liftIO $ toChain parenthost c systemdonly cmd <- liftIO $ toChain parenthost c systemdonly
pe <- liftIO standardPathEnv pe <- liftIO standardPathEnv
p <- liftIO $ mkproc (p, cleanup) <- liftIO $ mkproc
[ shim [ shim
, "--continue" , "--continue"
, show cmd , show cmd
] ]
let p' = p { env = Just pe } let p' = p { env = Just pe }
liftIO $ withHandle StdoutHandle createProcessSuccess p' r <- liftIO $ withHandle StdoutHandle createProcessSuccess p'
processChainOutput processChainOutput
liftIO cleanup
return r
toChain :: HostName -> Chroot -> Bool -> IO CmdLine toChain :: HostName -> Chroot -> Bool -> IO CmdLine
toChain parenthost (Chroot loc _ _ _) systemdonly = do toChain parenthost (Chroot loc _ _ _) systemdonly = do
@ -157,17 +159,23 @@ chain hostlist (ChrootChain hn loc systemdonly onconsole) =
putStrLn $ "\n" ++ show r putStrLn $ "\n" ++ show r
chain _ _ = errorMessage "bad chain command" chain _ _ = errorMessage "bad chain command"
inChrootProcess :: Chroot -> [String] -> IO CreateProcess inChrootProcess :: Bool -> Chroot -> [String] -> IO (CreateProcess, IO ())
inChrootProcess (Chroot loc _ _ _) cmd = do inChrootProcess keepprocmounted (Chroot loc _ _ _) cmd = do
mountproc mountproc
return $ proc "chroot" (loc:cmd) return (proc "chroot" (loc:cmd), cleanup)
where where
-- /proc needs to be mounted in the chroot for the linker to use -- /proc needs to be mounted in the chroot for the linker to use
-- /proc/self/exe which is necessary for some commands to work -- /proc/self/exe which is necessary for some commands to work
mountproc = unlessM (elem procloc <$> mountPointsBelow loc) $ mountproc = unlessM (elem procloc <$> mountPointsBelow loc) $
void $ mount "proc" "proc" procloc void $ mount "proc" "proc" procloc
procloc = loc </> "proc" procloc = loc </> "proc"
cleanup
| keepprocmounted = noop
| otherwise = whenM (elem procloc <$> mountPointsBelow loc) $
umountLazy procloc
provisioningLock :: FilePath -> FilePath provisioningLock :: FilePath -> FilePath
provisioningLock containerloc = "chroot" </> mungeloc containerloc ++ ".lock" provisioningLock containerloc = "chroot" </> mungeloc containerloc ++ ".lock"

View File

@ -39,7 +39,6 @@ import qualified Propellor.Property.Chroot as Chroot
import qualified Propellor.Property.Apt as Apt import qualified Propellor.Property.Apt as Apt
import qualified Propellor.Property.File as File import qualified Propellor.Property.File as File
import Propellor.Property.Systemd.Core import Propellor.Property.Systemd.Core
import Propellor.Property.Mount
import Utility.FileMode import Utility.FileMode
import Data.List import Data.List
@ -168,19 +167,7 @@ nspawned c@(Container name (Chroot.Chroot loc system builderconf _) h) =
-- Chroot provisioning is run in systemd-only mode, -- Chroot provisioning is run in systemd-only mode,
-- which sets up the chroot and ensures systemd and dbus are -- which sets up the chroot and ensures systemd and dbus are
-- installed, but does not handle the other provisions. -- installed, but does not handle the other provisions.
chrootprovisioned = chrootprovisioned = Chroot.provisioned' (Chroot.propigateChrootInfo chroot) chroot True
(toProp provisioner `onChange` umountProc)
<!>
(toProp (revert provisioner))
provisioner = Chroot.provisioned' (Chroot.propigateChrootInfo chroot) chroot True
-- The chroot's /proc is left mounted by the chroot provisioning,
-- but that will prevent systemd-nspawn from starting systemd in
-- it, so unmount.
umountProc = check (elem procloc <$> mountPointsBelow loc) $
property (procloc ++ " unmounted") $ do
makeChange $ umountLazy procloc
procloc = loc </> "proc"
-- Use nsenter to enter container and and run propellor to -- Use nsenter to enter container and and run propellor to
-- finish provisioning. -- finish provisioning.
@ -269,8 +256,8 @@ enterScript c@(Container name _ _) = setup <!> teardown
enterScriptFile :: Container -> FilePath enterScriptFile :: Container -> FilePath
enterScriptFile (Container name _ _ ) = "/usr/local/bin/enter-" ++ mungename name enterScriptFile (Container name _ _ ) = "/usr/local/bin/enter-" ++ mungename name
enterContainerProcess :: Container -> [String] -> IO CreateProcess enterContainerProcess :: Container -> [String] -> IO (CreateProcess, IO ())
enterContainerProcess c ps = pure $ proc (enterScriptFile c) ps enterContainerProcess c ps = pure (proc (enterScriptFile c) ps, noop)
nspawnServiceName :: MachineName -> ServiceName nspawnServiceName :: MachineName -> ServiceName
nspawnServiceName name = "systemd-nspawn@" ++ name ++ ".service" nspawnServiceName name = "systemd-nspawn@" ++ name ++ ".service"
@ -338,8 +325,9 @@ instance Publishable PortSpec where
-- | Publish a port from the container on the host. -- | Publish a port from the container on the host.
-- --
-- Note that this will only work if the container's network is set up -- Note that this will only work if the container is set up to use
-- by other properties. -- private networking. If the container does not use private networking,
-- this property is not needed.
-- --
-- This feature was first added in systemd version 220. -- This feature was first added in systemd version 220.
publish :: Publishable p => p -> RevertableProperty publish :: Publishable p => p -> RevertableProperty