Merge branch 'joeyconfig'

This commit is contained in:
Joey Hess 2014-05-29 14:29:34 -04:00
commit 2b77ee8e10
16 changed files with 672 additions and 501 deletions

View File

@ -30,8 +30,10 @@ clean:
find -name \*.hi -exec rm {} \; find -name \*.hi -exec rm {} \;
# hothasktags chokes on some template haskell etc, so ignore errors # hothasktags chokes on some template haskell etc, so ignore errors
# duplicate tags with Propellor.Property. removed from the start, as we
# often import qualified by just the module base name.
tags: tags:
find . | grep -v /.git/ | grep -v /tmp/ | grep -v /dist/ | grep -v /doc/ | egrep '\.hs$$' | xargs hothasktags > tags 2>/dev/null find . | grep -v /.git/ | grep -v /tmp/ | grep -v /dist/ | grep -v /doc/ | egrep '\.hs$$' | xargs hothasktags | perl -ne 'print; s/Propellor\.Property\.//; print' | sort > tags 2>/dev/null
# Upload to hackage. # Upload to hackage.
hackage: hackage:

View File

@ -21,32 +21,32 @@ import qualified Propellor.Property.Git as Git
import qualified Propellor.Property.Apache as Apache import qualified Propellor.Property.Apache as Apache
import qualified Propellor.Property.Postfix as Postfix import qualified Propellor.Property.Postfix as Postfix
import qualified Propellor.Property.Service as Service import qualified Propellor.Property.Service as Service
import qualified Propellor.Property.HostingProvider.DigitalOcean as DigitalOcean
import qualified Propellor.Property.HostingProvider.CloudAtCost as CloudAtCost
import qualified Propellor.Property.SiteSpecific.GitHome as GitHome import qualified Propellor.Property.SiteSpecific.GitHome as GitHome
import qualified Propellor.Property.SiteSpecific.GitAnnexBuilder as GitAnnexBuilder import qualified Propellor.Property.SiteSpecific.GitAnnexBuilder as GitAnnexBuilder
import qualified Propellor.Property.SiteSpecific.JoeySites as JoeySites import qualified Propellor.Property.SiteSpecific.JoeySites as JoeySites
main :: IO ()
main = defaultMain hosts
main :: IO () -- _ ______`| ,-.__
-- _ ______`| ,-.__ main = defaultMain hosts -- / \___-=O`/|O`/__| (____.'
{- Propellor -- / \___-=O`/|O`/__| (____.' {- Propellor -- \ / | / ) _.-"-._
Deployed -} -- \ / | / ) _.-"-._ Deployed -} -- `/-==__ _/__|/__=-| ( \_
-- `/-==__ _/__|/__=-| ( \_ hosts :: [Host] -- * \ | | '--------'
hosts :: [Host] -- * \ | | '--------' hosts = -- (o) `
hosts = -- (o) `
-- My laptop -- My laptop
[ host "darkstar.kitenet.net" [ host "darkstar.kitenet.net"
& ipv6 "2001:4830:1600:187::2" -- sixxs tunnel & ipv6 "2001:4830:1600:187::2" -- sixxs tunnel
& Docker.configured & Docker.configured
& Apt.buildDep ["git-annex"] `period` Daily & Apt.buildDep ["git-annex"] `period` Daily
& Docker.docked hosts "android-git-annex"
-- Nothing super-important lives here. -- Nothing super-important lives here.
, standardSystem "clam.kitenet.net" Unstable "amd64" , standardSystem "clam.kitenet.net" Unstable "amd64"
& ipv4 "162.248.143.249" & ipv4 "162.248.143.249"
& ipv6 "2002:5044:5531::1" & ipv6 "2002:5044:5531::1"
& cleanCloudAtCost & CloudAtCost.decruft
& Apt.unattendedUpgrades & Apt.unattendedUpgrades
& Network.ipv6to4 & Network.ipv6to4
& Tor.isBridge & Tor.isBridge
@ -96,6 +96,7 @@ hosts = -- (o) `
& Docker.docked hosts "i386-git-annex-builder" & Docker.docked hosts "i386-git-annex-builder"
& Docker.docked hosts "armel-git-annex-builder-companion" & Docker.docked hosts "armel-git-annex-builder-companion"
& Docker.docked hosts "armel-git-annex-builder" & Docker.docked hosts "armel-git-annex-builder"
& Docker.docked hosts "android-git-annex-builder"
& Docker.garbageCollected `period` Daily & Docker.garbageCollected `period` Daily
& Apt.buildDep ["git-annex"] `period` Daily & Apt.buildDep ["git-annex"] `period` Daily
@ -103,6 +104,7 @@ hosts = -- (o) `
, standardSystem "diatom.kitenet.net" Stable "amd64" , standardSystem "diatom.kitenet.net" Stable "amd64"
& ipv4 "107.170.31.195" & ipv4 "107.170.31.195"
& DigitalOcean.distroKernel
& Hostname.sane & Hostname.sane
& Ssh.hostKey SshDsa & Ssh.hostKey SshDsa
& Ssh.hostKey SshRsa & Ssh.hostKey SshRsa
@ -189,29 +191,18 @@ hosts = -- (o) `
(Just "remotes/origin/old-kitenet.net") (Just "remotes/origin/old-kitenet.net")
-- git-annex autobuilder containers -- git-annex autobuilder containers
, gitAnnexBuilder "amd64" 15 , GitAnnexBuilder.standardAutoBuilderContainer dockerImage "amd64" 15 "2h"
, gitAnnexBuilder "i386" 45 , GitAnnexBuilder.standardAutoBuilderContainer dockerImage "i386" 45 "2h"
-- armel builder has a companion container that run amd64 and , GitAnnexBuilder.armelCompanionContainer dockerImage
-- runs the build first to get TH splices. They share a home , GitAnnexBuilder.armelAutoBuilderContainer dockerImage "1 3 * * *" "5h"
-- directory, and need to have the same versions of all haskell , GitAnnexBuilder.androidAutoBuilderContainer dockerImage "1 1 * * *" "3h"
-- libraries installed.
, Docker.container "armel-git-annex-builder-companion"
(image $ System (Debian Unstable) "amd64")
& Docker.volume GitAnnexBuilder.homedir
& Apt.unattendedUpgrades
, Docker.container "armel-git-annex-builder"
(image $ System (Debian Unstable) "armel")
& Docker.link "armel-git-annex-builder-companion" "companion"
& Docker.volumes_from "armel-git-annex-builder-companion"
-- & GitAnnexBuilder.builder "armel" "15 * * * *" True
& Apt.unattendedUpgrades
] ++ monsters
gitAnnexBuilder :: Architecture -> Int -> Host -- for development of git-annex for android, using my git-annex
gitAnnexBuilder arch buildminute = Docker.container (arch ++ "-git-annex-builder") -- work tree
(image $ System (Debian Unstable) arch) , let gitannexdir = GitAnnexBuilder.homedir </> "git-annex"
& GitAnnexBuilder.builder arch (show buildminute ++ " * * * *") True in GitAnnexBuilder.androidContainer dockerImage "android-git-annex" doNothing gitannexdir
& Apt.unattendedUpgrades & Docker.volume ("/home/joey/src/git-annex:" ++ gitannexdir)
] ++ monsters
-- This is my standard system setup. -- This is my standard system setup.
standardSystem :: HostName -> DebianSuite -> Architecture -> Host standardSystem :: HostName -> DebianSuite -> Architecture -> Host
@ -239,7 +230,7 @@ standardSystem hn suite arch = host hn
-- This is my standard container setup, featuring automatic upgrades. -- This is my standard container setup, featuring automatic upgrades.
standardContainer :: Docker.ContainerName -> DebianSuite -> Architecture -> Host standardContainer :: Docker.ContainerName -> DebianSuite -> Architecture -> Host
standardContainer name suite arch = Docker.container name (image system) standardContainer name suite arch = Docker.container name (dockerImage system)
& os (System (Debian suite) arch) & os (System (Debian suite) arch)
& Apt.stdSourcesList suite & Apt.stdSourcesList suite
& Apt.unattendedUpgrades & Apt.unattendedUpgrades
@ -247,42 +238,10 @@ standardContainer name suite arch = Docker.container name (image system)
system = System (Debian suite) arch system = System (Debian suite) arch
-- Docker images I prefer to use. -- Docker images I prefer to use.
image :: System -> Docker.Image dockerImage :: System -> Docker.Image
image (System (Debian Unstable) arch) = "joeyh/debian-unstable-" ++ arch dockerImage (System (Debian Unstable) arch) = "joeyh/debian-unstable-" ++ arch
image (System (Debian Stable) arch) = "joeyh/debian-stable-" ++ arch dockerImage (System (Debian Stable) arch) = "joeyh/debian-stable-" ++ arch
image _ = "debian-stable-official" -- does not currently exist! dockerImage _ = "debian-stable-official" -- does not currently exist!
-- Digital Ocean does not provide any way to boot
-- the kernel provided by the distribution, except using kexec.
-- Without this, some old, and perhaps insecure kernel will be used.
--
-- Note that this only causes the new kernel to be loaded on reboot.
-- If the power is cycled, the old kernel still boots up.
-- TODO: detect this and reboot immediately?
digitalOceanDistroKernel :: Property
digitalOceanDistroKernel = propertyList "digital ocean distro kernel hack"
[ Apt.installed ["grub-pc", "kexec-tools"]
, "/etc/default/kexec" `File.containsLines`
[ "LOAD_KEXEC=true"
, "USE_GRUB_CONFIG=true"
]
]
-- Clean up a system as installed by cloudatcost.com
cleanCloudAtCost :: Property
cleanCloudAtCost = propertyList "cloudatcost cleanup"
[ Hostname.sane
, Ssh.randomHostKeys
, "worked around grub/lvm boot bug #743126" ==>
"/etc/default/grub" `File.containsLine` "GRUB_DISABLE_LINUX_UUID=true"
`onChange` cmdProperty "update-grub" []
`onChange` cmdProperty "update-initramfs" ["-u"]
, combineProperties "nuked cloudatcost cruft"
[ File.notPresent "/etc/rc.local"
, File.notPresent "/etc/init.d/S97-setup.sh"
, User.nuked "user" User.YesReallyDeleteHome
]
]
myDnsSecondary :: Property myDnsSecondary :: Property
myDnsSecondary = propertyList "dns secondary for all my domains" $ map toProp myDnsSecondary = propertyList "dns secondary for all my domains" $ map toProp
@ -347,7 +306,6 @@ monsters = -- but do want to track their public keys etc.
& alias "wortroot.kitenet.net" & alias "wortroot.kitenet.net"
& alias "www.wortroot.kitenet.net" & alias "www.wortroot.kitenet.net"
& alias "joey.kitenet.net" & alias "joey.kitenet.net"
& alias "annex.kitenet.net"
& alias "ipv6.kitenet.net" & alias "ipv6.kitenet.net"
& alias "bitlbee.kitenet.net" & alias "bitlbee.kitenet.net"
, host "mouse.kitenet.net" , host "mouse.kitenet.net"

