incomplete systemd container support
This commit is contained in:
parent
3669bd61d0
commit
f9cc7c149e
|
@ -20,6 +20,8 @@ propellor (1.0.0) UNRELEASED; urgency=medium
|
||||||
Docker.docked. (API change)
|
Docker.docked. (API change)
|
||||||
* Added support for using debootstrap from propellor.
|
* Added support for using debootstrap from propellor.
|
||||||
* Propellor can now be used to provision chroots.
|
* Propellor can now be used to provision chroots.
|
||||||
|
* systemd-nspawn containers can now be managed by propellor, very similar
|
||||||
|
to its handling of docker containers.
|
||||||
|
|
||||||
-- Joey Hess <id@joeyh.name> Mon, 10 Nov 2014 11:15:27 -0400
|
-- Joey Hess <id@joeyh.name> Mon, 10 Nov 2014 11:15:27 -0400
|
||||||
|
|
||||||
|
|
|
@ -95,6 +95,7 @@ Library
|
||||||
Propellor.Property.Service
|
Propellor.Property.Service
|
||||||
Propellor.Property.Ssh
|
Propellor.Property.Ssh
|
||||||
Propellor.Property.Sudo
|
Propellor.Property.Sudo
|
||||||
|
Propellor.Property.Systemd
|
||||||
Propellor.Property.Tor
|
Propellor.Property.Tor
|
||||||
Propellor.Property.User
|
Propellor.Property.User
|
||||||
Propellor.Property.HostingProvider.CloudAtCost
|
Propellor.Property.HostingProvider.CloudAtCost
|
||||||
|
|
|
@ -131,10 +131,6 @@ boolProperty desc a = property desc $ ifM (liftIO a)
|
||||||
revert :: RevertableProperty -> RevertableProperty
|
revert :: RevertableProperty -> RevertableProperty
|
||||||
revert (RevertableProperty p1 p2) = RevertableProperty p2 p1
|
revert (RevertableProperty p1 p2) = RevertableProperty p2 p1
|
||||||
|
|
||||||
-- | Turns a revertable property into a regular property.
|
|
||||||
unrevertable :: RevertableProperty -> Property
|
|
||||||
unrevertable (RevertableProperty p1 _p2) = p1
|
|
||||||
|
|
||||||
-- Changes the action that is performed to satisfy a property.
|
-- Changes the action that is performed to satisfy a property.
|
||||||
adjustProperty :: Property -> (Propellor Result -> Propellor Result) -> Property
|
adjustProperty :: Property -> (Propellor Result -> Propellor Result) -> Property
|
||||||
adjustProperty p f = p { propertySatisfy = f (propertySatisfy p) }
|
adjustProperty p f = p { propertySatisfy = f (propertySatisfy p) }
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
module Propellor.Property.Chroot (
|
module Propellor.Property.Chroot (
|
||||||
Chroot,
|
Chroot(..),
|
||||||
chroot,
|
chroot,
|
||||||
provisioned,
|
provisioned,
|
||||||
chain,
|
chain,
|
||||||
|
@ -24,7 +24,7 @@ instance Hostlike Chroot where
|
||||||
-- | Defines a Chroot at the given location, containing the specified
|
-- | Defines a Chroot at the given location, containing the specified
|
||||||
-- System. Properties can be added to configure the Chroot.
|
-- System. Properties can be added to configure the Chroot.
|
||||||
--
|
--
|
||||||
-- > chroot "/srv/chroot/ghc-dev" (System (Debian Unstable) "amd64"
|
-- > chroot "/srv/chroot/ghc-dev" (System (Debian Unstable) "amd64")
|
||||||
-- > & Apt.installed ["build-essential", "ghc", "haskell-platform"]
|
-- > & Apt.installed ["build-essential", "ghc", "haskell-platform"]
|
||||||
-- > & ...
|
-- > & ...
|
||||||
chroot :: FilePath -> System -> Chroot
|
chroot :: FilePath -> System -> Chroot
|
||||||
|
@ -48,7 +48,7 @@ provisioned c@(Chroot loc system _) = RevertableProperty
|
||||||
(System (Debian _) _) -> debootstrap
|
(System (Debian _) _) -> debootstrap
|
||||||
(System (Ubuntu _) _) -> debootstrap
|
(System (Ubuntu _) _) -> debootstrap
|
||||||
|
|
||||||
debootstrap = unrevertable (Debootstrap.built loc system [])
|
debootstrap = toProp (Debootstrap.built loc system [])
|
||||||
|
|
||||||
teardown = undefined
|
teardown = undefined
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ built target system@(System _ arch) extraparams =
|
||||||
RevertableProperty setup teardown
|
RevertableProperty setup teardown
|
||||||
where
|
where
|
||||||
setup = check (unpopulated target <||> ispartial) setupprop
|
setup = check (unpopulated target <||> ispartial) setupprop
|
||||||
`requires` unrevertable installed
|
`requires` toProp installed
|
||||||
|
|
||||||
teardown = check (not <$> unpopulated target) teardownprop
|
teardown = check (not <$> unpopulated target) teardownprop
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
module Propellor.Property.Systemd (
|
||||||
|
installed,
|
||||||
|
persistentJournal,
|
||||||
|
container,
|
||||||
|
nspawned,
|
||||||
|
) where
|
||||||
|
|
||||||
|
import Propellor
|
||||||
|
import qualified Propellor.Property.Chroot as Chroot
|
||||||
|
import qualified Propellor.Property.Apt as Apt
|
||||||
|
import Utility.SafeCommand
|
||||||
|
|
||||||
|
import Data.List.Utils
|
||||||
|
|
||||||
|
type MachineName = String
|
||||||
|
|
||||||
|
type NspawnParam = CommandParam
|
||||||
|
|
||||||
|
data Container = Container MachineName System [CommandParam] Host
|
||||||
|
|
||||||
|
instance Hostlike Container where
|
||||||
|
(Container n s ps h) & p = Container n s ps (h & p)
|
||||||
|
(Container n s ps h) &^ p = Container n s ps (h &^ p)
|
||||||
|
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"]
|
||||||
|
|
||||||
|
-- | Sets up persistent storage of the journal.
|
||||||
|
persistentJournal :: Property
|
||||||
|
persistentJournal = check (not <$> doesDirectoryExist dir) $
|
||||||
|
combineProperties "persistent systetemd journal"
|
||||||
|
[ cmdProperty "install" ["-d", "-g", "systemd-journal", dir]
|
||||||
|
, cmdProperty "setfacl" ["-R", "-nm", "g:adm:rx,d:g:adm:rx", dir]
|
||||||
|
]
|
||||||
|
`requires` Apt.installed ["acl"]
|
||||||
|
where
|
||||||
|
dir = "/var/log/journal"
|
||||||
|
|
||||||
|
-- | Defines a container with a given machine name, containing the specified
|
||||||
|
-- System. Properties can be added to configure the Container.
|
||||||
|
--
|
||||||
|
-- > container "webserver" (System (Debian Unstable) "amd64") []
|
||||||
|
container :: MachineName -> System -> [NspawnParam] -> Container
|
||||||
|
container name system ps = Container name system ps (Host name [] mempty)
|
||||||
|
|
||||||
|
-- | Runs a container using systemd-nspawn.
|
||||||
|
--
|
||||||
|
-- A systemd unit is set up for the container, so it will automatically
|
||||||
|
-- be started on boot.
|
||||||
|
--
|
||||||
|
-- Systemd is automatically installed inside the container, and will
|
||||||
|
-- communicate with the host's systemd. This allows systemctl to be used to
|
||||||
|
-- examine the status of services running inside the container.
|
||||||
|
--
|
||||||
|
-- When the host system has persistentJournal enabled, journactl can be
|
||||||
|
-- used to examine logs forwarded from the container.
|
||||||
|
--
|
||||||
|
-- Reverting this property stops the container, removes the systemd unit,
|
||||||
|
-- and deletes the chroot and all its contents.
|
||||||
|
nspawned :: Container -> RevertableProperty
|
||||||
|
nspawned c@(Container name system _ h) = RevertableProperty setup teardown
|
||||||
|
where
|
||||||
|
-- TODO after container is running, use nsenter to enter it
|
||||||
|
-- and run propellor to finish provisioning.
|
||||||
|
setup = toProp (nspawnService c)
|
||||||
|
`requires` toProp chrootprovisioned
|
||||||
|
|
||||||
|
teardown = toProp (revert (chrootprovisioned))
|
||||||
|
`requires` toProp (revert (nspawnService c))
|
||||||
|
|
||||||
|
-- When provisioning the chroot, pass a version of the Host
|
||||||
|
-- that only has the Property of systemd being installed.
|
||||||
|
-- This is to avoid starting any daemons in the chroot,
|
||||||
|
-- which would not run in the container's namespace.
|
||||||
|
chrootprovisioned = Chroot.provisioned $
|
||||||
|
Chroot.Chroot (containerDir name) system $
|
||||||
|
h { hostProperties = [installed] }
|
||||||
|
|
||||||
|
nspawnService :: Container -> RevertableProperty
|
||||||
|
nspawnService (Container name _ ps _) = RevertableProperty setup teardown
|
||||||
|
where
|
||||||
|
service = nspawnServiceName name
|
||||||
|
servicefile = "/etc/systemd/system/multi-user.target.wants" </> service
|
||||||
|
|
||||||
|
setup = check (not <$> doesFileExist servicefile) $
|
||||||
|
combineProperties ("container running " ++ service)
|
||||||
|
[ cmdProperty "systemctl" ["enable", service]
|
||||||
|
, cmdProperty "systemctl" ["start", service]
|
||||||
|
]
|
||||||
|
|
||||||
|
-- TODO adjust execStart line to reflect ps
|
||||||
|
|
||||||
|
teardown = undefined
|
||||||
|
|
||||||
|
nspawnServiceName :: MachineName -> String
|
||||||
|
nspawnServiceName name = "systemd-nspawn@" ++ name ++ ".service"
|
||||||
|
|
||||||
|
containerDir :: MachineName -> FilePath
|
||||||
|
containerDir name = "/var/lib/container" ++ replace "/" "_" name
|
Loading…
Reference in New Issue