propellor/src/Propellor/Property/SiteSpecific/JoeySites.hs

315 lines
11 KiB
Haskell
Raw Normal View History

2014-03-31 03:37:54 +00:00
-- | Specific configuation for Joey Hess's sites. Probably not useful to
-- others except as an example.
2014-03-31 02:14:14 +00:00
2014-04-01 20:58:11 +00:00
module Propellor.Property.SiteSpecific.JoeySites where
2014-03-31 02:14:14 +00:00
2014-03-31 03:55:59 +00:00
import Propellor
2014-03-31 03:37:54 +00:00
import qualified Propellor.Property.Apt as Apt
2014-04-13 18:01:30 +00:00
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
2014-04-14 18:53:19 +00:00
import qualified Propellor.Property.Cron as Cron
2014-04-13 18:01:30 +00:00
import qualified Propellor.Property.Service as Service
import qualified Propellor.Property.User as User
import qualified Propellor.Property.Obnam as Obnam
import qualified Propellor.Property.Apache as Apache
2014-04-13 20:38:58 +00:00
import Utility.SafeCommand
2014-05-01 00:55:12 +00:00
import Utility.FileMode
2014-03-31 02:14:14 +00:00
2014-04-18 03:32:42 +00:00
import Data.List
import System.Posix.Files
oldUseNetServer :: [Host] -> Property
oldUseNetServer hosts = propertyList ("olduse.net server")
[ oldUseNetInstalled "oldusenet-server"
, Obnam.latestVersion
, Obnam.backup datadir "33 4 * * *"
[ "--repository=sftp://2318@usw-s002.rsync.net/~/olduse.net"
, "--client-name=spool"
] Obnam.OnlyClient
`requires` Ssh.keyImported SshRsa "root"
`requires` Ssh.knownHost hosts "usw-s002.rsync.net" "root"
, check (not . isSymbolicLink <$> getSymbolicLinkStatus newsspool) $
property "olduse.net spool in place" $ makeChange $ do
2014-04-18 03:32:42 +00:00
removeDirectoryRecursive newsspool
createSymbolicLink (datadir </> "news") newsspool
, Apt.installed ["leafnode"]
, "/etc/news/leafnode/config" `File.hasContent`
[ "# olduse.net configuration (deployed by propellor)"
, "expire = 1000000" -- no expiry via texpire
, "server = " -- no upstream server
, "debugmode = 1"
, "allowSTRANGERS = 42" -- lets anyone connect
, "nopost = 1" -- no new posting (just gather them)
]
2014-04-18 13:37:28 +00:00
, "/etc/hosts.deny" `File.lacksLine` "leafnode: ALL"
2014-04-18 03:32:42 +00:00
, Apt.serviceInstalledRunning "openbsd-inetd"
, File.notPresent "/etc/cron.daily/leafnode"
, File.notPresent "/etc/cron.d/leafnode"
, Cron.niceJob "oldusenet-expire" "11 1 * * *" "news" newsspool $ intercalate ";"
[ "find \\( -path ./out.going -or -path ./interesting.groups -or -path './*/.overview' \\) -prune -or -type f -ctime +60 -print | xargs --no-run-if-empty rm"
, "find -type d -empty | xargs --no-run-if-empty rmdir"
]
, Cron.niceJob "oldusenet-uucp" "*/5 * * * *" "news" "/" $
"/usr/bin/uucp " ++ datadir
, toProp $ Apache.siteEnabled "nntp.olduse.net" $ apachecfg "nntp.olduse.net" False
[ " DocumentRoot " ++ datadir ++ "/"
, " <Directory " ++ datadir ++ "/>"
, " Options Indexes FollowSymlinks"
, " AllowOverride None"
2014-04-18 14:14:30 +00:00
-- I had this in the file before.
-- This may be needed by a newer version of apache?
--, " Require all granted"
2014-04-18 03:32:42 +00:00
, " </Directory>"
]
]
where
newsspool = "/var/spool/news"
datadir = "/var/spool/oldusenet"
2014-04-11 01:09:20 +00:00
oldUseNetShellBox :: Property
2014-04-18 03:32:42 +00:00
oldUseNetShellBox = oldUseNetInstalled "oldusenet"
oldUseNetInstalled :: Apt.Package -> Property
oldUseNetInstalled pkg = check (not <$> Apt.isInstalled pkg) $
propertyList ("olduse.net " ++ pkg)
2014-03-31 02:38:33 +00:00
[ Apt.installed (words "build-essential devscripts debhelper git libncursesw5-dev libpcre3-dev pkg-config bison libicu-dev libidn11-dev libcanlock2-dev libuu-dev ghc libghc-strptime-dev libghc-hamlet-dev libghc-ifelse-dev libghc-hxt-dev libghc-utf8-string-dev libghc-missingh-dev libghc-sha-dev")
2014-03-31 02:14:14 +00:00
`describe` "olduse.net build deps"
, scriptProperty
2014-03-31 02:25:11 +00:00
[ "rm -rf /root/tmp/oldusenet" -- idenpotency
2014-03-31 02:24:21 +00:00
, "git clone git://olduse.net/ /root/tmp/oldusenet/source"
2014-03-31 02:14:14 +00:00
, "cd /root/tmp/oldusenet/source/"
, "dpkg-buildpackage -us -uc"
2014-04-18 03:32:42 +00:00
, "dpkg -i ../" ++ pkg ++ "_*.deb || true"
2014-03-31 02:40:55 +00:00
, "apt-get -fy install" -- dependencies
2014-03-31 02:14:14 +00:00
, "rm -rf /root/tmp/oldusenet"
] `describe` "olduse.net built"
]
2014-04-13 18:01:30 +00:00
2014-04-18 03:32:42 +00:00
2014-04-13 20:38:58 +00:00
kgbServer :: Property
kgbServer = withOS desc $ \o -> case o of
(Just (System (Debian Unstable) _)) ->
ensureProperty $ propertyList desc
[ Apt.serviceInstalledRunning "kgb-bot"
, File.hasPrivContent "/etc/kgb-bot/kgb.conf"
`onChange` Service.restarted "kgb-bot"
, "/etc/default/kgb-bot" `File.containsLine` "BOT_ENABLED=1"
`describe` "kgb bot enabled"
`onChange` Service.running "kgb-bot"
]
_ -> error "kgb server needs Debian unstable (for kgb-bot 1.31+)"
where
desc = "kgb.kitenet.net setup"
2014-04-20 02:22:23 +00:00
mumbleServer :: [Host] -> Property
mumbleServer hosts = combineProperties "mumble.debian.net"
2014-05-09 12:42:45 +00:00
[ Apt.serviceInstalledRunning "mumble-server"
, Obnam.latestVersion
2014-04-20 02:22:23 +00:00
, Obnam.backup "/var/lib/mumble-server" "55 5 * * *"
[ "--repository=sftp://joey@turtle.kitenet.net/~/lib/backup/mumble.debian.net.obnam"
, "--client-name=mumble"
] Obnam.OnlyClient
`requires` Ssh.keyImported SshRsa "root"
`requires` Ssh.knownHost hosts "turtle.kitenet.net" "root"
2014-04-21 01:55:40 +00:00
, trivial $ cmdProperty "chown" ["-R", "mumble-server:mumble-server", "/var/lib/mumble-server"]
2014-04-20 02:22:23 +00:00
]
2014-04-21 05:00:59 +00:00
obnamLowMem :: Property
2014-04-21 15:10:14 +00:00
obnamLowMem = combineProperties "obnam tuned for low memory use"
2014-04-21 05:00:59 +00:00
[ Obnam.latestVersion
, "/etc/obnam.conf" `File.containsLines`
2014-04-23 17:53:51 +00:00
[ "[config]"
, "# Suggested by liw to keep Obnam memory consumption down (at some speed cost)."
2014-04-21 05:00:59 +00:00
, "upload-queue-size = 128"
, "lru-size = 128"
]
]
2014-04-13 18:01:30 +00:00
-- git.kitenet.net and git.joeyh.name
gitServer :: [Host] -> Property
gitServer hosts = propertyList "git.kitenet.net setup"
2014-04-18 02:25:09 +00:00
[ Obnam.latestVersion
, Obnam.backup "/srv/git" "33 3 * * *"
[ "--repository=sftp://2318@usw-s002.rsync.net/~/git.kitenet.net"
2014-04-13 18:01:30 +00:00
, "--encrypt-with=1B169BE1"
, "--client-name=wren"
] Obnam.OnlyClient
`requires` Gpg.keyImported "1B169BE1" "root"
`requires` Ssh.keyImported SshRsa "root"
`requires` Ssh.knownHost hosts "usw-s002.rsync.net" "root"
2014-04-13 18:01:30 +00:00
`requires` Ssh.authorizedKeys "family"
`requires` User.accountFor "family"
2014-04-13 20:06:23 +00:00
, Apt.installed ["git", "rsync", "kgb-client-git", "gitweb"]
, Apt.installedBackport ["git-annex"]
2014-04-13 18:01:30 +00:00
, File.hasPrivContentExposed "/etc/kgb-bot/kgb-client.conf"
, toProp $ Git.daemonRunning "/srv/git"
, "/etc/gitweb.conf" `File.containsLines`
2014-04-13 18:45:18 +00:00
[ "$projectroot = '/srv/git';"
2014-04-14 01:04:34 +00:00
, "@git_base_url_list = ('git://git.kitenet.net', 'http://git.kitenet.net/git', 'https://git.kitenet.net/git', 'ssh://git.kitenet.net/srv/git');"
2014-04-13 18:01:30 +00:00
, "# disable snapshot download; overloads server"
, "$feature{'snapshot'}{'default'} = [];"
]
`describe` "gitweb configured"
2014-04-13 20:49:49 +00:00
-- Repos push on to github.
, Ssh.knownHost hosts "github.com" "joey"
2014-04-13 18:12:11 +00:00
-- I keep the website used for gitweb checked into git..
2014-04-13 18:13:26 +00:00
, Git.cloned "root" "/srv/git/joey/git.kitenet.net.git" "/srv/web/git.kitenet.net" Nothing
2014-04-13 18:01:30 +00:00
, website "git.kitenet.net"
, website "git.joeyh.name"
2014-04-13 18:36:19 +00:00
, toProp $ Apache.modEnabled "cgi"
2014-04-13 18:01:30 +00:00
]
where
2014-04-14 00:22:35 +00:00
website hn = toProp $ Apache.siteEnabled hn $ apachecfg hn True
[ " DocumentRoot /srv/web/git.kitenet.net/"
, " <Directory /srv/web/git.kitenet.net/>"
, " Options Indexes ExecCGI FollowSymlinks"
, " AllowOverride None"
, " AddHandler cgi-script .cgi"
, " DirectoryIndex index.cgi"
, " </Directory>"
, ""
, " ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/"
, " <Directory /usr/lib/cgi-bin>"
, " SetHandler cgi-script"
, " Options ExecCGI"
, " </Directory>"
]
2014-04-13 18:01:30 +00:00
2014-04-13 20:38:58 +00:00
type AnnexUUID = String
-- | A website, with files coming from a git-annex repository.
2014-04-13 21:03:21 +00:00
annexWebSite :: [Host] -> Git.RepoUrl -> HostName -> AnnexUUID -> [(String, Git.RepoUrl)] -> Property
2014-04-14 01:04:34 +00:00
annexWebSite hosts origin hn uuid remotes = propertyList (hn ++" website using git-annex")
[ Git.cloned "joey" origin dir Nothing
`onChange` setup
2014-05-01 00:55:12 +00:00
, postupdatehook `File.hasContent`
2014-05-01 00:56:24 +00:00
[ "#!/bin/sh"
2014-05-01 00:55:12 +00:00
, "exec git update-server-info"
] `onChange`
(postupdatehook `File.mode` (combineModes (ownerWriteMode:readModes ++ executeModes)))
2014-04-14 01:04:34 +00:00
, setupapache
]
2014-04-13 20:38:58 +00:00
where
dir = "/srv/web/" ++ hn
2014-05-01 00:55:12 +00:00
postupdatehook = dir </> ".git/hooks/post-update"
2014-04-13 21:03:21 +00:00
setup = userScriptProperty "joey" setupscript
`requires` Ssh.keyImported SshRsa "joey"
`requires` Ssh.knownHost hosts "turtle.kitenet.net" "joey"
setupscript =
2014-04-13 20:38:58 +00:00
[ "cd " ++ shellEscape dir
, "git config annex.uuid " ++ shellEscape uuid
] ++ map addremote remotes ++
[ "git annex get"
]
addremote (name, url) = "git remote add " ++ shellEscape name ++ " " ++ shellEscape url
2014-04-14 00:22:35 +00:00
setupapache = toProp $ Apache.siteEnabled hn $ apachecfg hn True $
[ " ServerAlias www."++hn
, ""
, " DocumentRoot /srv/web/"++hn
, " <Directory /srv/web/"++hn++">"
, " Options FollowSymLinks"
, " AllowOverride None"
, " </Directory>"
, " <Directory /srv/web/"++hn++">"
, " Options Indexes FollowSymLinks ExecCGI"
, " AllowOverride None"
2014-04-14 18:04:18 +00:00
, " AddHandler cgi-script .cgi"
2014-04-14 18:05:42 +00:00
, " DirectoryIndex index.html index.cgi"
2014-04-14 00:22:35 +00:00
, " Order allow,deny"
, " allow from all"
, " </Directory>"
]
2014-04-13 20:38:58 +00:00
2014-04-14 00:22:35 +00:00
apachecfg :: HostName -> Bool -> Apache.ConfigFile -> Apache.ConfigFile
apachecfg hn withssl middle
| withssl = vhost False ++ vhost True
| otherwise = vhost False
2014-04-13 20:38:58 +00:00
where
2014-04-14 00:22:35 +00:00
vhost ssl =
[ "<VirtualHost *:"++show port++">"
, " ServerAdmin grue@joeyh.name"
, " ServerName "++hn++":"++show port
]
++ mainhttpscert ssl
++ middle ++
[ ""
, " ErrorLog /var/log/apache2/error.log"
, " LogLevel warn"
, " CustomLog /var/log/apache2/access.log combined"
, " ServerSignature On"
, " "
, " <Directory \"/usr/share/apache2/icons\">"
, " Options Indexes MultiViews"
, " AllowOverride None"
, " Order allow,deny"
, " Allow from all"
, " </Directory>"
, "</VirtualHost>"
2014-04-13 20:38:58 +00:00
]
where
2014-04-14 00:22:35 +00:00
port = if ssl then 443 else 80 :: Int
2014-04-13 20:38:58 +00:00
2014-04-14 00:22:35 +00:00
mainhttpscert :: Bool -> Apache.ConfigFile
mainhttpscert False = []
mainhttpscert True =
[ " SSLEngine on"
, " SSLCertificateFile /etc/ssl/certs/web.pem"
, " SSLCertificateKeyFile /etc/ssl/private/web.pem"
, " SSLCertificateChainFile /etc/ssl/certs/startssl.pem"
2014-04-13 18:01:30 +00:00
]
2014-04-14 18:00:37 +00:00
2014-04-21 15:10:14 +00:00
gitAnnexDistributor :: Property
gitAnnexDistributor = combineProperties "git-annex distributor, including rsync server and signer"
2014-04-14 18:00:37 +00:00
[ 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"
2014-04-21 15:11:47 +00:00
-- git-annex distribution signing key
2014-04-21 15:10:14 +00:00
, Gpg.keyImported "89C809CB" "joey"
2014-04-14 18:00:37 +00:00
]
where
endpoint d = combineProperties ("endpoint " ++ d)
[ File.dirExists d
, File.ownerGroup d "joey" "joey"
]
2014-04-14 18:40:57 +00:00
2014-04-14 18:53:19 +00:00
-- Twitter, you kill us.
2014-04-14 18:40:57 +00:00
twitRss :: Property
twitRss = combineProperties "twitter rss"
[ Git.cloned "joey" "git://git.kitenet.net/twitrss.git" dir Nothing
2014-04-14 18:43:04 +00:00
, check (not <$> doesFileExist (dir </> "twitRss")) $
userScriptProperty "joey"
[ "cd " ++ dir
, "ghc --make twitRss"
]
2014-04-14 18:44:45 +00:00
`requires` Apt.installed
[ "libghc-xml-dev"
, "libghc-feed-dev"
2014-04-14 18:46:53 +00:00
, "libghc-tagsoup-dev"
2014-04-14 18:44:45 +00:00
]
2014-04-14 18:55:03 +00:00
, 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"
2014-04-14 18:40:57 +00:00
]
where
dir = "/srv/web/tmp.kitenet.net/twitrss"
2014-04-14 18:53:19 +00:00
crontime = "15 * * * *"
2014-04-14 18:55:03 +00:00
feed url desc = Cron.job desc crontime "joey" dir $
"./twitRss " ++ shellEscape url ++ " > " ++ shellEscape ("../" ++ desc ++ ".rss")
2014-05-09 13:31:30 +00:00
ircBouncer :: Property
ircBouncer = propertyList "IRC bouncer"
[ Apt.installed ["znc"]
, User.accountFor "znc"
, File.hasPrivContent conf
, File.ownerGroup conf "znc" "znc"
, Cron.job "znconboot" "@reboot" "znc" "~" "znc"
, Cron.job "zncrunning" "@hourly" "znc" "~" "znc || true"
]
where
conf = "/home/znc/.znc/configs/znc.conf"