3
debian/changelog vendored
View File

@ -1,6 +1,9 @@
propellor (0.5.3) UNRELEASED; urgency=medium propellor (0.5.3) UNRELEASED; urgency=medium
* Fix unattended-upgrades config for !stable. * Fix unattended-upgrades config for !stable.
* Ensure that kernel hostname is same as /etc/hostname when configuring
hostname.
* Added modules for some hosting providers (DigitalOcean, CloudAtCost).
-- Joey Hess <joeyh@debian.org> Sun, 18 May 2014 13:44:00 -0400 -- Joey Hess <joeyh@debian.org> Sun, 18 May 2014 13:44:00 -0400

View File

@ -1,366 +1,366 @@
-----BEGIN PGP MESSAGE----- -----BEGIN PGP MESSAGE-----
Version: GnuPG v1 Version: GnuPG v1
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 zJs2Sje36Yv0hOsZrSngt65Ag83Ou4MkqI9y8SK65eTGVxKknPZTQYXzKsDO7enV
lKOkZjb9nqWpvZYuHinIYnO3yKm3XkvYcpr+vffujS1oT1XQmt1yijLiI2DwL6wt 49r88FVV9TIZJmhlo2pMyGLeb/ZDZnbjrSNudFnSHWGGQo0dVwuNabooLAba8B2s
libiViET2PsCvb1u0a4aMEHSliGJP7ul9mPiEV4F+B54+hAyUKBx5eZxRvCPi+vp pb7Id6LiAKBbMEH7MfeKdyXKwHuO3gIbzvZ+TiVNtdnqGiixxPd9++Z85D0GXBp0
yoc4gdhIKB4swA8dx1nVUALSCcqV57iHi1G51t99rbUb3gIwOqqU2eP/XUi/UBVB xQu5iVnnHelcmQP3XDC8J+wHP+9rO6LIXwd+7jwiC+Eojn4+9CkX7gke3oaNNbjZ
8i/4KlnQDNk2clPjWNxC7V4y2T++sbOwWymQrXdFvVirtuxp/SNhAJyJCOLkBSrV 4HKL0dG+zuimftYIy3s/+XQ/fyXj4iApi+fo7sjaew+j1/TKU/279g/Icct5en0C
MB92BPXmkFBdPTsuRsdaRnIWooYmKS96HxU6pnmFJFYSAGChxYhajzL40xITksOH lVTrsuoJfnMOuiId7G4raycjPFDeQY03dFYqqsFwnFAu7raj/+4ig6chrSwkgKNv
ad3AXvFHaJFe5GFGv5iu6X912gYydIJLutEyc9rg8/tL0G9rCb6wSKWNv0ZSoUms HJQ56h+bbin9Ug8tb0SgMFo2eBD9Gh5GJ8pKmYcefBvYXX3O9sb279SWpU37TczN
DC3vcA4fTZoWyXdVkjaZEKe7exbRwC08xLw5YGO/vKCnOBlj7+JsPZSqosTXLqX0 apF7VSslTVQqAQBZJGjmjlsSKdKhoXLcE6cic1RfH3RDxJ+amcr3bvnuG2RSg6Mf
RBBeYoqiHx6N0GBa80icYq4atRr2w/kbc4WhXNMDpNdALskfKzbPLViXpVgr8jvT sYqukcYtmOxlNk/wN+8piUDN0plRJFVtg7Yl/jhtKMmIzZMvLvvJgBqAt93ZfGBZ
1JZLfswiAUXACcULH4A4KnkitdkFTTBMxHrbDEjmhPyGfNVyIDWzyz8qFCe+LHaG cOml1FuR5ydFPiWEooMvNasrEvSwJoWXJVhL3g3v5WWEbC/PDM77kc5x3esH8g9F
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
ZeWCt3M2QDPYox2/qZBR23+JUsiT h2hkqPastvDLosRzCFpEhIUpefbTIdmgmstdua9jVJiK8w==
=n+YJ =RrAw
-----END PGP MESSAGE----- -----END PGP MESSAGE-----

