diff --git a/Propellor/Property.hs b/Propellor/Property.hs index 95d17c0..5b1800e 100644 --- a/Propellor/Property.hs +++ b/Propellor/Property.hs @@ -92,6 +92,19 @@ check c property = Property (propertyDesc property) $ ifM (liftIO c) , return NoChange ) +-- | Marks a Property as trivial. It can only return FailedChange or +-- NoChange. +-- +-- Useful when it's just as expensive to check if a change needs +-- to be made as it is to just idempotently assure the property is +-- satisfied. For example, chmodding a file. +trivial :: Property -> Property +trivial p = Property (propertyDesc p) $ do + r <- ensureProperty p + if r == MadeChange + then return NoChange + else return r + -- | Makes a property that is satisfied differently depending on the host's -- operating system. -- diff --git a/Propellor/Property/Apache.hs b/Propellor/Property/Apache.hs index f45ef9d..cf3e62c 100644 --- a/Propellor/Property/Apache.hs +++ b/Propellor/Property/Apache.hs @@ -10,12 +10,12 @@ type ConfigFile = [String] siteEnabled :: HostName -> ConfigFile -> RevertableProperty siteEnabled hn cf = RevertableProperty enable disable where - enable = cmdProperty "a2ensite" ["--quiet", hn] + enable = trivial $ cmdProperty "a2ensite" ["--quiet", hn] `describe` ("apache site enabled " ++ hn) `requires` siteAvailable hn cf `requires` installed `onChange` reloaded - disable = File.notPresent (siteCfg hn) + disable = trivial $ File.notPresent (siteCfg hn) `describe` ("apache site disabled " ++ hn) `onChange` cmdProperty "a2dissite" ["--quiet", hn] `requires` installed @@ -30,11 +30,11 @@ siteAvailable hn cf = siteCfg hn `File.hasContent` (comment:cf) modEnabled :: String -> RevertableProperty modEnabled modname = RevertableProperty enable disable where - enable = cmdProperty "a2enmod" ["--quiet", modname] + enable = trivial $ cmdProperty "a2enmod" ["--quiet", modname] `describe` ("apache module enabled " ++ modname) `requires` installed `onChange` reloaded - disable = cmdProperty "a2dismod" ["--quiet", modname] + disable = trivial $ cmdProperty "a2dismod" ["--quiet", modname] `describe` ("apache module disabled " ++ modname) `requires` installed `onChange` reloaded diff --git a/Propellor/Property/Apt.hs b/Propellor/Property/Apt.hs index f45bc2e..3842cb0 100644 --- a/Propellor/Property/Apt.hs +++ b/Propellor/Property/Apt.hs @@ -103,7 +103,7 @@ installed' params ps = robustly $ check (isInstallable ps) go go = runApt $ params ++ ["install"] ++ ps installedBackport :: [Package] -> Property -installedBackport ps = withOS desc $ \o -> case o of +installedBackport ps = trivial $ withOS desc $ \o -> case o of Nothing -> error "cannot install backports; os not declared" (Just (System (Debian suite) _)) | isStable suite -> @@ -200,7 +200,7 @@ reConfigure package vals = reconfigure `requires` setselections forM_ vals $ \(tmpl, tmpltype, value) -> hPutStrLn h $ unwords [package, tmpl, tmpltype, value] hClose h - reconfigure = cmdProperty "dpkg-reconfigure" ["-fnone", package] + reconfigure = cmdProperty' "dpkg-reconfigure" ["-fnone", package] noninteractiveEnv -- | Ensures that a service is installed and running. -- diff --git a/Propellor/Property/Hostname.hs b/Propellor/Property/Hostname.hs index 03613ac..30e0992 100644 --- a/Propellor/Property/Hostname.hs +++ b/Propellor/Property/Hostname.hs @@ -4,11 +4,10 @@ import Propellor import qualified Propellor.Property.File as File -- | Ensures that the hostname is set to the HostAttr value. --- Configures both /etc/hostname and the current hostname. +-- Configures /etc/hostname and the current hostname. -- --- When the hostname is a FQDN, also configures /etc/hosts, --- with an entry for 127.0.1.1, which is standard at least on Debian --- to set the FDQN (127.0.0.1 is localhost). +-- A FQDN also configures /etc/hosts, with an entry for 127.0.1.1, which is +-- standard at least on Debian to set the FDQN (127.0.0.1 is localhost). sane :: Property sane = Property ("sane hostname") (ensureProperty . setTo =<< getHostName) diff --git a/Propellor/Property/Postfix.hs b/Propellor/Property/Postfix.hs new file mode 100644 index 0000000..f4be27c --- /dev/null +++ b/Propellor/Property/Postfix.hs @@ -0,0 +1,25 @@ +module Propellor.Property.Postfix where + +import Propellor +import qualified Propellor.Property.Apt as Apt + +installed :: Property +installed = Apt.serviceInstalledRunning "postfix" + +-- | Configures postfix as a satellite system, which +-- relats all mail through a relay host, which defaults to smtp.domain. +-- +-- The smarthost may refuse to relay mail on to other domains, without +-- futher coniguration/keys. But this should be enough to get cron job +-- mail flowing to a place where it will be seen. +satellite :: Property +satellite = setup `requires` installed + where + setup = trivial $ Property "postfix satellite system" $ do + hn <- getHostName + ensureProperty $ Apt.reConfigure "postfix" + [ ("postfix/main_mailer_type", "select", "Satellite system") + , ("postfix/root_address", "string", "root") + , ("postfix/destinations", "string", " ") + , ("postfix/mailname", "string", hn) + ] diff --git a/Propellor/Property/SiteSpecific/JoeySites.hs b/Propellor/Property/SiteSpecific/JoeySites.hs index 73a8f71..dd24bb6 100644 --- a/Propellor/Property/SiteSpecific/JoeySites.hs +++ b/Propellor/Property/SiteSpecific/JoeySites.hs @@ -9,6 +9,7 @@ import qualified Propellor.Property.File as File import qualified Propellor.Property.Gpg as Gpg import qualified Propellor.Property.Ssh as Ssh import qualified Propellor.Property.Git as Git +import qualified Propellor.Property.Cron as Cron import qualified Propellor.Property.Service as Service import qualified Propellor.Property.User as User import qualified Propellor.Property.Obnam as Obnam @@ -127,6 +128,8 @@ annexWebSite hosts origin hn uuid remotes = propertyList (hn ++" website using g , " " , " Options Indexes FollowSymLinks ExecCGI" , " AllowOverride None" + , " AddHandler cgi-script .cgi" + , " DirectoryIndex index.html index.cgi" , " Order allow,deny" , " allow from all" , " " @@ -169,3 +172,43 @@ mainhttpscert True = , " SSLCertificateKeyFile /etc/ssl/private/web.pem" , " SSLCertificateChainFile /etc/ssl/certs/startssl.pem" ] + + +annexRsyncServer :: Property +annexRsyncServer = combineProperties "rsync server for git-annex autobuilders" + [ Apt.installed ["rsync"] + , File.hasPrivContent "/etc/rsyncd.conf" + , File.hasPrivContent "/etc/rsyncd.secrets" + , "/etc/default/rsync" `File.containsLine` "RSYNC_ENABLE=true" + `onChange` Service.running "rsync" + , endpoint "/srv/web/downloads.kitenet.net/git-annex/autobuild" + , endpoint "/srv/web/downloads.kitenet.net/git-annex/autobuild/x86_64-apple-mavericks" + ] + where + endpoint d = combineProperties ("endpoint " ++ d) + [ File.dirExists d + , File.ownerGroup d "joey" "joey" + ] + +-- Twitter, you kill us. +twitRss :: Property +twitRss = combineProperties "twitter rss" + [ Git.cloned "joey" "git://git.kitenet.net/twitrss.git" dir Nothing + , check (not <$> doesFileExist (dir "twitRss")) $ + userScriptProperty "joey" + [ "cd " ++ dir + , "ghc --make twitRss" + ] + `requires` Apt.installed + [ "libghc-xml-dev" + , "libghc-feed-dev" + , "libghc-tagsoup-dev" + ] + , feed "http://twitter.com/search/realtime?q=git-annex" "git-annex-twitter" + , feed "http://twitter.com/search/realtime?q=olduse+OR+git-annex+OR+debhelper+OR+etckeeper+OR+ikiwiki+-ashley_ikiwiki" "twittergrep" + ] + where + dir = "/srv/web/tmp.kitenet.net/twitrss" + crontime = "15 * * * *" + feed url desc = Cron.job desc crontime "joey" dir $ + "./twitRss " ++ shellEscape url ++ " > " ++ shellEscape ("../" ++ desc ++ ".rss") diff --git a/config-joey.hs b/config-joey.hs index 76860cb..6039a52 100644 --- a/config-joey.hs +++ b/config-joey.hs @@ -18,7 +18,7 @@ import qualified Propellor.Property.OpenId as OpenId import qualified Propellor.Property.Docker as Docker import qualified Propellor.Property.Git as Git import qualified Propellor.Property.Apache as Apache -import qualified Propellor.Property.Service as Service +import qualified Propellor.Property.Postfix as Postfix import qualified Propellor.Property.SiteSpecific.GitHome as GitHome import qualified Propellor.Property.SiteSpecific.GitAnnexBuilder as GitAnnexBuilder import qualified Propellor.Property.SiteSpecific.JoeySites as JoeySites @@ -41,7 +41,9 @@ hosts = -- (o) ` & Apt.unattendedUpgrades & Network.ipv6to4 & Tor.isBridge + & Postfix.satellite & Docker.configured + & cname "shell.olduse.net" & JoeySites.oldUseNetShellBox @@ -63,6 +65,7 @@ hosts = -- (o) ` , standardSystem "orca.kitenet.net" Unstable "amd64" & Hostname.sane & Apt.unattendedUpgrades + & Postfix.satellite & Docker.configured & Docker.docked hosts "amd64-git-annex-builder" & Docker.docked hosts "i386-git-annex-builder" @@ -80,6 +83,7 @@ hosts = -- (o) ` & Apt.unattendedUpgrades & Apt.serviceInstalledRunning "ntp" & Dns.zones myDnsSecondary + & Postfix.satellite & Apt.serviceInstalledRunning "apache2" & File.hasPrivContent "/etc/ssl/certs/web.pem" @@ -98,19 +102,14 @@ hosts = -- (o) ` "downloads.kitenet.net" "840760dc-08f0-11e2-8c61-576b7e66acfd" [("turtle", "ssh://turtle.kitenet.net/~/lib/downloads/")] - -- rsync server for git-annex autobuilders - & Apt.installed ["rsync"] - & File.hasPrivContent "/etc/rsyncd.conf" - & File.hasPrivContent "/etc/rsyncd.secrets" - & "/etc/default/rsync" `File.containsLine` "RSYNC_ENABLE=true" - `describe` "rsync server enabled" - `onChange` Service.running "rsync" + & JoeySites.annexRsyncServer & cname "tmp.kitenet.net" & JoeySites.annexWebSite hosts "/srv/git/joey/tmp.git" "tmp.kitenet.net" "26fd6e38-1226-11e2-a75f-ff007033bdba" [] + & JoeySites.twitRss & Apt.installed ["ntop"] diff --git a/debian/changelog b/debian/changelog index 18436b2..172ca7a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -4,6 +4,7 @@ propellor (0.3.1) UNRELEASED; urgency=medium * Support for provisioning hosts with ssh and gpg keys. * Obnam support. * Apache support. + * Postfix satellite system support. * Properties can now be satisfied differently on different operating systems. * Standard apt configuration for stable now includes backports. diff --git a/propellor.cabal b/propellor.cabal index 1d62538..482f2de 100644 --- a/propellor.cabal +++ b/propellor.cabal @@ -81,6 +81,7 @@ Library Propellor.Property.Network Propellor.Property.Obnam Propellor.Property.OpenId + Propellor.Property.Postfix Propellor.Property.Reboot Propellor.Property.Scheduled Propellor.Property.Service