summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoey Hess2014-04-03 00:59:26 -0400
committerJoey Hess2014-04-03 01:55:49 -0400
commit42f207232beb57c18f67884e7c28424dba3c84c6 (patch)
treefe389f774e2f0de6cd5562b9b349f727319cc03f
parent167609746d22951477abd6490b34480205c659af (diff)
debianization and a wrapper program for /usr/bin
-rw-r--r--Makefile27
-rw-r--r--Propellor/CmdLine.hs7
-rw-r--r--README.md76
-rw-r--r--debian/README.Debian (renamed from debian/README)0
-rw-r--r--debian/changelog8
-rw-r--r--debian/compat1
-rw-r--r--debian/control36
-rw-r--r--debian/copyright11
-rw-r--r--debian/lintian-overrides3
-rw-r--r--debian/propellor.115
-rwxr-xr-xdebian/rules14
-rw-r--r--propellor.cabal29
-rw-r--r--propellor.hs91
13 files changed, 266 insertions, 52 deletions
diff --git a/Makefile b/Makefile
index 0492e5d9..9b4a7d82 100644
--- a/Makefile
+++ b/Makefile
@@ -1,20 +1,30 @@
-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 {} \;
@@ -22,4 +32,9 @@ clean:
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
diff --git a/Propellor/CmdLine.hs b/Propellor/CmdLine.hs
index d1a758ab..ed762e70 100644
--- a/Propellor/CmdLine.hs
+++ b/Propellor/CmdLine.hs
@@ -74,9 +74,10 @@ defaultMain getprops = do
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 ()
diff --git a/README.md b/README.md
index 68201d85..c918b324 100644
--- a/README.md
+++ b/README.md
@@ -1,18 +1,18 @@
-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.
@@ -28,35 +28,41 @@ and so it's easy to factor out things like classes of hosts as desired.
## 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.
-
- 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. :)
+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 `~/.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 +76,10 @@ otherwise.
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 +87,17 @@ gpg key, and will use it to verify git fetches.
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/
diff --git a/debian/README b/debian/README.Debian
index e32a0ee3..e32a0ee3 100644
--- a/debian/README
+++ b/debian/README.Debian
diff --git a/debian/changelog b/debian/changelog
index 73ace3dd..09d8492d 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -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
diff --git a/debian/compat b/debian/compat
new file mode 100644
index 00000000..ec635144
--- /dev/null
+++ b/debian/compat
@@ -0,0 +1 @@
+9
diff --git a/debian/control b/debian/control
new file mode 100644
index 00000000..3f5cb2da
--- /dev/null
+++ b/debian/control
@@ -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.
diff --git a/debian/copyright b/debian/copyright
new file mode 100644
index 00000000..690a9af8
--- /dev/null
+++ b/debian/copyright
@@ -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.
diff --git a/debian/lintian-overrides b/debian/lintian-overrides
new file mode 100644
index 00000000..9071fe0f
--- /dev/null
+++ b/debian/lintian-overrides
@@ -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
diff --git a/debian/propellor.1 b/debian/propellor.1
new file mode 100644
index 00000000..3ee3bf4a
--- /dev/null
+++ b/debian/propellor.1
@@ -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>
diff --git a/debian/rules b/debian/rules
new file mode 100755
index 00000000..dafe10f6
--- /dev/null
+++ b/debian/rules
@@ -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
diff --git a/propellor.cabal b/propellor.cabal
index 78207cc3..17f48878 100644
--- a/propellor.cabal
+++ b/propellor.cabal
@@ -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 @@ Extra-Source-Files:
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 @@ Executable propellor
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
diff --git a/propellor.hs b/propellor.hs
new file mode 100644
index 00000000..e4653f30
--- /dev/null
+++ b/propellor.hs
@@ -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."
+ )