propellor spin

This commit is contained in:
Joey Hess 2015-02-01 17:34:04 -04:00
parent 30c8621f5c
commit 8edc7ed3ae
Failed to extract signature
7 changed files with 60 additions and 37 deletions

View File

@ -119,8 +119,8 @@ orca = standardSystem "orca.kitenet.net" Unstable "amd64"
& Docker.docked (GitAnnexBuilder.standardAutoBuilderContainer dockerImage "amd64" 15 "2h") & Docker.docked (GitAnnexBuilder.standardAutoBuilderContainer dockerImage "amd64" 15 "2h")
& Docker.docked (GitAnnexBuilder.standardAutoBuilderContainer dockerImage "i386" 45 "2h") & Docker.docked (GitAnnexBuilder.standardAutoBuilderContainer dockerImage "i386" 45 "2h")
& Docker.docked (GitAnnexBuilder.armelCompanionContainer dockerImage) & Docker.docked (GitAnnexBuilder.armelCompanionContainer dockerImage)
& Docker.docked (GitAnnexBuilder.armelAutoBuilderContainer dockerImage "1 3 * * *" "5h") & Docker.docked (GitAnnexBuilder.armelAutoBuilderContainer dockerImage (Cron.Times "1 3 * * *") "5h")
& Docker.docked (GitAnnexBuilder.androidAutoBuilderContainer dockerImage "1 1 * * *" "3h") & Docker.docked (GitAnnexBuilder.androidAutoBuilderContainer dockerImage (Cron.Times "1 1 * * *") "3h")
& Docker.garbageCollected `period` Daily & Docker.garbageCollected `period` Daily
& Apt.buildDep ["git-annex"] `period` Daily & Apt.buildDep ["git-annex"] `period` Daily
@ -151,7 +151,7 @@ kite = standardSystemUnhardened "kite.kitenet.net" Testing "amd64"
& Ssh.passwordAuthentication True & Ssh.passwordAuthentication True
-- Since ssh password authentication is allowed: -- Since ssh password authentication is allowed:
& Apt.serviceInstalledRunning "fail2ban" & Apt.serviceInstalledRunning "fail2ban"
& Obnam.backupEncrypted "/" "33 1 * * *" & Obnam.backupEncrypted "/" (Cron.Times "33 1 * * *")
[ "--repository=sftp://joey@eubackup.kitenet.net/~/lib/backup/kite.obnam" [ "--repository=sftp://joey@eubackup.kitenet.net/~/lib/backup/kite.obnam"
, "--client-name=kitenet.net" , "--client-name=kitenet.net"
, "--exclude=/var/cache" , "--exclude=/var/cache"
@ -331,11 +331,15 @@ elephant = standardSystem "elephant.kitenet.net" Unstable "amd64"
beaver :: Host beaver :: Host
beaver = host "beaver.kitenet.net" beaver = host "beaver.kitenet.net"
& ipv6 "2001:4830:1600:195::2" & ipv6 "2001:4830:1600:195::2"
& Apt.serviceInstalledRunning "aiccu"
& Apt.installed ["ssh"] & Apt.installed ["ssh"]
& Ssh.pubKey SshDsa "ssh-dss AAAAB3NzaC1kc3MAAACBAIrLX260fY0Jjj/p0syNhX8OyR8hcr6feDPGOj87bMad0k/w/taDSOzpXe0Wet7rvUTbxUjH+Q5wPd4R9zkaSDiR/tCb45OdG6JsaIkmqncwe8yrU+pqSRCxttwbcFe+UU+4AAcinjVedZjVRDj2rRaFPc9BXkPt7ffk8GwEJ31/AAAAFQCG/gOjObsr86vvldUZHCteaJttNQAAAIB5nomvcqOk/TD07DLaWKyG7gAcW5WnfY3WtnvLRAFk09aq1EuiJ6Yba99Zkb+bsxXv89FWjWDg/Z3Psa22JMyi0HEDVsOevy/1sEQ96AGH5ijLzFInfXAM7gaJKXASD7hPbVdjySbgRCdwu0dzmQWHtH+8i1CMVmA2/a5Y/wtlJAAAAIAUZj2US2D378jBwyX1Py7e4sJfea3WSGYZjn4DLlsLGsB88POuh32aOChd1yzF6r6C2sdoPBHQcWBgNGXcx4gF0B5UmyVHg3lIX2NVSG1ZmfuLNJs9iKNu4cHXUmqBbwFYQJBvB69EEtrOw4jSbiTKwHFmqdA/mw1VsMB+khUaVw==" & Ssh.pubKey SshDsa "ssh-dss AAAAB3NzaC1kc3MAAACBAIrLX260fY0Jjj/p0syNhX8OyR8hcr6feDPGOj87bMad0k/w/taDSOzpXe0Wet7rvUTbxUjH+Q5wPd4R9zkaSDiR/tCb45OdG6JsaIkmqncwe8yrU+pqSRCxttwbcFe+UU+4AAcinjVedZjVRDj2rRaFPc9BXkPt7ffk8GwEJ31/AAAAFQCG/gOjObsr86vvldUZHCteaJttNQAAAIB5nomvcqOk/TD07DLaWKyG7gAcW5WnfY3WtnvLRAFk09aq1EuiJ6Yba99Zkb+bsxXv89FWjWDg/Z3Psa22JMyi0HEDVsOevy/1sEQ96AGH5ijLzFInfXAM7gaJKXASD7hPbVdjySbgRCdwu0dzmQWHtH+8i1CMVmA2/a5Y/wtlJAAAAIAUZj2US2D378jBwyX1Py7e4sJfea3WSGYZjn4DLlsLGsB88POuh32aOChd1yzF6r6C2sdoPBHQcWBgNGXcx4gF0B5UmyVHg3lIX2NVSG1ZmfuLNJs9iKNu4cHXUmqBbwFYQJBvB69EEtrOw4jSbiTKwHFmqdA/mw1VsMB+khUaVw=="
& alias "backup.kitenet.net"
& alias "usbackup.kitenet.net" & alias "usbackup.kitenet.net"
& JoeySites.backupsBackedupFrom hosts "eubackup.kitenet.net" "/home/joey/lib/backup" & JoeySites.backupsBackedupFrom hosts "eubackup.kitenet.net" "/home/joey/lib/backup"
& Apt.serviceInstalledRunning "anacron"
& Cron.niceJob "system disk backed up" Cron.Weekly "root" "/"
"rsync -a -x / /home/joey/lib/backup/beaver.kitenet.net/"
--' __|II| ,. --' __|II| ,.
---- __|II|II|__ ( \_,/\ ---- __|II|II|__ ( \_,/\
@ -419,7 +423,7 @@ standardSystemUnhardened hn suite arch motd = host hn
& Sudo.enabledFor "joey" & Sudo.enabledFor "joey"
& GitHome.installedFor "joey" & GitHome.installedFor "joey"
& Apt.installed ["vim", "screen", "less"] & Apt.installed ["vim", "screen", "less"]
& Cron.runPropellor "30 * * * *" & Cron.runPropellor (Cron.Times "30 * * * *")
-- I use postfix, or no MTA. -- I use postfix, or no MTA.
& Apt.removed ["exim4", "exim4-daemon-light", "exim4-config", "exim4-base"] & Apt.removed ["exim4", "exim4-daemon-light", "exim4-config", "exim4-base"]
`onChange` Apt.autoRemove `onChange` Apt.autoRemove

4
debian/changelog vendored
View File

@ -1,7 +1,9 @@
propellor (2.0.1) UNRELEASED; urgency=medium propellor (2.1.0) UNRELEASED; urgency=medium
* Additional tor properties, including support for making relays, * Additional tor properties, including support for making relays,
and naming bridges, relays, etc. and naming bridges, relays, etc.
* New Cron.Times data type, which allows Cron.job to install
* daily/monthly/weekly jobs that anacron can run. (API change)
-- Joey Hess <id@joeyh.name> Thu, 29 Jan 2015 01:41:07 -0400 -- Joey Hess <id@joeyh.name> Thu, 29 Jan 2015 01:41:07 -0400

View File

@ -1,5 +1,5 @@
Name: propellor Name: propellor
Version: 2.0.0 Version: 2.1.0
Cabal-Version: >= 1.6 Cabal-Version: >= 1.6
License: BSD3 License: BSD3
Maintainer: Joey Hess <id@joeyh.name> Maintainer: Joey Hess <id@joeyh.name>

View File

@ -8,18 +8,26 @@ import Utility.FileMode
import Data.Char 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 -- | 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 -- directory. Note that the Desc must be unique, as it is used for the
-- cron.d/ filename. -- cron job filename.
-- --
-- Only one instance of the cron job is allowed to run at a time, no matter -- 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 -- how long it runs. This is accomplished using flock locking of the cron
-- job file. -- job file.
-- --
-- The cron job's output will only be emailed if it exits nonzero. -- 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) job desc times user cddir command = combineProperties ("cronned " ++ desc)
[ cronjobfile `File.hasContent` [ cronjobfile `File.hasContent`
[ "# Generated by propellor" [ "# Generated by propellor"
@ -27,7 +35,11 @@ job desc times user cddir command = combineProperties ("cronned " ++ desc)
, "SHELL=/bin/sh" , "SHELL=/bin/sh"
, "PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin" , "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 -- Use a separate script because it makes the cron job name
-- prettier in emails, and also allows running the job manually. -- 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"] `requires` Apt.installed ["util-linux", "moreutils"]
where where
cmdline = "cd " ++ cddir ++ " && ( " ++ command ++ " )" 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" scriptfile = "/usr/local/bin/" ++ name ++ "_cronjob"
name = map sanitize desc name = map sanitize desc
sanitize c sanitize c
@ -52,10 +69,10 @@ job desc times user cddir command = combineProperties ("cronned " ++ desc)
| otherwise = '_' | otherwise = '_'
-- | Installs a cron job, and runs it niced and ioniced. -- | 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 niceJob desc times user cddir command = job desc times user cddir
("nice ionice -c 3 sh -c " ++ shellEscape command) ("nice ionice -c 3 sh -c " ++ shellEscape command)
-- | Installs a cron job to run propellor. -- | Installs a cron job to run propellor.
runPropellor :: CronTimes -> Property NoInfo runPropellor :: Times -> Property NoInfo
runPropellor times = niceJob "propellor" times "root" localdir "./propellor" runPropellor times = niceJob "propellor" times "root" localdir "./propellor"

View File

@ -36,7 +36,7 @@ data NumClients = OnlyClient | MultipleClients
-- > `requires` Ssh.keyImported SshRsa "root" (Context hostname) -- > `requires` Ssh.keyImported SshRsa "root" (Context hostname)
-- --
-- How awesome is that? -- 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 =
backup' dir crontimes params numclients backup' dir crontimes params numclients
`requires` restored dir params `requires` restored dir params
@ -46,7 +46,7 @@ backup dir crontimes params numclients =
-- --
-- The gpg secret key will be automatically imported -- The gpg secret key will be automatically imported
-- into root's keyring using Propellor.Property.Gpg.keyImported -- 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 = backupEncrypted dir crontimes params numclients keyid =
backup dir crontimes params' numclients backup dir crontimes params' numclients
`requires` Gpg.keyImported keyid "root" `requires` Gpg.keyImported keyid "root"
@ -54,7 +54,7 @@ backupEncrypted dir crontimes params numclients keyid =
params' = ("--encrypt-with=" ++ Gpg.getGpgKeyId keyid) : params params' = ("--encrypt-with=" ++ Gpg.getGpgKeyId keyid) : params
-- | Does a backup, but does not automatically restore. -- | 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 backup' dir crontimes params numclients = cronjob `describe` desc
where where
desc = dir ++ " backed up by obnam" desc = dir ++ " backed up by obnam"

View File

@ -9,7 +9,7 @@ import qualified Propellor.Property.Cron as Cron
import qualified Propellor.Property.Ssh as Ssh import qualified Propellor.Property.Ssh as Ssh
import qualified Propellor.Property.File as File import qualified Propellor.Property.File as File
import qualified Propellor.Property.Docker as Docker import qualified Propellor.Property.Docker as Docker
import Propellor.Property.Cron (CronTimes) import Propellor.Property.Cron (Times)
builduser :: UserName builduser :: UserName
builduser = "builder" builduser = "builder"
@ -25,7 +25,7 @@ builddir = gitbuilderdir </> "build"
type TimeOut = String -- eg, 5h type TimeOut = String -- eg, 5h
autobuilder :: Architecture -> CronTimes -> TimeOut -> Property HasInfo autobuilder :: Architecture -> Times -> TimeOut -> Property HasInfo
autobuilder arch crontimes timeout = combineProperties "gitannexbuilder" $ props autobuilder arch crontimes timeout = combineProperties "gitannexbuilder" $ props
& Apt.serviceInstalledRunning "cron" & Apt.serviceInstalledRunning "cron"
& Cron.niceJob "gitannexbuilder" crontimes builduser gitbuilderdir & Cron.niceJob "gitannexbuilder" crontimes builduser gitbuilderdir
@ -102,10 +102,10 @@ standardAutoBuilderContainer dockerImage arch buildminute timeout = Docker.conta
& User.accountFor builduser & User.accountFor builduser
& tree arch & tree arch
& buildDepsApt & buildDepsApt
& autobuilder arch (show buildminute ++ " * * * *") timeout & autobuilder arch (Cron.Times $ show buildminute ++ " * * * *") timeout
& Docker.tweaked & Docker.tweaked
androidAutoBuilderContainer :: (System -> Docker.Image) -> Cron.CronTimes -> TimeOut -> Docker.Container androidAutoBuilderContainer :: (System -> Docker.Image) -> Times -> TimeOut -> Docker.Container
androidAutoBuilderContainer dockerImage crontimes timeout = androidAutoBuilderContainer dockerImage crontimes timeout =
androidContainer dockerImage "android-git-annex-builder" (tree "android") builddir androidContainer dockerImage "android-git-annex-builder" (tree "android") builddir
& Apt.unattendedUpgrades & Apt.unattendedUpgrades
@ -166,7 +166,7 @@ armelCompanionContainer dockerImage = Docker.container "armel-git-annex-builder-
& Ssh.authorizedKeys builduser (Context "armel-git-annex-builder") & Ssh.authorizedKeys builduser (Context "armel-git-annex-builder")
& Docker.tweaked & 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" armelAutoBuilderContainer dockerImage crontimes timeout = Docker.container "armel-git-annex-builder"
(dockerImage $ System (Debian Unstable) "armel") (dockerImage $ System (Debian Unstable) "armel")
& os (System (Debian Testing) "armel") & os (System (Debian Testing) "armel")

View File

@ -45,8 +45,8 @@ oldUseNetServer hosts = propertyList "olduse.net server" $ props
& Apt.serviceInstalledRunning "openbsd-inetd" & Apt.serviceInstalledRunning "openbsd-inetd"
& File.notPresent "/etc/cron.daily/leafnode" & File.notPresent "/etc/cron.daily/leafnode"
& File.notPresent "/etc/cron.d/leafnode" & File.notPresent "/etc/cron.d/leafnode"
& Cron.niceJob "oldusenet-expire" "11 1 * * *" "news" newsspool expirecommand & Cron.niceJob "oldusenet-expire" (Cron.Times "11 1 * * *") "news" newsspool expirecommand
& Cron.niceJob "oldusenet-uucp" "*/5 * * * *" "news" "/" uucpcommand & Cron.niceJob "oldusenet-uucp" (Cron.Times "*/5 * * * *") "news" "/" uucpcommand
& Apache.siteEnabled "nntp.olduse.net" nntpcfg & Apache.siteEnabled "nntp.olduse.net" nntpcfg
where where
newsspool = "/var/spool/news" newsspool = "/var/spool/news"
@ -65,7 +65,7 @@ oldUseNetServer hosts = propertyList "olduse.net server" $ props
, " </Directory>" , " </Directory>"
] ]
oldUseNetBackup = Obnam.backup datadir "33 4 * * *" oldUseNetBackup = Obnam.backup datadir (Cron.Times "33 4 * * *")
[ "--repository=sftp://2318@usw-s002.rsync.net/~/olduse.net" [ "--repository=sftp://2318@usw-s002.rsync.net/~/olduse.net"
, "--client-name=spool" , "--client-name=spool"
] Obnam.OnlyClient ] Obnam.OnlyClient
@ -113,7 +113,7 @@ mumbleServer :: [Host] -> Property HasInfo
mumbleServer hosts = combineProperties hn $ props mumbleServer hosts = combineProperties hn $ props
& Apt.serviceInstalledRunning "mumble-server" & Apt.serviceInstalledRunning "mumble-server"
& Obnam.latestVersion & 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" [ "--repository=sftp://2318@usw-s002.rsync.net/~/" ++ hn ++ ".obnam"
, "--client-name=mumble" , "--client-name=mumble"
] Obnam.OnlyClient ] Obnam.OnlyClient
@ -138,7 +138,7 @@ obnamLowMem = combineProperties "obnam tuned for low memory use"
gitServer :: [Host] -> Property HasInfo gitServer :: [Host] -> Property HasInfo
gitServer hosts = propertyList "git.kitenet.net setup" $ props gitServer hosts = propertyList "git.kitenet.net setup" $ props
& Obnam.latestVersion & 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" [ "--repository=sftp://2318@usw-s002.rsync.net/~/git.kitenet.net"
, "--client-name=wren" -- historical , "--client-name=wren" -- historical
] Obnam.OnlyClient (Gpg.GpgKeyId "1B169BE1") ] 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" & feed "http://twitter.com/search/realtime?q=olduse+OR+git-annex+OR+debhelper+OR+etckeeper+OR+ikiwiki+-ashley_ikiwiki" "twittergrep"
where where
dir = "/srv/web/tmp.kitenet.net/twitrss" dir = "/srv/web/tmp.kitenet.net/twitrss"
crontime = "15 * * * *" crontime = Cron.Times "15 * * * *"
feed url desc = Cron.job desc crontime "joey" dir $ feed url desc = Cron.job desc crontime "joey" dir $
"./twitRss " ++ shellEscape url ++ " > " ++ shellEscape ("../" ++ desc ++ ".rss") "./twitRss " ++ shellEscape url ++ " > " ++ shellEscape ("../" ++ desc ++ ".rss")
compiled = userScriptProperty "joey" compiled = userScriptProperty "joey"
@ -313,7 +313,7 @@ twitRss = combineProperties "twitter rss" $ props
-- Work around for expired ssl cert. -- Work around for expired ssl cert.
-- (no longer expired, TODO remove this and change urls) -- (no longer expired, TODO remove this and change urls)
pumpRss :: Property NoInfo 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" "wget https://pump2rss.com/feed/joeyh@identi.ca.atom -O pump.atom --no-check-certificate 2>/dev/null"
ircBouncer :: Property HasInfo ircBouncer :: Property HasInfo
@ -323,7 +323,7 @@ ircBouncer = propertyList "IRC bouncer" $ props
& File.dirExists (takeDirectory conf) & File.dirExists (takeDirectory conf)
& File.hasPrivContent conf anyContext & File.hasPrivContent conf anyContext
& File.ownerGroup conf "znc" "znc" & 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 -- ensure running if it was not already
& trivial (userScriptProperty "znc" ["znc || true"]) & trivial (userScriptProperty "znc" ["znc || true"])
`describe` "znc running" `describe` "znc running"
@ -347,9 +347,9 @@ githubBackup :: Property HasInfo
githubBackup = propertyList "github-backup box" $ props githubBackup = propertyList "github-backup box" $ props
& Apt.installed ["github-backup", "moreutils"] & Apt.installed ["github-backup", "moreutils"]
& githubKeys & githubKeys
& Cron.niceJob "github-backup run" "30 4 * * *" "joey" & Cron.niceJob "github-backup run" (Cron.Times "30 4 * * *") "joey"
"/home/joey/lib/backup" backupcmd "/home/joey/lib/backup" backupcmd
& Cron.niceJob "gitriddance" "30 4 * * *" "joey" & Cron.niceJob "gitriddance" (Cron.Times "30 4 * * *") "joey"
"/home/joey/lib/backup" gitriddancecmd "/home/joey/lib/backup" gitriddancecmd
where where
backupcmd = intercalate "&&" $ backupcmd = intercalate "&&" $
@ -385,13 +385,13 @@ githubMirrors =
plzuseurl u = "please submit changes to " ++ u ++ " instead of using github pull requests" plzuseurl u = "please submit changes to " ++ u ++ " instead of using github pull requests"
rsyncNetBackup :: [Host] -> Property NoInfo 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" "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" `requires` Ssh.knownHost hosts "usw-s002.rsync.net" "joey"
backupsBackedupFrom :: [Host] -> HostName -> FilePath -> Property NoInfo backupsBackedupFrom :: [Host] -> HostName -> FilePath -> Property NoInfo
backupsBackedupFrom hosts srchost destdir = Cron.niceJob desc backupsBackedupFrom hosts srchost destdir = Cron.niceJob desc
"@reboot" "joey" "/" cmd (Cron.Times "@reboot") "joey" "/" cmd
`requires` Ssh.knownHost hosts srchost "joey" `requires` Ssh.knownHost hosts srchost "joey"
where where
desc = "backups copied from " ++ srchost ++ " on boot" 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" `before` File.ownerGroup d "joey" "joey"
podcatcher :: Property NoInfo 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" "joey" "/home/joey/lib/sound/podcasts"
"xargs git-annex importfeed -c annex.genmetadata=true < feeds; mr --quiet update" "xargs git-annex importfeed -c annex.genmetadata=true < feeds; mr --quiet update"
`requires` Apt.installed ["git-annex", "myrepos"] `requires` Apt.installed ["git-annex", "myrepos"]