summaryrefslogtreecommitdiff
path: root/src/Propellor
diff options
context:
space:
mode:
authorJoey Hess2015-02-01 17:34:04 -0400
committerJoey Hess2015-02-01 17:34:04 -0400
commit8edc7ed3ae1062af745fbe21b0753df6ad83fe6a (patch)
treea5fdfe524441123971782f47902e3b84478267c1 /src/Propellor
parent30c8621f5c0c4833652ae04510f98706166efd7c (diff)
propellor spin
Diffstat (limited to 'src/Propellor')
-rw-r--r--src/Propellor/Property/Cron.hs35
-rw-r--r--src/Propellor/Property/Obnam.hs6
-rw-r--r--src/Propellor/Property/SiteSpecific/GitAnnexBuilder.hs10
-rw-r--r--src/Propellor/Property/SiteSpecific/JoeySites.hs26
4 files changed, 47 insertions, 30 deletions
diff --git a/src/Propellor/Property/Cron.hs b/src/Propellor/Property/Cron.hs
index 15cdd983..e75f5ee3 100644
--- a/src/Propellor/Property/Cron.hs
+++ b/src/Propellor/Property/Cron.hs
@@ -8,18 +8,26 @@ import Utility.FileMode
import Data.Char
-type CronTimes = String
+-- | When to run a cron job.
+--
+-- The Daily, Monthly, and Weekly options allow the cron job to be run
+-- by anacron, which is useful for non-servers.
+data Times
+ = Times String -- ^ formatted as in crontab(5)
+ | Daily
+ | Weekly
+ | Monthly
--- | Installs a cron job, run as a specified user, in a particular
--- directory. Note that the Desc must be unique, as it is used for the
--- cron.d/ filename.
+-- | Installs a cron job, that will run as a specified user in a particular
+-- directory. Note that the Desc must be unique, as it is used for the
+-- cron job filename.
--
-- Only one instance of the cron job is allowed to run at a time, no matter
-- how long it runs. This is accomplished using flock locking of the cron
-- job file.
--
-- The cron job's output will only be emailed if it exits nonzero.
-job :: Desc -> CronTimes -> UserName -> FilePath -> String -> Property NoInfo
+job :: Desc -> Times -> UserName -> FilePath -> String -> Property NoInfo
job desc times user cddir command = combineProperties ("cronned " ++ desc)
[ cronjobfile `File.hasContent`
[ "# Generated by propellor"
@@ -27,7 +35,11 @@ job desc times user cddir command = combineProperties ("cronned " ++ desc)
, "SHELL=/bin/sh"
, "PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin"
, ""
- , times ++ "\t" ++ user ++ "\tchronic " ++ shellEscape scriptfile
+ , case times of
+ Times t -> t ++ "\t" ++ user ++ "\tchronic " ++ shellEscape scriptfile
+ _ -> case user of
+ "root" -> "chronic " ++ shellEscape scriptfile
+ _ -> "chronic su " ++ user ++ " -c " ++ shellEscape scriptfile
]
-- Use a separate script because it makes the cron job name
-- prettier in emails, and also allows running the job manually.
@@ -44,7 +56,12 @@ job desc times user cddir command = combineProperties ("cronned " ++ desc)
`requires` Apt.installed ["util-linux", "moreutils"]
where
cmdline = "cd " ++ cddir ++ " && ( " ++ command ++ " )"
- cronjobfile = "/etc/cron.d/" ++ name
+ cronjobfile = "/etc" </> cronjobdir </> name
+ cronjobdir = case times of
+ Times _ -> "cron.d"
+ Daily -> "cron.daily"
+ Weekly -> "cron.weekly"
+ Monthly -> "cron.monthly"
scriptfile = "/usr/local/bin/" ++ name ++ "_cronjob"
name = map sanitize desc
sanitize c
@@ -52,10 +69,10 @@ job desc times user cddir command = combineProperties ("cronned " ++ desc)
| otherwise = '_'
-- | Installs a cron job, and runs it niced and ioniced.
-niceJob :: Desc -> CronTimes -> UserName -> FilePath -> String -> Property NoInfo
+niceJob :: Desc -> Times -> UserName -> FilePath -> String -> Property NoInfo
niceJob desc times user cddir command = job desc times user cddir
("nice ionice -c 3 sh -c " ++ shellEscape command)
-- | Installs a cron job to run propellor.
-runPropellor :: CronTimes -> Property NoInfo
+runPropellor :: Times -> Property NoInfo
runPropellor times = niceJob "propellor" times "root" localdir "./propellor"
diff --git a/src/Propellor/Property/Obnam.hs b/src/Propellor/Property/Obnam.hs
index adaf255c..c066d9f7 100644
--- a/src/Propellor/Property/Obnam.hs
+++ b/src/Propellor/Property/Obnam.hs
@@ -36,7 +36,7 @@ data NumClients = OnlyClient | MultipleClients
-- > `requires` Ssh.keyImported SshRsa "root" (Context hostname)
--
-- How awesome is that?
-backup :: FilePath -> Cron.CronTimes -> [ObnamParam] -> NumClients -> Property NoInfo
+backup :: FilePath -> Cron.Times -> [ObnamParam] -> NumClients -> Property NoInfo
backup dir crontimes params numclients =
backup' dir crontimes params numclients
`requires` restored dir params
@@ -46,7 +46,7 @@ backup dir crontimes params numclients =
--
-- The gpg secret key will be automatically imported
-- into root's keyring using Propellor.Property.Gpg.keyImported
-backupEncrypted :: FilePath -> Cron.CronTimes -> [ObnamParam] -> NumClients -> Gpg.GpgKeyId -> Property HasInfo
+backupEncrypted :: FilePath -> Cron.Times -> [ObnamParam] -> NumClients -> Gpg.GpgKeyId -> Property HasInfo
backupEncrypted dir crontimes params numclients keyid =
backup dir crontimes params' numclients
`requires` Gpg.keyImported keyid "root"
@@ -54,7 +54,7 @@ backupEncrypted dir crontimes params numclients keyid =
params' = ("--encrypt-with=" ++ Gpg.getGpgKeyId keyid) : params
-- | Does a backup, but does not automatically restore.
-backup' :: FilePath -> Cron.CronTimes -> [ObnamParam] -> NumClients -> Property NoInfo
+backup' :: FilePath -> Cron.Times -> [ObnamParam] -> NumClients -> Property NoInfo
backup' dir crontimes params numclients = cronjob `describe` desc
where
desc = dir ++ " backed up by obnam"
diff --git a/src/Propellor/Property/SiteSpecific/GitAnnexBuilder.hs b/src/Propellor/Property/SiteSpecific/GitAnnexBuilder.hs
index 7fc523f9..102e6a1d 100644
--- a/src/Propellor/Property/SiteSpecific/GitAnnexBuilder.hs
+++ b/src/Propellor/Property/SiteSpecific/GitAnnexBuilder.hs
@@ -9,7 +9,7 @@ import qualified Propellor.Property.Cron as Cron
import qualified Propellor.Property.Ssh as Ssh
import qualified Propellor.Property.File as File
import qualified Propellor.Property.Docker as Docker
-import Propellor.Property.Cron (CronTimes)
+import Propellor.Property.Cron (Times)
builduser :: UserName
builduser = "builder"
@@ -25,7 +25,7 @@ builddir = gitbuilderdir </> "build"
type TimeOut = String -- eg, 5h
-autobuilder :: Architecture -> CronTimes -> TimeOut -> Property HasInfo
+autobuilder :: Architecture -> Times -> TimeOut -> Property HasInfo
autobuilder arch crontimes timeout = combineProperties "gitannexbuilder" $ props
& Apt.serviceInstalledRunning "cron"
& Cron.niceJob "gitannexbuilder" crontimes builduser gitbuilderdir
@@ -102,10 +102,10 @@ standardAutoBuilderContainer dockerImage arch buildminute timeout = Docker.conta
& User.accountFor builduser
& tree arch
& buildDepsApt
- & autobuilder arch (show buildminute ++ " * * * *") timeout
+ & autobuilder arch (Cron.Times $ show buildminute ++ " * * * *") timeout
& Docker.tweaked
-androidAutoBuilderContainer :: (System -> Docker.Image) -> Cron.CronTimes -> TimeOut -> Docker.Container
+androidAutoBuilderContainer :: (System -> Docker.Image) -> Times -> TimeOut -> Docker.Container
androidAutoBuilderContainer dockerImage crontimes timeout =
androidContainer dockerImage "android-git-annex-builder" (tree "android") builddir
& Apt.unattendedUpgrades
@@ -166,7 +166,7 @@ armelCompanionContainer dockerImage = Docker.container "armel-git-annex-builder-
& Ssh.authorizedKeys builduser (Context "armel-git-annex-builder")
& Docker.tweaked
-armelAutoBuilderContainer :: (System -> Docker.Image) -> Cron.CronTimes -> TimeOut -> Docker.Container
+armelAutoBuilderContainer :: (System -> Docker.Image) -> Times -> TimeOut -> Docker.Container
armelAutoBuilderContainer dockerImage crontimes timeout = Docker.container "armel-git-annex-builder"
(dockerImage $ System (Debian Unstable) "armel")
& os (System (Debian Testing) "armel")
diff --git a/src/Propellor/Property/SiteSpecific/JoeySites.hs b/src/Propellor/Property/SiteSpecific/JoeySites.hs
index 9f960aba..32b19764 100644
--- a/src/Propellor/Property/SiteSpecific/JoeySites.hs
+++ b/src/Propellor/Property/SiteSpecific/JoeySites.hs
@@ -45,8 +45,8 @@ oldUseNetServer hosts = propertyList "olduse.net server" $ props
& Apt.serviceInstalledRunning "openbsd-inetd"
& File.notPresent "/etc/cron.daily/leafnode"
& File.notPresent "/etc/cron.d/leafnode"
- & Cron.niceJob "oldusenet-expire" "11 1 * * *" "news" newsspool expirecommand
- & Cron.niceJob "oldusenet-uucp" "*/5 * * * *" "news" "/" uucpcommand
+ & Cron.niceJob "oldusenet-expire" (Cron.Times "11 1 * * *") "news" newsspool expirecommand
+ & Cron.niceJob "oldusenet-uucp" (Cron.Times "*/5 * * * *") "news" "/" uucpcommand
& Apache.siteEnabled "nntp.olduse.net" nntpcfg
where
newsspool = "/var/spool/news"
@@ -65,7 +65,7 @@ oldUseNetServer hosts = propertyList "olduse.net server" $ props
, " </Directory>"
]
- oldUseNetBackup = Obnam.backup datadir "33 4 * * *"
+ oldUseNetBackup = Obnam.backup datadir (Cron.Times "33 4 * * *")
[ "--repository=sftp://2318@usw-s002.rsync.net/~/olduse.net"
, "--client-name=spool"
] Obnam.OnlyClient
@@ -113,7 +113,7 @@ mumbleServer :: [Host] -> Property HasInfo
mumbleServer hosts = combineProperties hn $ props
& Apt.serviceInstalledRunning "mumble-server"
& Obnam.latestVersion
- & Obnam.backup "/var/lib/mumble-server" "55 5 * * *"
+ & Obnam.backup "/var/lib/mumble-server" (Cron.Times "55 5 * * *")
[ "--repository=sftp://2318@usw-s002.rsync.net/~/" ++ hn ++ ".obnam"
, "--client-name=mumble"
] Obnam.OnlyClient
@@ -138,7 +138,7 @@ obnamLowMem = combineProperties "obnam tuned for low memory use"
gitServer :: [Host] -> Property HasInfo
gitServer hosts = propertyList "git.kitenet.net setup" $ props
& Obnam.latestVersion
- & Obnam.backupEncrypted "/srv/git" "33 3 * * *"
+ & Obnam.backupEncrypted "/srv/git" (Cron.Times "33 3 * * *")
[ "--repository=sftp://2318@usw-s002.rsync.net/~/git.kitenet.net"
, "--client-name=wren" -- historical
] Obnam.OnlyClient (Gpg.GpgKeyId "1B169BE1")
@@ -297,7 +297,7 @@ twitRss = combineProperties "twitter rss" $ props
& 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 * * * *"
+ crontime = Cron.Times "15 * * * *"
feed url desc = Cron.job desc crontime "joey" dir $
"./twitRss " ++ shellEscape url ++ " > " ++ shellEscape ("../" ++ desc ++ ".rss")
compiled = userScriptProperty "joey"
@@ -313,7 +313,7 @@ twitRss = combineProperties "twitter rss" $ props
-- Work around for expired ssl cert.
-- (no longer expired, TODO remove this and change urls)
pumpRss :: Property NoInfo
-pumpRss = Cron.job "pump rss" "15 * * * *" "joey" "/srv/web/tmp.kitenet.net/"
+pumpRss = Cron.job "pump rss" (Cron.Times "15 * * * *") "joey" "/srv/web/tmp.kitenet.net/"
"wget https://pump2rss.com/feed/joeyh@identi.ca.atom -O pump.atom --no-check-certificate 2>/dev/null"
ircBouncer :: Property HasInfo
@@ -323,7 +323,7 @@ ircBouncer = propertyList "IRC bouncer" $ props
& File.dirExists (takeDirectory conf)
& File.hasPrivContent conf anyContext
& File.ownerGroup conf "znc" "znc"
- & Cron.job "znconboot" "@reboot" "znc" "~" "znc"
+ & Cron.job "znconboot" (Cron.Times "@reboot") "znc" "~" "znc"
-- ensure running if it was not already
& trivial (userScriptProperty "znc" ["znc || true"])
`describe` "znc running"
@@ -347,9 +347,9 @@ githubBackup :: Property HasInfo
githubBackup = propertyList "github-backup box" $ props
& Apt.installed ["github-backup", "moreutils"]
& githubKeys
- & Cron.niceJob "github-backup run" "30 4 * * *" "joey"
+ & Cron.niceJob "github-backup run" (Cron.Times "30 4 * * *") "joey"
"/home/joey/lib/backup" backupcmd
- & Cron.niceJob "gitriddance" "30 4 * * *" "joey"
+ & Cron.niceJob "gitriddance" (Cron.Times "30 4 * * *") "joey"
"/home/joey/lib/backup" gitriddancecmd
where
backupcmd = intercalate "&&" $
@@ -385,13 +385,13 @@ githubMirrors =
plzuseurl u = "please submit changes to " ++ u ++ " instead of using github pull requests"
rsyncNetBackup :: [Host] -> Property NoInfo
-rsyncNetBackup hosts = Cron.niceJob "rsync.net copied in daily" "30 5 * * *"
+rsyncNetBackup hosts = Cron.niceJob "rsync.net copied in daily" (Cron.Times "30 5 * * *")
"joey" "/home/joey/lib/backup" "mkdir -p rsync.net && rsync --delete -az 2318@usw-s002.rsync.net: rsync.net"
`requires` Ssh.knownHost hosts "usw-s002.rsync.net" "joey"
backupsBackedupFrom :: [Host] -> HostName -> FilePath -> Property NoInfo
backupsBackedupFrom hosts srchost destdir = Cron.niceJob desc
- "@reboot" "joey" "/" cmd
+ (Cron.Times "@reboot") "joey" "/" cmd
`requires` Ssh.knownHost hosts srchost "joey"
where
desc = "backups copied from " ++ srchost ++ " on boot"
@@ -408,7 +408,7 @@ obnamRepos rs = propertyList ("obnam repos for " ++ unwords rs)
`before` File.ownerGroup d "joey" "joey"
podcatcher :: Property NoInfo
-podcatcher = Cron.niceJob "podcatcher run hourly" "55 * * * *"
+podcatcher = Cron.niceJob "podcatcher run hourly" (Cron.Times "55 * * * *")
"joey" "/home/joey/lib/sound/podcasts"
"xargs git-annex importfeed -c annex.genmetadata=true < feeds; mr --quiet update"
`requires` Apt.installed ["git-annex", "myrepos"]