propellor spin

This commit is contained in:
Joey Hess 2014-11-21 17:11:26 -04:00
parent 435244353c
commit 6e8b28cd3c
Failed to extract signature
6 changed files with 46 additions and 35 deletions

View File

@ -96,6 +96,7 @@ Library
Propellor.Property.Ssh Propellor.Property.Ssh
Propellor.Property.Sudo Propellor.Property.Sudo
Propellor.Property.Systemd Propellor.Property.Systemd
Propellor.Property.Systemd.Core
Propellor.Property.Tor Propellor.Property.Tor
Propellor.Property.User Propellor.Property.User
Propellor.Property.HostingProvider.CloudAtCost Propellor.Property.HostingProvider.CloudAtCost

View File

@ -85,7 +85,7 @@ defaultMain hostlist = do
go _ (Edit field context) = editPrivData field context go _ (Edit field context) = editPrivData field context
go _ ListFields = listPrivDataFields hostlist go _ ListFields = listPrivDataFields hostlist
go _ (AddKey keyid) = addKey keyid go _ (AddKey keyid) = addKey keyid
go _ (ChrootChain hn loc onconsole) = Chroot.chain hostlist hn loc onconsole go _ c@(ChrootChain _ _ _ _) = Chroot.chain hostlist c
go _ (DockerChain hn cid) = Docker.chain hostlist hn cid go _ (DockerChain hn cid) = Docker.chain hostlist hn cid
go _ (DockerInit hn) = Docker.init hn go _ (DockerInit hn) = Docker.init hn
go _ (GitPush fin fout) = gitPushHelper fin fout go _ (GitPush fin fout) = gitPushHelper fin fout

View File

