From be02ef96aa89a6af554a622f266d700ac0c98fdf Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Fri, 11 Apr 2014 01:19:05 -0400 Subject: propellor (0.3.0) unstable; urgency=medium * ipv6to4: Ensure interface is brought up automatically on boot. * Enabling unattended upgrades now ensures that cron is installed and running to perform them. * Properties can be scheduled to only be checked after a given time period. * Fix bootstrapping of dependencies. * Fix compilation on Debian stable. * Include security updates in sources.list for stable and testing. * Use ssh connection caching, especially when bootstrapping. * Properties now run in a Propellor monad, which provides access to attributes of the host. # imported from the archive --- Propellor/Property/File.hs | 70 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 Propellor/Property/File.hs (limited to 'Propellor/Property/File.hs') diff --git a/Propellor/Property/File.hs b/Propellor/Property/File.hs new file mode 100644 index 00000000..10dee75e --- /dev/null +++ b/Propellor/Property/File.hs @@ -0,0 +1,70 @@ +module Propellor.Property.File where + +import Propellor + +import System.Posix.Files + +type Line = String + +-- | Replaces all the content of a file. +hasContent :: FilePath -> [Line] -> Property +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. +hasPrivContent :: FilePath -> Property +hasPrivContent f = Property ("privcontent " ++ f) $ + withPrivData (PrivFile f) (\v -> ensureProperty $ f `hasContent` lines v) + +-- | 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 + where + go ls + | l `elem` ls = 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 +-- file will be written. +lacksLine :: FilePath -> Line -> Property +f `lacksLine` l = fileProperty (f ++ " remove: " ++ l) (filter (/= l)) f + +-- | Removes a file. Does not remove symlinks or non-plain-files. +notPresent :: FilePath -> Property +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) + where + go True = do + ls <- liftIO $ lines <$> readFile f + let ls' = a ls + if ls' == ls + then noChange + else makeChange $ viaTmp updatefile f (unlines ls') + go False = makeChange $ writeFile f (unlines $ a []) + + -- viaTmp makes the temp file mode 600. + -- Replicate the original file mode before moving it into place. + updatefile f' content = do + writeFile f' content + getFileStatus f >>= setFileMode f' . fileMode + +-- | Ensures a directory exists. +dirExists :: FilePath -> Property +dirExists d = check (not <$> doesDirectoryExist d) $ Property (d ++ " exists") $ + makeChange $ createDirectoryIfMissing True d + +-- | Ensures that a file/dir has the specified owner and group. +ownerGroup :: FilePath -> UserName -> GroupName -> Property +ownerGroup f owner group = Property (f ++ " owner " ++ og) $ do + r <- ensureProperty $ cmdProperty "chown" [og, f] + if r == FailedChange + then return r + else noChange + where + og = owner ++ ":" ++ group -- cgit v1.3-2-g0d8e