summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Propellor/CmdLine.hs16
-rw-r--r--debian/changelog1
2 files changed, 16 insertions, 1 deletions
diff --git a/Propellor/CmdLine.hs b/Propellor/CmdLine.hs
index d10211f0..3974f1d5 100644
--- a/Propellor/CmdLine.hs
+++ b/Propellor/CmdLine.hs
@@ -8,6 +8,8 @@ import System.Log.Formatter
import System.Log.Handler (setFormatter, LogHandler)
import System.Log.Handler.Simple
import System.PosixCompat
+import Control.Exception (bracket)
+import System.Posix.IO
import Propellor
import qualified Propellor.Property.Docker as Docker
@@ -71,7 +73,7 @@ defaultMain getprops = do
go True cmdline = updateFirst cmdline $ go False cmdline
go False (Spin host) = withprops host $ const $ spin host
go False (Run host) = ifM ((==) 0 <$> getRealUserID)
- ( withprops host ensureProperties
+ ( onlyProcess $ withprops host ensureProperties
, go True (Spin host)
)
go False (Boot host) = withprops host $ boot
@@ -79,6 +81,18 @@ defaultMain getprops = do
withprops host a = maybe (unknownhost host) a $
headMaybe $ catMaybes $ map (\get -> get host) getprops
+onlyProcess :: IO a -> IO a
+onlyProcess a = bracket lock unlock (const a)
+ where
+ lock = do
+ l <- openFd lockfile ReadWrite Nothing defaultFileFlags
+ setLock l (WriteLock, AbsoluteSeek, 0, 0)
+ `catchIO` (const alreadyrunning)
+ return l
+ unlock = closeFd
+ alreadyrunning = error "Propellor is already running on this host!"
+ lockfile = localdir </> ".lock"
+
unknownhost :: HostName -> IO a
unknownhost h = errorMessage $ unlines
[ "Unknown host: " ++ h
diff --git a/debian/changelog b/debian/changelog
index 0fdd42b2..a02c27d7 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -2,6 +2,7 @@ propellor (0.2.3) UNRELEASED; urgency=medium
* docker: Fix laziness bug that caused running containers to be
unnecessarily stopped and committed.
+ * Add locking so only one propellor can run at a time on a host.
-- Joey Hess <joeyh@debian.org> Fri, 04 Apr 2014 15:58:03 -0400