@ -11,6 +11,7 @@ module Propellor.Property.Chroot (
import Propellor import Propellor
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.Shim as Shim import qualified Propellor.Shim as Shim
import Utility.SafeCommand import Utility.SafeCommand
@ -52,16 +53,17 @@ debootstrapped system conf location = case system of
-- Reverting this property removes the chroot. Note that it does not ensure -- Reverting this property removes the chroot. Note that it does not ensure
-- that any processes that might be running inside the chroot are stopped. -- that any processes that might be running inside the chroot are stopped.
provisioned :: Chroot -> RevertableProperty provisioned :: Chroot -> RevertableProperty
provisioned c = provisioned' (propigateChrootInfo c) c provisioned c = provisioned' (propigateChrootInfo c) c False
provisioned' :: (Property -> Property) -> Chroot -> RevertableProperty provisioned' :: (Property -> Property) -> Chroot -> Bool -> RevertableProperty
provisioned' propigator c@(Chroot loc system builderconf _) = RevertableProperty provisioned' propigator c@(Chroot loc system builderconf _) systemdonly = RevertableProperty
(propigator $ go "exists" setup) (propigator $ go "exists" setup)
(go "removed" teardown) (go "removed" teardown)
where where
go desc a = property (chrootDesc c desc) $ ensureProperties [a] go desc a = property (chrootDesc c desc) $ ensureProperties [a]
setup = propellChroot c (inChrootProcess c) `requires` toProp built setup = propellChroot c (inChrootProcess c) systemdonly
`requires` toProp built
built = case (system, builderconf) of built = case (system, builderconf) of
((System (Debian _) _), UsingDeboostrap cf) -> debootstrap cf ((System (Debian _) _), UsingDeboostrap cf) -> debootstrap cf
@ -79,8 +81,8 @@ 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] -> CreateProcess) -> Property propellChroot :: Chroot -> ([String] -> CreateProcess) -> Bool -> Property
propellChroot c@(Chroot loc _ _ _) mkproc = 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"
shim <- liftIO $ ifM (doesDirectoryExist d) shim <- liftIO $ ifM (doesDirectoryExist d)
@ -105,7 +107,7 @@ propellChroot c@(Chroot loc _ _ _) mkproc = property (chrootDesc c "provisioned"
chainprovision shim = do chainprovision shim = do
parenthost <- asks hostName parenthost <- asks hostName
cmd <- liftIO $ toChain parenthost c cmd <- liftIO $ toChain parenthost c systemdonly
let p = mkproc let p = mkproc
[ shim [ shim
, "--continue" , "--continue"
@ -114,24 +116,29 @@ propellChroot c@(Chroot loc _ _ _) mkproc = property (chrootDesc c "provisioned"
liftIO $ withHandle StdoutHandle createProcessSuccess p liftIO $ withHandle StdoutHandle createProcessSuccess p
processChainOutput processChainOutput
toChain :: HostName -> Chroot -> IO CmdLine toChain :: HostName -> Chroot -> Bool -> IO CmdLine
toChain parenthost (Chroot loc _ _ _) = do toChain parenthost (Chroot loc _ _ _) systemdonly = do
onconsole <- isConsole <$> mkMessageHandle onconsole <- isConsole <$> mkMessageHandle
return $ ChrootChain parenthost loc onconsole return $ ChrootChain parenthost loc systemdonly onconsole
chain :: [Host] -> HostName -> FilePath -> Bool -> IO () chain :: [Host] -> CmdLine -> IO ()
chain hostlist hn loc onconsole = case findHostNoAlias hostlist hn of chain hostlist (ChrootChain hn loc systemdonly onconsole) =
Nothing -> errorMessage ("cannot find host " ++ hn) case findHostNoAlias hostlist hn of
Just parenthost -> case M.lookup loc (_chroots $ _chrootinfo $ hostInfo parenthost) of Nothing -> errorMessage ("cannot find host " ++ hn)
Nothing -> errorMessage ("cannot find chroot " ++ loc ++ " on host " ++ hn) Just parenthost -> case M.lookup loc (_chroots $ _chrootinfo $ hostInfo parenthost) of
Just h -> go h Nothing -> errorMessage ("cannot find chroot " ++ loc ++ " on host " ++ hn)
Just h -> go h
where where
go h = do go h = do
changeWorkingDirectory localdir changeWorkingDirectory localdir
when onconsole forceConsole when onconsole forceConsole
onlyProcess (provisioningLock loc) $ do onlyProcess (provisioningLock loc) $ do
r <- runPropellor h $ ensureProperties $ hostProperties h r <- runPropellor h $ ensureProperties $
if systemdonly
then [Systemd.installed]
else hostProperties h
putStrLn $ "\n" ++ show r putStrLn $ "\n" ++ show r
chain _ _ = errorMessage "bad chain command"
inChrootProcess :: Chroot -> [String] -> CreateProcess inChrootProcess :: Chroot -> [String] -> CreateProcess
inChrootProcess (Chroot loc _ _ _) cmd = proc "chroot" (loc:cmd) inChrootProcess (Chroot loc _ _ _) cmd = proc "chroot" (loc:cmd)

View File

@ -1,5 +1,5 @@
module Propellor.Property.Systemd ( module Propellor.Property.Systemd (
installed, module Propellor.Property.Systemd.Core,
started, started,
stopped, stopped,
enabled, enabled,
@ -14,6 +14,7 @@ import Propellor
import qualified Propellor.Property.Chroot as Chroot 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 Utility.SafeCommand import Utility.SafeCommand
import Utility.FileMode import Utility.FileMode
@ -30,12 +31,6 @@ instance Hostlike Container where
(Container n c h) &^ p = Container n c (h &^ p) (Container n c h) &^ p = Container n c (h &^ p)
getHost (Container _ _ h) = h getHost (Container _ _ h) = h
-- dbus is only a Recommends of systemd, but is needed for communication
-- from the systemd inside a container to the one outside, so make sure it
-- gets installed.
installed :: Property
installed = Apt.installed ["systemd", "dbus"]
-- | Starts a systemd service. -- | Starts a systemd service.
started :: ServiceName -> Property started :: ServiceName -> Property
started n = trivial $ cmdProperty "systemctl" ["start", n] started n = trivial $ cmdProperty "systemctl" ["start", n]
@ -110,20 +105,18 @@ nspawned c@(Container name (Chroot.Chroot loc system builderconf _) h) =
, nspawnService c , nspawnService c
] ]
-- When provisioning the chroot, pass a version of the Host -- Chroot provisioning is run in systemd-only mode,
-- that only has the Property of systemd being installed. -- which sets up the chroot and ensures systemd and dbus are
-- This is to avoid starting any daemons in the chroot, -- installed, but does not handle the other provisions.
-- which would not run in the container's namespace. chrootprovisioned = Chroot.provisioned'
chrootprovisioned = Chroot.provisioned' (Chroot.propigateChrootInfo chroot) $ (Chroot.propigateChrootInfo chroot) chroot True
mkChroot $ h { hostProperties = [installed] }
-- Use nsenter to enter container and and run propellor to -- Use nsenter to enter container and and run propellor to
-- finish provisioning. -- finish provisioning.
containerprovisioned = Chroot.propellChroot chroot containerprovisioned = Chroot.propellChroot chroot
(enterContainerProcess c) (enterContainerProcess c) False
mkChroot = Chroot.Chroot loc system builderconf chroot = Chroot.Chroot loc system builderconf h
chroot = mkChroot h
nspawnService :: Container -> RevertableProperty nspawnService :: Container -> RevertableProperty
nspawnService (Container name _ _) = RevertableProperty setup teardown nspawnService (Container name _ _) = RevertableProperty setup teardown

View File

@ -0,0 +1,10 @@
module Propellor.Property.Systemd.Core where
import Propellor
import qualified Propellor.Property.Apt as Apt
-- dbus is only a Recommends of systemd, but is needed for communication
-- from the systemd inside a container to the one outside, so make sure it
-- gets installed.
installed :: Property
installed = Apt.installed ["systemd", "dbus"]

View File

@ -155,7 +155,7 @@ data CmdLine
| Update HostName | Update HostName
| DockerInit HostName | DockerInit HostName
| DockerChain HostName String | DockerChain HostName String
| ChrootChain HostName FilePath Bool | ChrootChain HostName FilePath Bool Bool
| GitPush Fd Fd | GitPush Fd Fd
deriving (Read, Show, Eq) deriving (Read, Show, Eq)