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

173 lines
6.5 KiB
Haskell
Raw Normal View History

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
2014-04-01 20:58:11 +00:00
import Propellor.Property.Cron (CronTimes)
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
builder :: Architecture -> CronTimes -> TimeOut -> Bool -> Property
builder buildarch crontimes timeout rsyncupload = combineProperties "gitannexbuilder"
2014-05-20 22:28:13 +00:00
[ tree buildarch
2014-04-08 23:31:03 +00:00
, Apt.serviceInstalledRunning "cron"
2014-05-19 21:27:21 +00:00
, Cron.niceJob "gitannexbuilder" crontimes builduser gitbuilderdir $
"git pull ; timeout " ++ timeout ++ " ./autobuild"
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.
, property "rsync password" $ do
2014-04-08 05:42:59 +00:00
let f = homedir </> "rsyncpassword"
if rsyncupload
then withPrivData (Password builduser) $ \p -> do
oldp <- liftIO $ catchDefaultIO "" $
readFileStrict f
if p /= oldp
then makeChange $ writeFile f p
else noChange
else do
ifM (liftIO $ doesFileExist f)
( noChange
, makeChange $ writeFile f "no password configured"
)
2014-04-01 20:58:11 +00:00
]
2014-05-19 21:27:21 +00:00
2014-05-20 22:28:13 +00:00
tree :: Architecture -> Property
tree buildarch = combineProperties "gitannexbuilder tree"
[ User.accountFor builduser
, 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 builduser builduser
, check (not <$> (doesDirectoryExist (gitbuilderdir </> ".git"))) $
userScriptProperty builduser
[ "git clone git://git.kitenet.net/gitannexbuilder " ++ gitbuilderdir
, "cd " ++ gitbuilderdir
, "git checkout " ++ buildarch
]
`describe` "gitbuilder setup"
2014-05-19 21:27:21 +00:00
, check (not <$> doesDirectoryExist builddir) $ userScriptProperty builduser
[ "git clone git://git-annex.branchable.com/ " ++ builddir
]
2014-05-20 22:28:13 +00:00
]
buildDepsApt :: Property
buildDepsApt = combineProperties "gitannexbuilder build deps"
2014-05-20 23:49:07 +00:00
[ Apt.buildDep ["git-annex"]
2014-05-26 22:46:42 +00:00
, buildDepsFewHaskellLibs
2014-05-19 21:27:21 +00:00
, "git-annex source build deps installed" ==> Apt.buildDepIn builddir
]
2014-05-26 22:46:42 +00:00
buildDepsFewHaskellLibs :: Property
buildDepsFewHaskellLibs = combineProperties "gitannexbuilder build deps"
[ buildDepsNoHaskellLibs
-- these haskell libs depend on C libs and don't use TH
, Apt.installed ["libghc-dbus-dev", "libghc-fdo-notify-dev", "libghc-network-protocol-xmpp-dev"]
]
2014-05-20 22:28:13 +00:00
buildDepsNoHaskellLibs :: Property
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-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
cabalDeps = flagFile go cabalupdated
where
go = userScriptProperty builduser ["cabal update && cabal install git-annex --only-dependencies || true"]
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 -> Host
standardAutoBuilderContainer dockerImage arch buildminute timeout = Docker.container (arch ++ "-git-annex-builder")
2014-05-23 01:42:57 +00:00
(dockerImage $ System (Debian Unstable) arch)
& Apt.stdSourcesList Unstable
& Apt.unattendedUpgrades
& buildDepsApt
2014-05-23 01:42:57 +00:00
& builder arch (show buildminute ++ " * * * *") timeout True
androidAutoBuilderContainer :: (System -> Docker.Image) -> Cron.CronTimes -> TimeOut -> Host
androidAutoBuilderContainer dockerImage crontimes timeout =
androidContainer dockerImage "android-git-annex-builder"
& Apt.unattendedUpgrades
& builder "android" crontimes timeout True
2014-05-24 04:05:47 +00:00
-- Android is cross-built in a Debian i386 container, using the Android NDK.
androidContainer :: (System -> Docker.Image) -> Docker.ContainerName -> Host
androidContainer dockerImage name = Docker.container name
2014-05-24 04:05:47 +00:00
(dockerImage $ System (Debian Stable) "i386")
& Apt.stdSourcesList Stable
& buildDepsNoHaskellLibs
2014-05-24 04:52:37 +00:00
& flagFile chrootsetup ("/chrootsetup")
-- TODO: automate installing haskell libs
-- (Currently have to run
-- git-annex/standalone/android/install-haskell-packages
-- which is not fully automated.)
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-24 04:05:47 +00:00
[ "cd " ++ builddir ++ " && ./standalone/android/buildchroot-inchroot"
]
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) -> Host
armelCompanionContainer dockerImage = Docker.container "armel-git-annex-builder-companion"
(dockerImage $ System (Debian Unstable) "amd64")
& Apt.stdSourcesList Unstable
& Apt.unattendedUpgrades
-- This volume is shared with the armel builder.
& Docker.volume gitbuilderdir
-- Install current versions of build deps from cabal.
& tree "armel"
2014-05-26 22:46:42 +00:00
& buildDepsFewHaskellLibs
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 builduser
armelAutoBuilderContainer :: (System -> Docker.Image) -> Cron.CronTimes -> TimeOut -> Host
armelAutoBuilderContainer dockerImage crontimes timeout = Docker.container "armel-git-annex-builder"
2014-05-23 01:42:57 +00:00
(dockerImage $ System (Debian Unstable) "armel")
& Apt.stdSourcesList Unstable
& Apt.unattendedUpgrades
& Apt.installed ["openssh-client"]
& Docker.link "armel-git-annex-builder-companion" "companion"
& Docker.volumes_from "armel-git-annex-builder-companion"
-- TODO: automate installing haskell libs
-- (Currently have to run
-- git-annex/standalone/linux/install-haskell-packages
-- which is not fully automated.)
& buildDepsFewHaskellLibs
& builder "armel" crontimes timeout True
2014-05-23 01:42:57 +00:00
& Ssh.keyImported SshRsa builduser
2014-05-23 14:46:25 +00:00
& trivial writecompanionaddress
where
writecompanionaddress = scriptProperty
[ "echo \"$COMPANION_PORT_22_TCP_ADDR\" > " ++ homedir </> "companion_address"
2014-05-23 16:30:25 +00:00
] `describe` "companion_address file"