summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config-joey.hs47
-rw-r--r--debian/changelog4
-rw-r--r--src/Propellor/Bootstrap.hs4
-rw-r--r--src/Propellor/CmdLine.hs2
-rw-r--r--src/Propellor/Info.hs4
-rw-r--r--src/Propellor/Property/HostingProvider/CloudAtCost.hs1
-rw-r--r--src/Propellor/Property/Munin.hs57
-rw-r--r--src/Propellor/Property/Postfix.hs136
-rw-r--r--src/Propellor/Property/SiteSpecific/GitAnnexBuilder.hs1
-rw-r--r--src/Propellor/Property/SiteSpecific/JoeySites.hs9
10 files changed, 254 insertions, 11 deletions
diff --git a/config-joey.hs b/config-joey.hs
index df6e40dc..d18b4a7b 100644
--- a/config-joey.hs
+++ b/config-joey.hs
@@ -46,6 +46,8 @@ hosts = -- (o) `
[ darkstar
, gnu
, clam
+ , mayfly
+ , oyster
, orca
, honeybee
, kite
@@ -118,6 +120,8 @@ clam = standardSystem "clam.kitenet.net" Unstable "amd64"
]
& Apt.unattendedUpgrades
& Network.ipv6to4
+ & Systemd.persistentJournal
+ & Journald.systemMaxUse "500MiB"
& Tor.isRelay
& Tor.named "kite1"
@@ -134,14 +138,44 @@ clam = standardSystem "clam.kitenet.net" Unstable "amd64"
& JoeySites.scrollBox
& alias "scroll.joeyh.name"
& alias "us.scroll.joeyh.name"
+
+mayfly :: Host
+mayfly = standardSystem "mayfly.kitenet.net" (Stable "jessie") "amd64"
+ [ "Scratch VM. Contents can change at any time!" ]
+ & ipv4 "104.167.118.15"
+
+ & CloudAtCost.decruft
+ & Apt.unattendedUpgrades
+ & Network.ipv6to4
+ & Systemd.persistentJournal
+ & Journald.systemMaxUse "500MiB"
- -- ssh on some extra ports to deal with horrible networks
- -- while travelling
- & alias "travelling.kitenet.net"
- ! Ssh.listenPort 80
- ! Ssh.listenPort 443
+ & Tor.isRelay
+ & Tor.named "kite3"
+ & Tor.bandwidthRate (Tor.PerMonth "400 GB")
+oyster :: Host
+oyster = standardSystem "oyster.kitenet.net" Unstable "amd64"
+ [ "Unreliable server. Anything here may be lost at any time!" ]
+ & ipv4 "104.167.117.109"
+
+ & CloudAtCost.decruft
+ & Ssh.hostKeys hostContext
+ [ (SshEcdsa, "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBP0ws/IxQegVU0RhqnIm5A/vRSPTO70wD4o2Bd1jL970dTetNyXzvWGe1spEbLjIYSLIO7WvOBSE5RhplBKFMUU=")
+ ]
+ & Apt.unattendedUpgrades
+ & Network.ipv6to4
& Systemd.persistentJournal
+ & Journald.systemMaxUse "500MiB"
+
+ & Tor.isRelay
+ & Tor.named "kite2"
+ & Tor.bandwidthRate (Tor.PerMonth "400 GB")
+
+ -- Nothing is using http port 80, so listen on
+ -- that port for ssh, for traveling on bad networks that
+ -- block 22.
+ & Ssh.listenPort 80
orca :: Host
orca = standardSystem "orca.kitenet.net" Unstable "amd64"
@@ -184,6 +218,9 @@ honeybee = standardSystem "honeybee.kitenet.net" Testing "armhf"
-- ipv6 used for remote access thru firewalls
& Apt.serviceInstalledRunning "aiccu"
& ipv6 "2001:4830:1600:187::2"
+ -- restart to deal with failure to connect, tunnel issues, etc
+ & Cron.job "aiccu restart daily" Cron.Daily (User "root") "/"
+ "service aiccu stop; service aiccu start"
-- In case compiler needs more than available ram
& Apt.serviceInstalledRunning "swapspace"
diff --git a/debian/changelog b/debian/changelog
index d3c84858..314ba037 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -3,6 +3,10 @@ propellor (2.15.2) UNRELEASED; urgency=medium
* Added GNUPGBIN environment variable to control the command run for gpg.
Allows eg, GNUPGBIN=gpg2
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.
+ * Added Munin module, contributed by Jelmer Vernooij.
-- Joey Hess <id@joeyh.name> Wed, 30 Dec 2015 15:01:19 -0400
diff --git a/src/Propellor/Bootstrap.hs b/src/Propellor/Bootstrap.hs
index f2f5af55..c49cb5af 100644
--- a/src/Propellor/Bootstrap.hs
+++ b/src/Propellor/Bootstrap.hs
@@ -63,7 +63,7 @@ depsCommand = "( " ++ intercalate " ; " (concat [osinstall, cabalinstall]) ++ "
, "cabal install --only-dependencies"
]
- aptinstall p = "apt-get --no-upgrade --no-install-recommends -y install " ++ p
+ aptinstall p = "DEBIAN_FRONTEND=noninteractive apt-get --no-upgrade --no-install-recommends -y install " ++ p
-- This is the same deps listed in debian/control.
debdeps =
@@ -86,7 +86,7 @@ depsCommand = "( " ++ intercalate " ; " (concat [osinstall, cabalinstall]) ++ "
]
installGitCommand :: ShellCommand
-installGitCommand = "if ! git --version >/dev/null; then apt-get update && apt-get --no-install-recommends --no-upgrade -y install git; fi"
+installGitCommand = "if ! git --version >/dev/null; then apt-get update && DEBIAN_FRONTEND=noninteractive apt-get --no-install-recommends --no-upgrade -y install git; fi"
buildPropellor :: IO ()
buildPropellor = unlessM (actionMessage "Propellor build" build) $
diff --git a/src/Propellor/CmdLine.hs b/src/Propellor/CmdLine.hs
index 4a4f71fe..1e61adc8 100644
--- a/src/Propellor/CmdLine.hs
+++ b/src/Propellor/CmdLine.hs
@@ -118,7 +118,7 @@ defaultMain hostlist = withConcurrentOutput $ do
go True cmdline@(Spin _ _) = buildFirst cmdline $ go False cmdline
go True cmdline = updateFirst cmdline $ go False cmdline
go False (Spin hs mrelay) = do
- commitSpin
+ unless (isJust mrelay) commitSpin
forM_ hs $ \hn -> withhost hn $ spin mrelay hn
go False cmdline@(SimpleRun hn) = do
forceConsole
diff --git a/src/Propellor/Info.hs b/src/Propellor/Info.hs
index 499b901c..7eb7d4a8 100644
--- a/src/Propellor/Info.hs
+++ b/src/Propellor/Info.hs
@@ -34,7 +34,7 @@ os system = pureInfoProperty ("Operating " ++ show system) (InfoVal system)
getOS :: Propellor (Maybe System)
getOS = fromInfoVal <$> askInfo
--- | Indidate that a host has an A record in the DNS.
+-- | Indicate that a host has an A record in the DNS.
--
-- When propellor is used to deploy a DNS server for a domain,
-- the hosts in the domain are found by looking for these
@@ -46,7 +46,7 @@ getOS = fromInfoVal <$> askInfo
ipv4 :: String -> Property HasInfo
ipv4 = addDNS . Address . IPv4
--- | Indidate that a host has an AAAA record in the DNS.
+-- | Indicate that a host has an AAAA record in the DNS.
ipv6 :: String -> Property HasInfo
ipv6 = addDNS . Address . IPv6
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
]
]
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 <jelmer@jelmer.uk>
+--
+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 []
diff --git a/src/Propellor/Property/Postfix.hs b/src/Propellor/Property/Postfix.hs
index 1c8684c7..df244061 100644
--- a/src/Propellor/Property/Postfix.hs
+++ b/src/Propellor/Property/Postfix.hs
@@ -129,6 +129,142 @@ 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, Eq)
+
+data ServiceType
+ = InetService (Maybe HostName) ServicePort
+ | UnixService FilePath PrivateService
+ | FifoService FilePath PrivateService
+ | PassService FilePath PrivateService
+ deriving (Show, Eq)
+
+-- Can be a port number or service name such as "smtp".
+type ServicePort = String
+
+type PrivateService = Bool
+
+-- | Options for a service.
+data ServiceOpts = ServiceOpts
+ { serviceUnprivileged :: Maybe Bool
+ , serviceChroot :: Maybe Bool
+ , serviceWakeupTime :: Maybe Int
+ , serviceProcessLimit :: Maybe Int
+ }
+ deriving (Show, Eq)
+
+defServiceOpts :: ServiceOpts
+defServiceOpts = ServiceOpts
+ { 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, 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)
+ , (8, v show serviceProcessLimit)
+ , (0, serviceCommand s)
+ ]
+ where
+ v f sel = maybe "-" f (sel (serviceOpts s))
+ bool True = "y"
+ bool False = "n"
+ 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
+-- 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 <*> 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 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` desc
+ where
+ desc = "enabled postfix service " ++ show (serviceType s)
+ enable = masterCfFile `File.containsLine` (formatServiceLine s)
+ `onChange` reloaded
+ disable = File.fileProperty desc (filter (not . matches)) masterCfFile
+ `onChange` reloaded
+ 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/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
diff --git a/src/Propellor/Property/SiteSpecific/JoeySites.hs b/src/Propellor/Property/SiteSpecific/JoeySites.hs
index 732714db..f140404d 100644
--- a/src/Propellor/Property/SiteSpecific/JoeySites.hs
+++ b/src/Propellor/Property/SiteSpecific/JoeySites.hs
@@ -694,16 +694,23 @@ 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
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"