propellor spin

This commit is contained in:
Joey Hess 2014-04-12 22:36:36 -04:00
parent 596c6590e8
commit c7830f4e66
Failed to extract signature
6 changed files with 202 additions and 108 deletions

View File

@ -4,13 +4,15 @@ import Propellor
import qualified Propellor.Property.File as File
import qualified Propellor.Property.Apt as Apt
import Data.Char
type CronTimes = String
-- | Installs a cron job, run as a specificed user, in a particular
--directory. Note that the Desc must be unique, as it is used for the
--cron.d/ filename.
job :: Desc -> CronTimes -> UserName -> FilePath -> String -> Property
job desc times user cddir command = ("/etc/cron.d/" ++ desc) `File.hasContent`
job desc times user cddir command = cronjobfile `File.hasContent`
[ "# Generated by propellor"
, ""
, "SHELL=/bin/sh"
@ -20,6 +22,11 @@ job desc times user cddir command = ("/etc/cron.d/" ++ desc) `File.hasContent`
]
`requires` Apt.serviceInstalledRunning "cron"
`describe` ("cronned " ++ desc)
where
cronjobfile = "/etc/cron.d/" ++ map sanitize desc
sanitize c
| isAlphaNum c = c
| otherwise = '_'
-- | Installs a cron job, and runs it niced and ioniced.
niceJob :: Desc -> CronTimes -> UserName -> FilePath -> String -> Property

View File

@ -0,0 +1,77 @@
module Propellor.Property.Obnam where
import Propellor
import qualified Propellor.Property.Apt as Apt
import qualified Propellor.Property.Cron as Cron
import Utility.SafeCommand
installed :: Property
installed = Apt.installed ["obnam"]
type ObnamParam = String
-- | Installs a cron job that causes a given directory to be backed
-- up, by running obnam with some parameters.
--
-- If the directory does not exist, or exists but is completely empty,
-- this Property will immediately restore it from an existing backup.
--
-- So, this property can be used to deploy a directory of content
-- to a host, while also ensuring any changes made to it get backed up.
-- And since Obnam encrypts, just make this property depend on a gpg
-- key, and tell obnam to use the key, and your data will be backed
-- up securely. For example:
--
-- > & Obnam.backup "/srv/git" "33 3 * * *"
-- > [ "--repository=2318@usw-s002.rsync.net:mygitrepos.obnam"
-- > , "--encrypt-with=1B169BE1"
-- > ]
-- > `requires` Gpg.keyImported "1B169BE1" "root"
-- > `requires` Ssh.keyImported SshRsa "root"
--
-- How awesome is that?
backup :: FilePath -> Cron.CronTimes -> [ObnamParam] -> Property
backup dir crontimes params = cronjob `describe` desc
`requires` restored dir params
`requires` installed
where
desc = dir ++ " backed up by obnam"
cronjob = Cron.niceJob ("obnam_backup" ++ dir) crontimes "root" "/" $
unwords $
[ "obnam"
, "backup"
, shellEscape dir
] ++ map shellEscape params
-- | Restores a directory from an obnam backup.
--
-- Only does anything if the directory does not exist, or exists,
-- but is completely empty.
--
-- The restore is performed atomically; restoring to a temp directory
-- and then moving it to the directory.
restored :: FilePath -> [ObnamParam] -> Property
restored dir params = Property (dir ++ " restored by obnam") go
`requires` installed
where
go = ifM (liftIO needsRestore)
( liftIO restore
, noChange
)
needsRestore = null <$> catchDefaultIO [] (dirContents dir)
restore = withTmpDirIn (takeDirectory dir) "obnam-restore" $ \tmpdir -> do
ok <- boolSystem "obnam" $
[ Param "restore"
, Param "--to"
, Param tmpdir
] ++ map Param params
let restoreddir = tmpdir ++ "/" ++ dir
ifM (pure ok <&&> doesDirectoryExist restoreddir)
( do
void $ tryIO $ removeDirectory dir
renameDirectory restoreddir dir
return MadeChange
, return FailedChange
)

View File

@ -18,6 +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.Gpg as Gpg
import qualified Propellor.Property.Obnam as Obnam
import qualified Propellor.Property.SiteSpecific.GitHome as GitHome
import qualified Propellor.Property.SiteSpecific.GitAnnexBuilder as GitAnnexBuilder
import qualified Propellor.Property.SiteSpecific.JoeySites as JoeySites
@ -72,8 +73,13 @@ hosts =
& Apt.buildDep ["git-annex"] `period` Daily
& Git.daemonRunning "/srv/git"
& File.ownerGroup "/srv/git" "joey" "joey"
& Gpg.keyImported "git.kitenet.net obnam backup key" "root"
& Ssh.keyImported SshRsa "root"
& Obnam.backup "/srv/git" "33 3 * * *"
[ "--repository=2318@usw-s002.rsync.net:git.kitenet.net"
, "--encrypt-with=1B169BE1"
]
`requires` Gpg.keyImported "1B169BE1" "root"
`requires` Ssh.keyImported SshRsa "root"
-- git repos restore (how?) (also make backups!)
-- family annex needs family members to have accounts,
-- ssh host key etc.. finesse?

2
debian/changelog vendored
View File

@ -1,6 +1,8 @@
propellor (0.3.1) UNRELEASED; urgency=medium
* Merge scheduler bug fix from git-annex.
* Support for provisioning hosts with ssh and gpg keys.
* Obnam support.
-- Joey Hess <joeyh@debian.org> Fri, 11 Apr 2014 15:00:11 -0400

View File

@ -1,109 +1,110 @@
-----BEGIN PGP MESSAGE-----
Version: GnuPG v1
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
UUFGrYcSqu0P
=w6i8
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
/kCJ1kYezrPgaFt3p6JHzQ==
=5opC
-----END PGP MESSAGE-----

View File

@ -78,6 +78,7 @@ Library
Propellor.Property.Git
Propellor.Property.Gpg
Propellor.Property.Network
Propellor.Property.Obnam
Propellor.Property.OpenId
Propellor.Property.Reboot
Propellor.Property.Scheduled