summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--propellor.cabal3
-rw-r--r--src/Propellor/Property/ConfFile.hs72
-rw-r--r--src/Propellor/Property/LightDM.hs4
3 files changed, 76 insertions, 3 deletions
diff --git a/propellor.cabal b/propellor.cabal
index f00e5594..640d0293 100644
--- a/propellor.cabal
+++ b/propellor.cabal
@@ -73,7 +73,8 @@ Library
Propellor.Property.Apt
Propellor.Property.Cmd
Propellor.Property.Hostname
- Propellor.Property.Chroot
+ Propellor.Property.Chroot
+ Propellor.Property.ConfFile
Propellor.Property.Cron
Propellor.Property.Debootstrap
Propellor.Property.Dns
diff --git a/src/Propellor/Property/ConfFile.hs b/src/Propellor/Property/ConfFile.hs
new file mode 100644
index 00000000..72996c74
--- /dev/null
+++ b/src/Propellor/Property/ConfFile.hs
@@ -0,0 +1,72 @@
+module Propellor.Property.ConfFile (containsIniPair) where
+
+import Propellor
+import Propellor.Property.File
+
+import Data.List (isPrefixOf, foldl')
+
+type SectionStart = Line -> Bool -- ^ find the line that is the start of the
+ -- wanted section (eg, == "<Foo>")
+type SectionPast = Line -> Bool -- ^ find a line that indicates we are past
+ -- the section (eg, a new section header)
+type AdjustSection = [Line] -> [Line] -- ^ run on all lines in the section,
+ -- including the SectionStart line and any
+ -- SectionEnd line; can add/delete/modify
+ -- lines, or even delete entire section
+type InsertSection = [Line] -> [Line] -- ^ if SectionStart does not find the
+ -- section in the file, this is used to
+ -- insert the section somewhere within it
+
+adjustSection
+ :: String
+ -> SectionStart
+ -> SectionPast
+ -> AdjustSection
+ -> InsertSection
+ -> FilePath
+ -> Property NoInfo
+adjustSection desc start past adjust insert f =
+ fileProperty desc go f
+ where
+ go ls = let (pre, wanted, post) = foldl' find ([], [], []) ls
+ in if null wanted
+ then insert ls
+ else pre ++ (adjust wanted) ++ post
+ find (pre, wanted, post) l
+ | null wanted && null post && (not . start) l =
+ (pre ++ [l], wanted, post)
+ | (start l && null wanted && null post)
+ || ((not . null) wanted && null post && (not . past) l) =
+ (pre, wanted ++ [l], post)
+ | otherwise = (pre, wanted, post ++ [l])
+
+iniHeader :: String -> String
+iniHeader header = '[' : header ++ "]"
+
+adjustIniSection
+ :: String
+ -> String
+ -> AdjustSection
+ -> InsertSection
+ -> FilePath
+ -> Property NoInfo
+adjustIniSection desc header =
+ adjustSection
+ desc
+ (== iniHeader header)
+ ("[" `isPrefixOf`)
+
+containsIniPair :: FilePath -> (String, String, String) -> Property NoInfo
+containsIniPair f (header, key, value) =
+ adjustIniSection
+ (f ++ " section [" ++ header ++ "] contains " ++ key ++ "=" ++ value)
+ header
+ go
+ (++ [confheader, confline])
+ f
+ where
+ confheader = iniHeader header
+ confline = key ++ "=" ++ value
+ go [] = [confline]
+ go (l:ls) = if isKeyVal l then confline : ls else l : (go ls)
+ isKeyVal x = (filter (/= ' ') . takeWhile (/= '=')) x `elem` [key, '#':key]
diff --git a/src/Propellor/Property/LightDM.hs b/src/Propellor/Property/LightDM.hs
index b3756f6e..09f7165d 100644
--- a/src/Propellor/Property/LightDM.hs
+++ b/src/Propellor/Property/LightDM.hs
@@ -3,10 +3,10 @@
module Propellor.Property.LightDM where
import Propellor
-import qualified Propellor.Property.File as File
+import qualified Propellor.Property.ConfFile as ConfFile
-- | Configures LightDM to skip the login screen and autologin as a user.
autoLogin :: User -> Property NoInfo
-autoLogin (User u) = "/etc/lightdm/lightdm.conf" `File.containsConfPair`
+autoLogin (User u) = "/etc/lightdm/lightdm.conf" `ConfFile.containsIniPair`
("SeatDefaults", "autologin-user", u)
`describe` "lightdm autologin"