summaryrefslogtreecommitdiff
path: root/src/Propellor/Property/Systemd.hs
diff options
context:
space:
mode:
authorJoey Hess2014-11-21 12:17:03 -0400
committerJoey Hess2014-11-21 12:17:03 -0400
commit6a5a1bc76132128e4bd2312dfadc98e83b0baf40 (patch)
tree712f9edaf6833bc3c9df41405ce9fe9810c754ee /src/Propellor/Property/Systemd.hs
parent1af298dc10fddc3deb32fa8af2638d00dfbc2665 (diff)
systemd container may be mostly done (untested)
Diffstat (limited to 'src/Propellor/Property/Systemd.hs')
-rw-r--r--src/Propellor/Property/Systemd.hs60
1 files changed, 51 insertions, 9 deletions
diff --git a/src/Propellor/Property/Systemd.hs b/src/Propellor/Property/Systemd.hs
index be08a847..63a150f6 100644
--- a/src/Propellor/Property/Systemd.hs
+++ b/src/Propellor/Property/Systemd.hs
@@ -8,7 +8,9 @@ module Propellor.Property.Systemd (
import Propellor
import qualified Propellor.Property.Chroot as Chroot
import qualified Propellor.Property.Apt as Apt
+import qualified Propellor.Property.File as File
import Utility.SafeCommand
+import Utility.FileMode
import Data.List.Utils
@@ -29,7 +31,7 @@ instance Hostlike Container where
installed :: Property
installed = Apt.installed ["systemd", "dbus"]
--- | Sets up persistent storage of the journal.
+-- | Enables persistent storage of the journal.
persistentJournal :: Property
persistentJournal = check (not <$> doesDirectoryExist dir) $
combineProperties "persistent systetemd journal"
@@ -64,21 +66,29 @@ container name system ps = Container name system ps (Host name [] mempty)
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)
+ setup = containerprovisioned
+ `requires` toProp (nspawnService c)
`requires` toProp chrootprovisioned
+ `requires` toProp (enterScript c)
teardown = toProp (revert (chrootprovisioned))
`requires` toProp (revert (nspawnService c))
+ `requires` toProp (revert (enterScript 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] }
+ mkChroot $ h { hostProperties = [installed] }
+
+ -- Use nsenter to enter container and and run propellor to
+ -- finish provisioning.
+ containerprovisioned = Chroot.propellChroot
+ (mkChroot h)
+ (enterContainerProcess c)
+
+ mkChroot = Chroot.Chroot (containerDir name) system
nspawnService :: Container -> RevertableProperty
nspawnService (Container name _ ps _) = RevertableProperty setup teardown
@@ -91,13 +101,45 @@ nspawnService (Container name _ ps _) = RevertableProperty setup teardown
[ cmdProperty "systemctl" ["enable", service]
, cmdProperty "systemctl" ["start", service]
]
-
- -- TODO adjust execStart line to reflect ps
+ -- TODO ^ adjust execStart line to reflect ps
teardown = undefined
+-- | Installs a "enter-machinename" script that root can use to run a
+-- command inside the container.
+--
+-- This uses nsenter to enter the container, by looking up the pid of the
+-- container's init process and using its namespace.
+enterScript :: Container -> RevertableProperty
+enterScript c@(Container name _ _ _) = RevertableProperty setup teardown
+ where
+ setup = combineProperties ("generated " ++ enterScriptFile c)
+ [ scriptfile `File.hasContent`
+ [ "#!/bin/sh"
+ , "# Generated by propellor"
+ , "pid=\"$(machinectl show " ++ shellEscape name ++ " -p Leader | cut -d= -f2)\" || true"
+ , "if [ -n \"$pid\" ]; then"
+ , "\tnsenter -p -u -n -i -m -t \"$pid\""
+ , "else"
+ , "\texit 1"
+ , "fi"
+ ]
+ , scriptfile `File.mode` combineModes (readModes ++ executeModes)
+ ]
+ teardown = File.notPresent scriptfile
+ scriptfile = enterScriptFile c
+
+enterScriptFile :: Container -> FilePath
+enterScriptFile (Container name _ _ _ ) = "enter-" ++ mungename name
+
+enterContainerProcess :: Container -> [String] -> CreateProcess
+enterContainerProcess = proc . enterScriptFile
+
nspawnServiceName :: MachineName -> String
nspawnServiceName name = "systemd-nspawn@" ++ name ++ ".service"
containerDir :: MachineName -> FilePath
-containerDir name = "/var/lib/container" ++ replace "/" "_" name
+containerDir name = "/var/lib/container" ++ mungename name
+
+mungename :: MachineName -> String
+mungename = replace "/" "_"