summaryrefslogtreecommitdiff
path: root/src/Propellor/Property/SiteSpecific/GitAnnexBuilder.hs
blob: 1dbdbca7a98570b9564109a7a7863fb538fec227 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
module Propellor.Property.SiteSpecific.GitAnnexBuilder where

import Propellor
import qualified Propellor.Property.Apt as Apt
import qualified Propellor.Property.User as User
import qualified Propellor.Property.Cron as Cron
import Propellor.Property.Cron (CronTimes)

builduser :: UserName
builduser = "builder"

homedir :: FilePath
homedir = "/home/builder"

gitbuilderdir :: FilePath
gitbuilderdir = homedir </> "gitbuilder"

builddir :: FilePath
builddir = gitbuilderdir </> "build"

type TimeOut = String -- eg, 5h

builder :: Architecture -> CronTimes -> TimeOut -> Bool -> Property
builder = builder' buildDeps

builder' :: Property -> Architecture -> CronTimes -> TimeOut -> Bool -> Property
builder' buildepsprop buildarch crontimes timeout rsyncupload = combineProperties "gitannexbuilder"
	[ tree buildarch
	, buildepsprop
	, Apt.serviceInstalledRunning "cron"
	, Cron.niceJob "gitannexbuilder" crontimes builduser gitbuilderdir $
		"git pull ; timeout " ++ timeout ++ " ./autobuild"
	-- 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
		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"
					)
	]

tree :: Architecture -> Property
tree buildarch = combineProperties "gitannexbuilder tree"
	[ User.accountFor builduser
	, Apt.installed ["git"]
	, check (not <$> doesDirectoryExist gitbuilderdir) $ userScriptProperty builduser
		[ "git clone git://git.kitenet.net/gitannexbuilder " ++ gitbuilderdir
		, "cd " ++ gitbuilderdir
		, "git checkout " ++ buildarch
		]
		`describe` "gitbuilder setup"
	, check (not <$> doesDirectoryExist builddir) $ userScriptProperty builduser
		[ "git clone git://git-annex.branchable.com/ " ++ builddir
		]
	]

buildDeps :: Property
buildDeps = combineProperties "gitannexbuilder build deps"
	[ Apt.stdSourcesList Unstable
	, Apt.buildDep ["git-annex"]
	, buildDepsNoHaskellLibs
	, "git-annex source build deps installed" ==> Apt.buildDepIn builddir
	]

buildDepsNoHaskellLibs :: Property
buildDepsNoHaskellLibs = Apt.installed ["git", "rsync", "moreutils", "ca-certificates",
	"debhelper", "ghc", "curl", "openssh-client", "git-remote-gcrypt",
	"liblockfile-simple-perl", "cabal-install", "vim", "less"]

-- 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"

-- Ensure a ssh key is set up, and allow it to be used to ssh in
sshKeyGen :: Property
sshKeyGen = combineProperties "sshkeygen"
	[ flagFile gen privkey
	, flagFile auth authkeys
	]
  where
  	gen = userScriptProperty builduser ["ssh-keygen -t RSA -N '' -f " ++ privkey]
	auth = userScriptProperty builduser ["cp " ++ pubkey ++ " " ++ authkeys]
	privkey = homedir </> ".ssh" </> "id_rsa"
	pubkey = privkey ++ ".pub"
	authkeys = homedir </> ".ssh" </> "authorized_keys"