propellor 0.2.0 → 0.2.1
raw patch · 23 files changed
+362/−92 lines, 23 filesdep ~basenew-component:exe:config
Dependency ranges changed: base
Files
- .gitignore +5/−0
- CHANGELOG +7/−1
- Makefile +21/−6
- Propellor/CmdLine.hs +4/−3
- Propellor/Property.hs +11/−0
- Propellor/Property/Apt.hs +24/−7
- Propellor/Property/Docker.hs +18/−13
- Propellor/Property/SiteSpecific/GitAnnexBuilder.hs +17/−9
- README.md +41/−34
- TODO +1/−5
- config.hs +5/−4
- debian/README +0/−1
- debian/README.Debian +7/−0
- debian/changelog +7/−1
- debian/compat +1/−0
- debian/control +36/−0
- debian/copyright +11/−0
- debian/lintian-overrides +3/−0
- debian/propellor.1 +15/−0
- debian/rules +14/−0
- propellor.cabal +22/−7
- propellor.hs +91/−0
- simple-config.hs +1/−1
+ .gitignore view
@@ -0,0 +1,5 @@+dist/*+propellor+tags+privdata/local+privdata/keyring.gpg~
CHANGELOG view
@@ -1,4 +1,10 @@-propellor (0.2) unstable; urgency=low+propellor (0.2.1) unstable; urgency=medium++ * First release with Debian package.++ -- Joey Hess <joeyh@debian.org> Thu, 03 Apr 2014 01:43:14 -0400++propellor (0.2.0) unstable; urgency=low * Added support for provisioning Docker containers. * Bootstrap deployment now pushes the git repo to the remote host
Makefile view
@@ -1,25 +1,40 @@-run: build+CABAL?=cabal++run: deps build ./propellor dev: build tags -build: deps dist/setup-config- if ! cabal build; then cabal configure; cabal build; fi- ln -sf dist/build/propellor/propellor+build: dist/setup-config+ if ! $(CABAL) build; then $(CABAL) configure; $(CABAL) build; fi+ ln -sf dist/build/config/config propellor deps: @if [ $$(whoami) = root ]; then apt-get -y install gnupg ghc cabal-install libghc-missingh-dev libghc-ansi-terminal-dev libghc-ifelse-dev libghc-unix-compat-dev libghc-hslogger-dev libghc-network-dev libghc-async-dev; fi || true dist/setup-config: propellor.cabal- cabal configure+ if [ "$(CABAL)" = ./Setup ]; then ghc --make Setup; fi+ $(CABAL) configure +install:+ install -d $(DESTDIR)/usr/bin $(DESTDIR)/usr/src/propellor+ install -s dist/build/propellor/propellor $(DESTDIR)/usr/bin+ $(CABAL) sdist+ cat dist/propellor-*.tar.gz | \+ (cd $(DESTDIR)/usr/src/propellor && tar zx --strip-components=1)+ clean:- rm -rf dist Setup tags propellor privdata/local+ rm -rf dist Setup tags propellor propellor-wrapper privdata/local find -name \*.o -exec rm {} \; find -name \*.hi -exec rm {} \; # hothasktags chokes on some template haskell etc, so ignore errors tags: find . | grep -v /.git/ | grep -v /tmp/ | grep -v /dist/ | grep -v /doc/ | egrep '\.hs$$' | xargs hothasktags > tags 2>/dev/null++# Upload to hackage.+hackage:+ @cabal sdist+ @cabal upload dist/*.tar.gz .PHONY: tags
Propellor/CmdLine.hs view
@@ -74,9 +74,10 @@ headMaybe $ catMaybes $ map (\get -> get host) getprops unknownhost :: HostName -> IO a-unknownhost h = errorMessage $ unwords- [ "Unknown host:", h- , "(perhaps you should specify the real hostname on the command line?)"+unknownhost h = errorMessage $ unlines+ [ "Unknown host: " ++ h+ , "(Perhaps you should specify the real hostname on the command line?)"+ , "(Or, edit propellor's config.hs to configure this host)" ] buildFirst :: CmdLine -> IO () -> IO ()
Propellor/Property.hs view
@@ -69,6 +69,12 @@ , return NoChange ) +boolProperty :: Desc -> IO Bool -> Property+boolProperty desc a = Property desc $ ifM a+ ( return MadeChange+ , return FailedChange+ )+ -- | Undoes the effect of a property. revert :: RevertableProperty -> RevertableProperty revert (RevertableProperty p1 p2) = RevertableProperty p2 p1@@ -82,3 +88,8 @@ (&) :: IsProp p => [Property] -> p -> [Property] ps & p = ps ++ [toProp p] infixl 1 &++-- | Adds a property to the list in reverted form.+(!) :: [Property] -> RevertableProperty -> [Property]+ps ! p = ps ++ [toProp $ revert p]+infixl 1 !
Propellor/Property/Apt.hs view
@@ -60,9 +60,10 @@ setSourcesList ls = sourcesList `File.hasContent` ls `onChange` update runApt :: [String] -> Property-runApt ps = cmdProperty' "apt-get" ps env- where- env =+runApt ps = cmdProperty' "apt-get" ps noninteractiveEnv++noninteractiveEnv :: [(String, String)]+noninteractiveEnv = [ ("DEBIAN_FRONTEND", "noninteractive") , ("APT_LISTCHANGES_FRONTEND", "none") ]@@ -78,11 +79,18 @@ type Package = String installed :: [Package] -> Property-installed ps = robustly $ check (isInstallable ps) go+installed = installed' ["-y"]++installed' :: [String] -> [Package] -> Property+installed' params ps = robustly $ check (isInstallable ps) go `describe` (unwords $ "apt installed":ps) where- go = runApt $ ["-y", "install"] ++ ps+ go = runApt $ params ++ ["install"] ++ ps +-- | Minimal install of package, without recommends.+installedMin :: [Package] -> Property+installedMin = installed' ["--no-install-recommends", "-y"]+ removed :: [Package] -> Property removed ps = check (or <$> isInstalled' ps) go `describe` (unwords $ "apt removed":ps)@@ -95,8 +103,17 @@ where go = runApt $ ["-y", "build-dep"] ++ ps -{- Package installation may fail becuse the archive has changed.- - Run an update in that case and retry. -}+-- | Installs the build deps for the source package unpacked+-- in the specifed directory, with a dummy package also+-- installed so that autoRemove won't remove them.+buildDepIn :: FilePath -> Property+buildDepIn dir = go `requires` installedMin ["devscripts", "equivs"]+ where+ go = cmdProperty' "sh" ["-c", "cd '" ++ dir ++ "' && mk-build-deps debian/control --install --tool 'apt-get -y --no-install-recommends' --remove"]+ noninteractiveEnv++-- | Package installation may fail becuse the archive has changed.+-- Run an update in that case and retry. -} robustly :: Property -> Property robustly p = Property (propertyDesc p) $ do r <- ensureProperty p
Propellor/Property/Docker.hs view
@@ -52,13 +52,16 @@ let setup = provisionContainer cid `requires` runningContainer cid image containerprops- teardown = - Property ("undocked " ++ fromContainerId cid) $+ `requires`+ installed+ teardown = combineProperties ("undocked " ++ fromContainerId cid)+ [ stoppedContainer cid+ , Property ("cleaned up " ++ fromContainerId cid) $ report <$> mapM id- [ stopContainerIfRunning cid- , removeContainer cid+ [ removeContainer cid , removeImage image ]+ ] in RevertableProperty setup teardown where cid = ContainerId hn cn@@ -259,10 +262,9 @@ clearProvisionedFlag cid createDirectoryIfMissing True (takeDirectory $ identFile cid) writeFile (identFile cid) (show ident)- ifM (runContainer img (runps ++ ["-i", "-d", "-t"]) chaincmd)- ( return MadeChange- , return FailedChange- )+ ensureProperty $ boolProperty "run" $ runContainer img+ (runps ++ ["-i", "-d", "-t"])+ chaincmd -- | Called when propellor is running inside a docker container. -- The string should be the container's ContainerId.@@ -337,11 +339,14 @@ stopContainer :: ContainerId -> IO Bool stopContainer cid = boolSystem dockercmd [Param "stop", Param $ fromContainerId cid ] -stopContainerIfRunning :: ContainerId -> IO Bool-stopContainerIfRunning cid = ifM (elem cid <$> listContainers RunningContainers)- ( stopContainer cid- , return True- )+stoppedContainer :: ContainerId -> Property+stoppedContainer cid = containerDesc cid $ Property desc $ + ifM (elem cid <$> listContainers RunningContainers)+ ( ensureProperty $ boolProperty desc $ stopContainer cid+ , return NoChange+ )+ where+ desc = "stopped" removeContainer :: ContainerId -> IO Bool removeContainer cid = catchBoolIO $
Propellor/Property/SiteSpecific/GitAnnexBuilder.hs view
@@ -12,13 +12,12 @@ builddir :: FilePath builddir = "gitbuilder" -builder :: Architecture -> CronTimes -> Property-builder arch crontimes = combineProperties "gitannexbuilder"+builder :: Architecture -> CronTimes -> Bool -> Property+builder arch crontimes rsyncupload = combineProperties "gitannexbuilder" [ Apt.stdSourcesList Unstable , Apt.buildDep ["git-annex"] , Apt.installed ["git", "rsync", "moreutils", "ca-certificates",- "liblockfile-simple-perl", "cabal-install", "vim", "less",- "libghc-fdo-notify-dev"]+ "liblockfile-simple-perl", "cabal-install", "vim", "less"] , serviceRunning "cron" `requires` Apt.installed ["cron"] , User.accountFor builduser , check (lacksdir builddir) $ userScriptProperty builduser@@ -31,6 +30,9 @@ [ "cd " ++ builddir , "git clone git://git-annex.branchable.com/ build" ]+ , Property "git-annex source build deps installed" $ do+ d <- homedir+ ensureProperty $ Apt.buildDepIn (d </> builddir </> "build") , Cron.niceJob "gitannexbuilder" crontimes builduser ("~/" ++ builddir) "git pull ; ./autobuild" -- The builduser account does not have a password set, -- instead use the password privdata to hold the rsync server@@ -38,11 +40,17 @@ , Property "rsync password" $ do d <- homedir let f = d </> "rsyncpassword"- withPrivData (Password builduser) $ \p -> do- oldp <- catchDefaultIO "" $ readFileStrict f- if p /= oldp- then makeChange $ writeFile f p- else noChange+ if rsyncupload + then withPrivData (Password builduser) $ \p -> do+ oldp <- catchDefaultIO "" $ readFileStrict f+ if p /= oldp+ then makeChange $ writeFile f p+ else noChange+ else do+ ifM (doesFileExist f)+ ( noChange+ , makeChange $ writeFile f "no password configured"+ ) ] where homedir = fromMaybe ("/home/" ++ builduser) <$> User.homedir builduser
README.md view
@@ -1,20 +1,21 @@-This is a work in progress configuration management system using Haskell-and Git.+This is a configuration management system using Haskell and Git. -Propellor enures that the system it's run in satisfies a list of+Propellor enures that the system it's run against satisfies a list of properties, taking action as necessary when a property is not yet met. -The design is intentionally very minimal.+Propellor is configured via a git repository, which typically lives+in ~/.propellor/. The git repository contains a config.hs file,+and also the entire source code to propellor. -Propellor lives in a git repository. You'll typically want to have-the repository checked out on a laptop, in order to make changes and push-them out to hosts. Each host will also have a clone of the repository,-and in that clone "make" can be used to build and run propellor.-This can be done by a cron job (which propellor can set up),-or a remote host can be triggered to update by running propellor-on your laptop: propellor --spin $host+You typically want to have the repository checked out on a laptop, in order+to make changes and push them out to hosts. Each host will also have a+clone of the repository, and in that clone "make" can be used to build and+run propellor. This can be done by a cron job (which propellor can set up),+or a remote host can be triggered to update by running propellor on your+laptop: propellor --spin $host Properties are defined using Haskell. Edit config.hs to get started.+For API documentation, see <http://hackage.haskell.org/package/propellor/> There is no special language as used in puppet, chef, ansible, etc.. just the full power of Haskell. Hopefully that power can be put to good use in@@ -28,35 +29,41 @@ ## quick start -1. Clone propellor's git repository to your laptop (or whatever).- git clone git://git.kitenet.net/propellor- or joeyh/propellor on github-2. Run: sudo make deps # installs build dependencies-3. Run: make build-4. If you don't have a gpg private key, generate one: gpg --gen-key-5. Run: ./propellor --add-key $KEYID-7. Pick a host and run: ./propellor --spin $HOST-8. Now you have a simple propellor deployment, but it doesn't do anything- to the host yet, besides installing propellor.+1. Get propellor installed+ `cabal install propellor`+ or+ `apt-get install propellor`+2. Run propellor for the first time. It will set up a `~/.propellor/` git+ repository for you.+3. In `~/.propellor/`, use git to push the repository to a central+ server (github, or your own git server). Configure that central+ server as the origin remote of the repository.+4. If you don't have a gpg private key, generate one: `gpg --gen-key`+5. Run: `propellor --add-key $KEYID`+6. Edit `~/.propellor/config.hs`, and add a host you want to manage.+ You can start by not adding any properties, or only a few.+7. Pick a host and run: `propellor --spin $HOST`+8. Now you have a simple propellor deployment, but it doesn't do+ much to the host yet, besides installing propellor. - So, edit config.hs to configure the host (maybe start with a few simple- properties), and re-run step 7. Repeat until happy and move on to the- next host. :)+ So, edit `~/.propellor/config.hs` to configure the host (maybe+ start with a few simple properties), and re-run step 7.+ Repeat until happy and move on to the next host. :) 9. To move beyond manually running propellor --spin against hosts when you change configuration, add a property to your hosts- like: Cron.runPropellor "30 * * * *"+ like: `Cron.runPropellor "30 * * * *"` Now they'll automatically update every 30 minutes, and you can `git commit -S` and `git push` changes that affect any number of hosts.-10. Write some neat new properties and send patches to propellor@joeyh.name!+8. Write some neat new properties and send patches to <propellor@joeyh.name>! ## security Propellor's security model is that the hosts it's used to deploy are untrusted, and that the central git repository server is untrusted. -The only trusted machine is the laptop where you run propellor --spin+The only trusted machine is the laptop where you run `propellor --spin` to connect to a remote host. And that one only because you have a ssh key or login password to the host. @@ -70,10 +77,10 @@ That is only done when privdata/keyring.gpg exists. To set it up: -gpg --gen-key # only if you don't already have a gpg key-propellor --add-key $MYKEYID+ gpg --gen-key # only if you don't already have a gpg key+ propellor --add-key $MYKEYID -In order to be secure from the beginning, when propellor --spin is used+In order to be secure from the beginning, when `propellor --spin` is used to bootstrap propellor on a new host, it transfers the local git repositry to the remote host over ssh. After that, the remote host knows the gpg key, and will use it to verify git fetches.@@ -81,17 +88,17 @@ Since the propoellor git repository is public, you can't store in cleartext private data such as passwords, ssh private keys, etc. -Instead, propellor --spin $host looks for a privdata/$host.gpg file and+Instead, `propellor --spin $host` looks for a `~/.propellor/privdata/$host.gpg` file and if found decrypts it and sends it to the remote host using ssh. This lets a remote host know its own private data, without seeing all the rest. -To securely store private data, use: propellor --set $host $field+To securely store private data, use: `propellor --set $host $field` The field name will be something like 'Password "root"'; see PrivData.hs for available fields. ## debugging -Set PROPELLOR_DEBUG=1 to make propellor print out all the commands it runs-and any other debug messages Properties choose to emit.+Set `PROPELLOR_DEBUG=1` to make propellor print out all the commands it runs+and any other debug messages that Properties choose to emit. [1] http://reclass.pantsfullofunix.net/
TODO view
@@ -2,7 +2,6 @@ run it once for the whole. For example, may want to restart apache, but only once despite many config changes being made to satisfy properties. onChange is a poor substitute.-* I often seem to want to be able to combine Properties monadically. * --spin needs 4 ssh connections when bootstrapping a new host that does not have the git repo yet. Should be possible to get that down to 1.@@ -12,7 +11,4 @@ * Display of docker container properties is a bit wonky. It always says they are unchanged even when they changed and triggered a reprovision.-* Nothing brings up docker containers on boot. Although the next time- propellor runs it will notice if a container is done, and fix it.- Should propellor be run on boot? Or should provisioning a container- install a systemd service file to start it?+* Should properties be a tree rather than a list?
config.hs view
@@ -43,8 +43,8 @@ & JoeySites.oldUseNetshellBox & Docker.configured & File.dirExists "/var/www"- & revert (Docker.docked container hostname "webserver")- & revert (Docker.docked container hostname "amd64-git-annex-builder")+ ! Docker.docked container hostname "webserver"+ ! Docker.docked container hostname "amd64-git-annex-builder" & Docker.garbageCollected -- Should come last as it reboots. & Apt.installed ["systemd-sysv"] `onChange` Reboot.now@@ -53,8 +53,9 @@ & standardSystem Unstable & Apt.unattendedUpgrades & Docker.configured+ & Apt.buildDep ["git-annex"] & Docker.docked container hostname "amd64-git-annex-builder"- & revert (Docker.docked container hostname "i386-git-annex-builder")+ ! Docker.docked container hostname "i386-git-annex-builder" & Docker.garbageCollected -- add more hosts here... --host "foo.example.com" =@@ -76,7 +77,7 @@ let arch = takeWhile (/= '-') name in Just $ Docker.containerFrom (image $ System (Debian Unstable) arch)- [ Docker.inside $ props & GitAnnexBuilder.builder arch "15 * * * *" ]+ [ Docker.inside $ props & GitAnnexBuilder.builder arch "15 * * * *" True ] | otherwise = Nothing -- | Docker images I prefer to use.
− debian/README
@@ -1,1 +0,0 @@-I don't know a good way to Debianize propellor! Help appreciated. -- Joey
+ debian/README.Debian view
@@ -0,0 +1,7 @@+The Debian package of propellor ships its full source code because+propellor is configured by rebuilding it, and embraces modification of any+of the source code.++/usr/bin/propellor is a wrapper which will set up a propellor git+repository in ~/.propellor/, and run ~/.propellor/propellor if it exists.+Edit ~/.propellor/config.hs to configure it.
debian/changelog view
@@ -1,4 +1,10 @@-propellor (0.2) unstable; urgency=low+propellor (0.2.1) unstable; urgency=medium++ * First release with Debian package.++ -- Joey Hess <joeyh@debian.org> Thu, 03 Apr 2014 01:43:14 -0400++propellor (0.2.0) unstable; urgency=low * Added support for provisioning Docker containers. * Bootstrap deployment now pushes the git repo to the remote host
+ debian/compat view
@@ -0,0 +1,1 @@+9
+ debian/control view
@@ -0,0 +1,36 @@+Source: propellor+Section: admin+Priority: optional+Build-Depends: + debhelper (>= 9),+ ghc (>= 7.4),+ cabal-install,+ libghc-async-dev,+ libghc-missingh-dev,+ libghc-hslogger-dev,+ libghc-unix-compat-dev,+ libghc-ansi-terminal-dev,+ libghc-ifelse-dev,+Maintainer: Joey Hess <joeyh@debian.org>+Standards-Version: 3.9.5+Vcs-Git: git://git.kitenet.net/propellor+Homepage: http://joeyh.name/code/propellor/++Package: propellor+Architecture: any+Section: admin+Depends: ${misc:Depends}, ${shlibs:Depends},+ ghc (>= 7.4),+ cabal-install,+ libghc-async-dev,+ libghc-missingh-dev,+ libghc-hslogger-dev,+ libghc-unix-compat-dev,+ libghc-ansi-terminal-dev,+ libghc-ifelse-dev,+ git,+Description: property-based host configuration management in haskell+ Propellor enures that the system it's run in satisfies a list of+ properties, taking action as necessary when a property is not yet met.+ .+ It is configured using haskell.
+ debian/copyright view
@@ -0,0 +1,11 @@+Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/+Source: native package++Files: *+Copyright: © 2010-2014 Joey Hess <joey@kitenet.net>+License: GPL-3+++License: GPL-3++ The full text of version 3 of the GPL is distributed as GPL in+ this package's source, or in /usr/share/common-licenses/GPL-3 on+ Debian systems.
+ debian/lintian-overrides view
@@ -0,0 +1,3 @@+# These files are used in a git repository that propellor sets up.+propellor: package-contains-vcs-control-file usr/src/propellor/.gitignore+propellor: extra-license-file usr/src/propellor/GPL
+ debian/propellor.1 view
@@ -0,0 +1,15 @@+.\" -*- nroff -*-+.TH propellor 1 "Commands"+.SH NAME+propellor \- property-based host configuration management in haskell+.SH SYNOPSIS+.B propellor [options] host+.SH DESCRIPTION+.I propellor+is a property-based host configuration management program written +and configured in haskell.+.PP+The first time you run propellor, it will set up a ~/.propellor/+repository. Edit ~/.propellor/config.hs to configure it.+.SH AUTHOR +Joey Hess <joey@kitenet.net>
+ debian/rules view
@@ -0,0 +1,14 @@+#!/usr/bin/make -f++# Avoid using cabal, as it writes to $HOME+export CABAL=./Setup++%:+ dh $@++override_dh_auto_build:+ $(MAKE) build+override_dh_installdocs:+ dh_installdocs README.md TODO+override_dh_installman:+ dh_installman debian/propellor.1
propellor.cabal view
@@ -1,5 +1,5 @@ Name: propellor-Version: 0.2.0+Version: 0.2.1 Cabal-Version: >= 1.6 License: GPL Maintainer: Joey Hess <joey@kitenet.net>@@ -14,20 +14,35 @@ README.md TODO CHANGELOG+ simple-config.hs Makefile debian/changelog- debian/README- simple-config.hs+ debian/README.Debian+ debian/propellor.1+ debian/compat+ debian/control+ debian/copyright+ debian/rules+ debian/lintian-overrides+ .gitignore Synopsis: property-based host configuration management in haskell Description: Propellor enures that the system it's run in satisfies a list of properties, taking action as necessary when a property is not yet met. .- While Propellor can be installed from hackage, to customize and use it- you should fork its git repository and modify it from there:- git clone git://git.kitenet.net/propellor+ It is configured using haskell. Executable propellor+ Main-Is: propellor.hs+ GHC-Options: -Wall+ Build-Depends: MissingH, directory, filepath, base >= 4.5, base < 5, + IfElse, process, bytestring, hslogger, unix-compat, ansi-terminal,+ containers, network, async+ + if (! os(windows))+ Build-Depends: unix++Executable config Main-Is: config.hs GHC-Options: -Wall -threaded Build-Depends: MissingH, directory, filepath, base >= 4.5, base < 5, @@ -38,7 +53,7 @@ Build-Depends: unix Library- GHC-Options: -Wall -threaded+ GHC-Options: -Wall Build-Depends: MissingH, directory, filepath, base >= 4.5, base < 5, IfElse, process, bytestring, hslogger, unix-compat, ansi-terminal, containers, network, async
+ propellor.hs view
@@ -0,0 +1,91 @@+-- | Wrapper program for propellor distribution.+--+-- Distributions should install this program into PATH.+-- (Cabal builds it as dict/build/propellor.+--+-- This is not the propellor main program (that's config.hs)+--+-- This installs propellor's source into ~/.propellor,+-- uses it to build the real propellor program (if not already built),+-- and runs it.+-- +-- The source is either copied from /usr/src/propellor, or is cloned from+-- git over the network.++import Utility.UserInfo+import Utility.Monad+import Utility.Process+import Utility.SafeCommand+import Utility.Directory++import Control.Monad+import Control.Monad.IfElse+import System.Directory+import System.FilePath+import System.Environment (getArgs)+import System.Exit+import System.Posix.Directory++srcdir :: FilePath+srcdir = "/usr/src/propellor"++-- Using the github mirror of the main propellor repo because+-- it is accessible over https for better security.+srcrepo :: String+srcrepo = "https://github.com/joeyh/propellor.git"++main :: IO ()+main = do+ args <- getArgs+ home <- myHomeDir+ let propellordir = home </> ".propellor"+ let propellorbin = propellordir </> "propellor"+ wrapper args propellordir propellorbin++wrapper :: [String] -> FilePath -> FilePath -> IO ()+wrapper args propellordir propellorbin = do+ unlessM (doesDirectoryExist propellordir) $+ makeRepo+ buildruncfg+ where+ chain = do+ (_, _, _, pid) <- createProcess (proc propellorbin args) + exitWith =<< waitForProcess pid+ makeRepo = do+ putStrLn $ "Setting up your propellor repo in " ++ propellordir+ putStrLn ""+ ifM (doesDirectoryExist srcdir)+ ( do+ void $ boolSystem "cp" [Param "-a", File srcdir, File propellordir]+ changeWorkingDirectory propellordir+ void $ boolSystem "git" [Param "init"]+ void $ boolSystem "git" [Param "add", Param "."]+ setuprepo True+ , do+ void $ boolSystem "git" [Param "clone", Param srcrepo, File propellordir] + void $ boolSystem "git" [Param "remote", Param "rm", Param "origin"]+ setuprepo False+ )+ setuprepo fromsrcdir = do+ changeWorkingDirectory propellordir+ whenM (doesDirectoryExist "privdata") $+ mapM_ nukeFile =<< dirContents "privdata"+ void $ boolSystem "git" [Param "commit", Param "--allow-empty", Param "--quiet", Param "-m", Param "setting up propellor git repository"]+ void $ boolSystem "git" [Param "remote", Param "add", Param "upstream", Param srcrepo]+ -- Connect synthetic git repo with upstream history so+ -- merging with upstream will work going forward.+ -- Note -s outs is used to avoid getting any divergent+ -- changes from upstream.+ when fromsrcdir $ do+ void $ boolSystem "git" [Param "fetch", Param "upstream"]+ version <- readProcess "dpkg-query" ["--showformat", "${Version}", "--show", "propellor"]+ void $ boolSystem "git" [Param "merge", Param "-s", Param "ours", Param version]+ buildruncfg = do+ changeWorkingDirectory propellordir+ ifM (boolSystem "make" [Param "build"])+ ( do+ putStrLn ""+ putStrLn ""+ chain+ , error "Propellor build failed."+ )
simple-config.hs view
@@ -31,8 +31,8 @@ & Apt.installed ["ssh"] & User.hasSomePassword "root" & Network.ipv6to4+ & File.dirExists "/var/www" & Docker.docked container hostname "webserver"- `requires` File.dirExists "/var/www" & Docker.garbageCollected & Cron.runPropellor "30 * * * *" -- add more hosts here...