View File

@ -1,22 +1,57 @@
-----BEGIN PGP MESSAGE----- -----BEGIN PGP MESSAGE-----
Version: GnuPG v1 Version: GnuPG v1
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
=usce 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
=ZBoU
-----END PGP MESSAGE----- -----END PGP MESSAGE-----

View File

@ -1,7 +1,7 @@
Name: propellor Name: propellor
Version: 0.5.2 Version: 0.5.2
Cabal-Version: >= 1.6 Cabal-Version: >= 1.6
License: BSD License: BSD3
Maintainer: Joey Hess <joey@kitenet.net> Maintainer: Joey Hess <joey@kitenet.net>
Author: Joey Hess Author: Joey Hess
Stability: Stable Stability: Stable
@ -92,6 +92,8 @@ Library
Propellor.Property.Sudo Propellor.Property.Sudo
Propellor.Property.Tor Propellor.Property.Tor
Propellor.Property.User Propellor.Property.User
Propellor.Property.HostingProvider.DigitalOcean
Propellor.Property.HostingProvider.CloudAtCost
Propellor.Property.SiteSpecific.GitHome Propellor.Property.SiteSpecific.GitHome
Propellor.Property.SiteSpecific.JoeySites Propellor.Property.SiteSpecific.JoeySites
Propellor.Property.SiteSpecific.GitAnnexBuilder Propellor.Property.SiteSpecific.GitAnnexBuilder

