diff options
| author | Joey Hess <joey@kitenet.net> | 2014-11-19 01:28:38 -0400 |
|---|---|---|
| committer | Joey Hess <joey@kitenet.net> | 2014-11-19 01:28:38 -0400 |
| commit | 4dddbb725d9694b575bb665fa2369278b383f661 (patch) | |
| tree | f7b4dd30691beb357f6fe52656e2684019883895 /src/Propellor/Engine.hs | |
| parent | 818fcdfb344f170f887e7480e04150e224b2f61e (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.hs | 15 |
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!" |
