summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Wold <swold@sunet.se>2013-12-20 13:01:36 +0100
committerStefan Wold <swold@sunet.se>2013-12-20 13:01:36 +0100
commitccacc042e4c1b8a87e48b40ebcca5121b4ae5beb (patch)
tree3b648474d4bd3266abfe595606ea1e7b0183ee98
parentf1c2ae2e0495f279493d8989b1c72bf3f8ed122a (diff)
Verify git signatures for puppet modules
-rwxr-xr-xglobal/post-tasks.d/018packages98
1 files changed, 87 insertions, 11 deletions
diff --git a/global/post-tasks.d/018packages b/global/post-tasks.d/018packages
index 9e25e69..57dff1a 100755
--- a/global/post-tasks.d/018packages
+++ b/global/post-tasks.d/018packages
@@ -1,16 +1,92 @@
-#!/bin/sh
+#!/bin/bash
+
+CONFIG=${CONFIG:=/etc/puppet/cosmos-modules.conf}
+CACHE_DIR=/var/cache/puppet-modules
+MODULES_DIR=${MODULES_DIR:=/etc/puppet/cosmos-modules}
+GIT_TAG_PATTERN=${COSMOS_UPDATE_VERIFY_GIT_TAG_PATTERN:-multiverse*}
+export GNUPGHOME=/etc/cosmos/gnupg
python -c "import yaml" 2>/dev/null || apt-get -y install python-yaml
-if [ -f /etc/puppet/cosmos-modules.conf ]; then
- grep -E -v "^#" /etc/puppet/cosmos-modules.conf | (
- cd /etc/puppet/modules && while read module src update; do
- if [ ! -d /etc/puppet/modules/$module ]; then
- echo $src | grep -q "://" && git clone $src $module || puppet module install $src
- else
- if [ "x$update" = "xyes" ]; then
- echo $src | grep -q "://" && (cd /etc/puppet/modules/$module && git pull -q) || puppet module upgrade $src
+
+stage_module() {
+ rm -rf $CACHE_DIR/staging/$1
+ git archive --format=tar --prefix=$1/ $2 | (cd $CACHE_DIR/staging/ && tar xf -)
+}
+
+if [ -f $CONFIG ]; then
+ if [ ! -d $MODULES_DIR ]; then
+ mkdir -p $MODULES_DIR
+ fi
+ if [ ! -d $CACHE_DIR ]; then
+ mkdir -p $CACHE_DIR/{scm,staging}
+ fi
+
+ # First pass to clone any new modules, and update those marked for updating.
+ grep -E -v "^#" $CONFIG | (
+ while read module src update; do
+ # We only support git:// urls atm
+ if [ "${src:0:6}" = "git://" ]; then
+ if [ ! -d $CACHE_DIR/scm/$module ]; then
+ git clone -q $src $CACHE_DIR/scm/$module
+ elif [ -d $CACHE_DIR/scm/$module/.git ]; then
+ if [ "$update" = "yes" ]; then
+ cd $CACHE_DIR/scm/$module
+ git pull -q
+ else
+ continue
fi
- fi
- done)
+ else
+ echo "ERROR: Ignoring non-git repository"
+ continue
+ fi
+ fi
+ done
+ )
+
+ # Second pass to verify the signatures on all modules and stage those that
+ # have good signatures.
+ grep -E -v "^#" $CONFIG | (
+ while read module src update; do
+ # We only support git:// urls atm
+ if [ "${src:0:6}" = "git://" ]; then
+ # Verify git tag
+ cd $CACHE_DIR/scm/$module
+ TAG=$(git tag -l $GIT_TAG_PATTERN | sort | tail -1)
+ if [ "$COSMOS_VERBOSE" = "y" ]; then
+ echo ""
+ echo "Checking signature on tag ${TAG} for puppet-module $module"
+ fi
+ if [ -z "$TAG" ]; then
+ echo "ERROR: No git tag found for pattern '$GIT_TAG_PATTERN' on puppet-module $module"
+ continue
+ fi
+ fail=1
+ git tag -v $TAG > /dev/null 2>&1 && fail=0
+ if [ $fail == 0 ]; then
+ if [ "$COSMOS_VERBOSE" = "y" ]; then
+ # short output on good signature
+ git tag -v $TAG 2>&1 | grep "gpg: Good signature"
+ fi
+ # Put archive in staging since tag verified OK
+ stage_module $module $TAG
+ else
+ echo "################################################################"
+ echo "FAILED signature check on puppet-module $module"
+ echo "################################################################"
+ git tag -v $TAG
+ fi
+ fi
+ done
+ )
+
+ # Cleanup removed puppet modules from CACHE_DIR
+ for MODULE in $(ls -1 $CACHE_DIR/staging/); do
+ if ! grep -E -q "^$MODULE\s+" $CONFIG; then
+ rm -rf $CACHE_DIR/{scm,staging}/$MODULE
+ fi
+ done
+
+ # Installing verified puppet modules
+ rsync --archive --delete $CACHE_DIR/staging/ $MODULES_DIR/
fi