View File

@ -103,6 +103,9 @@ trivial p = adjustProperty p $ \satisfy -> do
then return NoChange then return NoChange
else return r else return r
doNothing :: Property
doNothing = property "noop property" noChange
-- | Makes a property that is satisfied differently depending on the host's -- | Makes a property that is satisfied differently depending on the host's
-- operating system. -- operating system.
-- --

View File

@ -156,6 +156,10 @@ name = runProp "name"
publish :: String -> Property publish :: String -> Property
publish = runProp "publish" publish = runProp "publish"
-- | Expose a container's port without publishing it.
expose :: String -> Property
expose = runProp "expose"
-- | Username or UID for container. -- | Username or UID for container.
user :: String -> Property user :: String -> Property
user = runProp "user" user = runProp "user"

View File

@ -0,0 +1,24 @@
module Propellor.Property.HostingProvider.CloudAtCost where
import Propellor
import qualified Propellor.Property.Hostname as Hostname
import qualified Propellor.Property.File as File
import qualified Propellor.Property.Ssh as Ssh
import qualified Propellor.Property.User as User
-- Clean up a system as installed by cloudatcost.com
decruft :: Property
decruft = propertyList "cloudatcost cleanup"
[ Hostname.sane
, Ssh.randomHostKeys
, "worked around grub/lvm boot bug #743126" ==>
"/etc/default/grub" `File.containsLine` "GRUB_DISABLE_LINUX_UUID=true"
`onChange` cmdProperty "update-grub" []
`onChange` cmdProperty "update-initramfs" ["-u"]
, combineProperties "nuked cloudatcost cruft"
[ File.notPresent "/etc/rc.local"
, File.notPresent "/etc/init.d/S97-setup.sh"
, User.nuked "user" User.YesReallyDeleteHome
]
]

