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

193 lines
7.3 KiB
Haskell
Raw Normal View History

{-# LANGUAGE FlexibleContexts #-}
2014-04-01 20:58:11 +00:00
module Propellor.Property.SiteSpecific.GitAnnexBuilder where
import Propellor
import qualified Propellor.Property.Apt as Apt
import qualified Propellor.Property.User as User
2014-04-01 22:06:02 +00:00
import qualified Propellor.Property.Cron as Cron
2014-05-23 01:42:57 +00:00
import qualified Propellor.Property.Ssh as Ssh
2014-05-20 22:49:03 +00:00
import qualified Propellor.Property.File as File
2014-05-23 01:42:57 +00:00
import qualified Propellor.Property.Docker as Docker
2015-02-01 21:34:04 +00:00
import Propellor.Property.Cron (Times)
2014-04-01 20:58:11 +00:00
builduser :: UserName
builduser = "builder"
2014-04-08 05:42:59 +00:00
homedir :: FilePath
homedir = "/home/builder"
gitbuilderdir :: FilePath
gitbuilderdir = homedir </> "gitbuilder"
2014-04-01 20:58:11 +00:00
builddir :: FilePath
2014-04-08 05:42:59 +00:00
builddir = gitbuilderdir </> "build"
2014-04-01 20:58:11 +00:00
2014-05-19 21:27:21 +00:00
type TimeOut = String -- eg, 5h
2015-02-01 21:34:04 +00:00
autobuilder :: Architecture -> Times -> TimeOut -> Property HasInfo
autobuilder arch crontimes timeout = combineProperties "gitannexbuilder" $ props
& Apt.serviceInstalledRunning "cron"
& Cron.niceJob "gitannexbuilder" crontimes (User builduser) gitbuilderdir
("git pull ; timeout " ++ timeout ++ " ./autobuild")
& rsyncpassword
where
context = Context ("gitannexbuilder " ++ arch)
pwfile = homedir </> "rsyncpassword"
2014-04-01 20:58:11 +00:00
-- The builduser account does not have a password set,
-- instead use the password privdata to hold the rsync server
-- password used to upload the built image.
rsyncpassword = withPrivData (Password builduser) context $ \getpw ->
2014-07-06 19:56:56 +00:00
property "rsync password" $ getpw $ \pw -> do
oldpw <- liftIO $ catchDefaultIO "" $
readFileStrict pwfile
if pw /= oldpw
then makeChange $ writeFile pwfile pw
else noChange
2014-05-19 21:27:21 +00:00
tree :: Architecture -> Property HasInfo
tree buildarch = combineProperties "gitannexbuilder tree" $ props
& Apt.installed ["git"]
2014-05-21 16:58:53 +00:00
-- gitbuilderdir directory already exists when docker volume is used,
-- but with wrong owner.
& File.dirExists gitbuilderdir
& File.ownerGroup gitbuilderdir (User builduser) (Group builduser)
& gitannexbuildercloned
& builddircloned
where
gitannexbuildercloned = check (not <$> (doesDirectoryExist (gitbuilderdir </> ".git"))) $
userScriptProperty (User builduser)
2014-05-21 16:58:53 +00:00
[ "git clone git://git.kitenet.net/gitannexbuilder " ++ gitbuilderdir
, "cd " ++ gitbuilderdir
, "git checkout " ++ buildarch
]
`describe` "gitbuilder setup"
builddircloned = check (not <$> doesDirectoryExist builddir) $ userScriptProperty (User builduser)
2014-05-19 21:27:21 +00:00
[ "git clone git://git-annex.branchable.com/ " ++ builddir
]
2014-05-20 22:28:13 +00:00
buildDepsApt :: Property HasInfo
buildDepsApt = combineProperties "gitannexbuilder build deps" $ props
& Apt.buildDep ["git-annex"]
& Apt.installed ["liblockfile-simple-perl"]
& buildDepsNoHaskellLibs
& Apt.buildDepIn builddir
`describe` "git-annex source build deps installed"
2014-05-19 21:27:21 +00:00
buildDepsNoHaskellLibs :: Property NoInfo
2014-05-26 22:46:42 +00:00
buildDepsNoHaskellLibs = Apt.installed
["git", "rsync", "moreutils", "ca-certificates",
2014-05-20 22:28:13 +00:00
"debhelper", "ghc", "curl", "openssh-client", "git-remote-gcrypt",
2014-05-20 23:49:07 +00:00
"liblockfile-simple-perl", "cabal-install", "vim", "less",
2014-06-10 14:08:12 +00:00
-- needed by haskell libs
2014-12-03 23:05:18 +00:00
"libxml2-dev", "libidn11-dev", "libgsasl7-dev", "libgnutls28-dev",
2014-05-26 22:46:42 +00:00
"alex", "happy", "c2hs"
2014-05-20 23:49:07 +00:00
]
2014-05-20 22:28:13 +00:00
2014-05-19 21:27:21 +00:00
-- Installs current versions of git-annex's deps from cabal, but only
-- does so once.
cabalDeps :: Property NoInfo
2014-05-19 21:27:21 +00:00
cabalDeps = flagFile go cabalupdated
where
go = userScriptProperty (User builduser) ["cabal update && cabal install git-annex --only-dependencies || true"]
2014-05-19 21:27:21 +00:00
cabalupdated = homedir </> ".cabal" </> "packages" </> "hackage.haskell.org" </> "00-index.cache"
2014-05-23 01:42:57 +00:00
standardAutoBuilderContainer :: (System -> Docker.Image) -> Architecture -> Int -> TimeOut -> Docker.Container
standardAutoBuilderContainer dockerImage arch buildminute timeout = Docker.container (arch ++ "-git-annex-builder")
2014-06-10 02:47:40 +00:00
(dockerImage $ System (Debian Testing) arch)
& os (System (Debian Testing) arch)
& Apt.stdSourcesList
2014-06-05 20:24:47 +00:00
& Apt.installed ["systemd"]
2014-05-23 01:42:57 +00:00
& Apt.unattendedUpgrades
& User.accountFor (User builduser)
2014-06-10 05:15:18 +00:00
& tree arch
& buildDepsApt
2015-02-01 21:34:04 +00:00
& autobuilder arch (Cron.Times $ show buildminute ++ " * * * *") timeout
2014-09-19 03:54:42 +00:00
& Docker.tweaked
2014-05-23 01:42:57 +00:00
2015-02-01 21:34:04 +00:00
androidAutoBuilderContainer :: (System -> Docker.Image) -> Times -> TimeOut -> Docker.Container
androidAutoBuilderContainer dockerImage crontimes timeout =
2014-05-28 14:38:29 +00:00
androidContainer dockerImage "android-git-annex-builder" (tree "android") builddir
& Apt.unattendedUpgrades
2014-07-06 19:56:56 +00:00
& autobuilder "android" crontimes timeout
2014-05-24 04:05:47 +00:00
-- Android is cross-built in a Debian i386 container, using the Android NDK.
androidContainer
:: (IsProp (Property (CInfo NoInfo i)), (Combines (Property NoInfo) (Property i)))
=> (System -> Docker.Image)
-> Docker.ContainerName
-> Property i
-> FilePath
-> Docker.Container
2014-05-28 14:38:29 +00:00
androidContainer dockerImage name setupgitannexdir gitannexdir = Docker.container name
(dockerImage osver)
& os osver
& Apt.stdSourcesList
2014-06-05 20:24:47 +00:00
& Apt.installed ["systemd"]
2014-10-16 16:13:55 +00:00
& Docker.tweaked
& User.accountFor (User builduser)
2014-05-28 15:10:55 +00:00
& File.dirExists gitbuilderdir
& File.ownerGroup homedir (User builduser) (Group builduser)
2014-10-15 04:49:39 +00:00
& buildDepsApt
2014-05-24 04:52:37 +00:00
& flagFile chrootsetup ("/chrootsetup")
2014-05-28 14:38:29 +00:00
`requires` setupgitannexdir
2014-10-16 16:13:55 +00:00
& flagFile haskellpkgsinstalled ("/haskellpkgsinstalled")
2014-05-24 04:52:37 +00:00
where
2014-05-24 04:05:47 +00:00
-- Use git-annex's android chroot setup script, which will install
2014-05-24 04:09:58 +00:00
-- ghc-android and the NDK, all build deps, etc, in the home
-- directory of the builder user.
2014-05-24 04:52:37 +00:00
chrootsetup = scriptProperty
2014-05-28 14:38:29 +00:00
[ "cd " ++ gitannexdir ++ " && ./standalone/android/buildchroot-inchroot"
2014-10-16 16:13:55 +00:00
]
haskellpkgsinstalled = userScriptProperty (User builduser)
2014-10-23 17:26:51 +00:00
[ "cd " ++ gitannexdir ++ " && ./standalone/android/install-haskell-packages"
2014-05-24 04:05:47 +00:00
]
2015-04-25 15:24:47 +00:00
osver = System (Debian Testing) "i386"
2014-05-24 04:05:47 +00:00
2014-05-23 01:42:57 +00:00
-- armel builder has a companion container using amd64 that
-- runs the build first to get TH splices. They need
-- to have the same versions of all haskell libraries installed.
armelCompanionContainer :: (System -> Docker.Image) -> Docker.Container
2014-05-23 01:42:57 +00:00
armelCompanionContainer dockerImage = Docker.container "armel-git-annex-builder-companion"
(dockerImage $ System (Debian Unstable) "amd64")
2014-06-10 03:32:53 +00:00
& os (System (Debian Testing) "amd64")
& Apt.stdSourcesList
2014-06-05 20:24:47 +00:00
& Apt.installed ["systemd"]
2014-05-23 01:42:57 +00:00
-- This volume is shared with the armel builder.
& Docker.volume gitbuilderdir
& User.accountFor (User builduser)
2014-05-23 01:42:57 +00:00
-- Install current versions of build deps from cabal.
& tree "armel"
2014-06-10 14:08:12 +00:00
& buildDepsNoHaskellLibs
2014-05-23 01:42:57 +00:00
& cabalDeps
2014-05-23 14:46:25 +00:00
-- The armel builder can ssh to this companion.
2014-05-23 01:42:57 +00:00
& Docker.expose "22"
& Apt.serviceInstalledRunning "ssh"
& Ssh.authorizedKeys (User builduser) (Context "armel-git-annex-builder")
2014-09-19 03:54:42 +00:00
& Docker.tweaked
2014-05-23 01:42:57 +00:00
2015-02-01 21:34:04 +00:00
armelAutoBuilderContainer :: (System -> Docker.Image) -> Times -> TimeOut -> Docker.Container
armelAutoBuilderContainer dockerImage crontimes timeout = Docker.container "armel-git-annex-builder"
2014-05-23 01:42:57 +00:00
(dockerImage $ System (Debian Unstable) "armel")
2014-06-10 03:32:53 +00:00
& os (System (Debian Testing) "armel")
& Apt.stdSourcesList
2014-06-05 20:24:47 +00:00
& Apt.installed ["systemd"]
2014-05-23 01:42:57 +00:00
& Apt.installed ["openssh-client"]
& Docker.link "armel-git-annex-builder-companion" "companion"
& Docker.volumes_from "armel-git-annex-builder-companion"
& User.accountFor (User builduser)
2014-05-23 01:42:57 +00:00
-- TODO: automate installing haskell libs
-- (Currently have to run
-- git-annex/standalone/linux/install-haskell-packages
-- which is not fully automated.)
2014-06-10 14:08:12 +00:00
& buildDepsNoHaskellLibs
2014-07-06 19:56:56 +00:00
& autobuilder "armel" crontimes timeout
2014-05-28 14:38:29 +00:00
`requires` tree "armel"
& Ssh.keyImported SshRsa (User builduser) (Context "armel-git-annex-builder")
2014-05-23 14:46:25 +00:00
& trivial writecompanionaddress
2014-09-19 03:54:42 +00:00
& Docker.tweaked
2014-05-23 14:46:25 +00:00
where
writecompanionaddress = scriptProperty
[ "echo \"$COMPANION_PORT_22_TCP_ADDR\" > " ++ homedir </> "companion_address"
2014-05-23 16:30:25 +00:00
] `describe` "companion_address file"