From 98f0daa2a20cf5e65735bba1acf245a5334c5841 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Wed, 14 Oct 2015 12:42:44 -0400 Subject: changelog --- debian/changelog | 1 + 1 file changed, 1 insertion(+) (limited to 'debian') diff --git a/debian/changelog b/debian/changelog index 55076ae8..dda8197b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -9,6 +9,7 @@ propellor (2.9.0) UNRELEASED; urgency=medium (API change) * Some renaming of instance methods, and moving of functions to more appropriate modules. (API change) + * Added File.isSymlinkedTo. Thanks, Per Olofsson. -- Joey Hess Thu, 08 Oct 2015 11:09:01 -0400 -- cgit v1.2.3 From 037d287a3a383471edbcd4cf8f490fc4027b67b7 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Wed, 14 Oct 2015 13:10:07 -0400 Subject: fileProperty, and properties derived from it now write the new file content via origfile.propellor-new~, instead of to a randomly named temp file. This allows them to clean up any temp file that may have been left by an interrupted run of propellor. Also converted the new isSymlinkedTo property to use the same implementation, with some simplifications. --- debian/changelog | 4 ++++ src/Propellor/Property/File.hs | 43 ++++++++++++++++++++++++--------------- src/Propellor/Property/Systemd.hs | 5 +++-- 3 files changed, 34 insertions(+), 18 deletions(-) (limited to 'debian') diff --git a/debian/changelog b/debian/changelog index dda8197b..292ec0be 100644 --- a/debian/changelog +++ b/debian/changelog @@ -10,6 +10,10 @@ propellor (2.9.0) UNRELEASED; urgency=medium * Some renaming of instance methods, and moving of functions to more appropriate modules. (API change) * Added File.isSymlinkedTo. Thanks, Per Olofsson. + * fileProperty, and properties derived from it now write the new + file content via origfile.propellor-new~, instead of to a randomly named + temp file. This allows them to clean up any temp file that may have + been left by an interrupted run of propellor. -- Joey Hess Thu, 08 Oct 2015 11:09:01 -0400 diff --git a/src/Propellor/Property/File.hs b/src/Propellor/Property/File.hs index f774272c..12a3e80a 100644 --- a/src/Propellor/Property/File.hs +++ b/src/Propellor/Property/File.hs @@ -82,12 +82,11 @@ fileProperty' writer desc a f = property desc $ go =<< liftIO (doesFileExist f) let new = unlines (a (lines old)) if old == new then noChange - else makeChange $ viaTmp updatefile f new + else makeChange $ updatefile new `viaStableTmp` f go False = makeChange $ writer f (unlines $ a []) - -- viaTmp makes the temp file mode 600. -- Replicate the original file's owner and mode. - updatefile f' content = do + updatefile content f' = do writer f' content s <- getFileStatus f setFileMode f' (fileMode s) @@ -119,19 +118,7 @@ link `isSymlinkedTo` target = property desc $ if target == target' then noChange else makeChange updateLink - updateLink = bracket_ setup cleanup $ rename link' link - link' = link ++ ".propellor-new~" - setup = do - whenM hasOldLink' removeOldLink' - createSymbolicLink target link' - cleanup = tryIO $ removeLink link' - hasOldLink' = (tryIO $ getSymbolicLinkStatus link') >>= \result -> - case result of - Right stat -> return $ isSymbolicLink stat - Left _ -> return False - removeOldLink' = do - warningMessage $ "removing cruft from previous run: " ++ link' - removeLink link' + updateLink = createSymbolicLink target `viaStableTmp` link -- | Ensures that a file/dir has the specified owner and group. ownerGroup :: FilePath -> User -> Group -> Property NoInfo @@ -148,3 +135,27 @@ mode :: FilePath -> FileMode -> Property NoInfo mode f v = property (f ++ " mode " ++ show v) $ do liftIO $ modifyFileMode f (const v) noChange + +-- | A temp file to use when writing new content for a file. +-- +-- This is a stable name so it can be removed idempotently. +-- +-- It ends with "~" so that programs that read many config files from a +-- directory will treat it as an editor backup file, and not read it. +stableTmpFor :: FilePath -> FilePath +stableTmpFor f = f ++ ".propellor-new~" + +-- | Creates/updates a file atomically, running the action to create the +-- stable tmp file, and then renaming it into place. +viaStableTmp :: (MonadMask m, MonadIO m) => (FilePath -> m ()) -> FilePath -> m () +viaStableTmp a f = bracketIO setup cleanup go + where + setup = do + createDirectoryIfMissing True (takeDirectory f) + let tmpfile = stableTmpFor f + nukeFile tmpfile + return tmpfile + cleanup tmpfile = tryIO $ removeFile tmpfile + go tmpfile = do + a tmpfile + liftIO $ rename tmpfile f diff --git a/src/Propellor/Property/Systemd.hs b/src/Propellor/Property/Systemd.hs index 8194fc85..a93c48bc 100644 --- a/src/Propellor/Property/Systemd.hs +++ b/src/Propellor/Property/Systemd.hs @@ -254,8 +254,9 @@ nspawnService (Container name _ _) cfg = setup teardown <$> servicefilecontent <*> catchDefaultIO "" (readFile servicefile) - writeservicefile = property servicefile $ makeChange $ - viaTmp writeFile servicefile =<< servicefilecontent + writeservicefile = property servicefile $ makeChange $ do + c <- servicefilecontent + File.viaStableTmp (\t -> writeFile t c) servicefile setupservicefile = check (not <$> goodservicefile) $ -- if it's running, it has the wrong configuration, -- cgit v1.2.3