View File

@ -0,0 +1,21 @@
module Propellor.Property.HostingProvider.DigitalOcean where
import Propellor
import qualified Propellor.Property.Apt as Apt
import qualified Propellor.Property.File as File
-- Digital Ocean does not provide any way to boot
-- the kernel provided by the distribution, except using kexec.
-- Without this, some old, and perhaps insecure kernel will be used.
--
-- Note that this only causes the new kernel to be loaded on reboot.
-- If the power is cycled, the old kernel still boots up.
-- TODO: detect this and reboot immediately?
distroKernel :: Property
distroKernel = propertyList "digital ocean distro kernel hack"
[ Apt.installed ["grub-pc", "kexec-tools"]
, "/etc/default/kexec" `File.containsLines`
[ "LOAD_KEXEC=true"
, "USE_GRUB_CONFIG=true"
] `describe` "kexec configured"
]

View File

@ -13,7 +13,6 @@ sane = property ("sane hostname") (ensureProperty . setTo =<< getHostName)
setTo :: HostName -> Property setTo :: HostName -> Property
setTo hn = combineProperties desc go setTo hn = combineProperties desc go
`onChange` cmdProperty "hostname" [basehost]
where where
desc = "hostname " ++ hn desc = "hostname " ++ hn
(basehost, domain) = separate (== '.') hn (basehost, domain) = separate (== '.') hn
@ -24,6 +23,7 @@ setTo hn = combineProperties desc go
then Nothing then Nothing
else Just $ File.fileProperty desc else Just $ File.fileProperty desc
addhostline "/etc/hosts" addhostline "/etc/hosts"
, Just $ trivial $ cmdProperty "hostname" [basehost]
] ]
hostip = "127.0.1.1" hostip = "127.0.1.1"

View File

