summaryrefslogtreecommitdiff
path: root/src/Propellor/Engine.hs
diff options
context:
space:
mode:
authorJoey Hess2014-11-19 01:28:38 -0400
committerJoey Hess2014-11-19 01:28:38 -0400
commit4dddbb725d9694b575bb665fa2369278b383f661 (patch)
treef7b4dd30691beb357f6fe52656e2684019883895 /src/Propellor/Engine.hs
parent818fcdfb344f170f887e7480e04150e224b2f61e (diff)
prevent multiple concurrent provisioning inside docker container
Lock a lock file while provisioning inside, otherwise propellor could be running to init the container when the system has just booted, or the container was just started from being stopped, and at the same time, propellor run outside the container chains into it to provision. Previously, simplesh prevented this in a different way.
Diffstat (limited to 'src/Propellor/Engine.hs')
-rw-r--r--src/Propellor/Engine.hs15
1 files changed, 15 insertions, 0 deletions
diff --git a/src/Propellor/Engine.hs b/src/Propellor/Engine.hs
index a3fc0f30..3fa9ffc0 100644
--- a/src/Propellor/Engine.hs
+++ b/src/Propellor/Engine.hs
@@ -8,11 +8,15 @@ import Data.Monoid
import Control.Applicative
import System.Console.ANSI
import "mtl" Control.Monad.Reader
+import Control.Exception (bracket)
+import System.PosixCompat
+import System.Posix.IO
import Propellor.Types
import Propellor.Message
import Propellor.Exception
import Propellor.Info
+import Utility.Exception
runPropellor :: Host -> Propellor a -> IO a
runPropellor host a = runReaderT (runWithHost a) host
@@ -47,3 +51,14 @@ fromHost l hn getter = case findHost l hn of
Nothing -> return Nothing
Just h -> liftIO $ Just <$>
runReaderT (runWithHost getter) h
+
+onlyProcess :: FilePath -> IO a -> IO a
+onlyProcess lockfile a = bracket lock unlock (const a)
+ where
+ lock = do
+ l <- createFile lockfile stdFileMode
+ setLock l (WriteLock, AbsoluteSeek, 0, 0)
+ `catchIO` const alreadyrunning
+ return l
+ unlock = closeFd
+ alreadyrunning = error "Propellor is already running on this host!"