summaryrefslogtreecommitdiff
path: root/Propellor/Property/File.hs
diff options
context:
space:
mode:
authorJoey Hess <joey@kitenet.net>2014-04-14 02:24:55 -0400
committerJoey Hess <joey@kitenet.net>2014-04-14 02:24:55 -0400
commit18d33cd39100981c5c6e5f3c1c0f88d336287f29 (patch)
tree7863ddbdf7b3255d42b7354c0d8b21184f452241 /Propellor/Property/File.hs
parent9e9d0f1d410f806b546abed6055b25ac81f7042e (diff)
parent3a45bfa1a2ae855cac0653e92f897c3d151f038d (diff)
Merge branch 'joeyconfig'
Diffstat (limited to 'Propellor/Property/File.hs')
-rw-r--r--Propellor/Property/File.hs48
1 files changed, 36 insertions, 12 deletions
diff --git a/Propellor/Property/File.hs b/Propellor/Property/File.hs
index 10dee75e..8f23dab7 100644
--- a/Propellor/Property/File.hs
+++ b/Propellor/Property/File.hs
@@ -1,8 +1,10 @@
module Propellor.Property.File where
import Propellor
+import Utility.FileMode
import System.Posix.Files
+import System.PosixCompat.Types
type Line = String
@@ -12,19 +14,31 @@ f `hasContent` newcontent = fileProperty ("replace " ++ f)
(\_oldcontent -> newcontent) f
-- | Ensures a file has contents that comes from PrivData.
--- Note: Does not do anything with the permissions of the file to prevent
--- it from being seen.
+--
+-- The file's permissions are preserved if the file already existed.
+-- Otherwise, they're set to 600.
hasPrivContent :: FilePath -> Property
-hasPrivContent f = Property ("privcontent " ++ f) $
- withPrivData (PrivFile f) (\v -> ensureProperty $ f `hasContent` lines v)
+hasPrivContent f = Property desc $ withPrivData (PrivFile f) $ \privcontent ->
+ ensureProperty $ fileProperty' writeFileProtected desc
+ (\_oldcontent -> lines privcontent) f
+ where
+ desc = "privcontent " ++ f
+
+-- | Leaves the file world-readable.
+hasPrivContentExposed :: FilePath -> Property
+hasPrivContentExposed f = hasPrivContent f `onChange`
+ mode f (combineModes (ownerWriteMode:readModes))
-- | Ensures that a line is present in a file, adding it to the end if not.
containsLine :: FilePath -> Line -> Property
-f `containsLine` l = fileProperty (f ++ " contains:" ++ l) go f
+f `containsLine` l = f `containsLines` [l]
+
+containsLines :: FilePath -> [Line] -> Property
+f `containsLines` l = fileProperty (f ++ " contains:" ++ show l) go f
where
go ls
- | l `elem` ls = ls
- | otherwise = ls++[l]
+ | all (`elem` ls) l = ls
+ | otherwise = ls++l
-- | Ensures that a line is not present in a file.
-- Note that the file is ensured to exist, so if it doesn't, an empty
@@ -38,7 +52,9 @@ notPresent f = check (doesFileExist f) $ Property (f ++ " not present") $
makeChange $ nukeFile f
fileProperty :: Desc -> ([Line] -> [Line]) -> FilePath -> Property
-fileProperty desc a f = Property desc $ go =<< liftIO (doesFileExist f)
+fileProperty = fileProperty' writeFile
+fileProperty' :: (FilePath -> String -> IO ()) -> Desc -> ([Line] -> [Line]) -> FilePath -> Property
+fileProperty' writer desc a f = Property desc $ go =<< liftIO (doesFileExist f)
where
go True = do
ls <- liftIO $ lines <$> readFile f
@@ -46,13 +62,15 @@ fileProperty desc a f = Property desc $ go =<< liftIO (doesFileExist f)
if ls' == ls
then noChange
else makeChange $ viaTmp updatefile f (unlines ls')
- go False = makeChange $ writeFile f (unlines $ a [])
+ go False = makeChange $ writer f (unlines $ a [])
-- viaTmp makes the temp file mode 600.
- -- Replicate the original file mode before moving it into place.
+ -- Replicate the original file's owner and mode.
updatefile f' content = do
- writeFile f' content
- getFileStatus f >>= setFileMode f' . fileMode
+ writer f' content
+ s <- getFileStatus f
+ setFileMode f' (fileMode s)
+ setOwnerAndGroup f' (fileOwner s) (fileGroup s)
-- | Ensures a directory exists.
dirExists :: FilePath -> Property
@@ -68,3 +86,9 @@ ownerGroup f owner group = Property (f ++ " owner " ++ og) $ do
else noChange
where
og = owner ++ ":" ++ group
+
+-- | Ensures that a file/dir has the specfied mode.
+mode :: FilePath -> FileMode -> Property
+mode f v = Property (f ++ " mode " ++ show v) $ do
+ liftIO $ modifyFileMode f (\_old -> v)
+ noChange