@ -4,6 +4,9 @@ import Propellor
import qualified Propellor.Property.Apt as Apt import qualified Propellor.Property.Apt as Apt
import qualified Propellor.Property.User as User import qualified Propellor.Property.User as User
import qualified Propellor.Property.Cron as Cron import qualified Propellor.Property.Cron as Cron
import qualified Propellor.Property.Ssh as Ssh
import qualified Propellor.Property.File as File
import qualified Propellor.Property.Docker as Docker
import Propellor.Property.Cron (CronTimes) import Propellor.Property.Cron (CronTimes)
builduser :: UserName builduser :: UserName
@ -18,25 +21,13 @@ gitbuilderdir = homedir </> "gitbuilder"
builddir :: FilePath builddir :: FilePath
builddir = gitbuilderdir </> "build" builddir = gitbuilderdir </> "build"
builder :: Architecture -> CronTimes -> Bool -> Property type TimeOut = String -- eg, 5h
builder arch crontimes rsyncupload = combineProperties "gitannexbuilder"
[ Apt.stdSourcesList Unstable autobuilder :: CronTimes -> TimeOut -> Bool -> Property
, Apt.buildDep ["git-annex"] autobuilder crontimes timeout rsyncupload = combineProperties "gitannexbuilder"
, Apt.installed ["git", "rsync", "moreutils", "ca-certificates", [ Apt.serviceInstalledRunning "cron"
"liblockfile-simple-perl", "cabal-install", "vim", "less"] , Cron.niceJob "gitannexbuilder" crontimes builduser gitbuilderdir $
, Apt.serviceInstalledRunning "cron" "git pull ; timeout " ++ timeout ++ " ./autobuild"
, User.accountFor builduser
, check (not <$> doesDirectoryExist gitbuilderdir) $ userScriptProperty builduser
[ "git clone git://git.kitenet.net/gitannexbuilder " ++ gitbuilderdir
, "cd " ++ gitbuilderdir
, "git checkout " ++ arch
]
`describe` "gitbuilder setup"
, check (not <$> doesDirectoryExist builddir) $ userScriptProperty builduser
[ "git clone git://git-annex.branchable.com/ " ++ builddir
]
, "git-annex source build deps installed" ==> Apt.buildDepIn builddir
, Cron.niceJob "gitannexbuilder" crontimes builduser gitbuilderdir "git pull ; ./autobuild"
-- The builduser account does not have a password set, -- The builduser account does not have a password set,
-- instead use the password privdata to hold the rsync server -- instead use the password privdata to hold the rsync server
-- password used to upload the built image. -- password used to upload the built image.
@ -55,3 +46,131 @@ builder arch crontimes rsyncupload = combineProperties "gitannexbuilder"
, makeChange $ writeFile f "no password configured" , makeChange $ writeFile f "no password configured"
) )
] ]
tree :: Architecture -> Property
tree buildarch = combineProperties "gitannexbuilder tree"
[ Apt.installed ["git"]
-- 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"
, check (not <$> doesDirectoryExist builddir) $ userScriptProperty builduser
[ "git clone git://git-annex.branchable.com/ " ++ builddir
]
]
buildDepsApt :: Property
buildDepsApt = combineProperties "gitannexbuilder build deps"
[ Apt.buildDep ["git-annex"]
, buildDepsFewHaskellLibs
, "git-annex source build deps installed" ==> Apt.buildDepIn builddir
]
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"]
]
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",
"alex", "happy", "c2hs"
]
-- 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"
standardAutoBuilderContainer :: (System -> Docker.Image) -> Architecture -> Int -> TimeOut -> Host
standardAutoBuilderContainer dockerImage arch buildminute timeout = Docker.container (arch ++ "-git-annex-builder")
(dockerImage $ System (Debian Unstable) arch)
& Apt.stdSourcesList Unstable
& Apt.unattendedUpgrades
& buildDepsApt
& autobuilder (show buildminute ++ " * * * *") timeout True
`requires` tree arch
androidAutoBuilderContainer :: (System -> Docker.Image) -> Cron.CronTimes -> TimeOut -> Host
androidAutoBuilderContainer dockerImage crontimes timeout =
androidContainer dockerImage "android-git-annex-builder" (tree "android") builddir
& Apt.unattendedUpgrades
& autobuilder crontimes timeout True
-- Android is cross-built in a Debian i386 container, using the Android NDK.
androidContainer :: (System -> Docker.Image) -> Docker.ContainerName -> Property -> FilePath -> Host
androidContainer dockerImage name setupgitannexdir gitannexdir = Docker.container name
(dockerImage $ System (Debian Stable) "i386")
& Apt.stdSourcesList Stable
& User.accountFor builduser
& File.dirExists gitbuilderdir
& File.ownerGroup homedir builduser builduser
& buildDepsNoHaskellLibs
& flagFile chrootsetup ("/chrootsetup")
`requires` setupgitannexdir
-- TODO: automate installing haskell libs
-- (Currently have to run
-- git-annex/standalone/android/install-haskell-packages
-- which is not fully automated.)
where
-- Use git-annex's android chroot setup script, which will install
-- ghc-android and the NDK, all build deps, etc, in the home
-- directory of the builder user.
chrootsetup = scriptProperty
[ "cd " ++ gitannexdir ++ " && ./standalone/android/buildchroot-inchroot"
]
-- 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"
& buildDepsFewHaskellLibs
& cabalDeps
-- The armel builder can ssh to this companion.
& 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"
(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
& autobuilder crontimes timeout True
`requires` tree "armel"
& Ssh.keyImported SshRsa builduser
& trivial writecompanionaddress
where
writecompanionaddress = scriptProperty
[ "echo \"$COMPANION_PORT_22_TCP_ADDR\" > " ++ homedir </> "companion_address"
] `describe` "companion_address file"

View File

@ -141,7 +141,10 @@ gitServer hosts = propertyList "git.kitenet.net setup"
`requires` Ssh.knownHost hosts "usw-s002.rsync.net" "root" `requires` Ssh.knownHost hosts "usw-s002.rsync.net" "root"
`requires` Ssh.authorizedKeys "family" `requires` Ssh.authorizedKeys "family"
`requires` User.accountFor "family" `requires` User.accountFor "family"
, Apt.installed ["git", "rsync", "kgb-client-git", "gitweb"] , Apt.installed ["git", "rsync", "gitweb"]
-- backport avoids channel flooding on branch merge
, Apt.installedBackport ["kgb-client"]
-- backport supports ssh event notification
, Apt.installedBackport ["git-annex"] , Apt.installedBackport ["git-annex"]
, File.hasPrivContentExposed "/etc/kgb-bot/kgb-client.conf" , File.hasPrivContentExposed "/etc/kgb-bot/kgb-client.conf"
, toProp $ Git.daemonRunning "/srv/git" , toProp $ Git.daemonRunning "/srv/git"
@ -264,9 +267,11 @@ gitAnnexDistributor :: Property
gitAnnexDistributor = combineProperties "git-annex distributor, including rsync server and signer" gitAnnexDistributor = combineProperties "git-annex distributor, including rsync server and signer"
[ Apt.installed ["rsync"] [ Apt.installed ["rsync"]
, File.hasPrivContent "/etc/rsyncd.conf" , File.hasPrivContent "/etc/rsyncd.conf"
`onChange` Service.restarted "rsync"
, File.hasPrivContent "/etc/rsyncd.secrets" , File.hasPrivContent "/etc/rsyncd.secrets"
`onChange` Service.restarted "rsync"
, "/etc/default/rsync" `File.containsLine` "RSYNC_ENABLE=true" , "/etc/default/rsync" `File.containsLine` "RSYNC_ENABLE=true"
`onChange` Service.running "rsync" `onChange` Service.running "rsync"
, endpoint "/srv/web/downloads.kitenet.net/git-annex/autobuild" , endpoint "/srv/web/downloads.kitenet.net/git-annex/autobuild"
, endpoint "/srv/web/downloads.kitenet.net/git-annex/autobuild/x86_64-apple-mavericks" , endpoint "/srv/web/downloads.kitenet.net/git-annex/autobuild/x86_64-apple-mavericks"
-- git-annex distribution signing key -- git-annex distribution signing key

View File

@ -107,11 +107,13 @@ keyImported keytype user = combineProperties desc
f <- liftIO $ keyfile ext f <- liftIO $ keyfile ext
ifM (liftIO $ doesFileExist f) ifM (liftIO $ doesFileExist f)
( noChange ( noChange
, ensureProperty $ combineProperties desc , ensureProperties
[ property desc $ [ property desc $
withPrivData p $ \key -> makeChange $ withPrivData p $ \key -> makeChange $ do
createDirectoryIfMissing True (takeDirectory f)
writer f key writer f key
, File.ownerGroup f user user , File.ownerGroup f user user
, File.ownerGroup (takeDirectory f) user user
] ]
) )
keyfile ext = do keyfile ext = do
@ -149,4 +151,7 @@ authorizedKeys user = property (user ++ " has authorized_keys") $
liftIO $ do liftIO $ do
createDirectoryIfMissing True (takeDirectory f) createDirectoryIfMissing True (takeDirectory f)
writeFileProtected f v writeFileProtected f v
ensureProperty $ File.ownerGroup f user user ensureProperties
[ File.ownerGroup f user user
, File.ownerGroup (takeDirectory f) user user
]

View File

@ -1,6 +1,5 @@
{-# LANGUAGE PackageImports #-} {-# LANGUAGE PackageImports #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE ExistentialQuantification #-}
module Propellor.Types module Propellor.Types
( Host(..) ( Host(..)
@ -35,6 +34,8 @@ import Propellor.Types.Attr
import Propellor.Types.OS import Propellor.Types.OS
import Propellor.Types.Dns import Propellor.Types.Dns
-- | Everything Propellor knows about a system: Its properties and
-- attributes.
data Host = Host [Property] SetAttr data Host = Host [Property] SetAttr
-- | Propellor's monad provides read-only access to attributes of the -- | Propellor's monad provides read-only access to attributes of the

View File

@ -167,10 +167,10 @@ processTranscript :: String -> [String] -> (Maybe String) -> IO (String, Bool)
processTranscript cmd opts input = processTranscript' cmd opts Nothing input processTranscript cmd opts input = processTranscript' cmd opts Nothing input
processTranscript' :: String -> [String] -> Maybe [(String, String)] -> (Maybe String) -> IO (String, Bool) processTranscript' :: String -> [String] -> Maybe [(String, String)] -> (Maybe String) -> IO (String, Bool)
processTranscript' cmd opts environ input = do
#ifndef mingw32_HOST_OS #ifndef mingw32_HOST_OS
{- This implementation interleves stdout and stderr in exactly the order {- This implementation interleves stdout and stderr in exactly the order
- the process writes them. -} - the process writes them. -}
processTranscript' cmd opts environ input = do
(readf, writef) <- createPipe (readf, writef) <- createPipe
readh <- fdToHandle readf readh <- fdToHandle readf
writeh <- fdToHandle writef writeh <- fdToHandle writef
@ -184,24 +184,13 @@ processTranscript' cmd opts environ input = do
hClose writeh hClose writeh
get <- mkreader readh get <- mkreader readh
writeinput input p
-- now write and flush any input
case input of
Just s -> do
let inh = stdinHandle p
unless (null s) $ do
hPutStr inh s
hFlush inh
hClose inh
Nothing -> return ()
transcript <- get transcript <- get
ok <- checkSuccessProcess pid ok <- checkSuccessProcess pid
return (transcript, ok) return (transcript, ok)
#else #else
{- This implementation for Windows puts stderr after stdout. -} {- This implementation for Windows puts stderr after stdout. -}
processTranscript' cmd opts environ input = do
p@(_, _, _, pid) <- createProcess $ p@(_, _, _, pid) <- createProcess $
(proc cmd opts) (proc cmd opts)
{ std_in = if isJust input then CreatePipe else Inherit { std_in = if isJust input then CreatePipe else Inherit
@ -212,17 +201,9 @@ processTranscript' cmd opts environ input = do
getout <- mkreader (stdoutHandle p) getout <- mkreader (stdoutHandle p)
geterr <- mkreader (stderrHandle p) geterr <- mkreader (stderrHandle p)
writeinput input p
case input of
Just s -> do
let inh = stdinHandle p
unless (null s) $ do
hPutStr inh s
hFlush inh
hClose inh
Nothing -> return ()
transcript <- (++) <$> getout <*> geterr transcript <- (++) <$> getout <*> geterr
ok <- checkSuccessProcess pid ok <- checkSuccessProcess pid
return (transcript, ok) return (transcript, ok)
#endif #endif
@ -237,6 +218,14 @@ processTranscript' cmd opts environ input = do
takeMVar v takeMVar v
return s return s
writeinput (Just s) p = do
let inh = stdinHandle p
unless (null s) $ do
hPutStr inh s
hFlush inh
hClose inh
writeinput Nothing _ = return ()
{- Runs a CreateProcessRunner, on a CreateProcess structure, that {- Runs a CreateProcessRunner, on a CreateProcess structure, that
- is adjusted to pipe only from/to a single StdHandle, and passes - is adjusted to pipe only from/to a single StdHandle, and passes
- the resulting Handle to an action. -} - the resulting Handle to an action. -}