From d26de1e5e07d88f188c52f73b9f1b4d0a405cee0 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Wed, 30 Dec 2015 23:16:02 -0400 Subject: shell script copied into bin dir by their provisioning script --- src/Propellor/Property/HostingProvider/CloudAtCost.hs | 1 + 1 file changed, 1 insertion(+) (limited to 'src/Propellor/Property') diff --git a/src/Propellor/Property/HostingProvider/CloudAtCost.hs b/src/Propellor/Property/HostingProvider/CloudAtCost.hs index ef7dd743..bfe3ae17 100644 --- a/src/Propellor/Property/HostingProvider/CloudAtCost.hs +++ b/src/Propellor/Property/HostingProvider/CloudAtCost.hs @@ -17,6 +17,7 @@ decruft = propertyList "cloudatcost cleanup" [ File.notPresent "/etc/rc.local" , File.notPresent "/etc/init.d/S97-setup.sh" , File.notPresent "/zang-debian.sh" + , File.notPresent "/bin/npasswd" , User.nuked (User "user") User.YesReallyDeleteHome ] ] -- cgit v1.2.3 From 39e1237146c046fd2f02fcc492a73079ee77a96f Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Thu, 31 Dec 2015 12:01:44 -0400 Subject: Postfix: Add service property to enable/disable services in master.cf. --- debian/changelog | 1 + src/Propellor/Property/Postfix.hs | 129 +++++++++++++++++++++++ src/Propellor/Property/SiteSpecific/JoeySites.hs | 6 ++ 3 files changed, 136 insertions(+) (limited to 'src/Propellor/Property') diff --git a/debian/changelog b/debian/changelog index fdf37fdb..1e3e74f0 100644 --- a/debian/changelog +++ b/debian/changelog @@ -5,6 +5,7 @@ propellor (2.15.2) UNRELEASED; urgency=medium Thanks, FĂ©lix Sipma. * Bootstrap apt-get installs run with deconf noninteractive frontend. * spin --via: Avoid committing on relay host. + * Postfix: Add service property to enable/disable services in master.cf. -- Joey Hess Wed, 30 Dec 2015 15:01:19 -0400 diff --git a/src/Propellor/Property/Postfix.hs b/src/Propellor/Property/Postfix.hs index 1c8684c7..c5abde6b 100644 --- a/src/Propellor/Property/Postfix.hs +++ b/src/Propellor/Property/Postfix.hs @@ -129,6 +129,135 @@ dedupCf ls = Just n | n > 1 -> dedup c (M.insert k (n - 1) kc) rest _ -> dedup (fmt k v:c) kc rest +-- | The master config file for postfix. +masterCfFile :: FilePath +masterCfFile = "/etc/postfix/master.cf" + +-- | A service that can be present in the master config file. +data Service = Service + { serviceType :: ServiceType + , serviceCommand :: String + , serviceOpts :: ServiceOpts + } + deriving (Show) + +data ServiceType + = InetService (Maybe HostName, ServicePort) + | UnixService FilePath + | FifoService FilePath + | PassService FilePath + deriving (Show) + +-- Can be a port number or service name such as "smtp". +type ServicePort = String + +-- | Options for a service. +data ServiceOpts = ServiceOpts + { servicePrivate :: Maybe Bool + , serviceUnprivileged :: Maybe Bool + , serviceChroot :: Maybe Bool + , serviceWakeupTime :: Maybe Int + , serviceProcessLimit :: Maybe Int + } + deriving (Show) + +defServiceOpts :: ServiceOpts +defServiceOpts = ServiceOpts + { servicePrivate = Nothing + , serviceUnprivileged = Nothing + , serviceChroot = Nothing + , serviceWakeupTime = Nothing + , serviceProcessLimit = Nothing + } + +formatServiceLine :: Service -> File.Line +formatServiceLine s = unwords $ map pad + [ (10, case serviceType s of + InetService (Just h, p) -> h ++ ":" ++ p + InetService (Nothing, p) -> p + UnixService f -> f + FifoService f -> f + PassService f -> f) + , (6, case serviceType s of + InetService _ -> "inet" + UnixService _ -> "unix" + FifoService _ -> "fifo" + PassService _ -> "pass") + , (8, v bool servicePrivate) + , (8, v bool serviceUnprivileged) + , (8, v bool serviceChroot) + , (8, v show serviceWakeupTime) + , (8, v show serviceProcessLimit) + , (0, serviceCommand s) + ] + where + v f sel = maybe "-" f (sel (serviceOpts s)) + bool True = "y" + bool False = "n" + pad (n, s) = s ++ replicate (n - 1 - length s) ' ' + +-- | Note that this does not handle multi-line service entries, +-- in which subsequent lines are indented. `serviceLine` does not generate +-- such entries. +parseServiceLine :: File.Line -> Maybe Service +parseServiceLine ('#':_) = Nothing +parseServiceLine (' ':_) = Nothing -- continuation of multiline entry +parseServiceLine l = Service + <$> parsetype + <*> parsecommand + <*> parseopts + where + parsetype = do + t <- getword 2 + case t of + "inet" -> do + v <- getword 1 + let (h,p) = separate (== ':') v + if null p + then Nothing + else Just $ InetService + (if null h then Nothing else Just h, p) + "unix" -> UnixService <$> getword 1 + "fifo" -> FifoService <$> getword 1 + "pass" -> PassService <$> getword 1 + _ -> Nothing + + parsecommand = case unwords (drop 7 ws) of + "" -> Nothing + s -> Just s + + parseopts = ServiceOpts + <$> (bool =<< getword 3) + <*> (bool =<< getword 4) + <*> (bool =<< getword 5) + <*> (int =<< getword 6) + <*> (int =<< getword 7) + + bool "-" = Just Nothing + bool "y" = Just (Just True) + bool "n" = Just (Just False) + bool _ = Nothing + + int "-" = Just Nothing + int n = maybe Nothing (Just . Just) (readish n) + + getword n + | nws >= n = Just (ws !! (n -1)) + | otherwise = Nothing + ws = words l + nws = length ws + +-- | Enables a `Service` in postfix's `masterCfFile`. +service :: Service -> RevertableProperty NoInfo +service s = (enable disable) + `describe` ("enabled postfix service " ++ show (serviceType s)) + where + enable = masterCfFile `File.containsLine` l + `onChange` reloaded + disable = masterCfFile `File.lacksLine` l + `onChange` reloaded + l = formatServiceLine s + -- | Installs saslauthd and configures it for postfix, authenticating -- against PAM. -- diff --git a/src/Propellor/Property/SiteSpecific/JoeySites.hs b/src/Propellor/Property/SiteSpecific/JoeySites.hs index 732714db..d7bd9068 100644 --- a/src/Propellor/Property/SiteSpecific/JoeySites.hs +++ b/src/Propellor/Property/SiteSpecific/JoeySites.hs @@ -694,11 +694,17 @@ kiteMailServer = propertyList "kitenet.net mail server" $ props `describe` "pine configured to use local imap server" & Apt.serviceInstalledRunning "mailman" + + & Postfix.service ssmtp where ctx = Context "kitenet.net" pinescript = "/usr/local/bin/pine" dovecotusers = "/etc/dovecot/users" + ssmtp = Postfix.Service + (Postfix.InetService (Nothing, "ssmtp")) + "smtpd" Postfix.defServiceOpts + -- Configures postfix to relay outgoing mail to kitenet.net, with -- verification via tls cert. postfixClientRelay :: Context -> Property HasInfo -- cgit v1.2.3 From 9c204a40ac68862dc50fede4419cda7e75906a04 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Thu, 31 Dec 2015 12:03:05 -0400 Subject: propellor spin --- src/Propellor/Property/Postfix.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/Propellor/Property') diff --git a/src/Propellor/Property/Postfix.hs b/src/Propellor/Property/Postfix.hs index c5abde6b..b8599376 100644 --- a/src/Propellor/Property/Postfix.hs +++ b/src/Propellor/Property/Postfix.hs @@ -194,7 +194,7 @@ formatServiceLine s = unwords $ map pad v f sel = maybe "-" f (sel (serviceOpts s)) bool True = "y" bool False = "n" - pad (n, s) = s ++ replicate (n - 1 - length s) ' ' + pad (n, t) = t ++ replicate (n - 1 - length t) ' ' -- | Note that this does not handle multi-line service entries, -- in which subsequent lines are indented. `serviceLine` does not generate -- cgit v1.2.3 From b016222a5bac06d67d8239db778541233338a2ed Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Thu, 31 Dec 2015 12:18:52 -0400 Subject: inet services cannot be private; adjust type --- src/Propellor/Property/Postfix.hs | 52 +++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 24 deletions(-) (limited to 'src/Propellor/Property') diff --git a/src/Propellor/Property/Postfix.hs b/src/Propellor/Property/Postfix.hs index b8599376..b6a1d170 100644 --- a/src/Propellor/Property/Postfix.hs +++ b/src/Propellor/Property/Postfix.hs @@ -142,19 +142,20 @@ data Service = Service deriving (Show) data ServiceType - = InetService (Maybe HostName, ServicePort) - | UnixService FilePath - | FifoService FilePath - | PassService FilePath + = InetService (Maybe HostName) ServicePort + | UnixService FilePath PrivateService + | FifoService FilePath PrivateService + | PassService FilePath PrivateService deriving (Show) -- Can be a port number or service name such as "smtp". type ServicePort = String +type PrivateService = Bool + -- | Options for a service. data ServiceOpts = ServiceOpts - { servicePrivate :: Maybe Bool - , serviceUnprivileged :: Maybe Bool + { serviceUnprivileged :: Maybe Bool , serviceChroot :: Maybe Bool , serviceWakeupTime :: Maybe Int , serviceProcessLimit :: Maybe Int @@ -163,8 +164,7 @@ data ServiceOpts = ServiceOpts defServiceOpts :: ServiceOpts defServiceOpts = ServiceOpts - { servicePrivate = Nothing - , serviceUnprivileged = Nothing + { serviceUnprivileged = Nothing , serviceChroot = Nothing , serviceWakeupTime = Nothing , serviceProcessLimit = Nothing @@ -173,17 +173,21 @@ defServiceOpts = ServiceOpts formatServiceLine :: Service -> File.Line formatServiceLine s = unwords $ map pad [ (10, case serviceType s of - InetService (Just h, p) -> h ++ ":" ++ p - InetService (Nothing, p) -> p - UnixService f -> f - FifoService f -> f - PassService f -> f) + InetService (Just h) p -> h ++ ":" ++ p + InetService Nothing p -> p + UnixService f _ -> f + FifoService f _ -> f + PassService f _ -> f) , (6, case serviceType s of - InetService _ -> "inet" - UnixService _ -> "unix" - FifoService _ -> "fifo" - PassService _ -> "pass") - , (8, v bool servicePrivate) + InetService _ _ -> "inet" + UnixService _ _ -> "unix" + FifoService _ _ -> "fifo" + PassService _ _ -> "pass") + , (8, case serviceType s of + InetService _ _ -> bool False + UnixService _ b -> bool b + FifoService _ b -> bool b + PassService _ b -> bool b) , (8, v bool serviceUnprivileged) , (8, v bool serviceChroot) , (8, v show serviceWakeupTime) @@ -216,19 +220,19 @@ parseServiceLine l = Service if null p then Nothing else Just $ InetService - (if null h then Nothing else Just h, p) - "unix" -> UnixService <$> getword 1 - "fifo" -> FifoService <$> getword 1 - "pass" -> PassService <$> getword 1 + (if null h then Nothing else Just h) p + "unix" -> UnixService <$> getword 1 <*> parseprivate + "fifo" -> FifoService <$> getword 1 <*> parseprivate + "pass" -> PassService <$> getword 1 <*> parseprivate _ -> Nothing + parseprivate = join . bool =<< getword 3 parsecommand = case unwords (drop 7 ws) of "" -> Nothing s -> Just s parseopts = ServiceOpts - <$> (bool =<< getword 3) - <*> (bool =<< getword 4) + <$> (bool =<< getword 4) <*> (bool =<< getword 5) <*> (int =<< getword 6) <*> (int =<< getword 7) -- cgit v1.2.3 From 5e73aa446e46b61ebea77af5a6addaa8be517c1d Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Thu, 31 Dec 2015 12:19:46 -0400 Subject: propellor spin --- src/Propellor/Property/SiteSpecific/JoeySites.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/Propellor/Property') diff --git a/src/Propellor/Property/SiteSpecific/JoeySites.hs b/src/Propellor/Property/SiteSpecific/JoeySites.hs index d7bd9068..987b4187 100644 --- a/src/Propellor/Property/SiteSpecific/JoeySites.hs +++ b/src/Propellor/Property/SiteSpecific/JoeySites.hs @@ -702,7 +702,7 @@ kiteMailServer = propertyList "kitenet.net mail server" $ props dovecotusers = "/etc/dovecot/users" ssmtp = Postfix.Service - (Postfix.InetService (Nothing, "ssmtp")) + (Postfix.InetService Nothing "ssmtp") "smtpd" Postfix.defServiceOpts -- Configures postfix to relay outgoing mail to kitenet.net, with -- cgit v1.2.3 From bfe8375d46e78bc6dd796ba1d0bdce577dbd123c Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Thu, 31 Dec 2015 12:40:42 -0400 Subject: actually parse service lines So whitespace etc changes don't matter --- src/Propellor/Property/Postfix.hs | 17 ++++++++++------- src/Propellor/Property/SiteSpecific/JoeySites.hs | 3 ++- 2 files changed, 12 insertions(+), 8 deletions(-) (limited to 'src/Propellor/Property') diff --git a/src/Propellor/Property/Postfix.hs b/src/Propellor/Property/Postfix.hs index b6a1d170..df244061 100644 --- a/src/Propellor/Property/Postfix.hs +++ b/src/Propellor/Property/Postfix.hs @@ -139,14 +139,14 @@ data Service = Service , serviceCommand :: String , serviceOpts :: ServiceOpts } - deriving (Show) + deriving (Show, Eq) data ServiceType = InetService (Maybe HostName) ServicePort | UnixService FilePath PrivateService | FifoService FilePath PrivateService | PassService FilePath PrivateService - deriving (Show) + deriving (Show, Eq) -- Can be a port number or service name such as "smtp". type ServicePort = String @@ -160,7 +160,7 @@ data ServiceOpts = ServiceOpts , serviceWakeupTime :: Maybe Int , serviceProcessLimit :: Maybe Int } - deriving (Show) + deriving (Show, Eq) defServiceOpts :: ServiceOpts defServiceOpts = ServiceOpts @@ -254,13 +254,16 @@ parseServiceLine l = Service -- | Enables a `Service` in postfix's `masterCfFile`. service :: Service -> RevertableProperty NoInfo service s = (enable disable) - `describe` ("enabled postfix service " ++ show (serviceType s)) + `describe` desc where - enable = masterCfFile `File.containsLine` l + desc = "enabled postfix service " ++ show (serviceType s) + enable = masterCfFile `File.containsLine` (formatServiceLine s) `onChange` reloaded - disable = masterCfFile `File.lacksLine` l + disable = File.fileProperty desc (filter (not . matches)) masterCfFile `onChange` reloaded - l = formatServiceLine s + matches l = case parseServiceLine l of + Just s' | s' == s -> True + _ -> False -- | Installs saslauthd and configures it for postfix, authenticating -- against PAM. diff --git a/src/Propellor/Property/SiteSpecific/JoeySites.hs b/src/Propellor/Property/SiteSpecific/JoeySites.hs index 987b4187..f140404d 100644 --- a/src/Propellor/Property/SiteSpecific/JoeySites.hs +++ b/src/Propellor/Property/SiteSpecific/JoeySites.hs @@ -709,7 +709,8 @@ kiteMailServer = propertyList "kitenet.net mail server" $ props -- verification via tls cert. postfixClientRelay :: Context -> Property HasInfo postfixClientRelay ctx = Postfix.mainCfFile `File.containsLines` - [ "relayhost = kitenet.net" + -- Using smtps not smtp because more networks firewall smtp + [ "relayhost = kitenet.net:smtps" , "smtp_tls_CAfile = /etc/ssl/certs/joeyca.pem" , "smtp_tls_cert_file = /etc/ssl/certs/postfix.pem" , "smtp_tls_key_file = /etc/ssl/private/postfix.pem" -- cgit v1.2.3 From 8c37f36b64268c24445f7f48247ae988d1f8d5ad Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sat, 2 Jan 2016 22:15:07 -0400 Subject: clean cache on autobuilders --- src/Propellor/Property/SiteSpecific/GitAnnexBuilder.hs | 1 + 1 file changed, 1 insertion(+) (limited to 'src/Propellor/Property') diff --git a/src/Propellor/Property/SiteSpecific/GitAnnexBuilder.hs b/src/Propellor/Property/SiteSpecific/GitAnnexBuilder.hs index 2312846c..153d714f 100644 --- a/src/Propellor/Property/SiteSpecific/GitAnnexBuilder.hs +++ b/src/Propellor/Property/SiteSpecific/GitAnnexBuilder.hs @@ -118,6 +118,7 @@ standardAutoBuilder osver@(System _ arch) flavor = & os osver & Apt.stdSourcesList & Apt.unattendedUpgrades + & Apt.cacheCleaned & User.accountFor (User builduser) & tree arch flavor -- cgit v1.2.3 From 7a998ab068aff4461948d1a189a6a3e02dbeaa21 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 2 Jan 2016 16:44:15 +0000 Subject: Add Munin module. Signed-off-by: Jelmer Vernooij --- src/Propellor/Property/Munin.hs | 57 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 src/Propellor/Property/Munin.hs (limited to 'src/Propellor/Property') diff --git a/src/Propellor/Property/Munin.hs b/src/Propellor/Property/Munin.hs new file mode 100644 index 00000000..43112a6c --- /dev/null +++ b/src/Propellor/Property/Munin.hs @@ -0,0 +1,57 @@ +-- | Maintainer: Jelmer Vernooij +-- +module Propellor.Property.Munin ( + hostListFragment, + hostListFragment', + nodePort, + nodeInstalled, + nodeRestarted, + nodeConfPath, + masterInstalled, + masterRestarted, + masterConfPath, +) where + +import Propellor +import qualified Propellor.Property.Apt as Apt +import qualified Propellor.Property.Service as Service + +nodePort :: Integer +nodePort = 4949 + +nodeInstalled :: Property NoInfo +nodeInstalled = Apt.serviceInstalledRunning "munin-node" + +nodeRestarted :: Property NoInfo +nodeRestarted = Service.restarted "munin-node" + +nodeConfPath :: FilePath +nodeConfPath = "/etc/munin/munin-node.conf" + +masterInstalled :: Property NoInfo +masterInstalled = Apt.serviceInstalledRunning "munin" + +masterRestarted :: Property NoInfo +masterRestarted = Service.restarted "munin" + +masterConfPath :: FilePath +masterConfPath = "/etc/munin/munin.conf" + + +-- | Create the host list fragment for master config. +-- Takes an optional override list for hosts that are accessible on a non-standard host/port. +-- TODO(jelmer): Only do this on hosts where munin is present (in other words, with Munin.installedNode) +hostListFragment' :: [Host] -> [(HostName, (IPAddr, Port))] -> [String] +hostListFragment' hs os = concatMap muninHost hs + where + muninHost :: Host -> [String] + muninHost h = [ "[" ++ (hostName h) ++ "]" + , " address " ++ maybe (hostName h) (fromIPAddr . fst) (hOverride h) + ] ++ (maybe [] (\x -> [" port " ++ (show $ fromPort $ snd x)]) (hOverride h)) ++ [""] + hOverride :: Host -> Maybe (IPAddr, Port) + hOverride h = lookup (hostName h) os + fromPort (Port p) = p + +-- | Create the host list fragment for master config. +hostListFragment :: [Host] -> [String] +hostListFragment hs = hostListFragment' hs [] -- cgit v1.2.3