diff --git a/crowbar/.loadpath b/crowbar/.loadpath
new file mode 100644
index 00000000000..c4415b3d019
--- /dev/null
+++ b/crowbar/.loadpath
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/crowbar/.project b/crowbar/.project
new file mode 100644
index 00000000000..e79fd0467c7
--- /dev/null
+++ b/crowbar/.project
@@ -0,0 +1,18 @@
+
+
+ crowbar
+
+
+
+
+
+ org.rubypeople.rdt.core.rubybuilder
+
+
+
+
+
+ org.rubypeople.rdt.core.rubynature
+ org.radrails.rails.core.railsnature
+
+
diff --git a/crowbar/CHANGE-LOG b/crowbar/CHANGE-LOG
new file mode 100644
index 00000000000..ceb80c7a653
--- /dev/null
+++ b/crowbar/CHANGE-LOG
@@ -0,0 +1,4 @@
+
+
+--- Initial Version ----
+
diff --git a/crowbar/README.build b/crowbar/README.build
new file mode 100644
index 00000000000..d30589e37d9
--- /dev/null
+++ b/crowbar/README.build
@@ -0,0 +1,142 @@
+This file documents how to build the Crowbar installation DVD image.
+
+Prerequisites:
+ * An unfiltered Internet connection and a decent amount of bandwidth.
+ The first time you try to build Crowbar it will need to download
+ about 1.5 gigs worth of data from the official Ubuntu apt repositories,
+ the Opscode chef repository, the official Openstack 2011.2 PPA, and
+ an official Ubuntu CD image mirror.
+ * bash version 4 or higher
+ build_crowbar.sh uses associative arrays, which bash got in version 4.
+ * mkisofs
+ The end product of the build script is an ISO image that will be used
+ to bootstrap the Crowbar admin node.
+ * debootstrap
+ The build process needs to download all the .debs and gems that
+ Crowbar requires, and we don't want to inadvertently mess up the build
+ machine when we do that. All extra packages are downloaded into a
+ chrooted minimal Ubuntu intall, and we use debootstrap to enable that.
+ * Sudo to root privileges for the following commands:
+ * /bin/mount, /bin/umount
+ We have to be able to mount and umount the Ubuntu .iso image, as well as
+ a tmpfs for debootstrap, and we have to be able to bind mount
+ /dev, /dev/pts, /proc, and /sys into the debootstrap chroot environment.
+ * /usr/sbin/debootstrap
+ debootstrap requires root privileges to run.
+ * /bin/cp
+ We need to copy things into and out of the debootstrap environment to
+ ensure it downloads and caches the right packages.
+ * /usr/sbin/chroot
+ All our package caching is done in a chroot environment, and chroot
+ requires root permissions to run.
+
+ If you want to allow build_crowbar to run the above commands as root
+ without having to enter a password each time, the build_crowbar.sh
+ includes a sample line you can fix up and add to /etc/sudoers.
+ * A working Sledgehammer tftpboot image.
+ Sledgehammer is a minimal CentOS 5.6 pxe bootable image that we use
+ to perform hardware discovery and configuration for devices that do not
+ have low-level management tools for Ubuntu. You can find information on
+ how to build Sledgehamemr by reading its HOWTO.Non.Redhat file. We do
+ not do fully automated builds of Sledgehammer due to a lack of a CentOS
+ equivalent of debootstrap.
+
+Usage:
+ * Run build_crowbar.sh.
+ The first time it is run, it will download and cache all the files it
+ needs from the official Ubuntu, Chef, and Openstack repositories. It will
+ then build the Crowbar installation image, save it to the current
+ working directory, and print out a message saying where it saved the image.
+ On subsequent runs it will run with the files it cached from the first
+ run, unless update-cache is passed as a parameter to the script.
+
+Customization:
+
+ build_crowbar.sh has several different parameters you can tune, either from
+ $HOME/.build-crowbar.conf (for developer use), or from build-crowbar.conf
+ in the current directory (for automated builds).
+
+ Here are the parameters you can change through the above configuration files:
+ * DEBUG
+ If DEBUG is set to anything, build_crowbar will run in debug mode, and will
+ print a transcript of everything it is doing to standard error.
+ * CACHE_DIR
+ This is the default location where build_crowbar.sh will keep the files
+ it caches, along with the temporary directories used to mount the
+ ISO image, the debootstrap chroot, and the directory we perform the build
+ in. It defaults to $HOME/.crowbar-build-cache.
+ * ISO_LIBRARY
+ This is the default location where the Ubuntu .iso is stored. It defaults
+ to $CACHE_DIR/iso
+ * ISO_DEST
+ This is the location that we will save the Crowbar install iamge to.
+ It defaults to the current directory.
+ * IMAGE_DIR
+ This is the location that we will mount isos in.
+ It defaults to $CACHE_DIR/image
+ * BUILD_DIR
+ This is the directory we will stage the Crowbar build into.
+ It defaults to $CACHE_DIR/build
+ * UBUNTU_VERSION
+ This is the numeric version of Ubuntu we are building Crowbar with.
+ Right now we base the build on 10.10
+ * UBUNTU_CODENAME
+ This is the one-word codename of $UBUNTU_VERSION. Weird things will
+ happen if it is not kept in sync with $UBUNTU_VERSION
+ * PPAS
+ This is an array of PPA archives to look in to gather packages from.
+ This defaults to ("openstack-release/2011.2"), which is the official
+ PPA for the Cactus release of Openstack.
+ * UBUNTU_ISO_MIRROR
+ This is the base URL for the mirror we will try to download the
+ Ubuntu server ISO from. It defaults to "http://mirror.anl.gov/pub".
+ * SLEDGEHAMMER_PXE_DIR
+ This points to the location we expect to find the unpacked Sledgehammer
+ PXE boot archive. It defaults to $CACHE_DIR/tftpboot
+ * VERSION
+ The default version of Crowbar. Defaults to dev.
+ * OPENSTACK_ISO
+ The name of the ISO that build_crowbar.sh generates.
+ Defaults to openstack-$VERSION.iso
+ * CROWBAR_DIR
+ The directory that the Crowbar source is cheched out to.
+ Defaults to the directory that build_crowbar.sh is in.
+ * SLEDGEHAMMER_DIR
+ The directory that the Sledgehammer source is checked out to.
+ Defaults to $CROWBAR_DIR/../sledgehammer
+ * VCS_CLEAN_CMD
+ This is the command that build_crowbar.sh will run to clean the tree before
+ staging the Crowbar build.
+ Defaults to 'git clean -f -x -d'
+ * DEBS
+ This is an array of additional packages that build_crowbar.sh will try
+ to populate the .deb cache with. It is empty by default.
+ * GEMS
+ This is an array of additional Ruby gems that build_crowbar will try to
+ populate its .gem cache with. It is empty by default.
+ * AMIS
+ This is an array of urls for AMI images that you want to prepopulate
+ Crowbar with. By default it contains the URL for the official release
+ AMI of Ubuntu 11.04 x86_64 server.
+ * UBUNTU_CHROOT
+ This is the directory that we will mount a tmpfs on when we debootstrap
+ a minimal Ubuntu install to prepopulate the deb and gem caches.
+ It defaults to $CACHE_DIR/$UBUNTU_CODENAME.chroot
+ * DEB_CACHE
+ This is the directory that will hold our .deb cache.
+ It defaults to $CACHE_DIR/$UBUNTU_CODENAME/debs
+ * GEM_CACHE
+ This is the directory that will hold our gem cache.
+ It defaults to $CACHE_DIR/gems
+ * AMI_CACHE
+ This is the directory that will hold our AMI cache.
+ It defaults to $CACHE_DIR/amis
+ * UBUNTU_ISO
+ This is the full name of the Ubuntu ISO we will use as the base of the
+ Crowbar installation image.
+ Defaults to "ubuntu-$UBUNTU_VERSION-server-amd64.iso", which will
+ base us on the amd64 server spin of Ubuntu.
+ * UBUNTU_DIR
+ This is the directory we will mount $UBUNTU_ISO on when we extract files
+ from it.
+ Defaults to $IMAGE_DIR/$UBUNTU_ISO minus the .iso at the end.
diff --git a/crowbar/build_crowbar.sh b/crowbar/build_crowbar.sh
new file mode 100755
index 00000000000..da9afe8f7f3
--- /dev/null
+++ b/crowbar/build_crowbar.sh
@@ -0,0 +1,453 @@
+#!/bin/bash
+# Copyright 2011, Dell
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Author: VictorLowther
+#
+
+# This script expects to be able to run certian commands as root.
+# Either run it as a user who can sudo to root, or give the user
+# you are running it as the following sudo rights:
+# crowbar-tester ALL = NOPASSWD: /bin/mount, /bin/umount, /usr/sbin/debootstrap, /bin/cp, /usr/sbin/chroot
+
+# When running this script for the first time, it will automatically create a
+# cache directory and try to populate it with all the build dependencies.
+# After that, if you need to pull in new dependencies, you will need to
+# call the script with the update-cache parameter.
+
+[[ $DEBUG ]] && {
+ set -x
+ export PS4='(${nodename:-none})${BASH_SOURCE}@${LINENO}(${FUNCNAME[0]}): '
+}
+
+export PATH="$PATH:/sbin:/usr/sbin:/usr/local/sbin"
+
+# Location for caches that should not be erased between runs
+CACHE_DIR="$HOME/.crowbar-build-cache"
+
+# Location to store .iso images
+ISO_LIBRARY="$CACHE_DIR/iso"
+ISO_DEST="$PWD"
+
+# Location that holds temporary mount images of our.isos
+# if we need to extract them onto our target image.
+IMAGE_DIR="$CACHE_DIR/image"
+
+# Location we will stage the new openstack iso at.
+BUILD_DIR="$CACHE_DIR/build"
+
+# Version of Ubuntu we are building openstack on to.
+UBUNTU_VERSION=10.10
+UBUNTU_CODENAME=maverick
+PPAS=("openstack-release/2011.2")
+
+# Server to download the mirror from if we need to.
+UBUNTU_ISO_MIRROR="http://mirror.anl.gov/pub"
+
+# Directory that holds our Sledgehammer PXE tree.
+SLEDGEHAMMER_PXE_DIR="$CACHE_DIR/tftpboot"
+
+# Version for ISO
+VERSION="dev"
+
+# Name of the openstack iso we will build
+OPENSTACK_ISO="openstack-${VERSION}.iso"
+
+# Location of the Crowbar checkout we are building from.
+CROWBAR_DIR="${0%/*}"
+SLEDGEHAMMER_DIR="${CROWBAR_DIR}/../sledgehammer"
+VCS_CLEAN_CMD='git clean -f -x -d'
+
+# Arrays holding the additional debs, gems, and AMI images we will populate
+# Crowbar with.
+DEBS=()
+GEMS=()
+AMIS=("http://uec-images.ubuntu.com/releases/11.04/release/ubuntu-11.04-server-uec-amd64.tar.gz")
+
+
+die() { shift; echo "$(date '+%F %T %z'): $*" >&2; exit 1; }
+debug() { echo "$(date '+%F %T %z'): $*" >&2; }
+clean_dirs() {
+ local d=''
+ for d in "$@"; do
+ ( mkdir -p "$d"
+ cd "$d"
+ chmod -R u+w .
+ rm -rf * )
+ done
+}
+
+update_caches() {
+ # Hold a list of directories we will need to umount
+ TO_UMOUNT=()
+
+ # Make sure our cache directories exist.
+ mkdir -p "$DEB_CACHE"
+ mkdir -p "$GEM_CACHE"
+
+ # A little helper function for doing bind mounts.
+ bind_mount() {
+ TO_UMOUNT=("${TO_UMOUNT[@]}" "$2")
+ [[ -d $2 ]] || mkdir -p "$2"
+ grep -q "$2" /proc/self/mounts || sudo mount --bind "$1" "$2"
+ }
+
+ # A little helper for running commands in the chroot.
+ in_chroot() { sudo -H chroot "$UBUNTU_CHROOT" "$@"; }
+
+ # second, debootstrap a minimal install of our target version of
+ # Ubuntu to ensure that we don't interfere with the host's package cache.
+ debug "Making package-fetching chroot"
+ mkdir -p "$UBUNTU_CHROOT"
+ sudo mount -t tmpfs -o size=1G none "$UBUNTU_CHROOT"
+ sudo debootstrap "$UBUNTU_CODENAME" "$UBUNTU_CHROOT" \
+ "file://$BUILD_DIR" || \
+ die 1 "Could not bootstrap our scratch target!"
+ # mount some important directories for the chroot
+ for d in proc sys dev dev/pts; do
+ bind_mount "/$d" "$UBUNTU_CHROOT/$d"
+ done
+ # make sure the chroot can resolve hostnames
+ sudo cp /etc/resolv.conf "$UBUNTU_CHROOT/etc/resolv.conf"
+
+ # Make sure we are using a correctly prepopulated sources.list.
+ sudo cp "$BUILD_DIR/extra/sources.list" \
+ "$UBUNTU_CHROOT/etc/apt/sources.list"
+
+ # if we have deb caches, copy them back in to save time on the downloads.
+ sudo cp -a "$DEB_CACHE/." "$UBUNTU_CHROOT/var/cache/apt/archives/."
+
+ debug "Fetching needed packages"
+ # update, add infrastructure for adding PPAs,
+ # add additional PPAs, and update again.
+ in_chroot /usr/bin/apt-get -y --force-yes --allow-unauthenticated update
+ in_chroot /usr/bin/apt-get -y --force-yes --allow-unauthenticated install \
+ python-software-properties
+ for ppa in "${PPAS[@]}"; do
+ in_chroot apt-add-repository "ppa:$ppa"
+ done
+ # Get the key for the Opscode repo we are grabbing Chef bits from.
+ wget -qO - http://apt.opscode.com/packages@opscode.com.gpg.key | \
+ in_chroot /usr/bin/apt-key add -
+ in_chroot /usr/bin/apt-get -y --force-yes --allow-unauthenticated update
+
+ # Download all the packages apt thinks we will need.
+ in_chroot /usr/bin/apt-get -y --force-yes \
+ --allow-unauthenticated --download-only install "${DEBS[@]}"
+ # actually install ruby1.8-dev and gem and their deps.
+ in_chroot /usr/bin/apt-get -y --force-yes \
+ --allow-unauthenticated install ruby1.8-dev rubygems1.8 build-essential
+ # install the gems we will need and all their dependencies
+ # We will get some build failures, but at this point we don't care because
+ # we are just caching the gems for the real install.
+ debug "Fetching Gems"
+ echo "There may be build failures here, we can safely ignore them."
+ gem_re='([^0-9].*)-([0-9].*)'
+ for gem in "${GEMS[@]}"; do
+ if [[ $gem =~ $gem_re ]]; then
+ echo "${BASH_REMATCH[*]}"
+ gemname="${BASH_REMATCH[1]}"
+ gemver="${BASH_REMATCH[2]}"
+ else
+ gemname="$gem"
+ gemver=''
+ fi
+ gemopts=(install --no-ri --no-rdoc)
+ [[ $gemver ]] && gemopts+=(--version "= ${gemver}")
+ in_chroot /usr/bin/gem "${gemopts[@]}" "$gemname"
+ done
+ debug "Saving downloaded packages"
+ # Save our updated gems and debs in the cache for later.
+ cp -a "$UBUNTU_CHROOT/var/cache/apt/archives/." "$DEB_CACHE/."
+ cp -a "$UBUNTU_CHROOT/var/lib/gems/1.8/cache/." "$GEM_CACHE/."
+ sync
+
+ debug "Cleaning up mounts"
+ # umount all the stuff we have mounted for the chroot.
+ while grep -q "$UBUNTU_CHROOT" /proc/self/mounts; do
+ for m in "${TO_UMOUNT[@]}"; do sudo umount "$m"; sleep 1; done
+ sudo umount "$UBUNTU_CHROOT"
+ done
+}
+
+copy_debs() {
+ # $1 = pool directory to build initial list of excludes against
+ # $2 = directory to copy from
+ # $3 = directory to copy to.
+
+ # First, a couple of hashes to hold deb => revision values
+ declare -A deb_pool
+ declare -A dest_pool
+
+ local debname=''
+ local debarr=()
+ local debs_to_copy=()
+
+
+ # Scan through our pool to find debs we can easily omit.
+ while read debname; do
+ [[ -f $debname && $debname = *.deb ]] || continue
+ debname="${debname##*/}"
+ debarr=(${debname//_/ }) # split into (name version arch)
+ deb_pool["${debarr[0]}"]="${debarr[1]}"
+ done < <(find "$1" -name '*.deb')
+
+ (
+ cd "$2"
+ for deb in *; do
+ [[ -f $deb && $deb = *.deb ]] || continue
+ debname="${deb##*/}" # don't care about the source path
+ debname="${debname%_*.deb}" # don't care about the arch
+ debver="${debname#*_}"
+ debname="${debname%_*}"
+ # First, have we already copied another version of this
+ # deb? If so, decide whether to copy it or not.
+ if [[ ${dest_pool["$debname"]} ]]; then
+ # We have seen it. If the version we already copied
+ # is older than this one, queue this for copying instead.
+ # This relies on * expansion returning names in order.
+ if [[ ${dest_pool["$debname"]} < $debver ]]; then
+ debug "Omitting ${debname}_${dest_pool[$debname]} in favor of ${debname}_${debver}"
+ debs_to_copy[$((${#debs_to_copy[@]} - 1))]="$deb"
+ dest_pool["$debname"]="$debver"
+ fi
+ # Second check and see if it is already inthe install pool.
+ # If it is and it is the same or lesser version, don't copy it
+ elif [[ ${deb_pool["$debname"]} ]]; then
+ if [[ ${deb_pool["$debname"]} < $debver ]]; then
+ debs_to_copy+=("$deb")
+ else
+ debug "${debname}_${debver} in CD pool, omitting"
+ fi
+ else
+ # It is not already in deb_pool or dest_pool, copy it.
+ debs_to_copy+=("$deb")
+ debug "Will copy ${debname}_${debver}"
+ fi
+ done
+ # Now, we have a list of debs to copy, so do it.
+ mkdir -p "$3"
+ cp -t "$3" "${debs_to_copy[@]}"
+ )
+}
+
+maybe_update_cache() {
+ local pkgfile deb gem pkg_type rest need_update _pwd
+ debug "Processing package lists"
+ # Zero out our sources.list
+ > "$BUILD_DIR/extra/sources.list"
+ # Download and stash any extra files we may need
+ # First, build our list of repos, ppas, debs, and gems
+ for pkgfile in "$BUILD_DIR/extra/packages/"*.list; do
+ [[ -f $pkgfile ]] || continue
+ while read pkg_type rest; do
+ case $pkg_type in
+ repository)
+ echo "${rest%%#*}" >> "$BUILD_DIR/extra/sources.list";;
+ ppas) PPAS+=(${rest%%#*});;
+ debs) DEBS+=(${rest%%#*});;
+ gems) GEMS+=(${rest%%#*});;
+ esac
+ done <"$pkgfile"
+ done
+
+ _pwd=$PWD
+ cd "$DEB_CACHE"
+ # second, verify that the debs we need are in the cache.
+ for deb in "${DEBS[@]}"; do
+ [[ $(echo "$deb"*.deb) != "$deb*.deb" ]] || {
+ need_update=true
+ break
+ }
+ done
+
+ cd "$GEM_CACHE"
+ # third, verify that the gems we need are in the cache
+ for gem in "${GEMS[@]}"; do
+ [[ $(echo "$gem"*.gem) != "$gem*.gem" ]] || {
+ need_update=true
+ break
+ }
+ done
+ cd "$_pwd"
+
+ if [[ $need_update = true || \
+ ( ! -d $DEB_CACHE ) || $* =~ update-cache ]]; then
+ update_caches
+ else
+ return 0
+ fi
+}
+
+for cmd in sudo chroot debootstrap mkisofs; do
+ which "$cmd" &>/dev/null || \
+ die 1 "Please install $cmd before trying to build Crowbar."
+done
+
+{
+ # Make sure only one instance of the ISO build runs at a time.
+ # Otherwise you can easily end up with a corrupted image.
+ flock 65
+
+ # Source our config file if we have one
+ [[ -f $HOME/.build-crowbar.conf ]] && \
+ . "$HOME/.build-crowbar.conf"
+
+ # Look for a local one.
+ [[ -f build-crowbar.conf ]] && \
+ . "build-crowbar.conf"
+
+ # Finalize where we expect to find our caches and out chroot.
+ # If they were set in one of the conf files, don't touch them.
+
+ # The directory we perform a minimal install of Ubuntu into if we need
+ # to refresh our gem or deb caches
+ [[ $UBUNTU_CHROOT ]] || UBUNTU_CHROOT="$CACHE_DIR/$UBUNTU_CODENAME.chroot"
+
+ # Directories where we cache our debs, gems, and ami files
+ [[ $DEB_CACHE ]] || DEB_CACHE="$CACHE_DIR/$UBUNTU_CODENAME/debs"
+ [[ $GEM_CACHE ]] || GEM_CACHE="$CACHE_DIR/gems"
+ [[ $AMI_CACHE ]] || AMI_CACHE="$CACHE_DIR/amis"
+
+ # The name of the Ubuntu iso we are using as a base.
+ [[ $UBUNTU_ISO ]] || UBUNTU_ISO="ubuntu-$UBUNTU_VERSION-server-amd64.iso"
+
+ # directory we will mount the Ubuntu .iso on to extract packages.
+ [[ $UBUNTU_DIR ]] || UBUNTU_DIR="$IMAGE_DIR/${UBUNTU_ISO%.iso}"
+
+
+ # Make any directories we don't already have
+ for d in "$ISO_LIBRARY" "$ISO_DEST" "$IMAGE_DIR" "$BUILD_DIR" "$AMI_CACHE" \
+ "$SLEDGEHAMMER_PXE_DIR" "$UBUNTU_CHROOT"; do
+ mkdir -p "$d"
+ done
+
+ # Make sure Sledgehammer has already been built and pre-staged.
+ if ! [[ -f $SLEDGEHAMMER_DIR/bin/sledgehammer-tftpboot.tar.gz || \
+ -f $SLEDGEHAMMER_PXE_DIR/initrd0.img ]]; then
+ echo "Slegehammer TFTP image missing!"
+ echo "Please build Sledgehammer from $SLEDGEHAMMER_DIR before buildin gCrowbar."
+ exit 1
+ fi
+
+ # make sure we have the AMIs we want
+ for ami in "${AMIS[@]}"; do
+ [[ -f $AMI_CACHE/${ami##*/} ]] && continue
+ echo "$(date '+%F %T %z'): Downloading and caching $ami"
+ curl -o "$AMI_CACHE/${ami##*/}" "$ami" || \
+ die 1 "Could not download $ami"
+ done
+
+ # Try and download our ISO if we don't already have it
+ [[ -f $ISO_LIBRARY/$UBUNTU_ISO ]] || {
+ echo "$(date '+%F %T %z'): Downloading and caching $UBUNTU_ISO"
+ curl -o "$ISO_LIBRARY/$UBUNTU_ISO" \
+ "$UBUNTU_ISO_MIRROR/ubuntu-iso/CDs/$UBUNTU_VERSION/$UBUNTU_ISO" || \
+ die 1 "Missing our Ubuntu source image"
+ }
+
+ # Start with a clean slate.
+ clean_dirs "$UBUNTU_DIR" "$BUILD_DIR"
+
+ (cd "$CROWBAR_DIR"; $VCS_CLEAN_CMD)
+ # Copy everything off the Ubuntu ISO to our build directory
+ debug "Copying Ubuntu off $UBUNTU_ISO"
+ sudo mount -t iso9660 -o loop "$ISO_LIBRARY/$UBUNTU_ISO" "$UBUNTU_DIR" || \
+ die "Could not mount $UBUNTU_ISO"
+ cp -rT "$UBUNTU_DIR" "$BUILD_DIR"
+ sudo umount -d "$UBUNTU_DIR"
+
+ # Make everything writable again.
+ chmod -R u+w "$BUILD_DIR"
+
+ # Make additional directories we will need.
+ for d in discovery extra ami updates ; do
+ mkdir -p "$BUILD_DIR/$d"
+ done
+
+ # Copy over the Crowbar bits and their prerequisites
+ debug "Staging extra Crowbar bits"
+ cp -r "$CROWBAR_DIR/ubuntu-$UBUNTU_VERSION-extra"/* "$BUILD_DIR/extra"
+ cp -r "$CROWBAR_DIR/change-image"/* "$BUILD_DIR"
+
+ # If we were asked to update our cache, do it.
+ maybe_update_cache "$@"
+
+ # Copy our extra debs, gems, and amis over
+ debug "Copying debs, gems, and amis"
+ copy_debs "$BUILD_DIR/pool" "$DEB_CACHE" "$BUILD_DIR/extra/debs"
+ cp -r "$GEM_CACHE" "$BUILD_DIR/extra"
+ cp -r "$AMI_CACHE/." "$BUILD_DIR/ami/."
+
+ # Make our new packages repository.
+ ( cd "$BUILD_DIR/extra"
+ debug "Recreating Packages.gz"
+ dpkg-scanpackages debs /dev/null 2>/dev/null |gzip -9 >Packages.gz)
+ # Store off the version
+ echo "$VERSION" >> "$BUILD_DIR/dell/Version"
+
+ # Fix up the initrd
+ ( cd "$CROWBAR_DIR/initrd"
+ debug "Fixing up initrd"
+ [[ -d scratch ]] && rm -rf scratch
+ mkdir scratch
+ # Grab _all_ the nic drivers. We probably don't need them,
+ # but a little paranoia never hurt anyone.
+ ( cd scratch;
+ debug "Adding all nic drivers"
+ for udeb in "$BUILD_DIR/pool/main/l/linux/"nic-*-generic-*.udeb; do
+ ar x "$udeb"
+ tar xzf data.tar.gz
+ rm -rf debian-binary *.tar.gz
+ done
+ # Make sure installing off a USB connected DVD will work
+ debug "Adding USB connected DVD support"
+ mkdir -p var/lib/dpkg/info
+ cp ../cdrom-detect.postinst var/lib/dpkg/info
+ # Append our new gzipped CPIO archive onto the old one.
+ find . |cpio --create --format=newc --owner root:root 2>/dev/null | \
+ gzip -9 >> "$BUILD_DIR/install/initrd.gz" )
+ rm -rf scratch )
+
+ # Copy over the Sledgehammer bits
+ debug "Copying over Sledgehammer bits"
+ for d in "$CROWBAR_DIR/"updates*; do
+ [[ -d $d ]] || continue
+ cp -r "$d"/* "$BUILD_DIR/updates"
+ done
+ # If we need to copy over a new Sledgehammer image, do so.
+ if [[ $SLEDGEHAMMER_DIR/bin/sledgehammer-tftpboot.tar.gz -nt \
+ $SLEDGEHAMMER_PXE_DIR/initrd0.img ]]; then
+ ( cd $SLEDGEHAMMER_PXE_DIR
+ debug "Extracting new Sledgehammer TFTP boot image"
+ rm -rf .
+ cd ..
+ tar xzf "$SLEDGEHAMMER_DIR/bin/sledgehammer-tftpboot.tar.gz"
+ rm -f "$SLEDGEHAMMER_DIR/bin/sledgehammer-tftpboot.tar.gz"
+ )
+ fi
+ cp -a "$SLEDGEHAMMER_PXE_DIR"/* "$BUILD_DIR/discovery"
+
+ # Make our image
+ debug "Creating new ISO"
+ ( cd "$BUILD_DIR"
+ find -name '.svn' -type d -exec rm -rf '{}' ';' 2>/dev/null >/dev/null
+ mkdir -p $ISO_DEST
+ mkisofs -r -V "Crowbar $VERSION DVD" -cache-inodes -J -l -quiet \
+ -b isolinux/isolinux.bin -c isolinux/boot.cat \
+ -no-emul-boot --boot-load-size 4 -boot-info-table \
+ -o "$ISO_DEST/$OPENSTACK_ISO" "$BUILD_DIR" ) || \
+ die 1 "There was a problem building our ISO."
+ echo "$(date '+%F %T %z'): Finshed. Image at $ISO_DEST/$OPENSTACK_ISO"
+} 65> /tmp/.build_crowbar.lock
diff --git a/crowbar/change-image/dell/PC6200v3.2.0.7.stk b/crowbar/change-image/dell/PC6200v3.2.0.7.stk
new file mode 100644
index 00000000000..9914bcd17a0
Binary files /dev/null and b/crowbar/change-image/dell/PC6200v3.2.0.7.stk differ
diff --git a/crowbar/change-image/dell/apt.conf b/crowbar/change-image/dell/apt.conf
new file mode 100644
index 00000000000..8602f01c0d5
--- /dev/null
+++ b/crowbar/change-image/dell/apt.conf
@@ -0,0 +1 @@
+APT::Get::AllowUnauthenticated 1 ;
diff --git a/crowbar/change-image/dell/barclamp_lib.rb b/crowbar/change-image/dell/barclamp_lib.rb
new file mode 100755
index 00000000000..675808a6c0f
--- /dev/null
+++ b/crowbar/change-image/dell/barclamp_lib.rb
@@ -0,0 +1,444 @@
+
+require 'rubygems'
+require 'net/http'
+require 'net/http/digest_auth'
+require 'uri'
+require 'json'
+require 'getoptlong'
+
+@debug = false
+@hostname = ENV["CROWBAR_IP"]
+# DO NOT CHANGE THE NEXT 2 LINES
+# gather_cli replies on the exact format they are in.
+@hostname = "127.0.0.1" unless @hostname
+@port = 3000
+@headers = {
+ "Accept" => "application/json",
+ "Content-Type" => "application/json"
+}
+@data = ""
+@allow_zero_args = false
+@timeout = 500
+@key = ENV["CROWBAR_KEY"]
+if @key
+ @username=@key.split(':',2)[0]
+ @password=@key.split(':',2)[1]
+end
+
+#
+# Parsing options can be added by adding to this list before calling opt_parse
+#
+@options = [
+ [ [ '--help', '-h', GetoptLong::NO_ARGUMENT ], "--help or -h - help" ],
+ [ [ '--username', '-U', GetoptLong::REQUIRED_ARGUMENT ], "--username or -U - specifies the username" ],
+ [ [ '--password', '-P', GetoptLong::REQUIRED_ARGUMENT ], "--password or -P - specifies the password" ],
+ [ [ '--hostname', '-n', GetoptLong::REQUIRED_ARGUMENT ], "--hostname or -n - specifies the destination server" ],
+ [ [ '--port', '-p', GetoptLong::REQUIRED_ARGUMENT ], "--port or -p - specifies the destination server port" ],
+ [ [ '--debug', '-d', GetoptLong::NO_ARGUMENT ], "--debug or -d - turns on debugging information" ],
+ [ [ '--data', GetoptLong::REQUIRED_ARGUMENT ], "--data - used by create or edit as data (must be in json format)" ],
+ [ [ '--file', GetoptLong::REQUIRED_ARGUMENT ], "--file - used by create or edit as data when read from a file (must be in json format)" ],
+ [ [ '--timeout', GetoptLong::REQUIRED_ARGUMENT ], "--timeout - timeout in seconds for read http reads" ]
+]
+
+#
+# New commands can be added by adding to this list before calling run_command
+#
+# Proposal is an example of running sub-commands
+#
+@proposal_commands = {
+ "list" => [ "proposal_list", "list - show a list of current proposals" ],
+ "create" => [ "proposal_create ARGV.shift", "create - create a proposal" ],
+ "show" => [ "proposal_show ARGV.shift", "show - show a specific proposal" ],
+ "edit" => [ "proposal_edit ARGV.shift", "edit - edit a new proposal" ],
+ "delete" => [ "proposal_delete ARGV.shift", "delete - delete a proposal" ],
+ "commit" => [ "proposal_commit ARGV.shift", "commit - Commit a proposal to active" ],
+ "dequeue" => [ "proposal_dequeue ARGV.shift", "dequeue - Dequeue a proposal to active" ]
+}
+
+@commands = {
+ "help" => [ "help", "help - this page" ],
+ "api_help" => [ "api_help", "crowbar API help - help for this barclamp." ],
+ "list" => [ "list", "list - show a list of current configs" ],
+ "show" => [ "show ARGV.shift", "show - show a specific config" ],
+ "delete" => [ "delete ARGV.shift", "delete - delete a config" ],
+ "proposal" => [ "run_sub_command(@proposal_commands, ARGV.shift)", "proposal - Proposal sub-commands", @proposal_commands ],
+ "elements" => [ "elements", "elements - List elements of a #{@barclamp} deploy" ],
+ "element_node" => [ "element_node ARGV.shift", "element_node - List nodes that could be that element" ],
+ "transition" => [ "transition(ARGV.shift,ARGV.shift)", "transition - Transition machine named name to state" ]
+}
+
+
+def print_commands(cmds, spacer = " ")
+ cmds.each do |key, command|
+ puts "#{spacer}#{command[1]}"
+ print_commands(command[2], " #{spacer}") if command[0] =~ /run_sub_command\(/
+ end
+end
+
+def usage (rc)
+ puts "Usage: crowbar #{@barclamp} [options] "
+ @options.each do |options|
+ puts " #{options[1]}"
+ end
+ print_commands(@commands)
+ exit rc
+end
+
+def help
+ usage 0
+end
+
+def authenticate(req,uri,data=nil)
+ uri.user=@username
+ uri.password=@password
+ res=nil
+ Net::HTTP.start(uri.host, uri.port) {|http|
+ http.read_timeout = @timeout
+ r = req.new(uri.request_uri,@headers)
+ r.body = data if data
+ res = http.request r
+ puts "DEBUG: (a) return code: #{res.code}" if @debug
+ puts "DEBUG: (a) return body: #{res.body}" if @debug
+ puts "DEBUG: (a) return headers: #{res.headers}" if @debug
+ if res['www-authenticate']
+ digest_auth=Net::HTTP::DigestAuth.new
+ auth=Net::HTTP::DigestAuth.new.auth_header(uri,
+ res['www-authenticate'],
+ req::METHOD)
+ r.add_field 'Authorization', auth
+ res = http.request r
+ end
+ }
+ res
+end
+
+def get_json(path)
+ uri = URI.parse("http://#{@hostname}:#{@port}/crowbar/#{@barclamp}/1.0#{path}")
+ res = authenticate(Net::HTTP::Get,uri)
+
+ puts "DEBUG: (g) hostname: #{uri.host}:#{uri.port}" if @debug
+ puts "DEBUG: (g) request: #{uri.path}" if @debug
+ puts "DEBUG: (g) return code: #{res.code}" if @debug
+ puts "DEBUG: (g) return body: #{res.body}" if @debug
+
+ return [res.body, res.code.to_i ] if res.code.to_i != 200
+
+ struct = JSON.parse(res.body)
+
+ puts "DEBUG: (g) JSON parse structure = #{struct.inspect}" if @debug
+
+ return [struct, 200]
+end
+
+def post_json(path, data)
+ uri = URI.parse("http://#{@hostname}:#{@port}/crowbar/#{@barclamp}/1.0#{path}")
+ res = authenticate(Net::HTTP::Post,uri,data)
+
+ puts "DEBUG: (post) hostname: #{uri.host}:#{uri.port}" if @debug
+ puts "DEBUG: (post) request: #{uri.path}" if @debug
+ puts "DEBUG: (post) data: #{@data}" if @debug
+ puts "DEBUG: (post) return code: #{res.code}" if @debug
+ puts "DEBUG: (post) return body: #{res.body}" if @debug
+
+ [res.body, res.code.to_i ]
+end
+
+def put_json(path, data)
+ uri = URI.parse("http://#{@hostname}:#{@port}/crowbar/#{@barclamp}/1.0#{path}")
+ res = authenticate(Net::HTTP::Put,uri,data)
+
+ puts "DEBUG: (put) hostname: #{uri.host}:#{uri.port}" if @debug
+ puts "DEBUG: (put) request: #{uri.path}" if @debug
+ puts "DEBUG: (put) data: #{@data}" if @debug
+ puts "DEBUG: (put) return code: #{res.code}" if @debug
+ puts "DEBUG: (put) return body: #{res.body}" if @debug
+
+ [res.body, res.code.to_i ]
+end
+
+def delete_json(path)
+ uri = URI.parse("http://#{@hostname}:#{@port}/crowbar/#{@barclamp}/1.0#{path}")
+ res = authenticate(Net::HTTP::Delete,uri)
+
+ puts "DEBUG: (d) hostname: #{uri.host}:#{uri.port}" if @debug
+ puts "DEBUG: (d) request: #{uri.path}" if @debug
+ puts "DEBUG: (d) return code: #{res.code}" if @debug
+ puts "DEBUG: (d) return body: #{res.body}" if @debug
+
+ [res.body, res.code.to_i ]
+end
+
+
+def list
+ struct = get_json("/")
+
+ if struct[1] != 200
+ [ "Failed to talk to service list: #{struct[1]}: #{struct[0]}", 1 ]
+ elsif struct[0].nil? or struct[0].empty?
+ [ "No current configurations", 0 ]
+ else
+ out = ""
+ struct[0].each do |name|
+ out = out + "\n" if out != ""
+ out = out + "#{name}"
+ end
+ [ out, 0 ]
+ end
+end
+
+def api_help
+ struct=get_json("/help")
+ if struct[1] != 200
+ [ "Failed to talk to service list: #{struct[1]}: #{struct[0]}", 1 ]
+ elsif struct[0].nil? or struct[0].empty?
+ [ "No help", 0 ]
+ else
+ [ jj(struct[0]), 0 ]
+ end
+end
+
+def show(name)
+ usage -1 if name.nil? or name == ""
+
+ struct = get_json("/#{name}")
+
+ if struct[1] == 200
+ [ "#{JSON.pretty_generate(struct[0])}", 0 ]
+ elsif struct[1] == 404
+ [ "No current configuration for #{name}", 1 ]
+ else
+ [ "Failed to talk to service show: #{struct[1]}: #{struct[0]}", 1 ]
+ end
+end
+
+def delete(name)
+ usage -1 if name.nil? or name == ""
+
+ struct = delete_json("/#{name}")
+
+ if struct[1] == 200
+ [ "Deleted #{name}", 0 ]
+ elsif struct[1] == 404
+ [ "Delete failed for #{name}: Not Found", 1 ]
+ else
+ [ "Failed to talk to service delete: #{struct[1]}: #{struct[0]}", 1 ]
+ end
+end
+
+def proposal_list
+ struct = get_json("/proposals/")
+
+ if struct[1] != 200
+ [ "Failed to talk to service proposal list: #{struct[1]}: #{struct[0]}", 1 ]
+ elsif struct[0].nil? or struct[0].empty?
+ [ "No current proposals", 0 ]
+ else
+ out = ""
+ struct[0].each do |name|
+ out = out + "\n" if out != ""
+ out = out + "#{name}"
+ end
+ [ out, 0 ]
+ end
+end
+
+def proposal_show(name)
+ usage -1 if name.nil? or name == ""
+
+ struct = get_json("/proposals/#{name}")
+
+ if struct[1] == 200
+ [ "#{JSON.pretty_generate(struct[0])}", 0 ]
+ elsif struct[1] == 404
+ [ "No current proposal for #{name}", 1 ]
+ else
+ [ "Failed to talk to service proposal show: #{struct[1]}: #{struct[0]}", 1 ]
+ end
+end
+
+def proposal_create(name)
+ usage -1 if name.nil? or name == ""
+
+ @data = "{\"id\":\"#{name}\"}" if @data.nil? or @data == ""
+
+ struct = put_json("/proposals", @data)
+
+ if struct[1] == 200
+ [ "Created #{name}", 0 ]
+ else
+ [ "Failed to talk to service proposal create: #{struct[1]}: #{struct[0]}", 1]
+ end
+end
+
+def proposal_edit(name)
+ usage -1 if name.nil? or name == ""
+
+ struct = post_json("/proposals/#{name}", @data)
+
+ if struct[1] == 200
+ [ "Edited #{name}", 0 ]
+ elsif struct[1] == 404
+ [ "Failed to edit: #{name} : Not Found", 1 ]
+ elsif struct[1] == 400
+ [ "Failed to edit: #{name} : Errors in data\n#{struct[0]}", 1 ]
+ else
+ [ "Failed to talk to service proposal edit: #{struct[1]}: #{struct[0]}", 1 ]
+ end
+end
+
+def proposal_delete(name)
+ usage -1 if name.nil? or name == ""
+
+ struct = delete_json("/proposals/#{name}")
+
+ if struct[1] == 200
+ [ "Deleted #{name}", 0 ]
+ elsif struct[1] == 404
+ [ "Delete failed for #{name}: Not Found", 1 ]
+ else
+ [ "Failed to talk to service delete: #{struct[1]}: #{struct[0]}", 1 ]
+ end
+end
+
+def proposal_commit(name)
+ usage -1 if name.nil? or name == ""
+
+ struct = post_json("/proposals/commit/#{name}", @data)
+
+ if struct[1] == 200
+ [ "Committed #{name}", 0 ]
+ elsif struct[1] == 202
+ [ "Queued #{name} because #{struct[0]}", 0 ]
+ else
+ [ "Failed to talk to service proposal commit: #{struct[1]}: #{struct[0]}", 1 ]
+ end
+end
+
+def proposal_dequeue(name)
+ usage -1 if name.nil? or name == ""
+
+ struct = post_json("/proposals/dequeue/#{name}", @data)
+
+ if struct[1] == 200
+ [ "Dequeued #{name}", 0 ]
+ else
+ [ "Failed to talk to service proposal dequeue: #{struct[1]}: #{struct[0]}", 1 ]
+ end
+end
+
+def elements
+ struct = get_json("/elements")
+
+ if struct[1] != 200
+ [ "Failed to talk to service elements: #{struct[1]}: #{struct[0]}", 1 ]
+ elsif struct[0].nil? or struct[0].empty?
+ [ "No current elements", 1 ]
+ else
+ out = ""
+ struct[0].each do |name|
+ out = out + "\n" if out != ""
+ out = out + "#{name}"
+ end
+ [ out, 0 ]
+ end
+end
+
+def element_node(element)
+ usage -1 if element.nil? or element == ""
+
+ struct = get_json("/elements/#{element}")
+
+ if struct[1] != 200
+ [ "Failed to talk to service element_node: #{struct[1]}: #{struct[0]}", 1 ]
+ elsif struct[0].nil? or struct[0].empty?
+ [ "No nodes for #{element}", 1 ]
+ else
+ out = ""
+ struct[0].each do |name|
+ out = out + "\n" if out != ""
+ out = out + "#{name}"
+ end
+ [ out, 0 ]
+ end
+end
+
+def transition(name, state)
+ usage -1 if name.nil? or name == ""
+
+ data = {
+ "name" => name,
+ "state" => state
+ }
+ struct = post_json("/transition/default", data.to_json)
+
+ if struct[1] == 200
+ [ "Transitioned #{name}", 0 ]
+ else
+ [ "Failed to talk to service transition: #{struct[1]}: #{struct[0]}", 1 ]
+ end
+end
+
+
+
+### Start MAIN ###
+
+def opt_parse()
+ sub_options = @options.map { |x| x[0] }
+ lsub_options = @options.map { |x| [ x[0][0], x[2] ] }
+ opts = GetoptLong.new(*sub_options)
+
+ opts.each do |opt, arg|
+ case opt
+ when '--help'
+ usage 0
+ when '--debug'
+ @debug = true
+ when '--hostname'
+ @hostname = arg
+ when '--username'
+ @username = arg
+ when '--password'
+ @password = arg
+ when '--port'
+ @port = arg.to_i
+ when '--data'
+ @data = arg
+ when '--timeout'
+ @timeout = arg
+ when '--file'
+ @data = File.read(arg)
+ else
+ found = false
+ lsub_options.each do |x|
+ next if x[0] != opt
+ eval x[1]
+ found = true
+ end
+ usage -1 unless found
+ end
+ end
+
+ if ARGV.length == 0 and !@allow_zero_args
+ usage -1
+ end
+
+ STDERR.puts "CROWBAR_KEY not set, will not be able to authenticate!" if @username.nil? or @password.nil?
+ STDERR.puts "Please set CROWBAR_KEY or use -U and -P" if @username.nil? or @password.nil?
+end
+
+def run_sub_command(cmds, subcmd)
+ cmd = cmds[subcmd]
+ usage -2 if cmd.nil?
+ eval cmd[0]
+end
+
+def run_command()
+ run_sub_command(@commands, ARGV.shift)
+end
+
+def main()
+ opt_parse
+ res = run_command
+ puts res[0]
+ exit res[1]
+end
diff --git a/crowbar/change-image/dell/barclamps/crowbar/Makefile b/crowbar/change-image/dell/barclamps/crowbar/Makefile
new file mode 100644
index 00000000000..6584fe2a4da
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/crowbar/Makefile
@@ -0,0 +1,21 @@
+
+clean:
+ @echo "Cleaning barclamp-crowbar"
+
+distclean:
+ @echo "Dist-Cleaning barclamp-crowbar"
+
+all: clean build install
+
+build:
+ @echo "Building barclamp-crowbar"
+
+install:
+ @echo "Installing barclamp-crowbar"
+ mkdir -p ${DESTDIR}/opt/crowbar/openstack_manager
+ cp -r app ${DESTDIR}/opt/crowbar/openstack_manager
+ mkdir -p ${DESTDIR}/usr/share/barclamp-crowbar
+ cp -r chef ${DESTDIR}/usr/share/barclamp-crowbar
+ mkdir -p ${DESTDIR}/usr/bin
+ cp -r command_line/* ${DESTDIR}/usr/bin
+
diff --git a/crowbar/change-image/dell/barclamps/crowbar/app/controllers/crowbar_controller.rb b/crowbar/change-image/dell/barclamps/crowbar/app/controllers/crowbar_controller.rb
new file mode 100644
index 00000000000..13ebcf3d7ec
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/crowbar/app/controllers/crowbar_controller.rb
@@ -0,0 +1,21 @@
+# Copyright 2011, Dell
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+class CrowbarController < BarclampController
+ def initialize
+ @service_object = CrowbarService.new(logger)
+ end
+end
+
diff --git a/crowbar/change-image/dell/barclamps/crowbar/app/models/crowbar_service.rb b/crowbar/change-image/dell/barclamps/crowbar/app/models/crowbar_service.rb
new file mode 100644
index 00000000000..7ee17a5e540
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/crowbar/app/models/crowbar_service.rb
@@ -0,0 +1,203 @@
+# Copyright 2011, Dell
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+class CrowbarService < ServiceObject
+
+ def initialize(thelogger)
+ @bc_name = "crowbar"
+ @logger = thelogger
+ end
+
+ #
+ # Below are the parts to handle transition requests.
+ #
+ # This routine handles name-based state transitions. The system will then inform barclamps.
+ # It will create a node and assign it an admin address.
+ #
+ def transition(inst, name, state)
+ save_it = false
+
+ @logger.info("Crowbar transition enter: #{name} to #{state}")
+
+ node = NodeObject.find_node_by_name name
+ if node.nil? and (state == "discovering" or state == "testing")
+ @logger.debug("Crowbar transition: creating new node for #{name} to #{state}")
+ node = Chef::Node.new
+ node["crowbar"] = {}
+
+ node[:fqdn] = name
+ node.name name
+
+ node = NodeObject.new node
+ node.save
+ end
+ if node.nil?
+ @logger.error("Crowbar transition leaving: node not found nor created - #{name} to #{state}")
+ return [200, {}]
+ end
+
+ node["crowbar"] = {} if node["crowbar"].nil?
+ node["crowbar"]["network"] = {} if node["crowbar"]["network"].nil?
+ node["crowbar"]["decoration"] = { :name=> name }
+
+ pop_it = false
+ if node[:state] != state
+ @logger.debug("Crowbar transition: state has changed so we need to do stuff for #{name} to #{state}")
+
+ node["crowbar"]["state_debug"] = {} if node["crowbar"]["state_debug"].nil?
+ if node["crowbar"]["state_debug"][state].nil?
+ node["crowbar"]["state_debug"][state] = 1
+ else
+ node["crowbar"]["state_debug"][state] = node["crowbar"]["state_debug"][state] + 1
+ end
+
+ node[:state] = state
+ save_it = true
+ pop_it = true
+ end
+
+ node.save if save_it
+
+ if pop_it
+ crole = RoleObject.find_role_by_name("crowbar-config-#{inst}")
+ ro = crole.default_attributes["crowbar"]["run_order"]
+
+ #
+ # If we are discovering the node and it is an admin, make sure that we add the crowbar config
+ #
+ if state == "discovering" and node.admin?
+ db = ProposalObject.find_proposal("crowbar", inst)
+ add_role_to_instance_and_node("crowbar", inst, name, db, crole, "crowbar")
+ end
+
+ roles = RoleObject.find_roles_by_search "transitions:true AND (transition_list:all OR transition_list:#{ChefObject.chef_escape(state)})"
+ # Make sure the deployer objects run first.
+ roles.sort! do |x,y|
+ xname = x.name.gsub(/-config-.*$/, "")
+ yname = y.name.gsub(/-config-.*$/, "")
+
+ xs = 1000
+ xs = ro[xname] unless ro[xname].nil?
+ ys = 1000
+ ys = ro[yname] unless ro[yname].nil?
+ xs <=> ys
+ end
+
+ roles.each do |role|
+ role.override_attributes.each do |bc, data|
+ jsondata = {
+ "name" => name,
+ "state" => state
+ }
+ rname = role.name.gsub("#{bc}-config-","")
+ begin
+ @logger.info("Crowbar transition: calling #{bc}:#{rname} for #{name} for #{state}")
+ service = eval("#{bc.capitalize}Service.new @logger")
+ answer = service.transition(rname, name, state)
+ if answer[0] != 200
+ @logger.error("Crowbar transition: finished #{bc}:#{rname} for #{name} for #{state}: FAILED #{answer[1]}")
+ else
+ @logger.debug("Crowbar transition: finished #{bc}:#{rname} for #{name} for #{state}")
+ unless answer[1]["name"].nil?
+ name = answer[1]["name"]
+ end
+ end
+ rescue Exception => e
+ @logger.fatal("json/transition for #{bc}:#{rname} failed: #{e.message}")
+ @logger.fatal("#{e.backtrace}")
+ end
+ end
+ end
+
+ # We have a node that has become ready, test to see if there are queued proposals to commit
+ process_queue if state == "ready"
+ end
+
+ @logger.debug("Crowbar transition leaving: #{name} to #{state}")
+ [200, NodeObject.find_node_by_name(name).to_hash ]
+ end
+
+ def create_proposal
+ @logger.debug("Crowbar create_proposal enter")
+ base = super
+ @logger.debug("Crowbar create_proposal exit")
+ base
+ end
+
+ def apply_role (role, inst)
+ @logger.debug("Crowbar apply_role: enter")
+ answer = super
+ @logger.debug("Crowbar apply_role: super apply_role finished")
+
+ node = role.default_attributes
+ @logger.debug("Crowbar apply_role: create initial instances")
+ unless node["crowbar"].nil? or node["crowbar"]["instances"].nil?
+ node["crowbar"]["instances"].each do |k,plist|
+ plist.each do |v|
+ id = "default"
+ data = "{\"id\":\"#{id}\"}"
+ if v != "default"
+ file = File.open(v, "r")
+ data = file.readlines.to_s
+ file.close
+
+ struct = JSON.parse(data)
+ id = struct["id"].gsub("bc-#{k}-", "")
+ end
+
+ @logger.debug("Crowbar apply_role: creating #{k}.#{id}")
+
+ # Create a service to talk to.
+ service = eval("#{k.capitalize}Service.new @logger")
+
+ @logger.debug("Crowbar apply_role: Calling get to see if it already exists: #{k}.#{id}")
+ answer = service.proposals
+ if answer[0] != 200
+ @logger.error("Failed to list #{k}: #{answer[0]} : #{answer[1]}")
+ else
+ unless answer[1].include?(id)
+ @logger.debug("Crowbar apply_role: didn't already exist, creating proposal for #{k}.#{id}")
+ answer = service.proposal_create JSON.parse(data)
+ if answer[0] != 200
+ @logger.error("Failed to create #{k}.#{id}: #{answer[0]} : #{answer[1]}")
+ end
+ end
+
+ @logger.debug("Crowbar apply_role: check to see if it is already active: #{k}.#{id}")
+ answer = service.list_active
+ if answer[0] != 200
+ @logger.error("Failed to list active #{k}: #{answer[0]} : #{answer[1]}")
+ else
+ unless answer[1].include?(id)
+ @logger.debug("Crowbar apply_role: #{k}.#{id} wasn't active: Activating")
+ answer = service.proposal_commit id
+ if answer[0] != 200
+ @logger.error("Failed to commit #{k}.#{id}: #{answer[0]} : #{answer[1]}")
+ end
+ end
+ end
+ end
+
+ @logger.fatal("Crowbar apply_role: Done with creating: #{k}.#{id}")
+ end
+ end
+ end
+
+ @logger.debug("Crowbar apply_role: leaving: #{answer}")
+ answer
+ end
+
+end
+
diff --git a/crowbar/change-image/dell/barclamps/crowbar/barclamp-crowbar.spec b/crowbar/change-image/dell/barclamps/crowbar/barclamp-crowbar.spec
new file mode 100644
index 00000000000..52fdbd76929
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/crowbar/barclamp-crowbar.spec
@@ -0,0 +1,52 @@
+
+%define _topdir BUILD_DIR
+%define name barclamp-crowbar
+%define release RPM_CONTEXT_NUMBER
+%define version MAJOR_VERSION.MINOR_VERSION
+%define buildroot %{_topdir}/%{name}-%{version}-root
+
+BuildRoot: %{buildroot}
+Summary: Core functionaly within Crowbar
+License: Apache 2.0
+Name: %{name}
+BuildArch: noarch
+Version: %{version}
+Release: %{release}
+Source: %{name}-%{version}.tar.gz
+Prefix: /
+Group: Development/Tools
+
+%description
+A Crowbar Barclamp that manages crowbar deployments within a Crowbar environment.
+
+%prep
+%setup -q
+
+%build
+
+%install
+make install DESTDIR=${RPM_BUILD_ROOT}
+
+%post
+cd /usr/share/barclamp-crowbar/chef/cookbooks
+knife cookbook upload -o . -a -u chef-webui -k /etc/chef/webui.pem
+
+cd /usr/share/barclamp-crowbar/chef/data_bags/crowbar
+for i in *.json; do
+ knife data bag from file crowbar $i
+done
+
+cd /usr/share/barclamp-crowbar/chef/roles
+for i in *.rb; do
+ knife role from file $i
+done
+
+service httpd graceful
+
+
+%files
+%defattr(-,root,root)
+/usr/bin
+/usr/share
+/opt
+
diff --git a/crowbar/change-image/dell/barclamps/crowbar/build_deb.sh b/crowbar/change-image/dell/barclamps/crowbar/build_deb.sh
new file mode 100755
index 00000000000..79bf21d2ba7
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/crowbar/build_deb.sh
@@ -0,0 +1,17 @@
+#
+# Must have tools:
+# apt-get install dpkg-dev debhelper devscripts fakeroot linda dh-make
+#
+
+. ./version.sh
+
+sed -e "s/CHANGE_LOG_LINE/barclamp-${BARCLAMP_NAME} (${MAJOR_VERSION}.${MINOR_VERSION}-${DEB_CONTEXT_NUMBER}) unstable; urgency=low/" debian/changelog.tmpl > debian/changelog
+
+
+yes | debuild -us -uc
+
+mkdir -p bin
+mv ../barclamp-${BARCLAMP_NAME}_*.deb bin
+mv ../barclamp-${BARCLAMP_NAME}_*gz bin
+rm ../barclamp-${BARCLAMP_NAME}_*
+
diff --git a/crowbar/change-image/dell/barclamps/crowbar/build_rpm.sh b/crowbar/change-image/dell/barclamps/crowbar/build_rpm.sh
new file mode 100755
index 00000000000..c15d9be527a
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/crowbar/build_rpm.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+
+#
+# Needs sudo apt-get install rpm
+#
+
+. ./version.sh
+
+BUILD_DIR="/tmp/build.$$"
+rm -rf ${BUILD_DIR}
+mkdir -p ${BUILD_DIR}/BUILD
+mkdir -p ${BUILD_DIR}/RPMS
+mkdir -p ${BUILD_DIR}/SOURCES
+mkdir -p ${BUILD_DIR}/SPECS
+mkdir -p ${BUILD_DIR}/SRPMS
+
+FULL_NAME="barclamp-${BARCLAMP_NAME}-${MAJOR_VERSION}.${MINOR_VERSION}"
+
+mkdir $FULL_NAME
+cp -r Makefile app chef command_line $FULL_NAME
+tar -zcf ${BUILD_DIR}/SOURCES/${FULL_NAME}.tar.gz ${FULL_NAME}
+rm -rf ${FULL_NAME}
+
+sed -e "s%BUILD_DIR%$BUILD_DIR%" barclamp-${BARCLAMP_NAME}.spec > ${BUILD_DIR}/SPECS/barclamp-${BARCLAMP_NAME}.spec
+sed -ie "s%MAJOR_VERSION%${MAJOR_VERSION}%" ${BUILD_DIR}/SPECS/barclamp-${BARCLAMP_NAME}.spec
+sed -ie "s%MINOR_VERSION%${MINOR_VERSION}%" ${BUILD_DIR}/SPECS/barclamp-${BARCLAMP_NAME}.spec
+sed -ie "s%RPM_CONTEXT_NUMBER%${RPM_CONTEXT_NUMBER}%" ${BUILD_DIR}/SPECS/barclamp-${BARCLAMP_NAME}.spec
+
+rpmbuild -v -ba --clean ${BUILD_DIR}/SPECS/barclamp-${BARCLAMP_NAME}.spec
+
+mkdir -p bin
+cp ${BUILD_DIR}/RPMS/noarch/* bin
+cp ${BUILD_DIR}/SRPMS/* bin
+#rm -rf ${BUILD_DIR}
diff --git a/crowbar/change-image/dell/barclamps/crowbar/chef/cookbooks/crowbar/README.rdoc b/crowbar/change-image/dell/barclamps/crowbar/chef/cookbooks/crowbar/README.rdoc
new file mode 100644
index 00000000000..bddd59c4be5
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/crowbar/chef/cookbooks/crowbar/README.rdoc
@@ -0,0 +1,51 @@
+= DESCRIPTION:
+
+
+= REQUIREMENTS:
+
+== Platform:
+
+
+== Cookbooks:
+
+
+* ruby
+* apache2
+* passenger
+
+= ATTRIBUTES:
+
+* rails[:version] - Install the specified version. Default false (installs latest).
+* rails[:environment] - Set Rails environment. Default production.
+
+= USAGE:
+
+The recommended Rails application deployment method is Passenger and use the Apache2 cookbook's web_app define.
+
+ include_recipe "apache2"
+ include_recipe "passenger"
+ include_recipe "rails"
+
+ web_app "some_rails_app" do
+ docroot "/srv/some_rails_app/public"
+ template "some_rails_app.conf.erb"
+ end
+
+We provide an example rails application vhost config file in this cookbook. Remember, for Passenger, DocumentRoot (docroot) needs 'public'. Per the web_app define, other parameters can be passed arbitrarily and used in the template.
+
+= LICENSE and AUTHOR:
+
+Author:: Joshua Timberman ()
+Copyright:: 2009, Opscode, Inc
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/crowbar/change-image/dell/barclamps/crowbar/chef/cookbooks/crowbar/files/default/crowbar b/crowbar/change-image/dell/barclamps/crowbar/chef/cookbooks/crowbar/files/default/crowbar
new file mode 100755
index 00000000000..8a073a4238f
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/crowbar/chef/cookbooks/crowbar/files/default/crowbar
@@ -0,0 +1,52 @@
+#!/bin/bash
+#
+# Mark the admin node as ready on reboot.
+#
+
+IP="127.0.0.1"
+
+exec 2>>/var/log/crowbar-join.errlog
+
+export PS4='${BASH_SOURCE}@${LINENO}(${FUNCNAME[0]}): '
+set -x
+
+if [[ -f /etc/crowbar.install.key ]]; then
+ export CROWBAR_KEY="$(cat /etc/crowbar.install.key)"
+fi
+
+# Run a command and log its output.
+log_to() {
+ # $1 = install log to log to
+ # $@ = rest of args
+ local __log="/var/log/install-$1"
+ local __timestamp="$(date '+%F %T %z')"
+ shift
+ printf "\n%s\n" "$__timestamp: Running $*" | \
+ tee -a "$__log.err" >> "$__log.log"
+ local _ret=0
+ if "$@" 2>> "$__log.err" >>"$__log.log"; then
+ _ret=0
+ else
+ _ret="$?"
+ echo "$__timestamp: $* failed."
+ echo "See $__log.log and $__log.err for more information."
+ fi
+ printf "\n$s\n--------\n" "$(date '+%F %T %z'): Done $*" | \
+ tee -a "$__log.err" >> "$__log.log"
+ return $_ret
+}
+
+post_state() {
+ local curlargs=(-o "/var/log/$1-$2.json" --connect-timeout 60 -s \
+ -L -X POST --data-binary "{ \"name\": \"$1\", \"state\": \"$2\" }" \
+ -H "Accept: application/json" -H "Content-Type: application/json" \
+ --max-time 240)
+ [[ $CROWBAR_KEY ]] && curlargs+=(-u "$CROWBAR_KEY" --digest)
+ curl "${curlargs[@]}" "http://$IP:3000/crowbar/crowbar/1.0/transition/default"
+}
+
+# Mark us as readying, and get our cert.
+post_state $HOSTNAME "readying"
+post_state $HOSTNAME "ready"
+
+echo "Done"
diff --git a/crowbar/change-image/dell/barclamps/crowbar/chef/cookbooks/crowbar/files/default/crowbar.sh b/crowbar/change-image/dell/barclamps/crowbar/chef/cookbooks/crowbar/files/default/crowbar.sh
new file mode 100644
index 00000000000..5336ffd4f43
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/crowbar/chef/cookbooks/crowbar/files/default/crowbar.sh
@@ -0,0 +1,15 @@
+#
+# Default path variables.
+#
+
+# Make sure /opt/dell/bin is in the root path
+if ! echo ${PATH} | /bin/grep -q /opt/dell/bin ; then
+ if [ `/usr/bin/id -u` = 0 ] ; then
+ PATH=${PATH}:/opt/dell/bin
+ fi
+fi
+
+if [ -f /etc/crowbar.install.key ] ; then
+ export CROWBAR_KEY=`cat /etc/crowbar.install.key`
+fi
+
diff --git a/crowbar/change-image/dell/barclamps/crowbar/chef/cookbooks/crowbar/files/default/knife.rb b/crowbar/change-image/dell/barclamps/crowbar/chef/cookbooks/crowbar/files/default/knife.rb
new file mode 100644
index 00000000000..7418889f085
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/crowbar/chef/cookbooks/crowbar/files/default/knife.rb
@@ -0,0 +1,2 @@
+node_name "chef-webui"
+client_key "/etc/chef/webui.pem"
diff --git a/crowbar/change-image/dell/barclamps/crowbar/chef/cookbooks/crowbar/metadata.json b/crowbar/change-image/dell/barclamps/crowbar/chef/cookbooks/crowbar/metadata.json
new file mode 100644
index 00000000000..5edb1128e35
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/crowbar/chef/cookbooks/crowbar/metadata.json
@@ -0,0 +1,58 @@
+{
+ "providing": {
+ },
+ "attributes": {
+ },
+ "replacing": {
+ },
+ "dependencies": {
+ "apache2": [
+
+ ],
+ "ruby": [
+
+ ],
+ "passenger_apache2": [
+
+ ],
+ "rails": [
+
+ ]
+ },
+ "groupings": {
+ },
+ "recommendations": {
+ },
+ "platforms": {
+ "debian": [
+
+ ],
+ "fedora": [
+
+ ],
+ "centos": [
+
+ ],
+ "ubuntu": [
+
+ ],
+ "redhat": [
+
+ ]
+ },
+ "license": "Apache 2.0",
+ "version": "0.9.5",
+ "maintainer": "Dell, Inc.",
+ "suggestions": {
+ },
+ "recipes": {
+ "crowbar": "Installs crowbar",
+ "crowbar::local_apt_repo": "Makes the local node a repos to itself"
+ },
+ "maintainer_email": "crowbar@dell.com",
+ "name": "crowbar",
+ "conflicting": {
+ },
+ "description": "Installs crowbar",
+ "long_description": ""
+ }
diff --git a/crowbar/change-image/dell/barclamps/crowbar/chef/cookbooks/crowbar/providers/user.rb b/crowbar/change-image/dell/barclamps/crowbar/chef/cookbooks/crowbar/providers/user.rb
new file mode 100644
index 00000000000..b2567ba2d3b
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/crowbar/chef/cookbooks/crowbar/providers/user.rb
@@ -0,0 +1,19 @@
+
+action :add do
+ filename = "/opt/dell/openstack_manager/htdigest"
+ digest = Digest::MD5.hexdigest("#{new_resource.name}:#{new_resource.description}:#{new_resource.password}")
+ utils_line "#{new_resource.name}:#{new_resource.description}:#{digest}" do
+ action :add
+ file filename
+ end
+end
+
+action :remove do
+ filename = "/opt/dell/openstack_manager/htdigest"
+ digest = Digest::MD5.hexdigest("#{new_resource.name}:#{new_resource.description}:#{new_resource.password}")
+ utils_line "#{new_resource.name}:#{new_resource.description}:#{digest}" do
+ action :remove
+ file filename
+ end
+end
+
diff --git a/crowbar/change-image/dell/barclamps/crowbar/chef/cookbooks/crowbar/recipes/default.rb b/crowbar/change-image/dell/barclamps/crowbar/chef/cookbooks/crowbar/recipes/default.rb
new file mode 100644
index 00000000000..9392a329757
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/crowbar/chef/cookbooks/crowbar/recipes/default.rb
@@ -0,0 +1,135 @@
+#
+# Cookbook Name:: crowbar
+# Recipe:: default
+#
+# Copyright 2011, Opscode, Inc. and Dell, Inc
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+include_recipe "apache2"
+include_recipe "apache2::mod_auth_digest"
+include_recipe "passenger_apache2"
+include_recipe "rails"
+
+package "ipmitool"
+
+group "crowbar"
+
+user "crowbar" do
+ comment "Crowbar"
+ gid "crowbar"
+ home "/home/random"
+ shell "/bin/false"
+end
+
+directory "/root/.chef" do
+ owner "root"
+ group "root"
+ mode "0700"
+ action :create
+end
+
+cookbook_file "/etc/profile.d/crowbar.sh" do
+ owner "root"
+ group "root"
+ mode "0755"
+ action :create
+ source "crowbar.sh"
+end
+
+cookbook_file "/root/.chef/knife.rb" do
+ owner "root"
+ group "root"
+ mode "0600"
+ action :create
+ source "knife.rb"
+end
+
+directory "/home/openstack/.chef" do
+ owner "openstack"
+ group "openstack"
+ mode "0700"
+ action :create
+end
+
+cookbook_file "/home/openstack/.chef/knife.rb" do
+ owner "openstack"
+ group "openstack"
+ mode "0600"
+ action :create
+ source "knife.rb"
+end
+
+bash "Add crowbar chef client" do
+ environment ({'EDITOR' => '/bin/true'})
+ code "knife client create crowbar -a --file /opt/dell/openstack_manager/config/client.pem -u chef-validator -k /etc/chef/validation.pem"
+ not_if "knife client list -u crowbar -k /opt/dell/openstack_manager/config/client.pem"
+end
+
+file "/opt/dell/openstack_manager/log/production.log" do
+ owner "crowbar"
+ group "crowbar"
+ mode "0666"
+ action :create
+end
+
+file "/opt/dell/openstack_manager/tmp/queue.lock" do
+ owner "crowbar"
+ group "crowbar"
+ mode "0644"
+ action :create
+end
+file "/opt/dell/openstack_manager/tmp/ip.lock" do
+ owner "crowbar"
+ group "crowbar"
+ mode "0644"
+ action :create
+end
+
+# Add crowbar users - system added machine-install in install-chef.sh
+node["crowbar"]["users"].each do |user,hash|
+ crowbar_user user do
+ action :add
+ description hash["description"]
+ password hash["password"]
+ end
+end unless node["crowbar"].nil? or node["crowbar"]["users"].nil?
+
+bash "set permissions" do
+ code "chown -R crowbar:crowbar /opt/dell/openstack_manager"
+ not_if "ls -al /opt/dell/openstack_manager/README | grep -q crowbar"
+end
+
+web_app "crowbar_app" do
+ server_name node[:fqdn]
+ docroot "/opt/dell/openstack_manager/public"
+ template "crowbar_app.conf.erb"
+end
+
+cookbook_file "/etc/init.d/crowbar" do
+ owner "root"
+ group "root"
+ mode "0755"
+ action :create
+ source "crowbar"
+end
+
+["3", "5", "2"].each do |i|
+ link "/etc/rc#{i}.d/S99xcrowbar" do
+ action :create
+ to "/etc/init.d/crowbar"
+ not_if "test -L /etc/rc#{i}.d/S99xcrowbar"
+ end
+end
+
diff --git a/crowbar/change-image/dell/barclamps/crowbar/chef/cookbooks/crowbar/recipes/local_apt_repo.rb b/crowbar/change-image/dell/barclamps/crowbar/chef/cookbooks/crowbar/recipes/local_apt_repo.rb
new file mode 100644
index 00000000000..750c0984f41
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/crowbar/chef/cookbooks/crowbar/recipes/local_apt_repo.rb
@@ -0,0 +1,14 @@
+
+apt_repository "local maverick main" do
+ uri "file:///tftpboot/ubuntu_dvd"
+ distribution "maverick"
+ components [ "main", "restricted" ]
+ action :add
+end
+
+apt_repository "local extra repos" do
+ uri "file:///tftpboot/ubuntu_dvd/extra/"
+ distribution "/"
+ action :add
+end
+
diff --git a/crowbar/change-image/dell/barclamps/crowbar/chef/cookbooks/crowbar/resources/user.rb b/crowbar/change-image/dell/barclamps/crowbar/chef/cookbooks/crowbar/resources/user.rb
new file mode 100644
index 00000000000..758ea1655c3
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/crowbar/chef/cookbooks/crowbar/resources/user.rb
@@ -0,0 +1,7 @@
+
+actions :add, :remove
+
+attribute :name, :kind_of => String, :name_attribute => true
+attribute :description, :kind_of => String
+attribute :password, :kind_of => String
+
diff --git a/crowbar/change-image/dell/barclamps/crowbar/chef/cookbooks/crowbar/templates/default/crowbar_app.conf.erb b/crowbar/change-image/dell/barclamps/crowbar/chef/cookbooks/crowbar/templates/default/crowbar_app.conf.erb
new file mode 100644
index 00000000000..bdcb9ba5f56
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/crowbar/chef/cookbooks/crowbar/templates/default/crowbar_app.conf.erb
@@ -0,0 +1,40 @@
+Listen 3000
+
+ ServerName <%= @params[:server_name] %>
+ DocumentRoot <%= @params[:docroot] %>
+
+
+ AuthType Digest
+ AuthName "Crowbar"
+ AuthDigestDomain http://192.168.124.10:3000/
+ AuthDigestProvider file
+ AuthUserFile /opt/dell/openstack_manager/htdigest
+ Require valid-user
+
+
+ RailsBaseURI /
+ RailsMaxPoolSize <%= node[:rails][:max_pool_size] %>
+ RailsPoolIdleTime 3600
+ RailsEnv '<%= node[:rails][:environment] %>'
+
+ LogLevel info
+ ErrorLog <%= node[:apache][:log_dir] %>/<%= @params[:name] %>_error.log
+ CustomLog <%= node[:apache][:log_dir] %>/<%= @params[:name] %>_access.log combined
+
+ ErrorDocument 404 /404.html
+ ErrorDocument 500 /500.html
+
+ RewriteEngine On
+
+ # Handle maintenance mode
+ RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f
+ RewriteCond %{SCRIPT_FILENAME} !maintenance.html
+ RewriteRule ^/(.*)$ /system/maintenance.html [L]
+
+ >
+ Options FollowSymLinks
+ AllowOverride None
+ Order allow,deny
+ Allow from all
+
+
diff --git a/crowbar/change-image/dell/barclamps/crowbar/chef/data_bags/crowbar/bc-template-crowbar.json b/crowbar/change-image/dell/barclamps/crowbar/chef/data_bags/crowbar/bc-template-crowbar.json
new file mode 100644
index 00000000000..24955df771d
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/crowbar/chef/data_bags/crowbar/bc-template-crowbar.json
@@ -0,0 +1,68 @@
+{
+ "id": "bc-template-crowbar",
+ "description": "Self-referential barclamp enabling other barclamps",
+ "attributes": {
+ "crowbar": {
+ "barclamps": [
+ "crowbar",
+ "deployer",
+ "ipmi",
+ "network",
+ "provisioner",
+ "ntp",
+ "dns",
+ "nagios",
+ "ganglia",
+ "logging"
+ ],
+ "run_order": {
+ "deployer": 10,
+ "ipmi": 17,
+ "network": 20,
+ "dns": 30,
+ "logging": 40,
+ "ntp": 50,
+ "nagios": 70,
+ "ganglia": 80,
+ "provisioner": 1060
+ },
+ "instances": {
+ "deployer": [ "default" ],
+ "ipmi": [ "default" ],
+ "provisioner": [ "default" ],
+ "network": [ "default" ],
+ "ntp": [ "default" ],
+ "dns": [ "default" ],
+ "nagios": [ "default" ],
+ "ganglia": [ "default" ],
+ "logging": [ "default" ]
+ },
+ "users": {
+ "crowbar": { "password": "crowbar", "description": "Crowbar" }
+ }
+ },
+ "rails": {
+ "max_pool_size": 256,
+ "environment": "production"
+ },
+ "passenger": {
+ "max_pool_size": 256
+ }
+ },
+ "deployment": {
+ "crowbar": {
+ "crowbar-revision": 0,
+ "elements": {},
+ "element_order": [
+ [ "crowbar" ]
+ ],
+ "config": {
+ "environment": "crowbar-config-test",
+ "mode": "full",
+ "transitions": false,
+ "transition_list": [ ]
+ }
+ }
+ }
+}
+
diff --git a/crowbar/change-image/dell/barclamps/crowbar/chef/data_bags/crowbar/bc-template-crowbar.schema b/crowbar/change-image/dell/barclamps/crowbar/chef/data_bags/crowbar/bc-template-crowbar.schema
new file mode 100644
index 00000000000..f185b273746
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/crowbar/chef/data_bags/crowbar/bc-template-crowbar.schema
@@ -0,0 +1,88 @@
+{
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "id": { "type": "str", "required": true, "pattern": "/^bc-crowbar-|^bc-template-crowbar$/" },
+ "description": { "type": "str", "required": true },
+ "attributes": { "type": "map", "required": true, "mapping": {
+ "crowbar": { "type": "map", "required": true, "mapping": {
+ "barclamps": { "type": "seq", "required": true, "sequence": [ { "type": "str" } ] },
+ "run_order": { "type": "map", "required": true, "mapping": {
+ = : { "type": "int", "required": true }
+ }
+ },
+ "instances": { "type": "map", "required": true, "mapping": {
+ = : { "type": "seq", "required": true, "sequence": [ { "type": "str" } ] }
+ }
+ },
+ "users": { "type": "map", "required": true, "mapping": {
+ = : { "type": "map", "required": true, "mapping": {
+ "password": { "type": "str", "required": true },
+ "description": { "type": "str", "required": true }
+ }
+ }
+ }
+ }
+ }
+ },
+ "rails": { "type": "map", "required": true, "mapping": {
+ "environment": { "type": "str", "required": true },
+ "max_pool_size": { "type": "int", "required": true }
+ }
+ },
+ "passenger": { "type": "map", "required": true, "mapping": {
+ "max_pool_size": { "type": "int", "required": true }
+ }
+ }
+ }
+ },
+ "deployment": {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "crowbar": {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "crowbar-revision": { "type": "int", "required": true },
+ "crowbar-committing": { "type": "bool" },
+ "crowbar-queued": { "type": "bool" },
+ "elements": {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ = : {
+ "type": "seq",
+ "required": true,
+ "sequence": [ { "type": "str" } ]
+ }
+ }
+ },
+ "element_order": {
+ "type": "seq",
+ "required": true,
+ "sequence": [ {
+ "type": "seq",
+ "sequence": [ { "type": "str" } ]
+ } ]
+ },
+ "config": {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "environment": { "type": "str", "required": true },
+ "mode": { "type": "str", "required": true },
+ "transitions": { "type": "bool", "required": true },
+ "transition_list": {
+ "type": "seq",
+ "required": true,
+ "sequence": [ { "type": "str" } ]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/crowbar/change-image/dell/barclamps/crowbar/chef/roles/crowbar.rb b/crowbar/change-image/dell/barclamps/crowbar/chef/roles/crowbar.rb
new file mode 100644
index 00000000000..70536941b29
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/crowbar/chef/roles/crowbar.rb
@@ -0,0 +1,24 @@
+
+name "crowbar"
+description "Crowbar role - Setups the rails app"
+run_list(
+ "recipe[crowbar::local_apt_repo]",
+ "recipe[utils]",
+ "recipe[apt]",
+ "recipe[sudo]",
+ "recipe[crowbar]"
+)
+default_attributes(
+ :crowbar => { :admin_node => true },
+ :rails => { :max_pool_size => 256, :environment => "production" },
+ :passenger => { :max_pool_size => 256 },
+ :authorization => {
+ :sudo => {
+ :groups => [ "admin" ],
+ :users => [ "crowbar" ],
+ :passwordless => true
+ }
+ }
+)
+override_attributes()
+
diff --git a/crowbar/change-image/dell/barclamps/crowbar/command_line/crowbar b/crowbar/change-image/dell/barclamps/crowbar/command_line/crowbar
new file mode 100755
index 00000000000..43149b01a6c
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/crowbar/command_line/crowbar
@@ -0,0 +1,23 @@
+#!/usr/bin/env ruby
+
+loc=File.expand_path(File.dirname(__FILE__))
+def usage (rc)
+ puts "Usage: crowbar "
+ puts " Areas: #{@areas.join(" ")}"
+ exit rc
+end
+
+@areas = Dir.glob("./crowbar_*").map! { |x| x.gsub("./crowbar_", "") }
+@areas << Dir.glob(File.join(loc,"crowbar_*")).map! { |x| x.gsub(File.join(loc,"crowbar_"), "") }
+@areas = @areas.flatten
+
+if ARGV.length == 0
+ usage -1
+end
+
+area = ARGV.shift
+
+usage -1 unless @areas.include?(area)
+
+exec("./crowbar_#{area}", *ARGV) if File.exists?("./crowbar_#{area}")
+exec(File.join(loc,"crowbar_#{area}"), *ARGV) if File.exists?(File.join(loc,"crowbar_#{area}"))
diff --git a/crowbar/change-image/dell/barclamps/crowbar/command_line/crowbar_crowbar b/crowbar/change-image/dell/barclamps/crowbar/command_line/crowbar_crowbar
new file mode 100755
index 00000000000..7fff66449e6
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/crowbar/command_line/crowbar_crowbar
@@ -0,0 +1,6 @@
+#!/usr/bin/env ruby
+
+require File.join(File.expand_path(File.dirname(__FILE__)), "barclamp_lib")
+@barclamp = "crowbar"
+
+main
diff --git a/crowbar/change-image/dell/barclamps/crowbar/command_line/crowbar_machines b/crowbar/change-image/dell/barclamps/crowbar/command_line/crowbar_machines
new file mode 100755
index 00000000000..3b2c128633d
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/crowbar/command_line/crowbar_machines
@@ -0,0 +1,331 @@
+#!/usr/bin/env ruby
+
+require 'rubygems'
+require 'net/http'
+require 'net/http/digest_auth'
+require 'uri'
+require 'json'
+require 'getoptlong'
+
+@debug = false
+@hostname = ENV["CROWBAR_IP"]
+# DO NOT CHANGE THE FORMAT OF THE NEXT 2 LINES.
+# gather_cli relies on the exact spacing of them to
+# rewrite the addreses when it is serving the CLI.
+@hostname = "127.0.0.1" unless @hostname
+@port = 3000
+@headers = {
+ "Accept" => "application/json",
+ "Content-Type" => "application/json"
+}
+@data = ""
+@allow_zero_args = false
+@timeout = 500
+@barclamp="machines"
+@key = ENV["CROWBAR_KEY"]
+if @key
+ @username=@key.split(':',2)[0]
+ @password=@key.split(':',2)[1]
+end
+
+#
+# Parsing options can be added by adding to this list before calling opt_parse
+#
+@options = [
+ [ [ '--help', '-h', GetoptLong::NO_ARGUMENT ], "--help or -h - help" ],
+ [ [ '--username', '-U', GetoptLong::REQUIRED_ARGUMENT ], "--username or -U - specifies the username to use" ],
+ [ [ '--password', '-P', GetoptLong::REQUIRED_ARGUMENT ], "--password or -P - specifies the password to use" ],
+ [ [ '--hostname', '-n', GetoptLong::REQUIRED_ARGUMENT ], "--hostname or -n - specifies the destination server" ],
+ [ [ '--port', '-p', GetoptLong::REQUIRED_ARGUMENT ], "--port or -p - specifies the destination server port" ],
+ [ [ '--debug', '-d', GetoptLong::NO_ARGUMENT ], "--debug or -d - turns on debugging information" ],
+ [ [ '--data', GetoptLong::REQUIRED_ARGUMENT ], "--data - used by create or edit as data (must be in json format)" ],
+ [ [ '--file', GetoptLong::REQUIRED_ARGUMENT ], "--file - used by create or edit as data when read from a file (must be in json format)" ],
+ [ [ '--timeout', GetoptLong::REQUIRED_ARGUMENT ], "--timeout - timeout in seconds for read http reads" ]
+]
+
+@commands = {
+ "help" => [ "help", "help - this page" ],
+ "api_help" => [ "api_help", "crowbar API help - help for this barclamp." ],
+ "list" => [ "list", "list - show a list of current configs" ],
+ "show" => [ "show ARGV.shift, ARGV.shift", "show [arg] - show a specific config" ],
+ "create" => [ "create ARGV.shift", "create - create a specific config" ],
+ "edit" => [ "edit ARGV.shift", "edit - edit a new config" ],
+ "delete" => [ "delete ARGV.shift", "delete - delete a node" ],
+ "reboot" => [ "action \"reboot\", ARGV.shift", "reboot - reboot a node" ],
+ "shutdown" => [ "action \"shutdown\", ARGV.shift", "shutdown - shutdown a node" ],
+ "poweron" => [ "action \"poweron\", ARGV.shift", "poweron - poweron a node" ],
+ "identify" => [ "action \"identify\", ARGV.shift", "identify - identify a node" ],
+ "allocate" => [ "action \"allocate\", ARGV.shift", "allocate - allocate a node" ],
+ "reset" => [ "action \"reset\", ARGV.shift", "reset - reset a node" ],
+ "reinstall" => [ "action \"reinstall\", ARGV.shift", "reinstall - reinstall a node" ]
+}
+
+
+def print_commands(cmds, spacer = " ")
+ cmds.each do |key, command|
+ puts "#{spacer}#{command[1]}"
+ print_commands(command[2], " #{spacer}") if command[0] =~ /run_sub_command\(/
+ end
+end
+
+def usage (rc)
+ puts "Usage: crowbar #{@barclamp} [options] "
+ @options.each do |options|
+ puts " #{options[1]}"
+ end
+ print_commands(@commands)
+ exit rc
+end
+
+def help
+ usage 0
+end
+
+def authenticate(req,uri,data=nil)
+ uri.user=@username
+ uri.password=@password
+ res=nil
+ Net::HTTP.start(uri.host, uri.port) {|http|
+ r = req.new(uri.request_uri,@headers)
+ r.body = data if data
+ res = http.request r
+ if res['www-authenticate']
+ digest_auth=Net::HTTP::DigestAuth.new
+ auth=Net::HTTP::DigestAuth.new.auth_header(uri,
+ res['www-authenticate'],
+ req::METHOD)
+ r.add_field 'Authorization', auth
+ res = http.request r
+ end
+ }
+ res
+end
+
+def get_json(path)
+ uri = URI.parse("http://#{@hostname}:#{@port}/crowbar/#{@barclamp}/1.0#{path}")
+ res = authenticate(Net::HTTP::Get,uri)
+
+ puts "DEBUG: (g) hostname: #{uri.host}:#{uri.port}" if @debug
+ puts "DEBUG: (g) request: #{uri.path}" if @debug
+ puts "DEBUG: (g) return code: #{res.code}" if @debug
+ puts "DEBUG: (g) return body: #{res.body}" if @debug
+
+ return [res.body, res.code.to_i ] if res.code.to_i != 200
+
+ struct = JSON.parse(res.body)
+
+ puts "DEBUG: (g) JSON parse structure = #{struct.inspect}" if @debug
+
+ return [struct, 200]
+end
+
+def post_json(path, data)
+ uri = URI.parse("http://#{@hostname}:#{@port}/crowbar/#{@barclamp}/1.0#{path}")
+ res = authenticate(Net::HTTP::Post,uri,data)
+
+ puts "DEBUG: (post) hostname: #{uri.host}:#{uri.port}" if @debug
+ puts "DEBUG: (post) request: #{uri.path}" if @debug
+ puts "DEBUG: (post) data: #{@data}" if @debug
+ puts "DEBUG: (post) return code: #{res.code}" if @debug
+ puts "DEBUG: (post) return body: #{res.body}" if @debug
+
+ [res.body, res.code.to_i ]
+end
+
+def put_json(path, data)
+ uri = URI.parse("http://#{@hostname}:#{@port}/crowbar/#{@barclamp}/1.0#{path}")
+ res = authenticate(Net::HTTP::Put,uri,data)
+
+ puts "DEBUG: (put) hostname: #{uri.host}:#{uri.port}" if @debug
+ puts "DEBUG: (put) request: #{uri.path}" if @debug
+ puts "DEBUG: (put) data: #{@data}" if @debug
+ puts "DEBUG: (put) return code: #{res.code}" if @debug
+ puts "DEBUG: (put) return body: #{res.body}" if @debug
+
+ [res.body, res.code.to_i ]
+end
+
+def delete_json(path)
+ uri = URI.parse("http://#{@hostname}:#{@port}/crowbar/#{@barclamp}/1.0#{path}")
+ res = authenticate(Net::HTTP::Delete,uri)
+
+ puts "DEBUG: (d) hostname: #{uri.host}:#{uri.port}" if @debug
+ puts "DEBUG: (d) request: #{uri.path}" if @debug
+ puts "DEBUG: (d) return code: #{res.code}" if @debug
+ puts "DEBUG: (d) return body: #{res.body}" if @debug
+
+ [res.body, res.code.to_i ]
+end
+
+def list
+ struct = get_json("/")
+
+ if struct[1] != 200
+ [ "Failed to talk to service list: #{struct[1]}: #{struct[0]}", 1 ]
+ elsif struct[0].nil? or struct[0].empty?
+ [ "No current configurations", 0 ]
+ else
+ out = ""
+ struct[0].each do |name|
+ out = out + "\n" if out != ""
+ out = out + "#{name}"
+ end
+ [ out, 0 ]
+ end
+end
+
+def api_help
+ struct=get_json("/help")
+ if struct[1] != 200
+ [ "Failed to talk to service list: #{struct[1]}: #{struct[0]}", 1 ]
+ elsif struct[0].nil? or struct[0].empty?
+ [ "No help", 0 ]
+ else
+ [ jj(struct[0]), 0 ]
+ end
+end
+
+def show(name, field = nil)
+ usage -1 if name.nil? or name == ""
+
+ struct = get_json("/0?name=#{name}")
+
+ if struct[1] == 200
+ if field.nil?
+ [ "#{JSON.pretty_generate(struct[0])}", 0 ]
+ else
+ data = struct[0]
+ fields = field.split(".")
+ fields.each { |x| data = data[x] }
+
+ [ "#{JSON.pretty_generate(data)}", 0 ]
+ end
+ elsif struct[1] == 404
+ [ "No current configuration for #{name}", 1 ]
+ else
+ [ "Failed to talk to service show: #{struct[1]}: #{struct[0]}", 1 ]
+ end
+end
+
+def create(name)
+ usage -1 if name.nil? or name == ""
+
+ @data = "{\"name\":\"#{name}\"}" if @data.nil? or @data == ""
+
+ struct = put_json("/", @data)
+
+ if struct[1] == 200
+ [ "Created #{name}", 0 ]
+ else
+ [ "Failed to talk to service create: #{struct[1]}: #{struct[0]}", 1 ]
+ end
+end
+
+def edit(name)
+ usage -1 if name.nil? or name == ""
+
+ struct = post_json("/#{name}", @data)
+
+ if struct[1] == 200
+ [ "Edited #{name}", 0 ]
+ elsif struct[1] == 404
+ [ "Failed to edit: #{name} : Not Found", 1 ]
+ elsif struct[1] == 400
+ [ "Failed to edit: #{name} : Errors in data\n#{struct[0]}", 1 ]
+ else
+ [ "Failed to talk to service edit: #{struct[1]}: #{struct[0]}", 1 ]
+ end
+end
+
+def delete(name)
+ usage -1 if name.nil? or name == ""
+
+ struct = delete_json("?name=#{name}")
+
+ if struct[1] == 200
+ [ "Deleted #{name}", 0 ]
+ elsif struct[1] == 404
+ [ "Delete failed for #{name}: Not Found", 1 ]
+ else
+ [ "Failed to talk to service delete: #{struct[1]}: #{struct[0]}", 1 ]
+ end
+end
+
+def action(aaa, name)
+ usage -1 if name.nil? or name == ""
+
+ @data = "{\"name\":\"#{name}\"}" if @data.nil? or @data == ""
+
+ struct = post_json("/#{aaa}/0", @data)
+
+ if struct[1] == 200
+ [ "#{aaa} #{name}", 0 ]
+ else
+ [ "Failed to talk to service #{aaa}: #{struct[1]}: #{struct[0]}", 1 ]
+ end
+end
+
+### Start MAIN ###
+
+def opt_parse()
+ sub_options = @options.map { |x| x[0] }
+ lsub_options = @options.map { |x| [ x[0][0], x[2] ] }
+ opts = GetoptLong.new(*sub_options)
+
+ opts.each do |opt, arg|
+ case opt
+ when '--help'
+ usage 0
+ when '--debug'
+ @debug = true
+ when '--hostname'
+ @hostname = arg
+ when '--username'
+ @username = arg
+ when '--password'
+ @password = arg
+ when '--port'
+ @port = arg.to_i
+ when '--data'
+ @data = arg
+ when '--timeout'
+ @timeout = arg
+ when '--file'
+ data = File.read(arg, "r")
+ else
+ found = false
+ lsub_options.each do |x|
+ next if x[0] != opt
+ eval x[1]
+ found = true
+ end
+ usage -1 unless found
+ end
+ end
+
+ STDERR.puts "CROWBAR_KEY not set, will not be able to authenticate!" if @username.nil? or @password.nil?
+ STDERR.puts "Please set CROWBAR_KEY or use -U and -P" if @username.nil? or @password.nil?
+ if ARGV.length == 0 and !@allow_zero_args
+ usage -1
+ end
+end
+
+def run_sub_command(cmds, subcmd)
+ cmd = cmds[subcmd]
+ usage -2 if cmd.nil?
+ eval cmd[0]
+end
+
+def run_command()
+ run_sub_command(@commands, ARGV.shift)
+end
+
+def main()
+ opt_parse
+ res = run_command
+ puts res[0]
+ exit res[1]
+end
+
+main
+
diff --git a/crowbar/change-image/dell/barclamps/crowbar/command_line/crowbar_node_state b/crowbar/change-image/dell/barclamps/crowbar/command_line/crowbar_node_state
new file mode 100755
index 00000000000..7e5bc71cfac
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/crowbar/command_line/crowbar_node_state
@@ -0,0 +1,184 @@
+#!/usr/bin/env ruby
+
+require 'rubygems'
+require 'net/http'
+require 'net/http/digest_auth'
+require 'uri'
+require 'json'
+require 'getoptlong'
+
+@debug = false
+@hostname = ENV["CROWBAR_IP"]
+# DO NOT CHANGE THE FORMAT OF THE NEXT 2 LINES.
+# gather_cli relies on the exact spacing of them to
+# rewrite the addreses when it is serving the CLI.
+@hostname = "127.0.0.1" unless @hostname
+@port = 3000
+@headers = {
+ "Accept" => "application/json",
+ "Content-Type" => "application/json"
+}
+@data = ""
+@allow_zero_args = false
+@timeout = 500
+@barclamp="machines"
+@key = ENV["CROWBAR_KEY"]
+if @key
+ @username=@key.split(':',2)[0]
+ @password=@key.split(':',2)[1]
+end
+
+#
+# Parsing options can be added by adding to this list before calling opt_parse
+#
+@options = [
+ [ [ '--help', '-h', GetoptLong::NO_ARGUMENT ], "--help or -h - help" ],
+ [ [ '--username', '-U', GetoptLong::REQUIRED_ARGUMENT ], "--username or -U - specifies the username to use" ],
+ [ [ '--password', '-P', GetoptLong::REQUIRED_ARGUMENT ], "--password or -P - specifies the password to use" ],
+ [ [ '--hostname', '-n', GetoptLong::REQUIRED_ARGUMENT ], "--hostname or -n - specifies the destination server" ],
+ [ [ '--port', '-p', GetoptLong::REQUIRED_ARGUMENT ], "--port or -p - specifies the destination server port" ],
+ [ [ '--debug', '-d', GetoptLong::NO_ARGUMENT ], "--debug or -d - turns on debugging information" ],
+ [ [ '--timeout', GetoptLong::REQUIRED_ARGUMENT ], "--timeout - timeout in seconds for read http reads" ]
+]
+
+@commands = {
+ "status" => [ "status", "status - show status of nodes" ],
+}
+
+
+def print_commands(cmds, spacer = " ")
+ cmds.each do |key, command|
+ puts "#{spacer}#{command[1]}"
+ print_commands(command[2], " #{spacer}") if command[0] =~ /run_sub_command\(/
+ end
+end
+
+def usage (rc)
+ puts "Usage: crowbar node_state [options] "
+ @options.each do |options|
+ puts " #{options[1]}"
+ end
+ print_commands(@commands)
+ exit rc
+end
+
+def help
+ usage 0
+end
+
+def authenticate(req,uri,data=nil)
+ uri.user=@username
+ uri.password=@password
+ res=nil
+ Net::HTTP.start(uri.host, uri.port) {|http|
+ r = req.new(uri.request_uri,@headers)
+ r.body = data if data
+ res = http.request r
+ if res['www-authenticate']
+ digest_auth=Net::HTTP::DigestAuth.new
+ auth=Net::HTTP::DigestAuth.new.auth_header(uri,
+ res['www-authenticate'],
+ req::METHOD)
+ r.add_field 'Authorization', auth
+ res = http.request r
+ end
+ }
+ res
+end
+
+def get_json(path)
+ uri = URI.parse("http://#{@hostname}:#{@port}/nodes#{path}")
+ res = authenticate(Net::HTTP::Get,uri)
+
+ puts "DEBUG: (g) hostname: #{uri.host}:#{uri.port}" if @debug
+ puts "DEBUG: (g) request: #{uri.path}" if @debug
+ puts "DEBUG: (g) return code: #{res.code}" if @debug
+ puts "DEBUG: (g) return body: #{res.body}" if @debug
+
+ return [res.body, res.code.to_i ] if res.code.to_i != 200
+
+ struct = JSON.parse(res.body)
+
+ puts "DEBUG: (g) JSON parse structure = #{struct.inspect}" if @debug
+
+ return [struct, 200]
+end
+
+def status()
+ struct = get_json("/status")
+
+ if struct[1] == 200
+ string = ""
+ struct[0]["nodes"].each do |n, hash|
+ string += "#{n} #{hash["state"]}\n"
+ end
+ [ "#{string}", 0 ]
+ elsif struct[1] == 404
+ [ "No current configuration for status", 1 ]
+ else
+ [ "Failed to talk to service show: #{struct[1]}: #{struct[0]}", 1 ]
+ end
+end
+
+def opt_parse()
+ sub_options = @options.map { |x| x[0] }
+ lsub_options = @options.map { |x| [ x[0][0], x[2] ] }
+ opts = GetoptLong.new(*sub_options)
+
+ opts.each do |opt, arg|
+ case opt
+ when '--help'
+ usage 0
+ when '--debug'
+ @debug = true
+ when '--hostname'
+ @hostname = arg
+ when '--username'
+ @username = arg
+ when '--password'
+ @password = arg
+ when '--port'
+ @port = arg.to_i
+ when '--data'
+ @data = arg
+ when '--timeout'
+ @timeout = arg
+ when '--file'
+ data = File.read(arg, "r")
+ else
+ found = false
+ lsub_options.each do |x|
+ next if x[0] != opt
+ eval x[1]
+ found = true
+ end
+ usage -1 unless found
+ end
+ end
+
+ STDERR.puts "CROWBAR_KEY not set, will not be able to authenticate!" if @username.nil? or @password.nil?
+ STDERR.puts "Please set CROWBAR_KEY or use -U and -P" if @username.nil? or @password.nil?
+ if ARGV.length == 0 and !@allow_zero_args
+ usage -1
+ end
+end
+
+def run_sub_command(cmds, subcmd)
+ cmd = cmds[subcmd]
+ usage -2 if cmd.nil?
+ eval cmd[0]
+end
+
+def run_command()
+ run_sub_command(@commands, ARGV.shift)
+end
+
+def main()
+ opt_parse
+ res = run_command
+ puts res[0]
+ exit res[1]
+end
+
+main
+
diff --git a/crowbar/change-image/dell/barclamps/crowbar/command_line/crowbar_node_status b/crowbar/change-image/dell/barclamps/crowbar/command_line/crowbar_node_status
new file mode 100755
index 00000000000..e86cc06d79e
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/crowbar/command_line/crowbar_node_status
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+[[ $CROWBAR_IP ]] || CROWBAR_IP="127.0.0.1"
+
+stat_line_re='status(OK|WARNING|CRITICAL|UNKNOWN|PENDING)'
+echo "Host OK WARN CRIT UNKNOWN PENDING"
+while read HOST; do
+ HOST=${HOST%%.*}
+ OK=0 WARN=0 CRIT=0 UNKN=0 PEND=0
+ while read -r line; do
+ [[ $line =~ $stat_line_re ]] || continue
+ case ${BASH_REMATCH[1]} in
+ OK) ((OK++));;
+ WARNING) ((WARN++));;
+ CRITICAL) ((CRIT++));;
+ UNKNOWN) ((UNKN++));;
+ PENDING) ((PEND++));;
+ esac
+ done < <(wget --user=nagiosadmin --password=password \
+ "http://${CROWBAR_IP:=127.0.0.1}/cgi-bin/nagios3/status.cgi?host=$HOST" -O- -q)
+ echo "$HOST $OK $WARN $CRIT $UNKN $PEND"
+done < <(knife node list | grep "\"" | awk -F\" '{ print $2 }')
diff --git a/crowbar/change-image/dell/barclamps/crowbar/command_line/crowbar_watch_status b/crowbar/change-image/dell/barclamps/crowbar/command_line/crowbar_watch_status
new file mode 100755
index 00000000000..c78465529ca
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/crowbar/command_line/crowbar_watch_status
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+watch "/opt/dell/bin/crowbar_node_state status ; echo ' ' ; /opt/dell/bin/crowbar_node_status"
+
diff --git a/crowbar/change-image/dell/barclamps/crowbar/command_line/transition.sh b/crowbar/change-image/dell/barclamps/crowbar/command_line/transition.sh
new file mode 100755
index 00000000000..357e92cc2c3
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/crowbar/command_line/transition.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+
+key_re='crowbar\.install\.key=([^ ]+)'
+if [[ $(cat /proc/cmdline) =~ $key_re ]]; then
+ export CROWBAR_KEY="${BASH_REMATCH[1]}"
+elif [[ -f /etc/crowbar.install.key ]]
+ export CROWBAR_KEY="$(cat /etc/crowbar.install.key)"
+fi
+
+
+post_state() {
+ local curlargs=(-o "/var/log/$1-$2.json" --connect-timeout 60 -s \
+ -L -X POST --data-binary "{ \"name\": \"$1\", \"state\": \"$2\" }" \
+ -H "Accept: application/json" -H "Content-Type: application/json")
+ [[ $CROWBAR_KEY ]] && curlargs+=(-u "$CROWBAR_KEY" --digest)
+ curl "${curlargs[@]}" "http://192.168.124.10:3000/crowbar/crowbar/1.0/transition/default"
+}
+
+if [ "$1" == "" ]
+then
+ echo "Please specify a node to transition"
+ exit -1
+fi
+
+if [ "$2" == "" ]
+then
+ echo "Please specify a state for $1 to transition"
+ exit -1
+fi
+
+post_state $1 $2
+
+exit 0
diff --git a/crowbar/change-image/dell/barclamps/crowbar/debian/changelog.tmpl b/crowbar/change-image/dell/barclamps/crowbar/debian/changelog.tmpl
new file mode 100644
index 00000000000..42694be8134
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/crowbar/debian/changelog.tmpl
@@ -0,0 +1,5 @@
+CHANGE_LOG_LINE
+
+ * Initial Release.
+
+ -- unknown Thu, 19 May 2011 15:50:02 -0500
diff --git a/crowbar/change-image/dell/barclamps/crowbar/debian/compat b/crowbar/change-image/dell/barclamps/crowbar/debian/compat
new file mode 100644
index 00000000000..7f8f011eb73
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/crowbar/debian/compat
@@ -0,0 +1 @@
+7
diff --git a/crowbar/change-image/dell/barclamps/crowbar/debian/control b/crowbar/change-image/dell/barclamps/crowbar/debian/control
new file mode 100644
index 00000000000..cec888c0da6
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/crowbar/debian/control
@@ -0,0 +1,13 @@
+Source: barclamp-crowbar
+Section: unknown
+Priority: extra
+Maintainer: Dell Openstack
+Build-Depends: debhelper (>= 7.0.50~)
+Standards-Version: 3.9.1
+Homepage: http://openstack.dell.com/
+
+Package: barclamp-crowbar
+Architecture: all
+Depends: barclamp-crowbar
+Description: Ganglia Barclamp for Crowbar
+ Provides the crowbar barclamp for crowbar
diff --git a/crowbar/change-image/dell/barclamps/crowbar/debian/copyright b/crowbar/change-image/dell/barclamps/crowbar/debian/copyright
new file mode 100644
index 00000000000..ef293d897c8
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/crowbar/debian/copyright
@@ -0,0 +1,26 @@
+This work was packaged for Debian by:
+
+ Dell Openstack Team on Thu, 19 May 2011 15:50:02 -0500
+
+It was downloaded from:
+
+
+
+Upstream Author(s):
+
+ Openstack Dell Team
+
+Copyright:
+
+ Copyright (C) 2011 Dell, Inc.
+
+License:
+
+GREG: Fill in Apache 2.0
+
+The Debian packaging is:
+
+ Copyright (C) 2011 Dell
+
+and is licensed under Apache 2.0, see above.
+
diff --git a/crowbar/change-image/dell/barclamps/crowbar/debian/postinst b/crowbar/change-image/dell/barclamps/crowbar/debian/postinst
new file mode 100644
index 00000000000..d8a0a2ae95b
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/crowbar/debian/postinst
@@ -0,0 +1,53 @@
+#!/bin/sh
+# postinst script for #PACKAGE#
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+# * `configure'
+# * `abort-upgrade'
+# * `abort-remove' `in-favour'
+#
+# * `abort-remove'
+# * `abort-deconfigure' `in-favour'
+# `removing'
+#
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+
+case "$1" in
+ configure)
+ cd /usr/share/barclamp-crowbar/chef/cookbooks
+ knife cookbook upload -o . -a -u chef-webui -k /etc/chef/webui.pem
+
+ cd /usr/share/barclamp-crowbar/chef/data_bags/crowbar
+ for i in *.json; do
+ knife data bag from file crowbar $i
+ done
+
+ cd /usr/share/barclamp-crowbar/chef/roles
+ for i in *.rb; do
+ knife role from file $i
+ done
+
+ service apache2 graceful
+ ;;
+
+ abort-upgrade|abort-remove|abort-deconfigure)
+ ;;
+
+ *)
+ echo "postinst called with unknown argument \`$1'" >&2
+ exit 1
+ ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
diff --git a/crowbar/change-image/dell/barclamps/crowbar/debian/rules b/crowbar/change-image/dell/barclamps/crowbar/debian/rules
new file mode 100755
index 00000000000..79fd842dcae
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/crowbar/debian/rules
@@ -0,0 +1,8 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+%:
+ dh $@
diff --git a/crowbar/change-image/dell/barclamps/crowbar/debian/source/format b/crowbar/change-image/dell/barclamps/crowbar/debian/source/format
new file mode 100644
index 00000000000..89ae9db8f88
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/crowbar/debian/source/format
@@ -0,0 +1 @@
+3.0 (native)
diff --git a/crowbar/change-image/dell/barclamps/crowbar/version.sh b/crowbar/change-image/dell/barclamps/crowbar/version.sh
new file mode 100644
index 00000000000..ee763fcd96c
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/crowbar/version.sh
@@ -0,0 +1,7 @@
+BARCLAMP_NAME=crowbar
+MAJOR_VERSION=0
+MINOR_VERSION=8
+SVN_REVISION=${SVN_REVISION:-custom}
+BUILD_NUMBER=${BUILD_NUMBER:-custom}
+RPM_CONTEXT_NUMBER=${SVN_REVISION}_${BUILD_NUMBER}
+DEB_CONTEXT_NUMBER=${SVN_REVISION}-${BUILD_NUMBER}
diff --git a/crowbar/change-image/dell/barclamps/deployer/Makefile b/crowbar/change-image/dell/barclamps/deployer/Makefile
new file mode 100644
index 00000000000..37e37fb0045
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/deployer/Makefile
@@ -0,0 +1,21 @@
+
+clean:
+ @echo "Cleaning barclamp-deployer"
+
+distclean:
+ @echo "Dist-Cleaning barclamp-deployer"
+
+all: clean build install
+
+build:
+ @echo "Building barclamp-deployer"
+
+install:
+ @echo "Installing barclamp-deployer"
+ mkdir -p ${DESTDIR}/opt/crowbar/openstack_manager
+ cp -r app ${DESTDIR}/opt/crowbar/openstack_manager
+ mkdir -p ${DESTDIR}/usr/share/barclamp-deployer
+ cp -r chef ${DESTDIR}/usr/share/barclamp-deployer
+ mkdir -p ${DESTDIR}/usr/bin
+ cp -r command_line/* ${DESTDIR}/usr/bin
+
diff --git a/crowbar/change-image/dell/barclamps/deployer/app/controllers/deployer_controller.rb b/crowbar/change-image/dell/barclamps/deployer/app/controllers/deployer_controller.rb
new file mode 100644
index 00000000000..6afe26cda6e
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/deployer/app/controllers/deployer_controller.rb
@@ -0,0 +1,21 @@
+# Copyright 2011, Dell
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+class DeployerController < BarclampController
+ def initialize
+ @service_object = DeployerService.new logger
+ end
+end
+
diff --git a/crowbar/change-image/dell/barclamps/deployer/app/models/deployer_service.rb b/crowbar/change-image/dell/barclamps/deployer/app/models/deployer_service.rb
new file mode 100644
index 00000000000..a93ce626bfe
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/deployer/app/models/deployer_service.rb
@@ -0,0 +1,276 @@
+# Copyright 2011, Dell
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+class DeployerService < ServiceObject
+
+ def initialize(thelogger)
+ @bc_name = "deployer"
+ @logger = thelogger
+ end
+
+ def create_proposal
+ @logger.debug("Deployer create_proposal: entering")
+ base = super
+ @logger.debug("Deployer create_proposal: leaving")
+ base
+ end
+
+ def transition(inst, name, state)
+ @logger.debug("Deployer transition: entering #{name} for #{state}")
+
+ node = NodeObject.find_node_by_name(name)
+ if node.nil?
+ @logger.error("Deployer transition: leaving #{name} for #{state}: Node not found")
+ return [404, "Failed to find node"]
+ end
+
+ #
+ # If we are discovering the node, make sure that we add the deployer client to the node
+ #
+ if state == "discovering"
+ @logger.debug("Deployer transition: leaving #{name} for #{state}: discovering mode")
+
+ db = ProposalObject.find_proposal("deployer", inst)
+ role = RoleObject.find_role_by_name "deployer-config-#{inst}"
+
+ result = add_role_to_instance_and_node("deployer", inst, name, db, role, "deployer-client")
+
+ @logger.debug("Deployer transition: leaving #{name} for #{state}: discovering mode: #{result}")
+ return [200, NodeObject.find_node_by_name(name).to_hash ] if result
+ return [404, "Failed to add role to node"] unless result
+ end
+
+ #
+ # The temp booting images need to have clients cleared.
+ #
+ if ["delete","discovered","hardware-installed","hardware-updated",
+ "hardware-installing","hardware-updating","reset","reinstall",
+ "update"].member?(state) and !node.admin?
+ @logger.debug("Deployer transition: should be deleting a client entry for #{node.name}")
+ client = ClientObject.find_client_by_name node.name
+ @logger.debug("Deployer transition: found and trying to delete a client entry for #{node.name}") unless client.nil?
+ client.destroy unless client.nil?
+
+ # Make sure that the node can be accessed by knife ssh or ssh
+ if ["reset","reinstall","update","delete"].member?(state)
+ system("sudo rm /root/.ssh/known_hosts")
+ end
+ end
+
+ # if delete - clear out stuff
+ if state == "delete"
+ # Do more work here - one day.
+ return [200, node.to_hash ]
+ end
+
+ #
+ # Decide on the nodes role for the cloud
+ # * This includes adding a role for node type (for bios/raid update/config)
+ # * This includes adding an attribute on the node for inclusion in clouds
+ #
+ if state == "discovered"
+ @logger.debug("Deployer transition: discovered state for #{name}")
+ save_it = false
+
+ if !node.admin?
+ @logger.debug("Deployer transition: check to see if we should rename: #{name}")
+ tname = node.name.split(".")[0]
+ tname = tname.gsub!("h", "d")
+ new_name = "#{tname}.#{ChefObject.cloud_domain}"
+ if new_name != node.name
+ @logger.debug("Deployer transition: renaming node for #{name} #{node.name} -> #{new_name}")
+ node.destroy
+
+ node.name = new_name
+ node[:fqdn] = new_name
+ node[:domain] = ChefObject.cloud_domain
+ save_it = true
+ name = new_name
+ end
+ else # We are an admin node - display bios updates for now.
+ node[:bios] ||= {}
+ node[:bios][:bios_setup_enable] = false
+ node[:bios][:bios_update_enable] = false
+ node[:raid] ||= {}
+ node[:raid][:enable] = false
+ save_it = true
+ end
+
+ #
+ # At this point, we need to create our resource maps and recommendations.
+ #
+ # This is hard coded for now. Should be parameter driven one day.
+ #
+ @logger.debug("Deployer transition: Update the inventory crowbar structures for #{name}")
+ node[:crowbar][:disks] = {} if node[:crowbar][:disks].nil?
+ node[:block_device].each do |disk, data|
+ # XXX: Make this into a config map one day.
+ next if disk.start_with?("ram")
+ next if disk.start_with?("sr")
+ next if disk.start_with?("loop")
+ next if disk.start_with?("dm")
+ next if disk.start_with?("ndb")
+ next if disk.start_with?("md")
+ next if disk.start_with?("sg")
+ next if disk.start_with?("fd")
+
+ next if data[:removable] == 1 or data[:removable] == "1" # Skip cdroms
+
+ # RedHat under KVM reports drives as hdX. Ubuntu reports them as sdX.
+ disk = disk.gsub("hd", "sd") if disk.start_with?("h") and node[:dmi][:system][:product_name] == "KVM"
+
+ node[:crowbar][:disks][disk] = data
+
+ node[:crowbar][:disks][disk][:usage] = "OS" if disk == "sda"
+ node[:crowbar][:disks][disk][:usage] = "Storage" unless disk == "sda"
+
+ save_it = true
+ end unless node[:block_device].nil? or node[:block_device].empty?
+
+ node[:crowbar][:usage] = [] if node[:crowbar][:usage].nil?
+ if (node[:crowbar][:disks].size > 1) and !node[:crowbar][:usage].include?("swift")
+ node[:crowbar][:usage] << "swift"
+ save_it = true
+ end
+
+ if !node[:crowbar][:usage].include?("nova")
+ node[:crowbar][:usage] << "nova"
+ save_it = true
+ end
+
+ node.save if save_it
+
+ # Allocate required addresses
+ range = node.admin? ? "admin" : "host"
+ @logger.debug("Deployer transition: Allocate admin address for #{name}")
+ ns = NetworkService.new @logger
+ result = ns.allocate_ip("default", "admin", range, name)
+ @logger.error("Failed to allocate admin address for: #{node.name}: #{result[0]}") if result[0] != 200
+ @logger.debug("Deployer transition: Done Allocate admin address for #{name}")
+
+ @logger.debug("Deployer transition: Allocate bmc address for #{name}")
+ result = ns.allocate_ip("default", "bmc", "host", name)
+ @logger.error("Failed to allocate bmc address for: #{node.name}: #{result[0]}") if result[0] != 200
+ @logger.debug("Deployer transition: Done Allocate bmc address for #{name}")
+
+ # If we are the admin node, we may need to add a vlan bmc address.
+ if node.admin?
+ # Add the vlan bmc if the bmc network and the admin network are not the same.
+ # not great to do it this way, but hey.
+ admin_net = ProposalObject.find_data_bag_item "crowbar/admin_network"
+ bmc_net = ProposalObject.find_data_bag_item "crowbar/bmc_network"
+ if admin_net["network"]["subnet"] != bmc_net["network"]["subnet"]
+ @logger.debug("Deployer transition: Allocate bmc_vlan address for #{name}")
+ result = ns.allocate_ip("default", "bmc_vlan", "host", name)
+ @logger.error("Failed to allocate bmc_vlan address for: #{node.name}: #{result[0]}") if result[0] != 200
+ @logger.debug("Deployer transition: Done Allocate bmc_vlan address for #{name}")
+ end
+ end
+
+ # Let it fly to the provisioner. Reload to get the address.
+ node = NodeObject.find_node_by_name node.name
+ node[:crowbar][:usedhcp] = true
+
+ role = RoleObject.find_role_by_name "deployer-config-#{inst}"
+ if role.default_attributes["deployer"]["use_allocate"] and !node.admin?
+ node.allocated = false
+ else
+ node.allocated = true
+ end
+
+ node.save
+
+ @logger.debug("Deployer transition: leaving discovered for #{name} EOF")
+ return [200, node.to_hash ]
+ end
+
+ save_it = false
+ #
+ # Once we have been allocated, we will fly through here and we will setup the raid/bios info
+ #
+ if state == "hardware-installing"
+ # build a list of current and pending roles to check against
+ roles = []
+ node["crowbar"]["pending"].each do |k,v|
+ roles << v
+ end unless node["crowbar"]["pending"].nil?
+ roles.flatten!
+ node.run_list.run_list_items.each do |item|
+ roles << item.name
+ end
+
+ # Walk map to categorize the node. Choose first one from the bios map that matches.
+ role = RoleObject.find_role_by_name "deployer-config-#{inst}"
+ done = false
+ role.default_attributes["deployer"]["bios_map"].each do |match|
+ roles.each do |role|
+ if role =~ /#{match["pattern"]}/
+ node["crowbar"]["hardware"] = {} if node["crowbar"]["hardware"].nil?
+ node["crowbar"]["hardware"]["bios_set"] = match["bios_set"] if node["crowbar"]["hardware"]["bios_set"].nil?
+ node["crowbar"]["hardware"]["raid_set"] = match["raid_set"] if node["crowbar"]["hardware"]["raid_set"].nil?
+ done = true
+ break
+ end
+ end
+ break if done
+ end
+ save_it = true
+ end
+
+ #
+ # The node is about to go into update.
+ # We should make sure that we save and setup the run-list for updating.
+ #
+ if state == "update" or state == "hardware-installing"
+ save_list = node["crowbar"]["save_run_list"] || []
+ seen_bios = false
+ node.run_list.run_list_items.each do |item|
+ if seen_bios and !(item.name =~ /^ipmi-/)
+ save_list << item.name
+ else
+ seen_bios = true if item.name =~ /^ipmi-/
+ end
+ end
+
+ save_list.each do |item|
+ node.run_list.run_list_items.delete "role[#{item}]"
+ end
+
+ node["crowbar"]["save_run_list"] = save_list
+ save_it = true
+ end
+
+ #
+ # Put the run-list back.
+ #
+ if state == "hardware-updated" or state == "hardware-installed"
+ unless node["crowbar"]["save_run_list"].nil?
+ node["crowbar"]["save_run_list"].each do |name|
+ node.run_list.run_list_items << "role[#{name}]"
+ end
+ end
+
+ node["crowbar"]["save_run_list"] = []
+ save_it = true
+ end
+
+ node.save if save_it
+
+ @logger.debug("Deployer transition: leaving state for #{name} EOF")
+ return [200, node.to_hash ]
+ end
+
+end
+
diff --git a/crowbar/change-image/dell/barclamps/deployer/barclamp-deployer.spec b/crowbar/change-image/dell/barclamps/deployer/barclamp-deployer.spec
new file mode 100644
index 00000000000..18ee13d041c
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/deployer/barclamp-deployer.spec
@@ -0,0 +1,52 @@
+
+%define _topdir BUILD_DIR
+%define name barclamp-deployer
+%define release RPM_CONTEXT_NUMBER
+%define version MAJOR_VERSION.MINOR_VERSION
+%define buildroot %{_topdir}/%{name}-%{version}-root
+
+BuildRoot: %{buildroot}
+Summary: Crowbar Barclamp to Support Deployments
+License: Apache 2.0
+Name: %{name}
+BuildArch: noarch
+Version: %{version}
+Release: %{release}
+Source: %{name}-%{version}.tar.gz
+Prefix: /
+Group: Development/Tools
+
+%description
+A Crowbar Barclamp that manages deployer deployments within a Crowbar environment.
+
+%prep
+%setup -q
+
+%build
+
+%install
+make install DESTDIR=${RPM_BUILD_ROOT}
+
+%post
+cd /usr/share/barclamp-deployer/chef/cookbooks
+knife cookbook upload -o . -a -u chef-webui -k /etc/chef/webui.pem
+
+cd /usr/share/barclamp-deployer/chef/data_bags/crowbar
+for i in *.json; do
+ knife data bag from file crowbar $i
+done
+
+cd /usr/share/barclamp-deployer/chef/roles
+for i in *.rb; do
+ knife role from file $i
+done
+
+service httpd graceful
+
+
+%files
+%defattr(-,root,root)
+/usr/bin
+/usr/share
+/opt
+
diff --git a/crowbar/change-image/dell/barclamps/deployer/build_deb.sh b/crowbar/change-image/dell/barclamps/deployer/build_deb.sh
new file mode 100755
index 00000000000..79bf21d2ba7
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/deployer/build_deb.sh
@@ -0,0 +1,17 @@
+#
+# Must have tools:
+# apt-get install dpkg-dev debhelper devscripts fakeroot linda dh-make
+#
+
+. ./version.sh
+
+sed -e "s/CHANGE_LOG_LINE/barclamp-${BARCLAMP_NAME} (${MAJOR_VERSION}.${MINOR_VERSION}-${DEB_CONTEXT_NUMBER}) unstable; urgency=low/" debian/changelog.tmpl > debian/changelog
+
+
+yes | debuild -us -uc
+
+mkdir -p bin
+mv ../barclamp-${BARCLAMP_NAME}_*.deb bin
+mv ../barclamp-${BARCLAMP_NAME}_*gz bin
+rm ../barclamp-${BARCLAMP_NAME}_*
+
diff --git a/crowbar/change-image/dell/barclamps/deployer/build_rpm.sh b/crowbar/change-image/dell/barclamps/deployer/build_rpm.sh
new file mode 100755
index 00000000000..c15d9be527a
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/deployer/build_rpm.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+
+#
+# Needs sudo apt-get install rpm
+#
+
+. ./version.sh
+
+BUILD_DIR="/tmp/build.$$"
+rm -rf ${BUILD_DIR}
+mkdir -p ${BUILD_DIR}/BUILD
+mkdir -p ${BUILD_DIR}/RPMS
+mkdir -p ${BUILD_DIR}/SOURCES
+mkdir -p ${BUILD_DIR}/SPECS
+mkdir -p ${BUILD_DIR}/SRPMS
+
+FULL_NAME="barclamp-${BARCLAMP_NAME}-${MAJOR_VERSION}.${MINOR_VERSION}"
+
+mkdir $FULL_NAME
+cp -r Makefile app chef command_line $FULL_NAME
+tar -zcf ${BUILD_DIR}/SOURCES/${FULL_NAME}.tar.gz ${FULL_NAME}
+rm -rf ${FULL_NAME}
+
+sed -e "s%BUILD_DIR%$BUILD_DIR%" barclamp-${BARCLAMP_NAME}.spec > ${BUILD_DIR}/SPECS/barclamp-${BARCLAMP_NAME}.spec
+sed -ie "s%MAJOR_VERSION%${MAJOR_VERSION}%" ${BUILD_DIR}/SPECS/barclamp-${BARCLAMP_NAME}.spec
+sed -ie "s%MINOR_VERSION%${MINOR_VERSION}%" ${BUILD_DIR}/SPECS/barclamp-${BARCLAMP_NAME}.spec
+sed -ie "s%RPM_CONTEXT_NUMBER%${RPM_CONTEXT_NUMBER}%" ${BUILD_DIR}/SPECS/barclamp-${BARCLAMP_NAME}.spec
+
+rpmbuild -v -ba --clean ${BUILD_DIR}/SPECS/barclamp-${BARCLAMP_NAME}.spec
+
+mkdir -p bin
+cp ${BUILD_DIR}/RPMS/noarch/* bin
+cp ${BUILD_DIR}/SRPMS/* bin
+#rm -rf ${BUILD_DIR}
diff --git a/crowbar/change-image/dell/barclamps/deployer/chef/cookbooks/barclamp/libraries/barclamp_library.rb b/crowbar/change-image/dell/barclamps/deployer/chef/cookbooks/barclamp/libraries/barclamp_library.rb
new file mode 100644
index 00000000000..8f50554385b
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/deployer/chef/cookbooks/barclamp/libraries/barclamp_library.rb
@@ -0,0 +1,100 @@
+
+module BarclampLibrary
+ class Barclamp
+ class Inventory
+ def self.list_networks(node)
+ answer = []
+ node[:crowbar][:network].each do |net, data|
+ answer << Network.new(net, data)
+ end unless node[:crowbar][:network].nil?
+ answer
+ end
+
+ def self.get_network_by_interface(node, intf)
+ node[:crowbar][:network].each do |net, data|
+ next if net != intf
+ return Network.new(net, data)
+ end unless node[:crowbar][:network].nil?
+ nil
+ end
+
+ def self.get_network_by_type(node, type)
+ node[:crowbar][:network].each do |net, data|
+ next if data[:usage] != type
+ return Network.new(net, data)
+ end unless node[:crowbar][:network].nil?
+ node[:crowbar][:network].each do |net, data|
+ next if data[:usage] != "admin"
+ return Network.new(net, data)
+ end unless node[:crowbar][:network].nil?
+ Network.new(type, { "address" => node[:ipaddress] })
+ end
+
+ def self.list_disks(node)
+ answer = []
+ node[:crowbar][:disks].each do |disk, data|
+ answer << Disk.new(disk, data)
+ end unless node[:crowbar][:disks].nil?
+ answer
+ end
+
+ class Network
+ attr_reader :name, :address, :broadcast, :mac, :netmask, :subnet, :router, :usage, :vlan, :use_vlan, :interface, :interface_list, :add_bridge
+ def initialize(net, data)
+ @name = net
+ @address = data["address"]
+ @broadcast = data["broadcast"]
+ @mac = data["mac"]
+ @netmask = data["netmask"]
+ @subnet = data["subnet"]
+ @router = data["router"]
+ @usage = data["usage"]
+ @vlan = data["vlan"]
+ @use_vlan = data["use_vlan"]
+ @interface = data["interface"]
+ @interface_list = data["interface_list"]
+ @add_bridge = data["add_bridge"]
+ end
+ end
+
+ class Disk
+ attr_reader :name, :model, :removable, :rev, :size, :state, :timeout, :vendor, :usage
+ def initialize(disk, data)
+ @name = "/dev/#{disk}"
+ @model = data["model"] || "Unknown"
+ @removable = data["removable"] != "0"
+ @rev = data["rev"] || "Unknown"
+ @size = (data["size"] || 0).to_i
+ @state = data["state"] || "Unknown"
+ @timeout = (data["timeout"] || 0).to_i
+ @vendor = data["vendor"] || "NA"
+ @usage = data["usage"] || "Unknown"
+ end
+
+ def self.size_to_bytes(s)
+ case s
+ when /^([0-9]+)$/
+ return $1.to_f
+
+ when /^([0-9]+)[Kk][Bb]$/
+ return $1.to_f * 1024
+
+ when /^([0-9]+)[Mm][Bb]$/
+ return $1.to_f * 1024 * 1024
+
+ when /^([0-9]+)[Gg][Bb]$/
+ return $1.to_f * 1024 * 1024 * 1024
+
+ when /^([0-9]+)[Tt][Bb]$/
+ return $1.to_f * 1024 * 1024 * 1024 * 1024
+ end
+ -1
+ end
+
+ end
+
+ end
+ end
+end
+
+
diff --git a/crowbar/change-image/dell/barclamps/deployer/chef/cookbooks/barclamp/metadata.json b/crowbar/change-image/dell/barclamps/deployer/chef/cookbooks/barclamp/metadata.json
new file mode 100644
index 00000000000..2008778432e
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/deployer/chef/cookbooks/barclamp/metadata.json
@@ -0,0 +1,36 @@
+{
+ "providing": {
+ },
+ "attributes": {
+ },
+ "replacing": {
+ },
+ "dependencies": {
+ },
+ "groupings": {
+ },
+ "recommendations": {
+ },
+ "platforms": {
+ "debian": [
+
+ ],
+ "ubuntu": [
+
+ ]
+ },
+ "license": "Apache 2.0",
+ "version": "0.9.5",
+ "maintainer": "Dell, Inc.",
+ "suggestions": {
+ },
+ "recipes": {
+ "barclamp": "Library for Barclamp functions"
+ },
+ "maintainer_email": "crowbar@dell.com",
+ "name": "barclamp",
+ "conflicting": {
+ },
+ "description": "Library for Barclamp functions",
+ "long_description": ""
+ }
diff --git a/crowbar/change-image/dell/barclamps/deployer/chef/cookbooks/barclamp/recipes/default.rb b/crowbar/change-image/dell/barclamps/deployer/chef/cookbooks/barclamp/recipes/default.rb
new file mode 100644
index 00000000000..4545dd8b1f9
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/deployer/chef/cookbooks/barclamp/recipes/default.rb
@@ -0,0 +1,5 @@
+
+class Chef::Recipe
+ include BarclampLibrary
+end
+
diff --git a/crowbar/change-image/dell/barclamps/deployer/chef/cookbooks/ohai/README.md b/crowbar/change-image/dell/barclamps/deployer/chef/cookbooks/ohai/README.md
new file mode 100644
index 00000000000..94f24e10632
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/deployer/chef/cookbooks/ohai/README.md
@@ -0,0 +1,41 @@
+Description
+===========
+
+Creates a configured plugin path for distributing custom Ohai plugins, and reloads them via Ohai within the context of a Chef Client run during the compile phase.
+
+Attributes
+==========
+
+`node[:ohai][:plugin_path]` - location to drop off plugins directory, default is `/etc/chef/ohai_plugins`. This is not FHS-compliant, an FHS location would be something like `/var/lib/ohai/plugins`, or `/var/lib/chef/ohai_plugins` or similar.
+
+Neither an FHS location or the default value of this attribute are in the default Ohai plugin path. Set the Ohai plugin path with the config setting "`Ohai::Config[:plugin_path`" in the Chef config file. The attribute is not set to the default plugin path that Ohai ships with because we don't want to risk destroying existing essential plugins for Ohai.
+
+Usage
+=====
+
+Put the recipe `ohai` at the start of the node's run list to make sure that custom plugins are loaded early on in the Chef run and data is available for later recipes.
+
+The execution of the custom plugins occurs within the recipe during the compile phase, so you can write new plugins and use the data they return in your Chef recipes.
+
+For information on how to write custom plugins for Ohai, please see the Chef wiki pages.
+
+http://wiki.opscode.com/display/chef/Writing+Ohai+Plugins
+
+License and Author
+==================
+
+Author:: Joshua Timberman ()
+
+Copyright:: 2010, Opscode, Inc
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/crowbar/change-image/dell/barclamps/deployer/chef/cookbooks/ohai/attributes/default.rb b/crowbar/change-image/dell/barclamps/deployer/chef/cookbooks/ohai/attributes/default.rb
new file mode 100644
index 00000000000..7e2b1585f07
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/deployer/chef/cookbooks/ohai/attributes/default.rb
@@ -0,0 +1,21 @@
+#
+# Cookbook Name:: ohai
+# Attribute:: default
+#
+# Copyright 2010, Opscode, Inc
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# FHS location would be /var/lib/chef/ohai_plugins or similar.
+default[:ohai][:plugin_path] = "/etc/chef/ohai_plugins"
diff --git a/crowbar/change-image/dell/barclamps/deployer/chef/cookbooks/ohai/files/default/plugins/README b/crowbar/change-image/dell/barclamps/deployer/chef/cookbooks/ohai/files/default/plugins/README
new file mode 100644
index 00000000000..72f12e3644f
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/deployer/chef/cookbooks/ohai/files/default/plugins/README
@@ -0,0 +1 @@
+This directory contains custom plugins for Ohai.
diff --git a/crowbar/change-image/dell/barclamps/deployer/chef/cookbooks/ohai/files/default/plugins/crowbar.rb b/crowbar/change-image/dell/barclamps/deployer/chef/cookbooks/ohai/files/default/plugins/crowbar.rb
new file mode 100644
index 00000000000..52dca060737
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/deployer/chef/cookbooks/ohai/files/default/plugins/crowbar.rb
@@ -0,0 +1,104 @@
+
+require 'timeout'
+
+provides "crowbar"
+
+class System
+ def self.background_time_command(timeout, background, name, command)
+ File.open("/tmp/tcpdump-#{name}.sh", "w+") { |fd|
+ fd.puts("#!/bin/bash")
+ fd.puts("#{command} &")
+ fd.puts("sleep #{timeout}")
+ fd.puts("kill %1")
+ }
+
+ system("chmod +x /tmp/tcpdump-#{name}.sh")
+ if background
+ system("/tmp/tcpdump-#{name}.sh &")
+ else
+ system("/tmp/tcpdump-#{name}.sh")
+ end
+ end
+end
+
+filename = "/usr/sbin/lshw"
+if !File.exists?(filename)
+ filename = "/usr/bin/lshw"
+end
+f = IO.popen("#{filename} -class network | egrep 'logical|bus info|-network|serial'")
+networks = []
+mac_map = {}
+bus_found=false
+logical_name=""
+mac_addr=""
+wait=false
+f.each { |line|
+ if line =~ /\*-network/
+ if bus_found
+ networks << logical_name
+ mac_map[logical_name] = mac_addr
+ if !File.exists?("/tmp/tcpdump.#{logical_name}.out")
+ System.background_time_command(45, true, logical_name, "ifconfig #{logical_name} up ; tcpdump -c 1 -lv -v -i #{logical_name} -a -e -s 1514 ether proto 0x88cc > /tmp/tcpdump.#{logical_name}.out")
+ wait=true
+ end
+ end
+ bus_found=false
+ end
+ if line =~ /bus info:/
+ bus_found = true
+ end
+ if line =~ /logical name: (.*)/
+ logical_name = $1
+ end
+ if line =~ /serial: (.*)/
+ mac_addr = $1
+ end
+}
+f.close
+if bus_found
+ networks << logical_name
+ mac_map[logical_name] = mac_addr
+ if !File.exists?("/tmp/tcpdump.#{logical_name}.out")
+ System.background_time_command(45, true, logical_name, "ifconfig #{logical_name} up ; tcpdump -c 1 -lv -v -i #{logical_name} -a -e -s 1514 ether proto 0x88cc > /tmp/tcpdump.#{logical_name}.out")
+ wait=true
+ end
+end
+system("sleep 45") if wait
+
+crowbar Mash.new
+crowbar[:switch_config] = Mash.new unless crowbar[:switch_config]
+
+networks.each do |network|
+ sw_port = -1
+ line = %x[cat /tmp/tcpdump.#{network}.out | grep "Subtype Interface Name"]
+ if line =~ /[\d]+\/[\d]+\/([\d]+)/
+ sw_port = $1
+ end
+ if line =~ /: Unit [\d]+ Port ([\d]+)/
+ sw_port = $1
+ end
+
+ sw_unit = -1
+ line = %x[cat /tmp/tcpdump.#{network}.out | grep "Subtype Interface Name"]
+ if line =~ /([\d]+)\/[\d]+\/[\d]+/
+ sw_unit = $1
+ end
+ if line =~ /: Unit ([\d]+) Port [\d]+/
+ sw_unit = $1
+ end
+
+ sw_name = -1
+ # GREG: Using mac for now, but should change to something else later.
+ line = %x[cat /tmp/tcpdump.#{network}.out | grep "Subtype MAC address"]
+ if line =~ /: (.*) \(oui/
+ sw_name = $1
+ end
+
+ crowbar[:switch_config][network] = Mash.new unless crowbar[:switch_config][network]
+ crowbar[:switch_config][network][:interface] = network
+ crowbar[:switch_config][network][:mac] = mac_map[network].downcase
+ crowbar[:switch_config][network][:switch_name] = sw_name
+ crowbar[:switch_config][network][:switch_port] = sw_port
+ crowbar[:switch_config][network][:switch_unit] = sw_unit
+end
+
diff --git a/crowbar/change-image/dell/barclamps/deployer/chef/cookbooks/ohai/metadata.json b/crowbar/change-image/dell/barclamps/deployer/chef/cookbooks/ohai/metadata.json
new file mode 100644
index 00000000000..25444416d92
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/deployer/chef/cookbooks/ohai/metadata.json
@@ -0,0 +1,30 @@
+{
+ "name": "ohai",
+ "description": "Distributes a directory of custom ohai plugins",
+ "long_description": "Description\n===========\n\nCreates a configured plugin path for distributing custom Ohai plugins, and reloads them via Ohai within the context of a Chef Client run during the compile phase.\n\nAttributes\n==========\n\n`node[:ohai][:plugin_path]` - location to drop off plugins directory, default is `/etc/chef/ohai_plugins`. This is not FHS-compliant, an FHS location would be something like `/var/lib/ohai/plugins`, or `/var/lib/chef/ohai_plugins` or similar.\n\nNeither an FHS location or the default value of this attribute are in the default Ohai plugin path. Set the Ohai plugin path with the config setting \"`Ohai::Config[:plugin_path`\" in the Chef config file. The attribute is not set to the default plugin path that Ohai ships with because we don't want to risk destroying existing essential plugins for Ohai.\n\nUsage\n=====\n\nPut the recipe `ohai` at the start of the node's run list to make sure that custom plugins are loaded early on in the Chef run and data is available for later recipes.\n\nThe execution of the custom plugins occurs within the recipe during the compile phase, so you can write new plugins and use the data they return in your Chef recipes.\n\nFor information on how to write custom plugins for Ohai, please see the Chef wiki pages.\n\nhttp://wiki.opscode.com/display/chef/Writing+Ohai+Plugins\n\nLicense and Author\n==================\n\nAuthor:: Joshua Timberman ()\n\nCopyright:: 2010, Opscode, Inc\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
+ "maintainer": "Opscode, Inc",
+ "maintainer_email": "cookbooks@opscode.com",
+ "license": "Apache 2.0",
+ "platforms": {
+ },
+ "dependencies": {
+ },
+ "recommendations": {
+ },
+ "suggestions": {
+ },
+ "conflicting": {
+ },
+ "providing": {
+ },
+ "replacing": {
+ },
+ "attributes": {
+ },
+ "groupings": {
+ },
+ "recipes": {
+ "ohai::default": "Distributes a directory of custom ohai plugins"
+ },
+ "version": "0.9.0"
+}
\ No newline at end of file
diff --git a/crowbar/change-image/dell/barclamps/deployer/chef/cookbooks/ohai/metadata.rb b/crowbar/change-image/dell/barclamps/deployer/chef/cookbooks/ohai/metadata.rb
new file mode 100644
index 00000000000..02f52da3d45
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/deployer/chef/cookbooks/ohai/metadata.rb
@@ -0,0 +1,7 @@
+maintainer "Opscode, Inc"
+maintainer_email "cookbooks@opscode.com"
+license "Apache 2.0"
+description "Distributes a directory of custom ohai plugins"
+long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
+version "0.9.0"
+recipe "ohai::default", "Distributes a directory of custom ohai plugins"
diff --git a/crowbar/change-image/dell/barclamps/deployer/chef/cookbooks/ohai/recipes/default.rb b/crowbar/change-image/dell/barclamps/deployer/chef/cookbooks/ohai/recipes/default.rb
new file mode 100644
index 00000000000..a1392e6d4bb
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/deployer/chef/cookbooks/ohai/recipes/default.rb
@@ -0,0 +1,45 @@
+#
+# Cookbook Name:: ohai
+# Recipe:: default
+#
+# Copyright 2010, Opscode, Inc
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+Ohai::Config[:plugin_path] << node.ohai.plugin_path
+Chef::Log.info("ohai plugins will be at: #{node.ohai.plugin_path}")
+
+d = directory node.ohai.plugin_path do
+ owner 'root'
+ group 'root'
+ mode 0755
+ recursive true
+ action :nothing
+end
+
+d.run_action(:create)
+
+rd = remote_directory node.ohai.plugin_path do
+ source 'plugins'
+ owner 'root'
+ group 'root'
+ mode 0755
+ action :nothing
+end
+
+rd.run_action(:create)
+
+o = Ohai::System.new
+o.all_plugins
+node.automatic_attrs.merge! o.data
diff --git a/crowbar/change-image/dell/barclamps/deployer/chef/data_bags/crowbar/bc-template-deployer.json b/crowbar/change-image/dell/barclamps/deployer/chef/data_bags/crowbar/bc-template-deployer.json
new file mode 100644
index 00000000000..523d0f3ffa2
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/deployer/chef/data_bags/crowbar/bc-template-deployer.json
@@ -0,0 +1,30 @@
+{
+ "id": "bc-template-deployer",
+ "description": "Initial classification system for the Crowbar environment ",
+ "attributes": {
+ "deployer": {
+ "use_allocate": true,
+ "bios_map": [
+ { "pattern": "nova-.*", "bios_set": "Virtualization", "raid_set": "SingleRaid10" },
+ { "pattern": "swift-.*", "bios_set": "Storage", "raid_set": "JBODOnly" },
+ { "pattern": ".*", "bios_set": "Virtualization", "raid_set": "SingleRaid10" }
+ ]
+ }
+ },
+ "deployment": {
+ "deployer": {
+ "crowbar-revision": 0,
+ "elements": {},
+ "element_order": [
+ [ "deployer-client" ]
+ ],
+ "config": {
+ "environment": "deployer-config-test",
+ "mode": "full",
+ "transitions": true,
+ "transition_list": [ "all" ]
+ }
+ }
+ }
+}
+
diff --git a/crowbar/change-image/dell/barclamps/deployer/chef/data_bags/crowbar/bc-template-deployer.schema b/crowbar/change-image/dell/barclamps/deployer/chef/data_bags/crowbar/bc-template-deployer.schema
new file mode 100644
index 00000000000..0db33d463f7
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/deployer/chef/data_bags/crowbar/bc-template-deployer.schema
@@ -0,0 +1,82 @@
+{
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "id": { "type": "str", "required": true, "pattern": "/^bc-deployer-|^bc-template-deployer$/" },
+ "description": { "type": "str", "required": true },
+ "attributes": {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "deployer": {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "use_allocate": { "type": "bool", "required": true },
+ "bios_map": {
+ "type": "seq",
+ "required": true,
+ "sequence": [ {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "pattern": { "type": "str", "required": true },
+ "bios_set": { "type": "str", "required": true },
+ "raid_set": { "type": "str", "required": true }
+ }
+ } ]
+ }
+ }
+ }
+ }
+ },
+ "deployment": {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "deployer": {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "crowbar-revision": { "type": "int", "required": true },
+ "crowbar-committing": { "type": "bool" },
+ "crowbar-queued": { "type": "bool" },
+ "elements": {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ = : {
+ "type": "seq",
+ "required": true,
+ "sequence": [ { "type": "str" } ]
+ }
+ }
+ },
+ "element_order": {
+ "type": "seq",
+ "required": true,
+ "sequence": [ {
+ "type": "seq",
+ "sequence": [ { "type": "str" } ]
+ } ]
+ },
+ "config": {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "environment": { "type": "str", "required": true },
+ "mode": { "type": "str", "required": true },
+ "transitions": { "type": "bool", "required": true },
+ "transition_list": {
+ "type": "seq",
+ "required": true,
+ "sequence": [ { "type": "str" } ]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/crowbar/change-image/dell/barclamps/deployer/chef/roles/deployer-client.rb b/crowbar/change-image/dell/barclamps/deployer/chef/roles/deployer-client.rb
new file mode 100644
index 00000000000..83884dfc4ba
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/deployer/chef/roles/deployer-client.rb
@@ -0,0 +1,10 @@
+
+name "deployer-client"
+description "Deployer Client role - Discovery components"
+run_list(
+ "recipe[ohai]",
+ "recipe[barclamp]"
+)
+default_attributes()
+override_attributes()
+
diff --git a/crowbar/change-image/dell/barclamps/deployer/command_line/crowbar_deployer b/crowbar/change-image/dell/barclamps/deployer/command_line/crowbar_deployer
new file mode 100755
index 00000000000..8b8d95b0823
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/deployer/command_line/crowbar_deployer
@@ -0,0 +1,6 @@
+#!/usr/bin/env ruby
+
+require File.join(File.expand_path(File.dirname(__FILE__)), "barclamp_lib")
+@barclamp = "deployer"
+
+main
diff --git a/crowbar/change-image/dell/barclamps/deployer/debian/changelog.tmpl b/crowbar/change-image/dell/barclamps/deployer/debian/changelog.tmpl
new file mode 100644
index 00000000000..42694be8134
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/deployer/debian/changelog.tmpl
@@ -0,0 +1,5 @@
+CHANGE_LOG_LINE
+
+ * Initial Release.
+
+ -- unknown Thu, 19 May 2011 15:50:02 -0500
diff --git a/crowbar/change-image/dell/barclamps/deployer/debian/compat b/crowbar/change-image/dell/barclamps/deployer/debian/compat
new file mode 100644
index 00000000000..7f8f011eb73
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/deployer/debian/compat
@@ -0,0 +1 @@
+7
diff --git a/crowbar/change-image/dell/barclamps/deployer/debian/control b/crowbar/change-image/dell/barclamps/deployer/debian/control
new file mode 100644
index 00000000000..a0ef4472fb8
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/deployer/debian/control
@@ -0,0 +1,13 @@
+Source: barclamp-deployer
+Section: unknown
+Priority: extra
+Maintainer: Dell Openstack
+Build-Depends: debhelper (>= 7.0.50~)
+Standards-Version: 3.9.1
+Homepage: http://openstack.dell.com/
+
+Package: barclamp-deployer
+Architecture: all
+Depends: barclamp-crowbar
+Description: Ganglia Barclamp for Crowbar
+ Provides the deployer barclamp for crowbar
diff --git a/crowbar/change-image/dell/barclamps/deployer/debian/copyright b/crowbar/change-image/dell/barclamps/deployer/debian/copyright
new file mode 100644
index 00000000000..ef293d897c8
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/deployer/debian/copyright
@@ -0,0 +1,26 @@
+This work was packaged for Debian by:
+
+ Dell Openstack Team on Thu, 19 May 2011 15:50:02 -0500
+
+It was downloaded from:
+
+
+
+Upstream Author(s):
+
+ Openstack Dell Team
+
+Copyright:
+
+ Copyright (C) 2011 Dell, Inc.
+
+License:
+
+GREG: Fill in Apache 2.0
+
+The Debian packaging is:
+
+ Copyright (C) 2011 Dell
+
+and is licensed under Apache 2.0, see above.
+
diff --git a/crowbar/change-image/dell/barclamps/deployer/debian/postinst b/crowbar/change-image/dell/barclamps/deployer/debian/postinst
new file mode 100644
index 00000000000..e1c58a3fc6c
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/deployer/debian/postinst
@@ -0,0 +1,53 @@
+#!/bin/sh
+# postinst script for #PACKAGE#
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+# * `configure'
+# * `abort-upgrade'
+# * `abort-remove' `in-favour'
+#
+# * `abort-remove'
+# * `abort-deconfigure' `in-favour'
+# `removing'
+#
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+
+case "$1" in
+ configure)
+ cd /usr/share/barclamp-deployer/chef/cookbooks
+ knife cookbook upload -o . -a -u chef-webui -k /etc/chef/webui.pem
+
+ cd /usr/share/barclamp-deployer/chef/data_bags/crowbar
+ for i in *.json; do
+ knife data bag from file crowbar $i
+ done
+
+ cd /usr/share/barclamp-deployer/chef/roles
+ for i in *.rb; do
+ knife role from file $i
+ done
+
+ service apache2 graceful
+ ;;
+
+ abort-upgrade|abort-remove|abort-deconfigure)
+ ;;
+
+ *)
+ echo "postinst called with unknown argument \`$1'" >&2
+ exit 1
+ ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
diff --git a/crowbar/change-image/dell/barclamps/deployer/debian/rules b/crowbar/change-image/dell/barclamps/deployer/debian/rules
new file mode 100755
index 00000000000..79fd842dcae
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/deployer/debian/rules
@@ -0,0 +1,8 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+%:
+ dh $@
diff --git a/crowbar/change-image/dell/barclamps/deployer/debian/source/format b/crowbar/change-image/dell/barclamps/deployer/debian/source/format
new file mode 100644
index 00000000000..89ae9db8f88
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/deployer/debian/source/format
@@ -0,0 +1 @@
+3.0 (native)
diff --git a/crowbar/change-image/dell/barclamps/deployer/version.sh b/crowbar/change-image/dell/barclamps/deployer/version.sh
new file mode 100644
index 00000000000..6cc48bef016
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/deployer/version.sh
@@ -0,0 +1,7 @@
+BARCLAMP_NAME=deployer
+MAJOR_VERSION=0
+MINOR_VERSION=8
+SVN_REVISION=${SVN_REVISION:-custom}
+BUILD_NUMBER=${BUILD_NUMBER:-custom}
+RPM_CONTEXT_NUMBER=${SVN_REVISION}_${BUILD_NUMBER}
+DEB_CONTEXT_NUMBER=${SVN_REVISION}-${BUILD_NUMBER}
diff --git a/crowbar/change-image/dell/barclamps/dns/Makefile b/crowbar/change-image/dell/barclamps/dns/Makefile
new file mode 100644
index 00000000000..ceaf3b5ce81
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/dns/Makefile
@@ -0,0 +1,21 @@
+
+clean:
+ @echo "Cleaning barclamp-dns"
+
+distclean:
+ @echo "Dist-Cleaning barclamp-dns"
+
+all: clean build install
+
+build:
+ @echo "Building barclamp-dns"
+
+install:
+ @echo "Installing barclamp-dns"
+ mkdir -p ${DESTDIR}/opt/crowbar/openstack_manager
+ cp -r app ${DESTDIR}/opt/crowbar/openstack_manager
+ mkdir -p ${DESTDIR}/usr/share/barclamp-dns
+ cp -r chef ${DESTDIR}/usr/share/barclamp-dns
+ mkdir -p ${DESTDIR}/usr/bin
+ cp -r command_line/* ${DESTDIR}/usr/bin
+
diff --git a/crowbar/change-image/dell/barclamps/dns/app/controllers/dns_controller.rb b/crowbar/change-image/dell/barclamps/dns/app/controllers/dns_controller.rb
new file mode 100644
index 00000000000..963fc1a61c5
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/dns/app/controllers/dns_controller.rb
@@ -0,0 +1,21 @@
+# Copyright 2011, Dell
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+class DnsController < BarclampController
+ def initialize
+ @service_object = DnsService.new logger
+ end
+end
+
diff --git a/crowbar/change-image/dell/barclamps/dns/app/models/dns_service.rb b/crowbar/change-image/dell/barclamps/dns/app/models/dns_service.rb
new file mode 100644
index 00000000000..28f539d61b1
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/dns/app/models/dns_service.rb
@@ -0,0 +1,62 @@
+# Copyright 2011, Dell
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+class DnsService < ServiceObject
+
+ def initialize(thelogger)
+ @bc_name = "dns"
+ @logger = thelogger
+ end
+
+ def create_proposal
+ @logger.debug("DNS create_proposal: entering")
+ base = super
+ @logger.debug("DNS create_proposal: exiting")
+ base
+ end
+
+ def transition(inst, name, state)
+ @logger.debug("DNS transition: entering for #{name} for #{state}")
+
+ #
+ # If we are discovering the node, make sure that we add the dns client or server to the node
+ #
+ if state == "discovered"
+ @logger.debug("DNS transition: handling for #{name} for #{state}: discovered")
+ db = ProposalObject.find_proposal "dns", inst
+ role = RoleObject.find_role_by_name "dns-config-#{inst}"
+
+ if role.override_attributes["dns"]["elements"]["dns-server"].nil? or
+ role.override_attributes["dns"]["elements"]["dns-server"].empty?
+ @logger.debug("DNS transition: adding #{name} to dns-server role")
+ result = add_role_to_instance_and_node("dns", inst, name, db, role, "dns-server")
+ end
+
+ # Always add the dns client
+ @logger.debug("DNS transition: adding #{name} to dns-client role")
+ result = add_role_to_instance_and_node("dns", inst, name, db, role, "dns-client")
+
+ a = [200, {}] if result
+ a = [400, "Failed to add role to node"] unless result
+ @logger.debug("DNS transition: leaving for #{name} for #{state}: discovered")
+ return a
+ end
+
+ @logger.debug("DNS transition: leaving for #{name} for #{state}")
+ [200, NodeObject.find_node_by_name(name).to_hash ]
+ end
+
+
+end
diff --git a/crowbar/change-image/dell/barclamps/dns/barclamp-dns.spec b/crowbar/change-image/dell/barclamps/dns/barclamp-dns.spec
new file mode 100644
index 00000000000..1b96bf11bc8
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/dns/barclamp-dns.spec
@@ -0,0 +1,52 @@
+
+%define _topdir BUILD_DIR
+%define name barclamp-dns
+%define release RPM_CONTEXT_NUMBER
+%define version MAJOR_VERSION.MINOR_VERSION
+%define buildroot %{_topdir}/%{name}-%{version}-root
+
+BuildRoot: %{buildroot}
+Summary: manages the DNS subsystem for the cluste
+License: Apache 2.0
+Name: %{name}
+BuildArch: noarch
+Version: %{version}
+Release: %{release}
+Source: %{name}-%{version}.tar.gz
+Prefix: /
+Group: Development/Tools
+
+%description
+A Crowbar Barclamp that manages dns deployments within a Crowbar environment.
+
+%prep
+%setup -q
+
+%build
+
+%install
+make install DESTDIR=${RPM_BUILD_ROOT}
+
+%post
+cd /usr/share/barclamp-dns/chef/cookbooks
+knife cookbook upload -o . -a -u chef-webui -k /etc/chef/webui.pem
+
+cd /usr/share/barclamp-dns/chef/data_bags/crowbar
+for i in *.json; do
+ knife data bag from file crowbar $i
+done
+
+cd /usr/share/barclamp-dns/chef/roles
+for i in *.rb; do
+ knife role from file $i
+done
+
+service httpd graceful
+
+
+%files
+%defattr(-,root,root)
+/usr/bin
+/usr/share
+/opt
+
diff --git a/crowbar/change-image/dell/barclamps/dns/build_deb.sh b/crowbar/change-image/dell/barclamps/dns/build_deb.sh
new file mode 100755
index 00000000000..79bf21d2ba7
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/dns/build_deb.sh
@@ -0,0 +1,17 @@
+#
+# Must have tools:
+# apt-get install dpkg-dev debhelper devscripts fakeroot linda dh-make
+#
+
+. ./version.sh
+
+sed -e "s/CHANGE_LOG_LINE/barclamp-${BARCLAMP_NAME} (${MAJOR_VERSION}.${MINOR_VERSION}-${DEB_CONTEXT_NUMBER}) unstable; urgency=low/" debian/changelog.tmpl > debian/changelog
+
+
+yes | debuild -us -uc
+
+mkdir -p bin
+mv ../barclamp-${BARCLAMP_NAME}_*.deb bin
+mv ../barclamp-${BARCLAMP_NAME}_*gz bin
+rm ../barclamp-${BARCLAMP_NAME}_*
+
diff --git a/crowbar/change-image/dell/barclamps/dns/build_rpm.sh b/crowbar/change-image/dell/barclamps/dns/build_rpm.sh
new file mode 100755
index 00000000000..c15d9be527a
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/dns/build_rpm.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+
+#
+# Needs sudo apt-get install rpm
+#
+
+. ./version.sh
+
+BUILD_DIR="/tmp/build.$$"
+rm -rf ${BUILD_DIR}
+mkdir -p ${BUILD_DIR}/BUILD
+mkdir -p ${BUILD_DIR}/RPMS
+mkdir -p ${BUILD_DIR}/SOURCES
+mkdir -p ${BUILD_DIR}/SPECS
+mkdir -p ${BUILD_DIR}/SRPMS
+
+FULL_NAME="barclamp-${BARCLAMP_NAME}-${MAJOR_VERSION}.${MINOR_VERSION}"
+
+mkdir $FULL_NAME
+cp -r Makefile app chef command_line $FULL_NAME
+tar -zcf ${BUILD_DIR}/SOURCES/${FULL_NAME}.tar.gz ${FULL_NAME}
+rm -rf ${FULL_NAME}
+
+sed -e "s%BUILD_DIR%$BUILD_DIR%" barclamp-${BARCLAMP_NAME}.spec > ${BUILD_DIR}/SPECS/barclamp-${BARCLAMP_NAME}.spec
+sed -ie "s%MAJOR_VERSION%${MAJOR_VERSION}%" ${BUILD_DIR}/SPECS/barclamp-${BARCLAMP_NAME}.spec
+sed -ie "s%MINOR_VERSION%${MINOR_VERSION}%" ${BUILD_DIR}/SPECS/barclamp-${BARCLAMP_NAME}.spec
+sed -ie "s%RPM_CONTEXT_NUMBER%${RPM_CONTEXT_NUMBER}%" ${BUILD_DIR}/SPECS/barclamp-${BARCLAMP_NAME}.spec
+
+rpmbuild -v -ba --clean ${BUILD_DIR}/SPECS/barclamp-${BARCLAMP_NAME}.spec
+
+mkdir -p bin
+cp ${BUILD_DIR}/RPMS/noarch/* bin
+cp ${BUILD_DIR}/SRPMS/* bin
+#rm -rf ${BUILD_DIR}
diff --git a/crowbar/change-image/dell/barclamps/dns/chef/cookbooks/bind9/README.rdoc b/crowbar/change-image/dell/barclamps/dns/chef/cookbooks/bind9/README.rdoc
new file mode 100644
index 00000000000..bddd59c4be5
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/dns/chef/cookbooks/bind9/README.rdoc
@@ -0,0 +1,51 @@
+= DESCRIPTION:
+
+
+= REQUIREMENTS:
+
+== Platform:
+
+
+== Cookbooks:
+
+
+* ruby
+* apache2
+* passenger
+
+= ATTRIBUTES:
+
+* rails[:version] - Install the specified version. Default false (installs latest).
+* rails[:environment] - Set Rails environment. Default production.
+
+= USAGE:
+
+The recommended Rails application deployment method is Passenger and use the Apache2 cookbook's web_app define.
+
+ include_recipe "apache2"
+ include_recipe "passenger"
+ include_recipe "rails"
+
+ web_app "some_rails_app" do
+ docroot "/srv/some_rails_app/public"
+ template "some_rails_app.conf.erb"
+ end
+
+We provide an example rails application vhost config file in this cookbook. Remember, for Passenger, DocumentRoot (docroot) needs 'public'. Per the web_app define, other parameters can be passed arbitrarily and used in the template.
+
+= LICENSE and AUTHOR:
+
+Author:: Joshua Timberman ()
+Copyright:: 2009, Opscode, Inc
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/crowbar/change-image/dell/barclamps/dns/chef/cookbooks/bind9/attributes/default.rb b/crowbar/change-image/dell/barclamps/dns/chef/cookbooks/bind9/attributes/default.rb
new file mode 100644
index 00000000000..98533aa2f04
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/dns/chef/cookbooks/bind9/attributes/default.rb
@@ -0,0 +1,5 @@
+
+default[:dns][:forwarders] = [
+ "143.166.33.44",
+ "143.166.220.125" ]
+
diff --git a/crowbar/change-image/dell/barclamps/dns/chef/cookbooks/bind9/metadata.json b/crowbar/change-image/dell/barclamps/dns/chef/cookbooks/bind9/metadata.json
new file mode 100644
index 00000000000..a66480df675
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/dns/chef/cookbooks/bind9/metadata.json
@@ -0,0 +1,65 @@
+{
+ "providing": {
+ },
+ "attributes": {
+ "dns": {
+ "display_name": "DNS Hash",
+ "description": "Hash of DNS attributes",
+ "type": "hash",
+ "choice": [
+
+ ],
+ "calculated": false,
+ "required": "optional",
+ "recipes": [
+
+ ]
+ },
+ "dns/forwarders": {
+ "display_name": "Forwarders",
+ "description": "List of IPs for the DNS server to forward requests",
+ "type": "array",
+ "default": [
+
+ ],
+ "choice": [
+
+ ],
+ "calculated": false,
+ "required": "optional",
+ "recipes": [
+
+ ]
+ }
+ },
+ "replacing": {
+ },
+ "dependencies": {
+ },
+ "groupings": {
+ },
+ "recommendations": {
+ },
+ "platforms": {
+ "debian": [
+
+ ],
+ "ubuntu": [
+
+ ]
+ },
+ "license": "Apache 2.0",
+ "version": "0.9.5",
+ "maintainer": "Dell, Inc.",
+ "suggestions": {
+ },
+ "recipes": {
+ "bind9": "Installs bind9"
+ },
+ "maintainer_email": "crowbar@dell.com",
+ "name": "bind9",
+ "conflicting": {
+ },
+ "description": "Installs bind9",
+ "long_description": ""
+}
diff --git a/crowbar/change-image/dell/barclamps/dns/chef/cookbooks/bind9/providers/host.rb b/crowbar/change-image/dell/barclamps/dns/chef/cookbooks/bind9/providers/host.rb
new file mode 100644
index 00000000000..f30070edb8c
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/dns/chef/cookbooks/bind9/providers/host.rb
@@ -0,0 +1,18 @@
+
+
+action :add do
+ utils_line "#{new_resource.ipaddress} #{new_resource.hostname}" do
+ action :add
+ file "/etc/bind/hosts"
+ notifies :run, resources(:bash => "build-domain-file"), :delayed
+ end
+end
+
+action :remove do
+ utils_line "#{new_resource.ipaddress} #{new_resource.hostname}" do
+ action :remove
+ file "/etc/bind/hosts"
+ notifies :run, resources(:bash => "build-domain-file"), :delayed
+ end
+end
+
diff --git a/crowbar/change-image/dell/barclamps/dns/chef/cookbooks/bind9/providers/net.rb b/crowbar/change-image/dell/barclamps/dns/chef/cookbooks/bind9/providers/net.rb
new file mode 100644
index 00000000000..67003bc7976
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/dns/chef/cookbooks/bind9/providers/net.rb
@@ -0,0 +1,18 @@
+
+
+action :add do
+ utils_line "-n #{new_resource.subnet} -N #{new_resource.netmask}" do
+ action :add
+ file "/etc/bind/netargs"
+ notifies :run, resources(:bash => "build-domain-file"), :delayed
+ end
+end
+
+action :remove do
+ utils_line "-n #{new_resource.subnet} -N #{new_resource.netmask}" do
+ action :remove
+ file "/etc/bind/netargs"
+ notifies :run, resources(:bash => "build-domain-file"), :delayed
+ end
+end
+
diff --git a/crowbar/change-image/dell/barclamps/dns/chef/cookbooks/bind9/recipes/default.rb b/crowbar/change-image/dell/barclamps/dns/chef/cookbooks/bind9/recipes/default.rb
new file mode 100644
index 00000000000..0b1cf91965e
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/dns/chef/cookbooks/bind9/recipes/default.rb
@@ -0,0 +1,94 @@
+
+include_recipe "utils"
+
+package "bind9"
+package "bind9utils"
+
+template "/etc/bind/named.conf.options" do
+ source "named.conf.options.erb"
+ variables(:forwarders => node[:dns][:forwarders])
+ mode 0644
+ owner "root"
+ group "bind"
+ notifies :restart, "service[bind9]"
+end
+
+service "bind9" do
+ supports :restart => true, :status => true, :reload => true
+ running true
+ enabled true
+ action :enable
+end
+
+file "/etc/bind/hosts" do
+ owner "root"
+ group "root"
+ mode 0644
+ content ""
+ action :create
+ not_if do File.exists?("/etc/bind/hosts") end
+end
+
+file "/etc/bind/netargs" do
+ owner "root"
+ group "root"
+ mode 0644
+ content ""
+ action :create
+ not_if do File.exists?("/etc/bind/netargs") end
+end
+
+bash "build-domain-file" do
+ code <<-EOH
+ mkdir /tmp/tmp.$$
+ cd /tmp/tmp.$$
+
+ NET_ARGS=`cat /etc/bind/netargs | while read line
+ do
+ echo -n "$line "
+ done`
+
+ /opt/dell/bin/h2n -d #{node[:dns][:domain]} -u #{node[:dns][:contact]} $NET_ARGS -H /etc/bind/hosts -h localhost +c named.conf.local -q
+ rm -f boot.cacheonly conf.cacheonly db.127.0.0 named.boot dns.hosts
+ sed -i 's/"db/"\\/etc\\/bind\\/db/' named.conf.local
+ grep zone named.conf.local | grep -v "zone \\".\\"" | grep -v "0.0.127" > named.conf.new
+ mv named.conf.new named.conf.local
+ cp * /etc/bind
+
+ rm -rf /tmp/tmp.$$
+EOH
+ action :nothing
+ notifies :restart, resources(:service => "bind9"), :immediately
+end
+
+#
+# This relies on the network barclamp networks - GREG: Not sure I like this!
+#
+storage_network = data_bag_item('crowbar', 'storage_network')
+admin_network = data_bag_item('crowbar', 'admin_network')
+bmc_network = data_bag_item('crowbar', 'bmc_network')
+
+[ admin_network, bmc_network, storage_network ].each do |network|
+ network_name = network[:id].gsub("_network","")
+ base_name = ""
+ network[:allocated].each do |ip,h|
+ base_name = "#{h[:machine]} " if network_name == "admin"
+ hostname_str = "#{base_name}#{network_name}.#{h[:machine]}"
+ bind9_host ip do
+ hostname hostname_str
+ action :add
+ end
+ end
+ bind9_net network[:network][:subnet] do
+ netmask network[:network][:netmask]
+ action :add
+ end
+end
+
+node[:dns][:static].each do |name,ip|
+ bind9_host ip do
+ hostname name
+ action :add
+ end
+end
+
diff --git a/crowbar/change-image/dell/barclamps/dns/chef/cookbooks/bind9/resources/host.rb b/crowbar/change-image/dell/barclamps/dns/chef/cookbooks/bind9/resources/host.rb
new file mode 100644
index 00000000000..2819a417eea
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/dns/chef/cookbooks/bind9/resources/host.rb
@@ -0,0 +1,6 @@
+
+actions :add, :remove
+
+attribute :ipaddress, :kind_of => String, :name_attribute => true
+attribute :hostname, :kind_of => String
+
diff --git a/crowbar/change-image/dell/barclamps/dns/chef/cookbooks/bind9/resources/net.rb b/crowbar/change-image/dell/barclamps/dns/chef/cookbooks/bind9/resources/net.rb
new file mode 100644
index 00000000000..06208fddac1
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/dns/chef/cookbooks/bind9/resources/net.rb
@@ -0,0 +1,6 @@
+
+actions :add, :remove
+
+attribute :subnet, :kind_of => String, :name_attribute => true
+attribute :netmask, :kind_of => String
+
diff --git a/crowbar/change-image/dell/barclamps/dns/chef/cookbooks/bind9/templates/default/named.conf.options.erb b/crowbar/change-image/dell/barclamps/dns/chef/cookbooks/bind9/templates/default/named.conf.options.erb
new file mode 100644
index 00000000000..8c945f296f2
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/dns/chef/cookbooks/bind9/templates/default/named.conf.options.erb
@@ -0,0 +1,24 @@
+options {
+ directory "/var/cache/bind";
+
+ // If there is a firewall between you and nameservers you want
+ // to talk to, you may need to fix the firewall to allow multiple
+ // ports to talk. See http://www.kb.cert.org/vuls/id/800113
+
+ // If your ISP provided one or more IP addresses for stable
+ // nameservers, you probably want to use them as forwarders.
+ // Uncomment the following block, and insert the addresses replacing
+ // the all-0's placeholder.
+
+ forwarders {
+<% if !@forwarders.nil? and !@forwarders.empty? -%>
+<% @forwarders.each do |i| -%>
+ <%= i %>;
+<% end -%>
+<% end -%>
+ };
+
+ auth-nxdomain no; # conform to RFC1035
+ listen-on-v6 { any; };
+};
+
diff --git a/crowbar/change-image/dell/barclamps/dns/chef/cookbooks/resolver/README.md b/crowbar/change-image/dell/barclamps/dns/chef/cookbooks/resolver/README.md
new file mode 100644
index 00000000000..28affb876ff
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/dns/chef/cookbooks/resolver/README.md
@@ -0,0 +1,40 @@
+DESCRIPTION
+===========
+
+Configures /etc/resolv.conf.
+
+USAGE
+=====
+
+Set the resolver attributes in a role, for example from my base.rb:
+
+ "resolver" => {
+ "nameservers" => ["10.13.37.120", "10.13.37.40"],
+ "search" => "int.example.org"
+ }
+
+The resulting /etc/resolv.conf will look like:
+
+ domain int.example.org
+ search int.example.org
+ nameserver 10.13.37.120
+ nameserver 10.13.37.40
+
+LICENSE AND AUTHOR
+==================
+
+Author:: Joshua Timberman ()
+
+Copyright 2009, Opscode, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/crowbar/change-image/dell/barclamps/dns/chef/cookbooks/resolver/attributes/default.rb b/crowbar/change-image/dell/barclamps/dns/chef/cookbooks/resolver/attributes/default.rb
new file mode 100644
index 00000000000..361e18b0c8d
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/dns/chef/cookbooks/resolver/attributes/default.rb
@@ -0,0 +1,2 @@
+default[:dns][:domain] = domain
+default[:dns][:nameservers] = [ ]
diff --git a/crowbar/change-image/dell/barclamps/dns/chef/cookbooks/resolver/metadata.json b/crowbar/change-image/dell/barclamps/dns/chef/cookbooks/resolver/metadata.json
new file mode 100644
index 00000000000..542f14d72ed
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/dns/chef/cookbooks/resolver/metadata.json
@@ -0,0 +1,97 @@
+{
+ "providing": {
+ },
+ "attributes": {
+ "dns/nameservers": {
+ "required": "optional",
+ "calculated": false,
+ "choice": [
+
+ ],
+ "default": [
+ ""
+ ],
+ "type": "array",
+ "recipes": [
+
+ ],
+ "description": "Default nameservers",
+ "display_name": "Resolver Nameservers"
+ },
+ "dns/domain": {
+ "required": "optional",
+ "calculated": false,
+ "choice": [
+
+ ],
+ "default": "domain",
+ "type": "string",
+ "recipes": [
+
+ ],
+ "description": "Default domain to domain",
+ "display_name": "Resolver Search"
+ },
+ "dns": {
+ "required": "optional",
+ "calculated": false,
+ "choice": [
+
+ ],
+ "type": "hash",
+ "recipes": [
+
+ ],
+ "description": "Hash of Resolver attributes",
+ "display_name": "Resolver"
+ }
+ },
+ "replacing": {
+ },
+ "dependencies": {
+ },
+ "groupings": {
+ },
+ "recommendations": {
+ },
+ "platforms": {
+ "openbsd": [
+
+ ],
+ "debian": [
+
+ ],
+ "centos": [
+
+ ],
+ "fedora": [
+
+ ],
+ "macosx": [
+
+ ],
+ "freebsd": [
+
+ ],
+ "ubuntu": [
+
+ ],
+ "redhat": [
+
+ ]
+ },
+ "license": "Apache 2.0",
+ "version": "0.8.2",
+ "maintainer": "Opscode, Inc.",
+ "suggestions": {
+ },
+ "recipes": {
+ "resolver": "Configures /etc/resolv.conf via attributes"
+ },
+ "maintainer_email": "cookbooks@opscode.com",
+ "name": "resolver",
+ "conflicting": {
+ },
+ "description": "Configures /etc/resolv.conf",
+ "long_description": "DESCRIPTION\n===========\n\nConfigures /etc/resolv.conf.\n\nUSAGE\n=====\n\nSet the resolver attributes in a role, for example from my base.rb:\n\n \"resolver\" => {\n \"nameservers\" => [\"10.13.37.120\", \"10.13.37.40\"],\n \"domain\" => \"int.example.org\"\n }\n\nThe resulting /etc/resolv.conf will look like:\n\n domain int.example.org\n search int.example.org\n nameserver 10.13.37.120\n nameserver 10.13.37.40\n\nLICENSE AND AUTHOR\n==================\n\nAuthor:: Joshua Timberman ()\n\nCopyright 2009, Opscode, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
+ }
diff --git a/crowbar/change-image/dell/barclamps/dns/chef/cookbooks/resolver/metadata.rb b/crowbar/change-image/dell/barclamps/dns/chef/cookbooks/resolver/metadata.rb
new file mode 100644
index 00000000000..0a4185281a0
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/dns/chef/cookbooks/resolver/metadata.rb
@@ -0,0 +1,29 @@
+maintainer "Opscode, Inc."
+maintainer_email "cookbooks@opscode.com"
+license "Apache 2.0"
+description "Configures /etc/resolv.conf"
+long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
+version "0.8.2"
+
+recipe "resolver", "Configures /etc/resolv.conf via attributes"
+
+%w{ ubuntu debian fedora centos redhat freebsd openbsd macosx }.each do |os|
+ supports os
+end
+
+attribute "resolver",
+ :display_name => "Resolver",
+ :description => "Hash of Resolver attributes",
+ :type => "hash"
+
+attribute "resolver/domain",
+ :display_name => "Resolver Search",
+ :description => "Default domain to domain",
+ :default => "domain"
+
+attribute "resolver/nameservers",
+ :display_name => "Resolver Nameservers",
+ :description => "Default nameservers",
+ :type => "array",
+ :default => [""]
+
diff --git a/crowbar/change-image/dell/barclamps/dns/chef/cookbooks/resolver/recipes/default.rb b/crowbar/change-image/dell/barclamps/dns/chef/cookbooks/resolver/recipes/default.rb
new file mode 100644
index 00000000000..84f6a9c030d
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/dns/chef/cookbooks/resolver/recipes/default.rb
@@ -0,0 +1,35 @@
+#
+# Cookbook Name:: resolver
+# Recipe:: default
+#
+# Copyright 2009, Opscode, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+env_filter = " AND dns_config_environment:#{node[:dns][:config][:environment]}"
+nodes = search(:node, "roles:dns-server#{env_filter}")
+
+dns_list = []
+if !nodes.nil? and !nodes.empty?
+ dns_list = nodes.map { |x| Chef::Recipe::Barclamp::Inventory.get_network_by_type(x, "admin").address }
+end
+dns_list << node[:dns][:nameservers]
+
+template "/etc/resolv.conf" do
+ source "resolv.conf.erb"
+ owner "root"
+ group "root"
+ mode 0644
+ variables(:nameservers => dns_list.flatten, :search => node[:dns][:domain])
+end
diff --git a/crowbar/change-image/dell/barclamps/dns/chef/cookbooks/resolver/templates/default/resolv.conf.erb b/crowbar/change-image/dell/barclamps/dns/chef/cookbooks/resolver/templates/default/resolv.conf.erb
new file mode 100644
index 00000000000..4ff74863206
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/dns/chef/cookbooks/resolver/templates/default/resolv.conf.erb
@@ -0,0 +1,6 @@
+<% unless @search.nil? -%>
+search <%= @search %>
+<% end -%>
+<% @nameservers.each do |nameserver| -%>
+nameserver <%= nameserver %>
+<% end -%>
diff --git a/crowbar/change-image/dell/barclamps/dns/chef/data_bags/crowbar/bc-template-dns.json b/crowbar/change-image/dell/barclamps/dns/chef/data_bags/crowbar/bc-template-dns.json
new file mode 100644
index 00000000000..aeef6a22845
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/dns/chef/data_bags/crowbar/bc-template-dns.json
@@ -0,0 +1,31 @@
+{
+ "id": "bc-template-dns",
+ "description": "manages the DNS subsystem for the cluster",
+ "attributes": {
+ "dns": {
+ "domain": "pod.cloud.openstack.org",
+ "contact": "support@pod.cloud.openstack.org",
+ "forwarders": [ ],
+ "static": { }
+ }
+ },
+ "deployment": {
+ "dns": {
+ "crowbar-revision": 0,
+ "elements": {},
+ "element_order": [
+ [ "dns-server" ],
+ [ "dns-client" ]
+ ],
+ "config": {
+ "environment": "dns-base-config",
+ "mode": "full",
+ "transitions": true,
+ "transition_list": [
+ "discovered"
+ ]
+ }
+ }
+ }
+}
+
diff --git a/crowbar/change-image/dell/barclamps/dns/chef/data_bags/crowbar/bc-template-dns.schema b/crowbar/change-image/dell/barclamps/dns/chef/data_bags/crowbar/bc-template-dns.schema
new file mode 100644
index 00000000000..749d02741f8
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/dns/chef/data_bags/crowbar/bc-template-dns.schema
@@ -0,0 +1,82 @@
+{
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "id": { "type": "str", "required": true, "pattern": "/^bc-dns-|^bc-template-dns$/" },
+ "description": { "type": "str", "required": true },
+ "attributes": {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "dns": {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "domain": { "type": "str", "required": true, "name": "DomainName" },
+ "contact": { "type": "str", "required": true, "name": "Email" },
+ "forwarders": {
+ "type": "seq",
+ "required": true,
+ "sequence": [ { "type": "str", "name": "IpAddress" } ]
+ },
+ "static": {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ = : { "type": "str", "name": "IpAddress" }
+ }
+ }
+ }
+ }
+ }
+ },
+ "deployment": {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "dns": {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "crowbar-revision": { "type": "int", "required": true },
+ "crowbar-committing": { "type": "bool" },
+ "crowbar-queued": { "type": "bool" },
+ "elements": {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ = : {
+ "type": "seq",
+ "required": true,
+ "sequence": [ { "type": "str" } ]
+ }
+ }
+ },
+ "element_order": {
+ "type": "seq",
+ "required": true,
+ "sequence": [ {
+ "type": "seq",
+ "sequence": [ { "type": "str" } ]
+ } ]
+ },
+ "config": {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "environment": { "type": "str", "required": true },
+ "mode": { "type": "str", "required": true },
+ "transitions": { "type": "bool", "required": true },
+ "transition_list": {
+ "type": "seq",
+ "required": true,
+ "sequence": [ { "type": "str" } ]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/crowbar/change-image/dell/barclamps/dns/chef/roles/dns-client.rb b/crowbar/change-image/dell/barclamps/dns/chef/roles/dns-client.rb
new file mode 100644
index 00000000000..4b3fe0c3a81
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/dns/chef/roles/dns-client.rb
@@ -0,0 +1,9 @@
+
+name "dns-client"
+description "DNS Client Role - Configures the resolver to point at the DNS server"
+run_list(
+ "recipe[resolver]"
+)
+default_attributes()
+override_attributes()
+
diff --git a/crowbar/change-image/dell/barclamps/dns/chef/roles/dns-server.rb b/crowbar/change-image/dell/barclamps/dns/chef/roles/dns-server.rb
new file mode 100644
index 00000000000..8138c1ddf3e
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/dns/chef/roles/dns-server.rb
@@ -0,0 +1,9 @@
+
+name "dns-server"
+description "DNS Server Role - DNS server for the cloud"
+run_list(
+ "recipe[bind9]"
+)
+default_attributes()
+override_attributes()
+
diff --git a/crowbar/change-image/dell/barclamps/dns/command_line/crowbar_dns b/crowbar/change-image/dell/barclamps/dns/command_line/crowbar_dns
new file mode 100755
index 00000000000..54371ad949d
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/dns/command_line/crowbar_dns
@@ -0,0 +1,6 @@
+#!/usr/bin/env ruby
+
+require File.join(File.expand_path(File.dirname(__FILE__)), "barclamp_lib")
+@barclamp = "dns"
+
+main
diff --git a/crowbar/change-image/dell/barclamps/dns/debian/changelog.tmpl b/crowbar/change-image/dell/barclamps/dns/debian/changelog.tmpl
new file mode 100644
index 00000000000..42694be8134
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/dns/debian/changelog.tmpl
@@ -0,0 +1,5 @@
+CHANGE_LOG_LINE
+
+ * Initial Release.
+
+ -- unknown Thu, 19 May 2011 15:50:02 -0500
diff --git a/crowbar/change-image/dell/barclamps/dns/debian/compat b/crowbar/change-image/dell/barclamps/dns/debian/compat
new file mode 100644
index 00000000000..7f8f011eb73
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/dns/debian/compat
@@ -0,0 +1 @@
+7
diff --git a/crowbar/change-image/dell/barclamps/dns/debian/control b/crowbar/change-image/dell/barclamps/dns/debian/control
new file mode 100644
index 00000000000..31e03ce8795
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/dns/debian/control
@@ -0,0 +1,13 @@
+Source: barclamp-dns
+Section: unknown
+Priority: extra
+Maintainer: Dell Openstack
+Build-Depends: debhelper (>= 7.0.50~)
+Standards-Version: 3.9.1
+Homepage: http://openstack.dell.com/
+
+Package: barclamp-dns
+Architecture: all
+Depends: barclamp-crowbar
+Description: Ganglia Barclamp for Crowbar
+ Provides the dns barclamp for crowbar
diff --git a/crowbar/change-image/dell/barclamps/dns/debian/copyright b/crowbar/change-image/dell/barclamps/dns/debian/copyright
new file mode 100644
index 00000000000..ef293d897c8
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/dns/debian/copyright
@@ -0,0 +1,26 @@
+This work was packaged for Debian by:
+
+ Dell Openstack Team on Thu, 19 May 2011 15:50:02 -0500
+
+It was downloaded from:
+
+
+
+Upstream Author(s):
+
+ Openstack Dell Team
+
+Copyright:
+
+ Copyright (C) 2011 Dell, Inc.
+
+License:
+
+GREG: Fill in Apache 2.0
+
+The Debian packaging is:
+
+ Copyright (C) 2011 Dell
+
+and is licensed under Apache 2.0, see above.
+
diff --git a/crowbar/change-image/dell/barclamps/dns/debian/postinst b/crowbar/change-image/dell/barclamps/dns/debian/postinst
new file mode 100644
index 00000000000..8a5dfb14566
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/dns/debian/postinst
@@ -0,0 +1,53 @@
+#!/bin/sh
+# postinst script for #PACKAGE#
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+# * `configure'
+# * `abort-upgrade'
+# * `abort-remove' `in-favour'
+#
+# * `abort-remove'
+# * `abort-deconfigure' `in-favour'
+# `removing'
+#
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+
+case "$1" in
+ configure)
+ cd /usr/share/barclamp-dns/chef/cookbooks
+ knife cookbook upload -o . -a -u chef-webui -k /etc/chef/webui.pem
+
+ cd /usr/share/barclamp-dns/chef/data_bags/crowbar
+ for i in *.json; do
+ knife data bag from file crowbar $i
+ done
+
+ cd /usr/share/barclamp-dns/chef/roles
+ for i in *.rb; do
+ knife role from file $i
+ done
+
+ service apache2 graceful
+ ;;
+
+ abort-upgrade|abort-remove|abort-deconfigure)
+ ;;
+
+ *)
+ echo "postinst called with unknown argument \`$1'" >&2
+ exit 1
+ ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
diff --git a/crowbar/change-image/dell/barclamps/dns/debian/rules b/crowbar/change-image/dell/barclamps/dns/debian/rules
new file mode 100755
index 00000000000..79fd842dcae
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/dns/debian/rules
@@ -0,0 +1,8 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+%:
+ dh $@
diff --git a/crowbar/change-image/dell/barclamps/dns/debian/source/format b/crowbar/change-image/dell/barclamps/dns/debian/source/format
new file mode 100644
index 00000000000..89ae9db8f88
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/dns/debian/source/format
@@ -0,0 +1 @@
+3.0 (native)
diff --git a/crowbar/change-image/dell/barclamps/dns/version.sh b/crowbar/change-image/dell/barclamps/dns/version.sh
new file mode 100644
index 00000000000..471ba66571e
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/dns/version.sh
@@ -0,0 +1,7 @@
+BARCLAMP_NAME=dns
+MAJOR_VERSION=0
+MINOR_VERSION=8
+SVN_REVISION=${SVN_REVISION:-custom}
+BUILD_NUMBER=${BUILD_NUMBER:-custom}
+RPM_CONTEXT_NUMBER=${SVN_REVISION}_${BUILD_NUMBER}
+DEB_CONTEXT_NUMBER=${SVN_REVISION}-${BUILD_NUMBER}
diff --git a/crowbar/change-image/dell/barclamps/ganglia/Makefile b/crowbar/change-image/dell/barclamps/ganglia/Makefile
new file mode 100644
index 00000000000..d722202875c
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/ganglia/Makefile
@@ -0,0 +1,21 @@
+
+clean:
+ @echo "Cleaning barclamp-ganglia"
+
+distclean:
+ @echo "Dist-Cleaning barclamp-ganglia"
+
+all: clean build install
+
+build:
+ @echo "Building barclamp-ganglia"
+
+install:
+ @echo "Installing barclamp-ganglia"
+ mkdir -p ${DESTDIR}/opt/crowbar/openstack_manager
+ cp -r app ${DESTDIR}/opt/crowbar/openstack_manager
+ mkdir -p ${DESTDIR}/usr/share/barclamp-ganglia
+ cp -r chef ${DESTDIR}/usr/share/barclamp-ganglia
+ mkdir -p ${DESTDIR}/usr/bin
+ cp -r command_line/* ${DESTDIR}/usr/bin
+
diff --git a/crowbar/change-image/dell/barclamps/ganglia/app/controllers/ganglia_controller.rb b/crowbar/change-image/dell/barclamps/ganglia/app/controllers/ganglia_controller.rb
new file mode 100644
index 00000000000..da56bb29b30
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/ganglia/app/controllers/ganglia_controller.rb
@@ -0,0 +1,21 @@
+# Copyright 2011, Dell
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+class GangliaController < BarclampController
+ def initialize
+ @service_object = GangliaService.new logger
+ end
+end
+
diff --git a/crowbar/change-image/dell/barclamps/ganglia/app/models/ganglia_service.rb b/crowbar/change-image/dell/barclamps/ganglia/app/models/ganglia_service.rb
new file mode 100644
index 00000000000..b5d8d5a5561
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/ganglia/app/models/ganglia_service.rb
@@ -0,0 +1,89 @@
+# Copyright 2011, Dell
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+class GangliaService < ServiceObject
+
+ def initialize(thelogger)
+ @bc_name = "ganglia"
+ @logger = thelogger
+ end
+
+ def create_proposal
+ @logger.debug("Ganglia create_proposal: entering")
+ base = super
+ @logger.debug("Ganglia create_proposal: exiting")
+ base
+ end
+
+ def transition(inst, name, state)
+ @logger.debug("Ganglia transition: make sure that network role is on all nodes: #{name} for #{state}")
+
+ #
+ # If we are discovering the node, make sure that we add the ganglia client or server to the node
+ #
+ if state == "discovered"
+ @logger.debug("Ganglia transition: discovered state for #{name} for #{state}")
+ db = ProposalObject.find_proposal "ganglia", inst
+ role = RoleObject.find_role_by_name "ganglia-config-#{inst}"
+
+ if role.override_attributes["ganglia"]["elements"]["ganglia-server"].nil? or
+ role.override_attributes["ganglia"]["elements"]["ganglia-server"].empty?
+ @logger.debug("Ganglia transition: make sure that ganglia-server role is on first: #{name} for #{state}")
+ result = add_role_to_instance_and_node("ganglia", inst, name, db, role, "ganglia-server")
+ else
+ node = NodeObject.find_node_by_name name
+ unless node.role? "ganglia-server"
+ @logger.debug("Ganglia transition: make sure that ganglia-client role is on all nodes but first: #{name} for #{state}")
+ result = add_role_to_instance_and_node("ganglia", inst, name, db, role, "ganglia-client")
+ end
+ end
+
+ # Set up the client url
+ if result
+ role = RoleObject.find_role_by_name "ganglia-config-#{inst}"
+
+ # Get the server IP address
+ server_ip = nil
+ [ "ganglia-server" ].each do |element|
+ tnodes = role.override_attributes["ganglia"]["elements"][element]
+ next if tnodes.nil? or tnodes.empty?
+ tnodes.each do |n|
+ next if n.nil?
+ node = NodeObject.find_node_by_name(n)
+ server_ip = node.get_network_by_type("admin")["address"]
+ end
+ end
+
+ unless server_ip.nil?
+ node = NodeObject.find_node_by_name(name)
+ node["crowbar"] = {} if node["crowbar"].nil?
+ node["crowbar"]["links"] = {} if node["crowbar"]["links"].nil?
+ node["crowbar"]["links"]["Ganglia"] = "http://#{server_ip}/ganglia/?c=Crowbar PoC&h=#{node.name}&m=load_one&r=hour&s=descending&hc=4&mc=2"
+ node.save
+ end
+ end
+
+ @logger.debug("Ganglia transition: leaving from discovered state for #{name} for #{state}")
+ a = [200, NodeObject.find_node_by_name(name).to_hash ] if result
+ a = [400, "Failed to add role to node"] unless result
+ return a
+ end
+
+ @logger.debug("Ganglia transition: leaving for #{name} for #{state}")
+ [200, NodeObject.find_node_by_name(name).to_hash ]
+ end
+
+end
+
diff --git a/crowbar/change-image/dell/barclamps/ganglia/barclamp-ganglia.spec b/crowbar/change-image/dell/barclamps/ganglia/barclamp-ganglia.spec
new file mode 100644
index 00000000000..fb0825a2421
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/ganglia/barclamp-ganglia.spec
@@ -0,0 +1,52 @@
+
+%define _topdir BUILD_DIR
+%define name barclamp-ganglia
+%define release RPM_CONTEXT_NUMBER
+%define version MAJOR_VERSION.MINOR_VERSION
+%define buildroot %{_topdir}/%{name}-%{version}-root
+
+BuildRoot: %{buildroot}
+Summary: Crowbar Barclamp to Support Ganglia
+License: Apache 2.0
+Name: %{name}
+BuildArch: noarch
+Version: %{version}
+Release: %{release}
+Source: %{name}-%{version}.tar.gz
+Prefix: /
+Group: Development/Tools
+
+%description
+A Crowbar Barclamp that manages ganglia deployments within a Crowbar environment.
+
+%prep
+%setup -q
+
+%build
+
+%install
+make install DESTDIR=${RPM_BUILD_ROOT}
+
+%post
+cd /usr/share/barclamp-ganglia/chef/cookbooks
+knife cookbook upload -o . -a -u chef-webui -k /etc/chef/webui.pem
+
+cd /usr/share/barclamp-ganglia/chef/data_bags/crowbar
+for i in *.json; do
+ knife data bag from file crowbar $i
+done
+
+cd /usr/share/barclamp-ganglia/chef/roles
+for i in *.rb; do
+ knife role from file $i
+done
+
+service httpd graceful
+
+
+%files
+%defattr(-,root,root)
+/usr/bin
+/usr/share
+/opt
+
diff --git a/crowbar/change-image/dell/barclamps/ganglia/build_deb.sh b/crowbar/change-image/dell/barclamps/ganglia/build_deb.sh
new file mode 100755
index 00000000000..79bf21d2ba7
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/ganglia/build_deb.sh
@@ -0,0 +1,17 @@
+#
+# Must have tools:
+# apt-get install dpkg-dev debhelper devscripts fakeroot linda dh-make
+#
+
+. ./version.sh
+
+sed -e "s/CHANGE_LOG_LINE/barclamp-${BARCLAMP_NAME} (${MAJOR_VERSION}.${MINOR_VERSION}-${DEB_CONTEXT_NUMBER}) unstable; urgency=low/" debian/changelog.tmpl > debian/changelog
+
+
+yes | debuild -us -uc
+
+mkdir -p bin
+mv ../barclamp-${BARCLAMP_NAME}_*.deb bin
+mv ../barclamp-${BARCLAMP_NAME}_*gz bin
+rm ../barclamp-${BARCLAMP_NAME}_*
+
diff --git a/crowbar/change-image/dell/barclamps/ganglia/build_rpm.sh b/crowbar/change-image/dell/barclamps/ganglia/build_rpm.sh
new file mode 100755
index 00000000000..c15d9be527a
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/ganglia/build_rpm.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+
+#
+# Needs sudo apt-get install rpm
+#
+
+. ./version.sh
+
+BUILD_DIR="/tmp/build.$$"
+rm -rf ${BUILD_DIR}
+mkdir -p ${BUILD_DIR}/BUILD
+mkdir -p ${BUILD_DIR}/RPMS
+mkdir -p ${BUILD_DIR}/SOURCES
+mkdir -p ${BUILD_DIR}/SPECS
+mkdir -p ${BUILD_DIR}/SRPMS
+
+FULL_NAME="barclamp-${BARCLAMP_NAME}-${MAJOR_VERSION}.${MINOR_VERSION}"
+
+mkdir $FULL_NAME
+cp -r Makefile app chef command_line $FULL_NAME
+tar -zcf ${BUILD_DIR}/SOURCES/${FULL_NAME}.tar.gz ${FULL_NAME}
+rm -rf ${FULL_NAME}
+
+sed -e "s%BUILD_DIR%$BUILD_DIR%" barclamp-${BARCLAMP_NAME}.spec > ${BUILD_DIR}/SPECS/barclamp-${BARCLAMP_NAME}.spec
+sed -ie "s%MAJOR_VERSION%${MAJOR_VERSION}%" ${BUILD_DIR}/SPECS/barclamp-${BARCLAMP_NAME}.spec
+sed -ie "s%MINOR_VERSION%${MINOR_VERSION}%" ${BUILD_DIR}/SPECS/barclamp-${BARCLAMP_NAME}.spec
+sed -ie "s%RPM_CONTEXT_NUMBER%${RPM_CONTEXT_NUMBER}%" ${BUILD_DIR}/SPECS/barclamp-${BARCLAMP_NAME}.spec
+
+rpmbuild -v -ba --clean ${BUILD_DIR}/SPECS/barclamp-${BARCLAMP_NAME}.spec
+
+mkdir -p bin
+cp ${BUILD_DIR}/RPMS/noarch/* bin
+cp ${BUILD_DIR}/SRPMS/* bin
+#rm -rf ${BUILD_DIR}
diff --git a/crowbar/change-image/dell/barclamps/ganglia/chef/cookbooks/ganglia/attributes/default.rb b/crowbar/change-image/dell/barclamps/ganglia/chef/cookbooks/ganglia/attributes/default.rb
new file mode 100644
index 00000000000..b1e9841670c
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/ganglia/chef/cookbooks/ganglia/attributes/default.rb
@@ -0,0 +1,5 @@
+#
+# Default attributes for system.
+#
+default[:ganglia][:interface_eval] = '#{"eth0"}'
+
diff --git a/crowbar/change-image/dell/barclamps/ganglia/chef/cookbooks/ganglia/libraries/eval.rb b/crowbar/change-image/dell/barclamps/ganglia/chef/cookbooks/ganglia/libraries/eval.rb
new file mode 100644
index 00000000000..80e4809879d
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/ganglia/chef/cookbooks/ganglia/libraries/eval.rb
@@ -0,0 +1,43 @@
+#
+# Copyright 2011, Dell
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Author: andi abes
+#
+
+class Ganglia
+class Evaluator
+
+ def initialize(node)
+ @b = binding
+ end
+
+ def eval_with_context(str)
+ eval(str,@b)
+ end
+
+ def log_eval_vars()
+ eval("Chef::Log.info('locals:'+local_variables.join(':') + '\nglobals:'+global_variables.join(':'))")
+ end
+
+ def self.get_value_by_type(node, type)
+ location = node[:ganglia][type]
+ e = Evaluator.new(node)
+ val = e.eval_with_context(location)
+ Chef::Log.info("Looking at #{location} for #{type}. Got: #{val}")
+ val
+ end
+
+end
+end
diff --git a/crowbar/change-image/dell/barclamps/ganglia/chef/cookbooks/ganglia/metadata.json b/crowbar/change-image/dell/barclamps/ganglia/chef/cookbooks/ganglia/metadata.json
new file mode 100644
index 00000000000..a65b2ce6db3
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/ganglia/chef/cookbooks/ganglia/metadata.json
@@ -0,0 +1,38 @@
+{
+ "providing": {
+ },
+ "attributes": {
+ },
+ "replacing": {
+ },
+ "dependencies": {
+ },
+ "groupings": {
+ },
+ "recommendations": {
+ },
+ "platforms": {
+ "debian": [
+
+ ],
+ "ubuntu": [
+
+ ]
+ },
+ "license": "Apache 2.0",
+ "version": "0.9.5",
+ "maintainer": "Dell, Inc.",
+ "suggestions": {
+ },
+ "recipes": {
+ "ganglia": "Ganglia",
+ "ganglia::server": "Ganglia Server",
+ "ganglia::client": "Ganglia Monitoring Client"
+ },
+ "maintainer_email": "crowbar@dell.com",
+ "name": "ganglia",
+ "conflicting": {
+ },
+ "description": "Installs ganglia",
+ "long_description": ""
+}
diff --git a/crowbar/change-image/dell/barclamps/ganglia/chef/cookbooks/ganglia/recipes/client.rb b/crowbar/change-image/dell/barclamps/ganglia/chef/cookbooks/ganglia/recipes/client.rb
new file mode 100644
index 00000000000..6918c1cab77
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/ganglia/chef/cookbooks/ganglia/recipes/client.rb
@@ -0,0 +1,26 @@
+# GANLIA monitoring client recipe
+
+package "ganglia-monitor"
+
+# Begin recipe transactions
+Chef::Log.debug("BEGIN ganlia-client")
+
+admin_interface = Ganglia::Evaluator.get_value_by_type(node,:interface_eval)
+
+template "/etc/ganglia/gmond.conf" do
+ source "gmond.conf.erb"
+ variables( :admin_interface => admin_interface )
+ notifies :restart, "service[ganglia-monitor]"
+end
+
+service "ganglia-monitor" do
+ supports :restart => true
+ pattern "gmond"
+ running true
+ enabled true
+ action [ :enable, :start ]
+end
+
+# End of recipe transactions
+Chef::Log.debug("END ganglia-client")
+
diff --git a/crowbar/change-image/dell/barclamps/ganglia/chef/cookbooks/ganglia/recipes/default.rb b/crowbar/change-image/dell/barclamps/ganglia/chef/cookbooks/ganglia/recipes/default.rb
new file mode 100644
index 00000000000..8b137891791
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/ganglia/chef/cookbooks/ganglia/recipes/default.rb
@@ -0,0 +1 @@
+
diff --git a/crowbar/change-image/dell/barclamps/ganglia/chef/cookbooks/ganglia/recipes/server.rb b/crowbar/change-image/dell/barclamps/ganglia/chef/cookbooks/ganglia/recipes/server.rb
new file mode 100644
index 00000000000..721892d9e90
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/ganglia/chef/cookbooks/ganglia/recipes/server.rb
@@ -0,0 +1,31 @@
+# GANLIA monitoring server recipe
+
+include_recipe "ganglia::client"
+
+package "gmetad"
+package "ganglia-webfrontend"
+
+# Begin recipe transactions
+Chef::Log.debug("BEGIN ganglia-server")
+
+link "/etc/apache2/conf.d/ganglia.conf" do
+ to "/etc/ganglia-webfrontend/apache.conf"
+ not_if "test -L /etc/apache2/conf.d/ganglia.conf"
+ notifies :reload, "service[apache2]"
+end
+
+template "/etc/ganglia/gmetad.conf" do
+ source "gmetad.conf.erb"
+ notifies :restart, "service[gmetad]"
+end
+
+service "gmetad" do
+ supports :restart => true
+ running true
+ enabled true
+ action [ :enable, :start ]
+end
+
+# End of recipe transactions
+Chef::Log.debug("END ganglia-server")
+
diff --git a/crowbar/change-image/dell/barclamps/ganglia/chef/cookbooks/ganglia/templates/default/gmetad.conf.erb b/crowbar/change-image/dell/barclamps/ganglia/chef/cookbooks/ganglia/templates/default/gmetad.conf.erb
new file mode 100644
index 00000000000..9bfef9d6bc5
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/ganglia/chef/cookbooks/ganglia/templates/default/gmetad.conf.erb
@@ -0,0 +1,125 @@
+# This is an example of a Ganglia Meta Daemon configuration file
+# http://ganglia.sourceforge.net/
+#
+# $Id: gmetad.conf.in 2014 2009-08-10 10:44:09Z d_pocock $
+#
+#-------------------------------------------------------------------------------
+# Setting the debug_level to 1 will keep daemon in the forground and
+# show only error messages. Setting this value higher than 1 will make
+# gmetad output debugging information and stay in the foreground.
+# default: 0
+# debug_level 10
+#
+#-------------------------------------------------------------------------------
+# What to monitor. The most important section of this file.
+#
+# The data_source tag specifies either a cluster or a grid to
+# monitor. If we detect the source is a cluster, we will maintain a complete
+# set of RRD databases for it, which can be used to create historical
+# graphs of the metrics. If the source is a grid (it comes from another gmetad),
+# we will only maintain summary RRDs for it.
+#
+# Format:
+# data_source "my cluster" [polling interval] address1:port addreses2:port ...
+#
+# The keyword 'data_source' must immediately be followed by a unique
+# string which identifies the source, then an optional polling interval in
+# seconds. The source will be polled at this interval on average.
+# If the polling interval is omitted, 15sec is asssumed.
+#
+# A list of machines which service the data source follows, in the
+# format ip:port, or name:port. If a port is not specified then 8649
+# (the default gmond port) is assumed.
+# default: There is no default value
+#
+# data_source "my cluster" 10 localhost my.machine.edu:8649 1.2.3.5:8655
+# data_source "my grid" 50 1.3.4.7:8655 grid.org:8651 grid-backup.org:8651
+# data_source "another source" 1.3.4.7:8655 1.3.4.8
+
+data_source "Crowbar PoC" localhost
+
+#
+# Round-Robin Archives
+# You can specify custom Round-Robin archives here (defaults are listed below)
+#
+# RRAs "RRA:AVERAGE:0.5:1:244" "RRA:AVERAGE:0.5:24:244" "RRA:AVERAGE:0.5:168:244" "RRA:AVERAGE:0.5:672:244" \
+# "RRA:AVERAGE:0.5:5760:374"
+#
+
+#
+#-------------------------------------------------------------------------------
+# Scalability mode. If on, we summarize over downstream grids, and respect
+# authority tags. If off, we take on 2.5.0-era behavior: we do not wrap our output
+# in tags, we ignore all tags we see, and always assume
+# we are the "authority" on data source feeds. This approach does not scale to
+# large groups of clusters, but is provided for backwards compatibility.
+# default: on
+# scalable off
+#
+#-------------------------------------------------------------------------------
+# The name of this Grid. All the data sources above will be wrapped in a GRID
+# tag with this name.
+# default: unspecified
+# gridname "MyGrid"
+#
+#-------------------------------------------------------------------------------
+# The authority URL for this grid. Used by other gmetads to locate graphs
+# for our data sources. Generally points to a ganglia/
+# website on this machine.
+# default: "http://hostname/ganglia/",
+# where hostname is the name of this machine, as defined by gethostname().
+# authority "http://mycluster.org/newprefix/"
+#
+#-------------------------------------------------------------------------------
+# List of machines this gmetad will share XML with. Localhost
+# is always trusted.
+# default: There is no default value
+# trusted_hosts 127.0.0.1 169.229.50.165 my.gmetad.org
+#
+#-------------------------------------------------------------------------------
+# If you want any host which connects to the gmetad XML to receive
+# data, then set this value to "on"
+# default: off
+# all_trusted on
+#
+#-------------------------------------------------------------------------------
+# If you don't want gmetad to setuid then set this to off
+# default: on
+# setuid off
+#
+#-------------------------------------------------------------------------------
+# User gmetad will setuid to (defaults to "nobody")
+# default: "nobody"
+# setuid_username "nobody"
+#
+#-------------------------------------------------------------------------------
+# The port gmetad will answer requests for XML
+# default: 8651
+# xml_port 8651
+#
+#-------------------------------------------------------------------------------
+# The port gmetad will answer queries for XML. This facility allows
+# simple subtree and summation views of the XML tree.
+# default: 8652
+# interactive_port 8652
+#
+#-------------------------------------------------------------------------------
+# The number of threads answering XML requests
+# default: 4
+# server_threads 10
+#
+#-------------------------------------------------------------------------------
+# Where gmetad stores its round-robin databases
+# default: "/var/lib/ganglia/rrds"
+# rrd_rootdir "/some/other/place"
+#
+#-------------------------------------------------------------------------------
+# In earlier versions of gmetad, hostnames were handled in a case
+# sensitive manner
+# If your hostname directories have been renamed to lower case,
+# set this option to 0 to disable backward compatibility.
+# From version 3.2, backwards compatibility will be disabled by default.
+# default: 1 (for gmetad < 3.2)
+# default: 0 (for gmetad >= 3.2)
+case_sensitive_hostnames 1
+
diff --git a/crowbar/change-image/dell/barclamps/ganglia/chef/cookbooks/ganglia/templates/default/gmond.conf.erb b/crowbar/change-image/dell/barclamps/ganglia/chef/cookbooks/ganglia/templates/default/gmond.conf.erb
new file mode 100644
index 00000000000..00577f66e36
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/ganglia/chef/cookbooks/ganglia/templates/default/gmond.conf.erb
@@ -0,0 +1,339 @@
+/* This configuration is as close to 2.5.x default behavior as possible
+ The values closely match ./gmond/metric.h definitions in 2.5.x */
+globals {
+ daemonize = yes
+ setuid = yes
+ user = ganglia
+ debug_level = 0
+ max_udp_msg_len = 1472
+ mute = no
+ deaf = no
+ host_dmax = 1200 /*secs */
+ cleanup_threshold = 300 /*secs */
+ gexec = no
+ send_metadata_interval = 0
+}
+
+/* If a cluster attribute is specified, then all gmond hosts are wrapped inside
+ * of a tag. If you do not specify a cluster tag, then all will
+ * NOT be wrapped inside of a tag. */
+cluster {
+ name = "Crowbar PoC"
+ owner = "unspecified"
+ latlong = "unspecified"
+ url = "unspecified"
+}
+
+/* The host section describes attributes of the host, like the location */
+host {
+ location = "unspecified"
+}
+
+/* Feel free to specify as many udp_send_channels as you like. Gmond
+ used to only support having a single channel */
+udp_send_channel {
+ mcast_join = 239.2.11.71
+ mcast_if = <%= @admin_interface %>
+ port = 8649
+ ttl = 1
+}
+
+/* You can specify as many udp_recv_channels as you like as well. */
+udp_recv_channel {
+ mcast_join = 239.2.11.71
+ mcast_if = <%= @admin_interface %>
+ port = 8649
+ bind = 239.2.11.71
+}
+
+/* You can specify as many tcp_accept_channels as you like to share
+ an xml description of the state of the cluster */
+tcp_accept_channel {
+ port = 8649
+}
+
+/* Each metrics module that is referenced by gmond must be specified and
+ loaded. If the module has been statically linked with gmond, it does not
+ require a load path. However all dynamically loadable modules must include
+ a load path. */
+modules {
+ module {
+ name = "core_metrics"
+ }
+ module {
+ name = "cpu_module"
+ path = "/usr/lib/ganglia/modcpu.so"
+ }
+ module {
+ name = "disk_module"
+ path = "/usr/lib/ganglia/moddisk.so"
+ }
+ module {
+ name = "load_module"
+ path = "/usr/lib/ganglia/modload.so"
+ }
+ module {
+ name = "mem_module"
+ path = "/usr/lib/ganglia/modmem.so"
+ }
+ module {
+ name = "net_module"
+ path = "/usr/lib/ganglia/modnet.so"
+ }
+ module {
+ name = "proc_module"
+ path = "/usr/lib/ganglia/modproc.so"
+ }
+ module {
+ name = "sys_module"
+ path = "/usr/lib/ganglia/modsys.so"
+ }
+}
+
+include ('/etc/ganglia/conf.d/*.conf')
+
+
+/* The old internal 2.5.x metric array has been replaced by the following
+ collection_group directives. What follows is the default behavior for
+ collecting and sending metrics that is as close to 2.5.x behavior as
+ possible. */
+
+/* This collection group will cause a heartbeat (or beacon) to be sent every
+ 20 seconds. In the heartbeat is the GMOND_STARTED data which expresses
+ the age of the running gmond. */
+collection_group {
+ collect_once = yes
+ time_threshold = 20
+ metric {
+ name = "heartbeat"
+ }
+}
+
+/* This collection group will send general info about this host every 1200 secs.
+ This information doesn't change between reboots and is only collected once. */
+collection_group {
+ collect_once = yes
+ time_threshold = 1200
+ metric {
+ name = "cpu_num"
+ title = "CPU Count"
+ }
+ metric {
+ name = "cpu_speed"
+ title = "CPU Speed"
+ }
+ metric {
+ name = "mem_total"
+ title = "Memory Total"
+ }
+ /* Should this be here? Swap can be added/removed between reboots. */
+ metric {
+ name = "swap_total"
+ title = "Swap Space Total"
+ }
+ metric {
+ name = "boottime"
+ title = "Last Boot Time"
+ }
+ metric {
+ name = "machine_type"
+ title = "Machine Type"
+ }
+ metric {
+ name = "os_name"
+ title = "Operating System"
+ }
+ metric {
+ name = "os_release"
+ title = "Operating System Release"
+ }
+ metric {
+ name = "location"
+ title = "Location"
+ }
+}
+
+/* This collection group will send the status of gexecd for this host every 300 secs */
+/* Unlike 2.5.x the default behavior is to report gexecd OFF. */
+collection_group {
+ collect_once = yes
+ time_threshold = 300
+ metric {
+ name = "gexec"
+ title = "Gexec Status"
+ }
+}
+
+/* This collection group will collect the CPU status info every 20 secs.
+ The time threshold is set to 90 seconds. In honesty, this time_threshold could be
+ set significantly higher to reduce unneccessary network chatter. */
+collection_group {
+ collect_every = 20
+ time_threshold = 90
+ /* CPU status */
+ metric {
+ name = "cpu_user"
+ value_threshold = "1.0"
+ title = "CPU User"
+ }
+ metric {
+ name = "cpu_system"
+ value_threshold = "1.0"
+ title = "CPU System"
+ }
+ metric {
+ name = "cpu_idle"
+ value_threshold = "5.0"
+ title = "CPU Idle"
+ }
+ metric {
+ name = "cpu_nice"
+ value_threshold = "1.0"
+ title = "CPU Nice"
+ }
+ metric {
+ name = "cpu_aidle"
+ value_threshold = "5.0"
+ title = "CPU aidle"
+ }
+ metric {
+ name = "cpu_wio"
+ value_threshold = "1.0"
+ title = "CPU wio"
+ }
+ /* The next two metrics are optional if you want more detail...
+ ... since they are accounted for in cpu_system.
+ metric {
+ name = "cpu_intr"
+ value_threshold = "1.0"
+ title = "CPU intr"
+ }
+ metric {
+ name = "cpu_sintr"
+ value_threshold = "1.0"
+ title = "CPU sintr"
+ }
+ */
+}
+
+collection_group {
+ collect_every = 20
+ time_threshold = 90
+ /* Load Averages */
+ metric {
+ name = "load_one"
+ value_threshold = "1.0"
+ title = "One Minute Load Average"
+ }
+ metric {
+ name = "load_five"
+ value_threshold = "1.0"
+ title = "Five Minute Load Average"
+ }
+ metric {
+ name = "load_fifteen"
+ value_threshold = "1.0"
+ title = "Fifteen Minute Load Average"
+ }
+}
+
+/* This group collects the number of running and total processes */
+collection_group {
+ collect_every = 80
+ time_threshold = 950
+ metric {
+ name = "proc_run"
+ value_threshold = "1.0"
+ title = "Total Running Processes"
+ }
+ metric {
+ name = "proc_total"
+ value_threshold = "1.0"
+ title = "Total Processes"
+ }
+}
+
+/* This collection group grabs the volatile memory metrics every 40 secs and
+ sends them at least every 180 secs. This time_threshold can be increased
+ significantly to reduce unneeded network traffic. */
+collection_group {
+ collect_every = 40
+ time_threshold = 180
+ metric {
+ name = "mem_free"
+ value_threshold = "1024.0"
+ title = "Free Memory"
+ }
+ metric {
+ name = "mem_shared"
+ value_threshold = "1024.0"
+ title = "Shared Memory"
+ }
+ metric {
+ name = "mem_buffers"
+ value_threshold = "1024.0"
+ title = "Memory Buffers"
+ }
+ metric {
+ name = "mem_cached"
+ value_threshold = "1024.0"
+ title = "Cached Memory"
+ }
+ metric {
+ name = "swap_free"
+ value_threshold = "1024.0"
+ title = "Free Swap Space"
+ }
+}
+
+collection_group {
+ collect_every = 40
+ time_threshold = 300
+ metric {
+ name = "bytes_out"
+ value_threshold = 4096
+ title = "Bytes Sent"
+ }
+ metric {
+ name = "bytes_in"
+ value_threshold = 4096
+ title = "Bytes Received"
+ }
+ metric {
+ name = "pkts_in"
+ value_threshold = 256
+ title = "Packets Received"
+ }
+ metric {
+ name = "pkts_out"
+ value_threshold = 256
+ title = "Packets Sent"
+ }
+}
+
+/* Different than 2.5.x default since the old config made no sense */
+collection_group {
+ collect_every = 1800
+ time_threshold = 3600
+ metric {
+ name = "disk_total"
+ value_threshold = 1.0
+ title = "Total Disk Space"
+ }
+}
+
+collection_group {
+ collect_every = 40
+ time_threshold = 180
+ metric {
+ name = "disk_free"
+ value_threshold = 1.0
+ title = "Disk Space Available"
+ }
+ metric {
+ name = "part_max_used"
+ value_threshold = 1.0
+ title = "Maximum Disk Space Used"
+ }
+}
+
diff --git a/crowbar/change-image/dell/barclamps/ganglia/chef/data_bags/crowbar/bc-template-ganglia.json b/crowbar/change-image/dell/barclamps/ganglia/chef/data_bags/crowbar/bc-template-ganglia.json
new file mode 100644
index 00000000000..a5097f87d58
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/ganglia/chef/data_bags/crowbar/bc-template-ganglia.json
@@ -0,0 +1,27 @@
+{
+ "id": "bc-template-ganglia",
+ "description": "a common Ganglia service for the cluster that can be used by other barclamps",
+ "attributes": {
+ "ganglia": {
+ "interface_eval": "Chef::Recipe::Barclamp::Inventory.get_network_by_type(node, \"admin\").interface"
+ }
+ },
+ "deployment": {
+ "ganglia": {
+ "crowbar-revision": 0,
+ "elements": {},
+ "element_order": [
+ [ "ganglia-server", "ganglia-client" ]
+ ],
+ "config": {
+ "environment": "ganglia-base-config",
+ "mode": "full",
+ "transitions": true,
+ "transition_list": [
+ "discovered"
+ ]
+ }
+ }
+ }
+}
+
diff --git a/crowbar/change-image/dell/barclamps/ganglia/chef/data_bags/crowbar/bc-template-ganglia.schema b/crowbar/change-image/dell/barclamps/ganglia/chef/data_bags/crowbar/bc-template-ganglia.schema
new file mode 100644
index 00000000000..02e76710630
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/ganglia/chef/data_bags/crowbar/bc-template-ganglia.schema
@@ -0,0 +1,69 @@
+{
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "id": { "type": "str", "required": true, "pattern": "/^bc-ganglia-|^bc-template-ganglia$/" },
+ "description": { "type": "str", "required": true },
+ "attributes": {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "ganglia": {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "interface_eval": { "type": "str", "required": true }
+ }
+ }
+ }
+ },
+ "deployment": {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "ganglia": {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "crowbar-revision": { "type": "int", "required": true },
+ "crowbar-committing": { "type": "bool" },
+ "crowbar-queued": { "type": "bool" },
+ "elements": {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ = : {
+ "type": "seq",
+ "required": true,
+ "sequence": [ { "type": "str" } ]
+ }
+ }
+ },
+ "element_order": {
+ "type": "seq",
+ "required": true,
+ "sequence": [ {
+ "type": "seq",
+ "sequence": [ { "type": "str" } ]
+ } ]
+ },
+ "config": {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "environment": { "type": "str", "required": true },
+ "mode": { "type": "str", "required": true },
+ "transitions": { "type": "bool", "required": true },
+ "transition_list": {
+ "type": "seq",
+ "required": true,
+ "sequence": [ { "type": "str" } ]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/crowbar/change-image/dell/barclamps/ganglia/chef/roles/ganglia-client.rb b/crowbar/change-image/dell/barclamps/ganglia/chef/roles/ganglia-client.rb
new file mode 100644
index 00000000000..1d003382076
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/ganglia/chef/roles/ganglia-client.rb
@@ -0,0 +1,8 @@
+
+name "ganglia-client"
+description "GANGLIA Client Role - Nodes in the environment that should be monitored"
+run_list(
+ "recipe[ganglia::client]"
+)
+default_attributes()
+override_attributes()
diff --git a/crowbar/change-image/dell/barclamps/ganglia/chef/roles/ganglia-server.rb b/crowbar/change-image/dell/barclamps/ganglia/chef/roles/ganglia-server.rb
new file mode 100644
index 00000000000..cc603b450ed
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/ganglia/chef/roles/ganglia-server.rb
@@ -0,0 +1,9 @@
+
+name "ganglia-server"
+description "GANGLIA Server Role - GANGLIA master for the cloud"
+run_list(
+ "recipe[ganglia::server]"
+)
+default_attributes()
+override_attributes()
+
diff --git a/crowbar/change-image/dell/barclamps/ganglia/command_line/crowbar_ganglia b/crowbar/change-image/dell/barclamps/ganglia/command_line/crowbar_ganglia
new file mode 100755
index 00000000000..e14481daa4b
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/ganglia/command_line/crowbar_ganglia
@@ -0,0 +1,6 @@
+#!/usr/bin/env ruby
+
+require File.join(File.expand_path(File.dirname(__FILE__)), "barclamp_lib")
+@barclamp = "ganglia"
+
+main
diff --git a/crowbar/change-image/dell/barclamps/ganglia/debian/changelog.tmpl b/crowbar/change-image/dell/barclamps/ganglia/debian/changelog.tmpl
new file mode 100644
index 00000000000..42694be8134
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/ganglia/debian/changelog.tmpl
@@ -0,0 +1,5 @@
+CHANGE_LOG_LINE
+
+ * Initial Release.
+
+ -- unknown Thu, 19 May 2011 15:50:02 -0500
diff --git a/crowbar/change-image/dell/barclamps/ganglia/debian/compat b/crowbar/change-image/dell/barclamps/ganglia/debian/compat
new file mode 100644
index 00000000000..7f8f011eb73
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/ganglia/debian/compat
@@ -0,0 +1 @@
+7
diff --git a/crowbar/change-image/dell/barclamps/ganglia/debian/control b/crowbar/change-image/dell/barclamps/ganglia/debian/control
new file mode 100644
index 00000000000..232c4768cee
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/ganglia/debian/control
@@ -0,0 +1,13 @@
+Source: barclamp-ganglia
+Section: unknown
+Priority: extra
+Maintainer: Dell Openstack
+Build-Depends: debhelper (>= 7.0.50~)
+Standards-Version: 3.9.1
+Homepage: http://openstack.dell.com/
+
+Package: barclamp-ganglia
+Architecture: all
+Depends: barclamp-crowbar
+Description: Ganglia Barclamp for Crowbar
+ Provides the ganglia barclamp for crowbar
diff --git a/crowbar/change-image/dell/barclamps/ganglia/debian/copyright b/crowbar/change-image/dell/barclamps/ganglia/debian/copyright
new file mode 100644
index 00000000000..ef293d897c8
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/ganglia/debian/copyright
@@ -0,0 +1,26 @@
+This work was packaged for Debian by:
+
+ Dell Openstack Team on Thu, 19 May 2011 15:50:02 -0500
+
+It was downloaded from:
+
+
+
+Upstream Author(s):
+
+ Openstack Dell Team
+
+Copyright:
+
+ Copyright (C) 2011 Dell, Inc.
+
+License:
+
+GREG: Fill in Apache 2.0
+
+The Debian packaging is:
+
+ Copyright (C) 2011 Dell
+
+and is licensed under Apache 2.0, see above.
+
diff --git a/crowbar/change-image/dell/barclamps/ganglia/debian/postinst b/crowbar/change-image/dell/barclamps/ganglia/debian/postinst
new file mode 100644
index 00000000000..20724309131
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/ganglia/debian/postinst
@@ -0,0 +1,53 @@
+#!/bin/sh
+# postinst script for #PACKAGE#
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+# * `configure'
+# * `abort-upgrade'
+# * `abort-remove' `in-favour'
+#
+# * `abort-remove'
+# * `abort-deconfigure' `in-favour'
+# `removing'
+#
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+
+case "$1" in
+ configure)
+ cd /usr/share/barclamp-ganglia/chef/cookbooks
+ knife cookbook upload -o . -a -u chef-webui -k /etc/chef/webui.pem
+
+ cd /usr/share/barclamp-ganglia/chef/data_bags/crowbar
+ for i in *.json; do
+ knife data bag from file crowbar $i
+ done
+
+ cd /usr/share/barclamp-ganglia/chef/roles
+ for i in *.rb; do
+ knife role from file $i
+ done
+
+ service apache2 graceful
+ ;;
+
+ abort-upgrade|abort-remove|abort-deconfigure)
+ ;;
+
+ *)
+ echo "postinst called with unknown argument \`$1'" >&2
+ exit 1
+ ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
diff --git a/crowbar/change-image/dell/barclamps/ganglia/debian/rules b/crowbar/change-image/dell/barclamps/ganglia/debian/rules
new file mode 100755
index 00000000000..79fd842dcae
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/ganglia/debian/rules
@@ -0,0 +1,8 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+%:
+ dh $@
diff --git a/crowbar/change-image/dell/barclamps/ganglia/debian/source/format b/crowbar/change-image/dell/barclamps/ganglia/debian/source/format
new file mode 100644
index 00000000000..89ae9db8f88
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/ganglia/debian/source/format
@@ -0,0 +1 @@
+3.0 (native)
diff --git a/crowbar/change-image/dell/barclamps/ganglia/version.sh b/crowbar/change-image/dell/barclamps/ganglia/version.sh
new file mode 100644
index 00000000000..3224c1bc199
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/ganglia/version.sh
@@ -0,0 +1,7 @@
+BARCLAMP_NAME=ganglia
+MAJOR_VERSION=0
+MINOR_VERSION=8
+SVN_REVISION=${SVN_REVISION:-custom}
+BUILD_NUMBER=${BUILD_NUMBER:-custom}
+RPM_CONTEXT_NUMBER=${SVN_REVISION}_${BUILD_NUMBER}
+DEB_CONTEXT_NUMBER=${SVN_REVISION}-${BUILD_NUMBER}
diff --git a/crowbar/change-image/dell/barclamps/ipmi/app/controllers/ipmi_controller.rb b/crowbar/change-image/dell/barclamps/ipmi/app/controllers/ipmi_controller.rb
new file mode 100755
index 00000000000..d3a629adf19
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/ipmi/app/controllers/ipmi_controller.rb
@@ -0,0 +1,20 @@
+# Copyright 2011, Dell
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+class IpmiController < BarclampController
+ def initialize
+ @service_object = IpmiService.new logger
+ end
+end
diff --git a/crowbar/change-image/dell/barclamps/ipmi/app/models/ipmi_service.rb b/crowbar/change-image/dell/barclamps/ipmi/app/models/ipmi_service.rb
new file mode 100755
index 00000000000..5cae1ee2938
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/ipmi/app/models/ipmi_service.rb
@@ -0,0 +1,51 @@
+# Copyright 2011, Dell
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+class IpmiService < ServiceObject
+
+ def initialize(thelogger)
+ @bc_name = "ipmi"
+ @logger = thelogger
+ end
+
+ def create_proposal
+ @logger.debug("IPMI create_proposal: entering")
+ base = super
+ @logger.debug("IPMI create_proposal: exiting")
+ base
+ end
+
+ def transition(inst, name, state)
+ @logger.debug("IPMI transition: make sure that network role is on all nodes: #{name} for #{state}")
+
+ #
+ # If we are discovering the node, make sure that we add the ipmi role to the node
+ #
+ if state == "discovered"
+ @logger.debug("IPMI transition: installed state for #{name} for #{state}")
+ db = ProposalObject.find_proposal "ipmi", inst
+ role = RoleObject.find_role_by_name "ipmi-config-#{inst}"
+ result = add_role_to_instance_and_node("ipmi", inst, name, db, role, "ipmi-configure")
+ @logger.debug("ipmi transition: leaving from installed state for #{name} for #{state}")
+ a = [200, {}] if result
+ a = [400, "Failed to add role to node"] unless result
+ return a
+ end
+
+ @logger.debug("ipmi transition: leaving for #{name} for #{state}")
+ [200, {}]
+ end
+
+end
diff --git a/crowbar/change-image/dell/barclamps/ipmi/chef/cookbooks/ipmi/attributes/default.rb b/crowbar/change-image/dell/barclamps/ipmi/chef/cookbooks/ipmi/attributes/default.rb
new file mode 100755
index 00000000000..4685a420d3e
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/ipmi/chef/cookbooks/ipmi/attributes/default.rb
@@ -0,0 +1,28 @@
+#
+# Copyright (c) 2011 Dell Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+default[:ipmi][:config] = {}
+default[:ipmi][:config][:environment] = "bios-config-default"
+
+default[:ipmi][:bmc_user] = "crowbar"
+default[:ipmi][:bmc_password] = "crowbar"
+default[:ipmi][:bmc_enable] = true
+default[:ipmi][:debug] = true
+
+default[:crowbar][:network][:bmc][:address] = "192.168.124.161"
+default[:crowbar][:network][:bmc][:netmask] = "255.255.255.0"
+default[:crowbar][:network][:bmc][:router] = "192.168.124.10"
+
diff --git a/crowbar/change-image/dell/barclamps/ipmi/chef/cookbooks/ipmi/metadata.json b/crowbar/change-image/dell/barclamps/ipmi/chef/cookbooks/ipmi/metadata.json
new file mode 100755
index 00000000000..3a09289587f
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/ipmi/chef/cookbooks/ipmi/metadata.json
@@ -0,0 +1,41 @@
+{
+ "platforms": {
+
+ },
+ "suggestions": {
+
+ },
+ "license": "Apache 2.0",
+ "conflicting": {
+
+ },
+ "long_description": "",
+ "providing": {
+
+ },
+ "description": "configures BMC",
+ "version": "0.1.0",
+ "maintainer": "Dell, Inc.",
+ "replacing": {
+
+ },
+ "attributes": {
+
+ },
+ "maintainer_email": "openstack@dell.com",
+ "name": "ipmi",
+ "recipes": {
+
+ },
+ "groupings": {
+
+ },
+ "dependencies": {
+ "utils": [
+
+ ]
+ },
+ "recommendations": {
+
+ }
+}
\ No newline at end of file
diff --git a/crowbar/change-image/dell/barclamps/ipmi/chef/cookbooks/ipmi/metadata.rb b/crowbar/change-image/dell/barclamps/ipmi/chef/cookbooks/ipmi/metadata.rb
new file mode 100755
index 00000000000..a08651e87fa
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/ipmi/chef/cookbooks/ipmi/metadata.rb
@@ -0,0 +1,24 @@
+#
+# Copyright 2011, Dell
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Author: andi abes
+#
+maintainer "Dell, Inc."
+maintainer_email "crowbar@dell.com"
+license "Apache 2.0"
+description "Configures IPMI/BMC parameters for management access"
+long_description "Configures IPMI/BMC parameters for management access"
+version "0.1"
+depends "utils"
\ No newline at end of file
diff --git a/crowbar/change-image/dell/barclamps/ipmi/chef/cookbooks/ipmi/recipes/ipmi-configure.rb b/crowbar/change-image/dell/barclamps/ipmi/chef/cookbooks/ipmi/recipes/ipmi-configure.rb
new file mode 100755
index 00000000000..90a999c6967
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/ipmi/chef/cookbooks/ipmi/recipes/ipmi-configure.rb
@@ -0,0 +1,117 @@
+#
+# Copyright (c) 2011 Dell Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Note : This script runs on both the admin and compute nodes.
+# It intentionally ignores the bios->enable node data flag.
+
+include_recipe "utils"
+
+
+
+# for now, assume it's there.
+# package "ipmitool"
+
+
+bmc_user = node[:ipmi][:bmc_user]
+bmc_password = node[:ipmi][:bmc_password]
+bmc_address = node[:crowbar][:network][:bmc][:address]
+bmc_netmask = node[:crowbar][:network][:bmc][:netmask]
+bmc_router = node[:crowbar][:network][:bmc][:router]
+
+def log_debug(msg)
+ log(msg) {level :info} if node[:ipmi][:debug]
+end
+
+## utility to check if a lan parameter needs to be set (if it's current value is different than desired one).
+def check_ipmi_lan_value(header, desired)
+ c_awk = "awk -F : ' /#{header}\\W*:/ { print \$2 } '"
+ current = %x{ipmitool lan print 1 | #{c_awk} }
+ current = current.chomp.strip
+ log_debug " header #{header} should have: #{desired} current: #{current}"
+ ret = current.casecmp(desired) == 0 # true if matching
+ log_debug ("#{ret ? "will not": "will" } change value" )
+ ret
+end
+
+
+
+if node[:ipmi][:bmc_enable]
+ # Make sure the IPMI kernel modules are installed
+ bash "install-ipmi_si" do
+ code "/sbin/modprobe ipmi_si"
+ not_if { ::File.exists?("/sys/module/ipmi_si") }
+ returns [0,1]
+ ignore_failure true
+ end
+
+ bash "install-devintf" do
+ code "/sbin/modprobe ipmi_devintf"
+ not_if { ::File.exists?("/sys/module/ipmi_devintf") }
+ returns [0,1]
+ ignore_failure true
+ end
+
+ ## failed to load ipmi support... occurs on virtual machines and machines without IPMI
+ if !File.exists?("/sys/module/ipmi_si")
+ node[:ipmi][:bmc_enable] = false # won't try again..
+ log ("Unsupported product found #{node[:dmi][:system][:product_name]} - skipping IPMI") {level :warn}
+ else
+ ### lan parameters to check and set. The loop that follows iterates over this array.
+ # [0] = name in "print" output, [1] command to issue, [2] desired value.
+ lan_params = [
+ [ "IP Address" ,"ipmitool lan set 1 ipaddr #{bmc_address}", bmc_address ] ,
+ [ "IP Address Source" ,"ipmitool lan set 1 ipsrc static", "Static Address" ] ,
+ [ "Subnet Mask" , "ipmitool lan set 1 netmask #{bmc_netmask}", bmc_netmask ]
+ ]
+
+ lan_params << [ "Default Gateway IP", "ipmitool lan set 1 defgw ipaddr #{bmc_router}", bmc_router ] unless bmc_router.nil?
+
+
+ # Set BMC LAN parameters
+ lan_params.each { |param|
+ bash "bmc-set-lan-#{param[0]}" do
+ code <<-EOH
+#{param[1]}
+sleep 1
+EOH
+ end unless check_ipmi_lan_value(param[0], param[2])
+ }
+
+ # Set the BMC channel user parameters
+ bash "bmc-set-user" do
+ code <<-EOH
+ ipmitool user set name 3 #{bmc_user}
+ sleep 1
+ ipmitool user set password 3 #{bmc_password}
+ sleep 1
+ ipmitool user priv 3 4 1
+ sleep 1
+ ipmitool channel setaccess 1 3 callin=on link=on ipmi=on privilege=4
+ sleep 1
+ ipmitool user enable 3
+ sleep 1
+EOH
+ end
+
+ s = ""
+ s << "BMC info: user: [#{bmc_user}] "
+ s << "password [#{bmc_password}] "
+ s << "address:[#{bmc_address}] "
+ s << "netmask [#{bmc_netmask}]"
+ s << "router [#{bmc_router}]" unless bmc_router.nil?
+ log (s) { level :info } if node[:ipmi][:debug]
+
+ end
+end
diff --git a/crowbar/change-image/dell/barclamps/ipmi/chef/data_bags/crowbar/bc-template-ipmi.json b/crowbar/change-image/dell/barclamps/ipmi/chef/data_bags/crowbar/bc-template-ipmi.json
new file mode 100755
index 00000000000..a1405f07474
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/ipmi/chef/data_bags/crowbar/bc-template-ipmi.json
@@ -0,0 +1,30 @@
+{
+ "id": "bc-template-ipmi",
+ "description": "The default proposal for the ipmi barclamp",
+ "attributes": {
+ "ipmi": {
+ "bmc_enable" : true,
+ "bmc_user": "crowbar",
+ "bmc_password": "crowbar",
+ "debug": true
+ }
+ },
+ "deployment": {
+ "ipmi": {
+ "crowbar-revision": 0,
+ "elements": {},
+ "element_order": [
+ [ "ipmi-configure" ]
+ ],
+ "config": {
+ "environment": "ipmi-base-config",
+ "mode": "full",
+ "transitions": true,
+ "transition_list": [
+ "discovered"
+ ]
+ }
+ }
+ }
+}
+
diff --git a/crowbar/change-image/dell/barclamps/ipmi/chef/data_bags/crowbar/bc-template-ipmi.schema b/crowbar/change-image/dell/barclamps/ipmi/chef/data_bags/crowbar/bc-template-ipmi.schema
new file mode 100755
index 00000000000..4042749d557
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/ipmi/chef/data_bags/crowbar/bc-template-ipmi.schema
@@ -0,0 +1,45 @@
+{
+ "type": "map", "required": true, "mapping": {
+ "id": { "type": "str", "required": true, "pattern": "/^bc-ipmi-|^bc-template-ipmi$/" },
+ "description": { "type": "str", "required": true },
+ "attributes": { "type": "map", "required": true, "mapping": {
+ "ipmi": { "type": "map", "required": true, "mapping": {
+ "bmc_enable": { "type": "bool", "required": true},
+ "bmc_user": { "type": "str", "required": true },
+ "bmc_password": { "type": "str", "required": true },
+ "debug": { "type": "bool", "required": true}
+ }
+ }
+ }
+ },
+ "deployment": { "type": "map", "required": true, "mapping": {
+ "ipmi": { "type": "map", "required": true, "mapping": {
+ "crowbar-revision": { "type": "int", "required": true },
+ "crowbar-committing": { "type": "bool" },
+ "crowbar-queued": { "type": "bool" },
+ "elements": { "type": "map", "required": true, "mapping": {
+ = : { "type": "seq", "required": true,
+ "sequence": [ { "type": "str" } ]
+ }
+ }
+ },
+ "element_order": { "type": "seq", "required": true,
+ "sequence": [ { "type": "seq",
+ "sequence": [ { "type": "str" } ]
+ } ]
+ },
+ "config": { "type": "map", "required": true, "mapping": {
+ "environment": { "type": "str", "required": true },
+ "mode": { "type": "str", "required": true },
+ "transitions": { "type": "bool", "required": true },
+ "transition_list": { "type": "seq", "required": true,
+ "sequence": [ { "type": "str" } ]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/crowbar/change-image/dell/barclamps/ipmi/chef/roles/ipmi-configure.rb b/crowbar/change-image/dell/barclamps/ipmi/chef/roles/ipmi-configure.rb
new file mode 100755
index 00000000000..7a30e535712
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/ipmi/chef/roles/ipmi-configure.rb
@@ -0,0 +1,24 @@
+#
+# Cookbook Name: bios
+# Role: bios-install
+#
+# Copyright (c) 2011 Dell Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+name "ipmi-configure"
+description "IPMI configure - configure the BMC to allow remote management"
+run_list(
+ "recipe[ipmi::ipmi-configure]"
+)
diff --git a/crowbar/change-image/dell/barclamps/logging/Makefile b/crowbar/change-image/dell/barclamps/logging/Makefile
new file mode 100644
index 00000000000..598bd8be13f
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/logging/Makefile
@@ -0,0 +1,21 @@
+
+clean:
+ @echo "Cleaning barclamp-logging"
+
+distclean:
+ @echo "Dist-Cleaning barclamp-logging"
+
+all: clean build install
+
+build:
+ @echo "Building barclamp-logging"
+
+install:
+ @echo "Installing barclamp-logging"
+ mkdir -p ${DESTDIR}/opt/crowbar/openstack_manager
+ cp -r app ${DESTDIR}/opt/crowbar/openstack_manager
+ mkdir -p ${DESTDIR}/usr/share/barclamp-logging
+ cp -r chef ${DESTDIR}/usr/share/barclamp-logging
+ mkdir -p ${DESTDIR}/usr/bin
+ cp -r command_line/* ${DESTDIR}/usr/bin
+
diff --git a/crowbar/change-image/dell/barclamps/logging/app/controllers/logging_controller.rb b/crowbar/change-image/dell/barclamps/logging/app/controllers/logging_controller.rb
new file mode 100644
index 00000000000..4db254eafc4
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/logging/app/controllers/logging_controller.rb
@@ -0,0 +1,21 @@
+# Copyright 2011, Dell
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+class LoggingController < BarclampController
+ def initialize
+ @service_object = LoggingService.new logger
+ end
+end
+
diff --git a/crowbar/change-image/dell/barclamps/logging/app/models/logging_service.rb b/crowbar/change-image/dell/barclamps/logging/app/models/logging_service.rb
new file mode 100644
index 00000000000..c55e0ade681
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/logging/app/models/logging_service.rb
@@ -0,0 +1,64 @@
+# Copyright 2011, Dell
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+class LoggingService < ServiceObject
+
+ def initialize(thelogger)
+ @bc_name = "logging"
+ @logger = thelogger
+ end
+
+ def create_proposal
+ @logger.debug("Logging create_proposal: entering")
+ base = super
+ @logger.debug("Logging create_proposal: exiting")
+ base
+ end
+
+ def transition(inst, name, state)
+ @logger.debug("Logging transition: entering: #{name} for #{state}")
+
+ #
+ # If we are discovering the node, make sure that we add the logging client or server to the node
+ #
+ if state == "discovered"
+ @logger.debug("Logging transition: discovered state for #{name} for #{state}")
+ db = ProposalObject.find_proposal "logging", inst
+ role = RoleObject.find_role_by_name "logging-config-#{inst}"
+
+ if role.override_attributes["logging"]["elements"]["logging-server"].nil? or
+ role.override_attributes["logging"]["elements"]["logging-server"].empty?
+ @logger.debug("Logging transition: make sure that logging-server role is on first: #{name} for #{state}")
+ result = add_role_to_instance_and_node("logging", inst, name, db, role, "logging-server")
+ else
+ node = NodeObject.find_node_by_name name
+ unless node.role? "logging-server"
+ @logger.debug("Logging transition: make sure that logging-client role is on all nodes but first: #{name} for #{state}")
+ result = add_role_to_instance_and_node("logging", inst, name, db, role, "logging-client")
+ end
+ end
+
+ @logger.debug("Logging transition: leaving from discovered state for #{name} for #{state}")
+ a = [200, {}] if result
+ a = [400, "Failed to add logging role to node"] unless result
+ return a
+ end
+
+ @logger.debug("Logging transition: leaving for #{name} for #{state}")
+ [200, NodeObject.find_node_by_name(name).to_hash ]
+ end
+
+end
+
diff --git a/crowbar/change-image/dell/barclamps/logging/barclamp-logging.spec b/crowbar/change-image/dell/barclamps/logging/barclamp-logging.spec
new file mode 100644
index 00000000000..0ebeafbebe5
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/logging/barclamp-logging.spec
@@ -0,0 +1,52 @@
+
+%define _topdir BUILD_DIR
+%define name barclamp-logging
+%define release RPM_CONTEXT_NUMBER
+%define version MAJOR_VERSION.MINOR_VERSION
+%define buildroot %{_topdir}/%{name}-%{version}-root
+
+BuildRoot: %{buildroot}
+Summary: centralized logging system based on syslog
+License: Apache 2.0
+Name: %{name}
+BuildArch: noarch
+Version: %{version}
+Release: %{release}
+Source: %{name}-%{version}.tar.gz
+Prefix: /
+Group: Development/Tools
+
+%description
+A Crowbar Barclamp that manages logging deployments within a Crowbar environment.
+
+%prep
+%setup -q
+
+%build
+
+%install
+make install DESTDIR=${RPM_BUILD_ROOT}
+
+%post
+cd /usr/share/barclamp-logging/chef/cookbooks
+knife cookbook upload -o . -a -u chef-webui -k /etc/chef/webui.pem
+
+cd /usr/share/barclamp-logging/chef/data_bags/crowbar
+for i in *.json; do
+ knife data bag from file crowbar $i
+done
+
+cd /usr/share/barclamp-logging/chef/roles
+for i in *.rb; do
+ knife role from file $i
+done
+
+service httpd graceful
+
+
+%files
+%defattr(-,root,root)
+/usr/bin
+/usr/share
+/opt
+
diff --git a/crowbar/change-image/dell/barclamps/logging/build_deb.sh b/crowbar/change-image/dell/barclamps/logging/build_deb.sh
new file mode 100755
index 00000000000..79bf21d2ba7
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/logging/build_deb.sh
@@ -0,0 +1,17 @@
+#
+# Must have tools:
+# apt-get install dpkg-dev debhelper devscripts fakeroot linda dh-make
+#
+
+. ./version.sh
+
+sed -e "s/CHANGE_LOG_LINE/barclamp-${BARCLAMP_NAME} (${MAJOR_VERSION}.${MINOR_VERSION}-${DEB_CONTEXT_NUMBER}) unstable; urgency=low/" debian/changelog.tmpl > debian/changelog
+
+
+yes | debuild -us -uc
+
+mkdir -p bin
+mv ../barclamp-${BARCLAMP_NAME}_*.deb bin
+mv ../barclamp-${BARCLAMP_NAME}_*gz bin
+rm ../barclamp-${BARCLAMP_NAME}_*
+
diff --git a/crowbar/change-image/dell/barclamps/logging/build_rpm.sh b/crowbar/change-image/dell/barclamps/logging/build_rpm.sh
new file mode 100755
index 00000000000..c15d9be527a
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/logging/build_rpm.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+
+#
+# Needs sudo apt-get install rpm
+#
+
+. ./version.sh
+
+BUILD_DIR="/tmp/build.$$"
+rm -rf ${BUILD_DIR}
+mkdir -p ${BUILD_DIR}/BUILD
+mkdir -p ${BUILD_DIR}/RPMS
+mkdir -p ${BUILD_DIR}/SOURCES
+mkdir -p ${BUILD_DIR}/SPECS
+mkdir -p ${BUILD_DIR}/SRPMS
+
+FULL_NAME="barclamp-${BARCLAMP_NAME}-${MAJOR_VERSION}.${MINOR_VERSION}"
+
+mkdir $FULL_NAME
+cp -r Makefile app chef command_line $FULL_NAME
+tar -zcf ${BUILD_DIR}/SOURCES/${FULL_NAME}.tar.gz ${FULL_NAME}
+rm -rf ${FULL_NAME}
+
+sed -e "s%BUILD_DIR%$BUILD_DIR%" barclamp-${BARCLAMP_NAME}.spec > ${BUILD_DIR}/SPECS/barclamp-${BARCLAMP_NAME}.spec
+sed -ie "s%MAJOR_VERSION%${MAJOR_VERSION}%" ${BUILD_DIR}/SPECS/barclamp-${BARCLAMP_NAME}.spec
+sed -ie "s%MINOR_VERSION%${MINOR_VERSION}%" ${BUILD_DIR}/SPECS/barclamp-${BARCLAMP_NAME}.spec
+sed -ie "s%RPM_CONTEXT_NUMBER%${RPM_CONTEXT_NUMBER}%" ${BUILD_DIR}/SPECS/barclamp-${BARCLAMP_NAME}.spec
+
+rpmbuild -v -ba --clean ${BUILD_DIR}/SPECS/barclamp-${BARCLAMP_NAME}.spec
+
+mkdir -p bin
+cp ${BUILD_DIR}/RPMS/noarch/* bin
+cp ${BUILD_DIR}/SRPMS/* bin
+#rm -rf ${BUILD_DIR}
diff --git a/crowbar/change-image/dell/barclamps/logging/chef/cookbooks/logging/metadata.json b/crowbar/change-image/dell/barclamps/logging/chef/cookbooks/logging/metadata.json
new file mode 100644
index 00000000000..3ed5739812b
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/logging/chef/cookbooks/logging/metadata.json
@@ -0,0 +1,37 @@
+{
+ "providing": {
+ },
+ "attributes": {
+ },
+ "replacing": {
+ },
+ "dependencies": {
+ },
+ "groupings": {
+ },
+ "recommendations": {
+ },
+ "platforms": {
+ "debian": [
+
+ ],
+ "ubuntu": [
+
+ ]
+ },
+ "license": "Apache 2.0",
+ "version": "0.9.5",
+ "maintainer": "Dell, Inc.",
+ "suggestions": {
+ },
+ "recipes": {
+ "logging-server": "Installs the logging server",
+ "logging-client": "Installs the logging client"
+ },
+ "maintainer_email": "crowbar@dell.com",
+ "name": "logging",
+ "conflicting": {
+ },
+ "description": "Installs the logging",
+ "long_description": ""
+}
diff --git a/crowbar/change-image/dell/barclamps/logging/chef/cookbooks/logging/recipes/client.rb b/crowbar/change-image/dell/barclamps/logging/chef/cookbooks/logging/recipes/client.rb
new file mode 100644
index 00000000000..ffb1a96df60
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/logging/chef/cookbooks/logging/recipes/client.rb
@@ -0,0 +1,28 @@
+
+package "rsyslog"
+
+env_filter = " AND environment:#{node[:logging][:config][:environment]}"
+servers = search(:node, "roles:logging\\-server#{env_filter}")
+
+if servers.nil?
+ servers = []
+else
+ servers = servers.map { |x| Chef::Recipe::Barclamp::Inventory.get_network_by_type(x, "admin").address }
+end
+
+service "rsyslog" do
+ supports :restart => true, :status => true, :reload => true
+ running true
+ enabled true
+ action [ :enable, :start ]
+end
+
+template "/etc/rsyslog.d/10-crowbar-client.conf" do
+ owner "root"
+ group "root"
+ mode 0644
+ source "rsyslog.client.erb"
+ variables(:servers => servers)
+ notifies :restart, "service[rsyslog]"
+end
+
diff --git a/crowbar/change-image/dell/barclamps/logging/chef/cookbooks/logging/recipes/default.rb b/crowbar/change-image/dell/barclamps/logging/chef/cookbooks/logging/recipes/default.rb
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/crowbar/change-image/dell/barclamps/logging/chef/cookbooks/logging/recipes/server.rb b/crowbar/change-image/dell/barclamps/logging/chef/cookbooks/logging/recipes/server.rb
new file mode 100644
index 00000000000..1fc6d553830
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/logging/chef/cookbooks/logging/recipes/server.rb
@@ -0,0 +1,19 @@
+
+
+package "rsyslog"
+
+service "rsyslog" do
+ supports :restart => true, :status => true, :reload => true
+ running true
+ enabled true
+ action [ :enable, :start ]
+end
+
+template "/etc/rsyslog.d/10-crowbar-server.conf" do
+ owner "root"
+ group "root"
+ mode 0644
+ source "rsyslog.server.erb"
+ notifies :restart, "service[rsyslog]"
+end
+
diff --git a/crowbar/change-image/dell/barclamps/logging/chef/cookbooks/logging/templates/default/rsyslog.client.erb b/crowbar/change-image/dell/barclamps/logging/chef/cookbooks/logging/templates/default/rsyslog.client.erb
new file mode 100644
index 00000000000..d2ed2b13113
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/logging/chef/cookbooks/logging/templates/default/rsyslog.client.erb
@@ -0,0 +1,5 @@
+
+<% @servers.each do |server| -%>
+*.* @@<%= server %>
+<% end -%>
+
diff --git a/crowbar/change-image/dell/barclamps/logging/chef/cookbooks/logging/templates/default/rsyslog.server.erb b/crowbar/change-image/dell/barclamps/logging/chef/cookbooks/logging/templates/default/rsyslog.server.erb
new file mode 100644
index 00000000000..aef9510a72f
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/logging/chef/cookbooks/logging/templates/default/rsyslog.server.erb
@@ -0,0 +1,8 @@
+
+# remote rsyslog from Ubuntu will log here using TCP
+$ModLoad imtcp
+$InputTCPServerRun 514
+
+# remote syslog from CentOS will log here using UDP
+$ModLoad imudp
+$InputUDPServerRun 514
diff --git a/crowbar/change-image/dell/barclamps/logging/chef/data_bags/crowbar/bc-template-logging.json b/crowbar/change-image/dell/barclamps/logging/chef/data_bags/crowbar/bc-template-logging.json
new file mode 100644
index 00000000000..983498cc71a
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/logging/chef/data_bags/crowbar/bc-template-logging.json
@@ -0,0 +1,27 @@
+{
+ "id": "bc-template-logging",
+ "description": "centralized logging system based on syslog",
+ "attributes": {
+ "logging": {
+ "external_servers": [ ]
+ }
+ },
+ "deployment": {
+ "logging": {
+ "crowbar-revision": 0,
+ "elements": {},
+ "element_order": [
+ [ "logging-server", "logging-client" ]
+ ],
+ "config": {
+ "environment": "logging-base-config",
+ "mode": "full",
+ "transitions": true,
+ "transition_list": [
+ "discovered"
+ ]
+ }
+ }
+ }
+}
+
diff --git a/crowbar/change-image/dell/barclamps/logging/chef/data_bags/crowbar/bc-template-logging.schema b/crowbar/change-image/dell/barclamps/logging/chef/data_bags/crowbar/bc-template-logging.schema
new file mode 100644
index 00000000000..717adcd0c1f
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/logging/chef/data_bags/crowbar/bc-template-logging.schema
@@ -0,0 +1,73 @@
+{
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "id": { "type": "str", "required": true, "pattern": "/^bc-logging-|^bc-template-logging$/" },
+ "description": { "type": "str", "required": true },
+ "attributes": {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "logging": {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "external_servers": {
+ "type": "seq",
+ "required": true,
+ "sequence": [ { "type": "str" } ]
+ }
+ }
+ }
+ }
+ },
+ "deployment": {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "logging": {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "crowbar-revision": { "type": "int", "required": true },
+ "crowbar-committing": { "type": "bool" },
+ "crowbar-queued": { "type": "bool" },
+ "elements": {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ = : {
+ "type": "seq",
+ "required": true,
+ "sequence": [ { "type": "str" } ]
+ }
+ }
+ },
+ "element_order": {
+ "type": "seq",
+ "required": true,
+ "sequence": [ {
+ "type": "seq",
+ "sequence": [ { "type": "str" } ]
+ } ]
+ },
+ "config": {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "environment": { "type": "str", "required": true },
+ "mode": { "type": "str", "required": true },
+ "transitions": { "type": "bool", "required": true },
+ "transition_list": {
+ "type": "seq",
+ "required": true,
+ "sequence": [ { "type": "str" } ]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/crowbar/change-image/dell/barclamps/logging/chef/roles/logging-client.rb b/crowbar/change-image/dell/barclamps/logging/chef/roles/logging-client.rb
new file mode 100644
index 00000000000..4278a418954
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/logging/chef/roles/logging-client.rb
@@ -0,0 +1,9 @@
+
+name "logging-client"
+description "Logging Client Role - Logging client for the cloud points to Master"
+run_list(
+ "recipe[logging::client]"
+)
+default_attributes()
+override_attributes()
+
diff --git a/crowbar/change-image/dell/barclamps/logging/chef/roles/logging-server.rb b/crowbar/change-image/dell/barclamps/logging/chef/roles/logging-server.rb
new file mode 100644
index 00000000000..097bcbb2562
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/logging/chef/roles/logging-server.rb
@@ -0,0 +1,9 @@
+
+name "logging-server"
+description "Logging Servier Role - Logging master for the cloud"
+run_list(
+ "recipe[logging::server]"
+)
+default_attributes()
+override_attributes()
+
diff --git a/crowbar/change-image/dell/barclamps/logging/command_line/crowbar_logging b/crowbar/change-image/dell/barclamps/logging/command_line/crowbar_logging
new file mode 100755
index 00000000000..1d16ca55027
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/logging/command_line/crowbar_logging
@@ -0,0 +1,6 @@
+#!/usr/bin/env ruby
+
+require File.join(File.expand_path(File.dirname(__FILE__)), "barclamp_lib")
+@barclamp = "logging"
+
+main
diff --git a/crowbar/change-image/dell/barclamps/logging/debian/changelog.tmpl b/crowbar/change-image/dell/barclamps/logging/debian/changelog.tmpl
new file mode 100644
index 00000000000..42694be8134
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/logging/debian/changelog.tmpl
@@ -0,0 +1,5 @@
+CHANGE_LOG_LINE
+
+ * Initial Release.
+
+ -- unknown Thu, 19 May 2011 15:50:02 -0500
diff --git a/crowbar/change-image/dell/barclamps/logging/debian/compat b/crowbar/change-image/dell/barclamps/logging/debian/compat
new file mode 100644
index 00000000000..7f8f011eb73
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/logging/debian/compat
@@ -0,0 +1 @@
+7
diff --git a/crowbar/change-image/dell/barclamps/logging/debian/control b/crowbar/change-image/dell/barclamps/logging/debian/control
new file mode 100644
index 00000000000..1e43c1291ef
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/logging/debian/control
@@ -0,0 +1,13 @@
+Source: barclamp-logging
+Section: unknown
+Priority: extra
+Maintainer: Dell Openstack
+Build-Depends: debhelper (>= 7.0.50~)
+Standards-Version: 3.9.1
+Homepage: http://openstack.dell.com/
+
+Package: barclamp-logging
+Architecture: all
+Depends: barclamp-crowbar
+Description: Ganglia Barclamp for Crowbar
+ Provides the logging barclamp for crowbar
diff --git a/crowbar/change-image/dell/barclamps/logging/debian/copyright b/crowbar/change-image/dell/barclamps/logging/debian/copyright
new file mode 100644
index 00000000000..ef293d897c8
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/logging/debian/copyright
@@ -0,0 +1,26 @@
+This work was packaged for Debian by:
+
+ Dell Openstack Team on Thu, 19 May 2011 15:50:02 -0500
+
+It was downloaded from:
+
+
+
+Upstream Author(s):
+
+ Openstack Dell Team
+
+Copyright:
+
+ Copyright (C) 2011 Dell, Inc.
+
+License:
+
+GREG: Fill in Apache 2.0
+
+The Debian packaging is:
+
+ Copyright (C) 2011 Dell
+
+and is licensed under Apache 2.0, see above.
+
diff --git a/crowbar/change-image/dell/barclamps/logging/debian/postinst b/crowbar/change-image/dell/barclamps/logging/debian/postinst
new file mode 100644
index 00000000000..14e5692f406
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/logging/debian/postinst
@@ -0,0 +1,53 @@
+#!/bin/sh
+# postinst script for #PACKAGE#
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+# * `configure'
+# * `abort-upgrade'
+# * `abort-remove' `in-favour'
+#
+# * `abort-remove'
+# * `abort-deconfigure' `in-favour'
+# `removing'
+#
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+
+case "$1" in
+ configure)
+ cd /usr/share/barclamp-logging/chef/cookbooks
+ knife cookbook upload -o . -a -u chef-webui -k /etc/chef/webui.pem
+
+ cd /usr/share/barclamp-logging/chef/data_bags/crowbar
+ for i in *.json; do
+ knife data bag from file crowbar $i
+ done
+
+ cd /usr/share/barclamp-logging/chef/roles
+ for i in *.rb; do
+ knife role from file $i
+ done
+
+ service apache2 graceful
+ ;;
+
+ abort-upgrade|abort-remove|abort-deconfigure)
+ ;;
+
+ *)
+ echo "postinst called with unknown argument \`$1'" >&2
+ exit 1
+ ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
diff --git a/crowbar/change-image/dell/barclamps/logging/debian/rules b/crowbar/change-image/dell/barclamps/logging/debian/rules
new file mode 100755
index 00000000000..79fd842dcae
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/logging/debian/rules
@@ -0,0 +1,8 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+%:
+ dh $@
diff --git a/crowbar/change-image/dell/barclamps/logging/debian/source/format b/crowbar/change-image/dell/barclamps/logging/debian/source/format
new file mode 100644
index 00000000000..89ae9db8f88
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/logging/debian/source/format
@@ -0,0 +1 @@
+3.0 (native)
diff --git a/crowbar/change-image/dell/barclamps/logging/version.sh b/crowbar/change-image/dell/barclamps/logging/version.sh
new file mode 100644
index 00000000000..d989dc95988
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/logging/version.sh
@@ -0,0 +1,7 @@
+BARCLAMP_NAME=logging
+MAJOR_VERSION=0
+MINOR_VERSION=8
+SVN_REVISION=${SVN_REVISION:-custom}
+BUILD_NUMBER=${BUILD_NUMBER:-custom}
+RPM_CONTEXT_NUMBER=${SVN_REVISION}_${BUILD_NUMBER}
+DEB_CONTEXT_NUMBER=${SVN_REVISION}-${BUILD_NUMBER}
diff --git a/crowbar/change-image/dell/barclamps/mk_pkg.sh b/crowbar/change-image/dell/barclamps/mk_pkg.sh
new file mode 100755
index 00000000000..0edc75aee9c
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/mk_pkg.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+
+# copies the ganglia packing scripts into the specified directory making the changes for the name.
+
+NEW_PKG=$1
+
+cd ganglia
+FILE_LIST=`find debian version.sh Makefile build_* barclamp* -type f | grep -v svn`
+cd ..
+
+cd $1
+mkdir -p debian/source
+
+svn delete debian/changelog
+svn delete debian/files
+
+for i in $FILE_LIST
+do
+ file=`echo $i | sed -e "s/ganglia/$1/"`
+ echo $file
+
+ cp ../ganglia/$i $file
+
+ sed -i -e "s/ganglia/$1/g" $file
+done
+
+svn add version.sh
+svn add debian/changelog.tmpl
+
+cd -
diff --git a/crowbar/change-image/dell/barclamps/nagios/Makefile b/crowbar/change-image/dell/barclamps/nagios/Makefile
new file mode 100644
index 00000000000..82820d3ea99
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/Makefile
@@ -0,0 +1,21 @@
+
+clean:
+ @echo "Cleaning barclamp-nagios"
+
+distclean:
+ @echo "Dist-Cleaning barclamp-nagios"
+
+all: clean build install
+
+build:
+ @echo "Building barclamp-nagios"
+
+install:
+ @echo "Installing barclamp-nagios"
+ mkdir -p ${DESTDIR}/opt/crowbar/openstack_manager
+ cp -r app ${DESTDIR}/opt/crowbar/openstack_manager
+ mkdir -p ${DESTDIR}/usr/share/barclamp-nagios
+ cp -r chef ${DESTDIR}/usr/share/barclamp-nagios
+ mkdir -p ${DESTDIR}/usr/bin
+ cp -r command_line/* ${DESTDIR}/usr/bin
+
diff --git a/crowbar/change-image/dell/barclamps/nagios/app/controllers/nagios_controller.rb b/crowbar/change-image/dell/barclamps/nagios/app/controllers/nagios_controller.rb
new file mode 100644
index 00000000000..4824aff3d3e
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/app/controllers/nagios_controller.rb
@@ -0,0 +1,7 @@
+
+class NagiosController < BarclampController
+ def initialize
+ @service_object = NagiosService.new logger
+ end
+end
+
diff --git a/crowbar/change-image/dell/barclamps/nagios/app/models/nagios_service.rb b/crowbar/change-image/dell/barclamps/nagios/app/models/nagios_service.rb
new file mode 100644
index 00000000000..0d6abac23d0
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/app/models/nagios_service.rb
@@ -0,0 +1,78 @@
+
+class NagiosService < ServiceObject
+
+ def initialize(thelogger)
+ @bc_name = "nagios"
+ @logger = thelogger
+ end
+
+ def create_proposal
+ @logger.debug("Nagios create_proposal: entering")
+ base = super
+ @logger.debug("Nagios create_proposal: exiting")
+ base
+ end
+
+ def transition(inst, name, state)
+ @logger.debug("Nagios transition: make sure that network role is on all nodes: #{name} for #{state}")
+
+ #
+ # If we are discovering the node, make sure that we add the nagios client or server to the node
+ #
+ if state == "discovered"
+ @logger.debug("Nagios transition: discovered state for #{name} for #{state}")
+ db = ProposalObject.find_proposal "nagios", inst
+ role = RoleObject.find_role_by_name "nagios-config-#{inst}"
+
+ if role.override_attributes["nagios"]["elements"]["nagios-server"].nil? or
+ role.override_attributes["nagios"]["elements"]["nagios-server"].empty?
+ @logger.debug("Nagios transition: make sure that nagios-server role is on first: #{name} for #{state}")
+ result = add_role_to_instance_and_node("nagios", inst, name, db, role, "nagios-server")
+ else
+ node = NodeObject.find_node_by_name name
+ unless node.role? "nagios-server"
+ @logger.debug("Nagios transition: make sure that nagios-client role is on all nodes but first: #{name} for #{state}")
+ result = add_role_to_instance_and_node("nagios", inst, name, db, role, "nagios-client")
+ else
+ result = true
+ end
+ end
+
+ # Set up the client url
+ if result
+ role = RoleObject.find_role_by_name "nagios-config-#{inst}"
+
+ # Get the server IP address
+ server_ip = nil
+ [ "nagios-server" ].each do |element|
+ tnodes = role.override_attributes["nagios"]["elements"][element]
+ next if tnodes.nil? or tnodes.empty?
+ tnodes.each do |n|
+ next if n.nil?
+ node = NodeObject.find_node_by_name(n)
+ server_ip = node.get_network_by_type("admin")["address"]
+ end
+ end
+
+ unless server_ip.nil?
+ node = NodeObject.find_node_by_name(name)
+ node["crowbar"] = {} if node["crowbar"].nil?
+ node["crowbar"]["links"] = {} if node["crowbar"]["links"].nil?
+ node["crowbar"]["links"]["Nagios"] = "http://#{server_ip}/nagios3/cgi-bin/extinfo.cgi?type=1&host=#{node.shortname}"
+ node.save
+ end
+ end
+
+ @logger.debug("Nagios transition: leaving from discovered state for #{name} for #{state}")
+ a = [200, NodeObject.find_node_by_name(name).to_hash ] if result
+ a = [400, "Failed to add role to node"] unless result
+ return a
+ end
+
+ @logger.debug("Nagios transition: leaving for #{name} for #{state}")
+ [200, NodeObject.find_node_by_name(name).to_hash ]
+ end
+
+end
+
+
diff --git a/crowbar/change-image/dell/barclamps/nagios/barclamp-nagios.spec b/crowbar/change-image/dell/barclamps/nagios/barclamp-nagios.spec
new file mode 100644
index 00000000000..c603921c36f
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/barclamp-nagios.spec
@@ -0,0 +1,52 @@
+
+%define _topdir BUILD_DIR
+%define name barclamp-nagios
+%define release RPM_CONTEXT_NUMBER
+%define version MAJOR_VERSION.MINOR_VERSION
+%define buildroot %{_topdir}/%{name}-%{version}-root
+
+BuildRoot: %{buildroot}
+Summary: common Nagios service for the cluster that can be used by other barclamps
+License: Apache 2.0
+Name: %{name}
+BuildArch: noarch
+Version: %{version}
+Release: %{release}
+Source: %{name}-%{version}.tar.gz
+Prefix: /
+Group: Development/Tools
+
+%description
+A Crowbar Barclamp that manages nagios deployments within a Crowbar environment.
+
+%prep
+%setup -q
+
+%build
+
+%install
+make install DESTDIR=${RPM_BUILD_ROOT}
+
+%post
+cd /usr/share/barclamp-nagios/chef/cookbooks
+knife cookbook upload -o . -a -u chef-webui -k /etc/chef/webui.pem
+
+cd /usr/share/barclamp-nagios/chef/data_bags/crowbar
+for i in *.json; do
+ knife data bag from file crowbar $i
+done
+
+cd /usr/share/barclamp-nagios/chef/roles
+for i in *.rb; do
+ knife role from file $i
+done
+
+service httpd graceful
+
+
+%files
+%defattr(-,root,root)
+/usr/bin
+/usr/share
+/opt
+
diff --git a/crowbar/change-image/dell/barclamps/nagios/build_deb.sh b/crowbar/change-image/dell/barclamps/nagios/build_deb.sh
new file mode 100755
index 00000000000..79bf21d2ba7
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/build_deb.sh
@@ -0,0 +1,17 @@
+#
+# Must have tools:
+# apt-get install dpkg-dev debhelper devscripts fakeroot linda dh-make
+#
+
+. ./version.sh
+
+sed -e "s/CHANGE_LOG_LINE/barclamp-${BARCLAMP_NAME} (${MAJOR_VERSION}.${MINOR_VERSION}-${DEB_CONTEXT_NUMBER}) unstable; urgency=low/" debian/changelog.tmpl > debian/changelog
+
+
+yes | debuild -us -uc
+
+mkdir -p bin
+mv ../barclamp-${BARCLAMP_NAME}_*.deb bin
+mv ../barclamp-${BARCLAMP_NAME}_*gz bin
+rm ../barclamp-${BARCLAMP_NAME}_*
+
diff --git a/crowbar/change-image/dell/barclamps/nagios/build_rpm.sh b/crowbar/change-image/dell/barclamps/nagios/build_rpm.sh
new file mode 100755
index 00000000000..c15d9be527a
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/build_rpm.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+
+#
+# Needs sudo apt-get install rpm
+#
+
+. ./version.sh
+
+BUILD_DIR="/tmp/build.$$"
+rm -rf ${BUILD_DIR}
+mkdir -p ${BUILD_DIR}/BUILD
+mkdir -p ${BUILD_DIR}/RPMS
+mkdir -p ${BUILD_DIR}/SOURCES
+mkdir -p ${BUILD_DIR}/SPECS
+mkdir -p ${BUILD_DIR}/SRPMS
+
+FULL_NAME="barclamp-${BARCLAMP_NAME}-${MAJOR_VERSION}.${MINOR_VERSION}"
+
+mkdir $FULL_NAME
+cp -r Makefile app chef command_line $FULL_NAME
+tar -zcf ${BUILD_DIR}/SOURCES/${FULL_NAME}.tar.gz ${FULL_NAME}
+rm -rf ${FULL_NAME}
+
+sed -e "s%BUILD_DIR%$BUILD_DIR%" barclamp-${BARCLAMP_NAME}.spec > ${BUILD_DIR}/SPECS/barclamp-${BARCLAMP_NAME}.spec
+sed -ie "s%MAJOR_VERSION%${MAJOR_VERSION}%" ${BUILD_DIR}/SPECS/barclamp-${BARCLAMP_NAME}.spec
+sed -ie "s%MINOR_VERSION%${MINOR_VERSION}%" ${BUILD_DIR}/SPECS/barclamp-${BARCLAMP_NAME}.spec
+sed -ie "s%RPM_CONTEXT_NUMBER%${RPM_CONTEXT_NUMBER}%" ${BUILD_DIR}/SPECS/barclamp-${BARCLAMP_NAME}.spec
+
+rpmbuild -v -ba --clean ${BUILD_DIR}/SPECS/barclamp-${BARCLAMP_NAME}.spec
+
+mkdir -p bin
+cp ${BUILD_DIR}/RPMS/noarch/* bin
+cp ${BUILD_DIR}/SRPMS/* bin
+#rm -rf ${BUILD_DIR}
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/README.rdoc b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/README.rdoc
new file mode 100644
index 00000000000..614abc7d40c
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/README.rdoc
@@ -0,0 +1,195 @@
+= DESCRIPTION:
+
+Installs and configures Nagios 3 for a server and for clients using Chef 0.8 search capabilities.
+
+= REQUIREMENTS:
+
+Requires Chef 0.8+ for search capability of roles and data bags.
+
+A data bag named 'users' should exist, see "DATA BAG" below.
+
+The monitoring server that uses this recipe should have a role named 'monitoring' or similar. A "per-environment" role should be created as well. See "ROLES" below.
+
+Because of the heavy use of search, this recipe will not work with Chef Solo, as it cannot do any searches without a server.
+
+== Platform:
+
+Tested on Ubuntu 9.04+ and Debian 5+.
+
+== Cookbooks:
+
+* apache2
+
+= ATTRIBUTES:
+
+Attributes under the 'nagios' namespace.
+
+== Client:
+
+The following attributes are used for the client NRPE checks for warning and critical levels.
+
+checks.memory.critical
+checks.memory.warning
+checks.load.critical
+checks.load.warning
+checks.smtp_host - default relayhost to check for connectivity. Default is an empty string, set via an attribute in a role.
+server_role - the role that the nagios server will have in its run list that the clients can search for.
+
+== Server:
+
+dir - base server configuration directory.
+log_dir - where the server logs.
+cache_dir - cached directory.
+docroot - DocumentRoot for webui.
+config_subdir - for dropping in configurations as needed.
+notifications_enabled - set to 1 to enable notification.
+check_external_commands
+default_contact_groups
+sysadmin_email - default notification email.
+sysadmin_sms_email - default notification sms.
+server_auth_method - authentication with the server can be done with openid (using apache2::mod_auth_openid), or htauth (basic). The default is openid, any other value will use htauth (basic).
+templates
+interval_length - minimum interval.
+default_host.check_interval
+default_host.retry_interval
+default_host.max_check_attempts
+default_host.notification_interval
+default_service.check_interval
+default_service.retry_interval
+default_service.max_check_attempts
+default_service.notification_interval
+
+= DATA BAGS:
+
+Create a `users` data bag that will contain the users that will be able to log into the Nagios webui. Each user can use htauth with a specified password, or an openid. Users that should be able to log in should be in the sysadmin group. Example user data bag item:
+
+ {
+ "id": "nagiosadmin",
+ "groups": "sysadmin",
+ "htpasswd": "hashed_htpassword",
+ "openid": "http://nagiosadmin.myopenid.com/",
+ "nagios": {
+ "pager": "nagiosadmin_pager@example.com",
+ "email": "nagiosadmin@example.com"
+ }
+ }
+
+When using server_auth_method 'openid', use the openid in the data bag item. Any other value for this attribute (e.g., "htauth", "htpasswd", etc) will use the htpasswd value as the password in `/etc/nagios3/htpasswd.users`.
+
+The openid must have the http:// and trailing /. The htpasswd must be the hashed value. Get this value with:
+
+ % htpasswd -n nagiosadmin
+ New password:
+ Re-type new password:
+ nagiosadmin:mbfzZrHsUUjds
+
+For example use the "mbfzZrHsUUjds" value in the data bag.
+
+= ROLES:
+
+Create a role to use for the monitoring server. The role name should match the value of the attribute "nagios[:server_role]". By default, this is 'monitoring'. For example:
+
+ % cat roles/monitoring.rb
+ name "monitoring"
+ description "Monitoring server"
+ run_list(
+ "recipe[nagios::server]"
+ )
+
+ default_attributes(
+ "nagios" => {
+ "server_auth_method" => "htauth"
+ }
+ )
+
+Also create per-environment role. For example, production nodes:
+
+ % cat roles/production.rb
+ name "production"
+ description "Nodes in the production environment."
+ default_attributes(
+ "app_environment" => "production"
+ )
+
+Make sure to apply the production role to all nodes that should be monitored by the production monitoring server.
+
+= USAGE:
+
+For a Nagios server, create a role named 'monitoring', and add the following recipe to the run_list:
+
+ recipe[nagios::server]
+
+This will allow client nodes to search for the server by this role and add its IP address to the allowed list for NRPE.
+
+To install Nagios and NRPE on a client node:
+
+ include_recipe "nagios::client"
+
+This is a fairly complicated cookbook. We'll describe the components in detail.
+
+== Definitions:
+
+nagios_conf:: This definition is used to drop in a configuration file in the base Nagios configuration directory's conf.d. This can be used for customized configurations for various services.
+
+== Libraries:
+
+default:: The library included with the cookbook provides some helper methods used in templates.
+
+* nagios_boolean
+* nagios_interval - calculates interval based on interval length and a given number of seconds.
+* nagios_attr - retrieves a nagios attribute from the node.
+
+== Recipes:
+
+=== Client
+
+The client recipe searches for allowed servers via a role named 'monitoring'. The recipe will also install the required packages and start the NRPE service. A custom plugin for checking memory is also added.
+
+Client commands for NRPE can be modified by editing the nrpe.cfg.erb template.
+
+=== Server
+
+The server recipe sets up Apache as the web front end. The nagios::client recipe is also included. This recipe also does a number of searches to dynamically build the hostgroups to monitor, hosts that belong to them and admins to notify of events/alerts.
+
+The recipe does the following:
+
+1. Searches for members of the sysadmins group by searching through 'users' data bag and adds them to a list for notification/contacts.
+2. Search all nodes for a role matching the app_environment.
+3. Search all available roles and build a list which will be the Nagios hostgroups.
+4. Search for all nodes of each role and add the hostnames to the hostgroups.
+5. Installs various packages required for the server.
+6. Sets up some configuration directories.
+7. Moves the package-installed Nagios configuration to a 'dist' directory.
+8. Disables the 000-default site (present on Debian/Ubuntu Apache2 package installations).
+9. Enables the Nagios web front end configuration.
+10. Sets up the configuration templates for services, contacts, hostgroups and hosts.
+
+*NOTE*: You will probably need to change the services.cfg.erb template for your environment.
+
+To add custom commands for service checks, these can be done on a per-role basis by editing the 'services.cfg.erb' template. This template has some pre-configured checks that use role names used in an example infrastructure. Here's a brief description:
+
+* monitoring - check_smtp (e.g., postfix relayhost) w/ NRPE and tcp port 514 (e.g., rsyslog)
+* load_balancer - check_nginx with NRPE.
+* appserver - check_unicorn with NRPE, e.g. a Rails application using Unicorn.
+* database_master - check_mysql_server with NRPE for a MySQL database master.
+
+= LICENSE and AUTHOR:
+
+Author:: Joshua Sierles
+Author:: Nathan Haneysmith
+Author:: Joshua Timberman
+
+Copyright 2009, 37signals
+Copyright 2009-2010, Opscode, Inc
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/attributes/client.rb b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/attributes/client.rb
new file mode 100644
index 00000000000..ce687e4f27d
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/attributes/client.rb
@@ -0,0 +1,39 @@
+#
+# Author:: Joshua Sierles
+# Author:: Joshua Timberman
+# Author:: Nathan Haneysmith
+# Cookbook Name:: nagios
+# Attributes:: client
+#
+# Copyright 2009, 37signals
+# Copyright 2009-2010, Opscode, Inc
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+default[:nagios][:checks][:memory][:critical] = 150
+default[:nagios][:checks][:memory][:warning] = 250
+default[:nagios][:checks][:load][:critical] = "30,20,10"
+default[:nagios][:checks][:load][:warning] = "15,10,5"
+default[:nagios][:checks][:smtp_host] = String.new
+
+# default[:nagios][:server_role] = "monitoring"
+default[:nagios][:server_role] = "nagios-server"
+
+default[:nagios][:user] = "nagios"
+default[:nagios][:group]= "nagios"
+
+default[:nagios][:config] = {}
+default[:nagios][:config][:environment] = "nagios-config-default"
+default[:nagios][:config][:mode] = "full"
+
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/attributes/server.rb b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/attributes/server.rb
new file mode 100644
index 00000000000..cd11f7e6c4d
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/attributes/server.rb
@@ -0,0 +1,56 @@
+#
+# Author:: Joshua Sierles
+# Author:: Joshua Timberman
+# Author:: Nathan Haneysmith
+# Cookbook Name:: nagios
+# Attributes:: server
+#
+# Copyright 2009, 37signals
+# Copyright 2009-2010, Opscode, Inc
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+set[:nagios][:dir] = "/etc/nagios3"
+set[:nagios][:log_dir] = "/var/log/nagios3"
+set[:nagios][:cache_dir] = "/var/cache/nagios3"
+set[:nagios][:state_dir] = "/var/lib/nagios3"
+set[:nagios][:docroot] = "/usr/share/nagios3/htdocs"
+set[:nagios][:config_subdir] = "conf.d"
+
+default[:nagios][:notifications_enabled] = 0
+default[:nagios][:check_external_commands] = true
+default[:nagios][:default_contact_groups] = %w(admins)
+default[:nagios][:sysadmin_email] = "root@localhost"
+default[:nagios][:sysadmin_sms_email] = "root@localhost"
+default[:nagios][:server_auth_method] = "openid"
+
+# This setting is effectively sets the minimum interval (in seconds) nagios can handle.
+# Other interval settings provided in seconds will calculate their actual from this value, since nagios works in 'time units' rather than allowing definitions everywhere in seconds
+
+default[:nagios][:templates] = Mash.new
+default[:nagios][:interval_length] = 1
+
+# Provide all interval values in seconds
+default[:nagios][:default_host][:check_interval] = 15
+default[:nagios][:default_host][:retry_interval] = 15
+default[:nagios][:default_host][:max_check_attempts] = 1
+default[:nagios][:default_host][:notification_interval] = 300
+
+default[:nagios][:default_service][:check_interval] = 60
+default[:nagios][:default_service][:retry_interval] = 15
+default[:nagios][:default_service][:max_check_attempts] = 3
+default[:nagios][:default_service][:notification_interval] = 1200
+
+default[:nagios][:config] = {}
+default[:nagios][:config][:environment] = "nagios-config-default"
+default[:nagios][:config][:mode] = "full"
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/definitions/nagios_conf.rb b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/definitions/nagios_conf.rb
new file mode 100644
index 00000000000..23f0679592d
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/definitions/nagios_conf.rb
@@ -0,0 +1,40 @@
+#
+# Author:: Joshua Sierles
+# Author:: Joshua Timberman
+# Author:: Nathan Haneysmith
+# Cookbook Name:: nagios
+# Definition:: nagios_conf
+#
+# Copyright 2009, 37signals
+# Copyright 2009-2010, Opscode, Inc
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+define :nagios_conf, :variables => {}, :config_subdir => true do
+
+ subdir = if params[:config_subdir]
+ "/#{node[:nagios][:config_subdir]}/"
+ else
+ "/"
+ end
+
+ template "#{node[:nagios][:dir]}#{subdir}#{params[:name]}.cfg" do
+ owner "nagios"
+ group "nagios"
+ source "#{params[:name]}.cfg.erb"
+ mode 0644
+ variables params[:variables]
+ notifies :restart, resources(:service => "nagios3")
+ backup 0
+ end
+end
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/icons/centos.gd2 b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/icons/centos.gd2
new file mode 100644
index 00000000000..1da67773af4
Binary files /dev/null and b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/icons/centos.gd2 differ
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/icons/centos.gif b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/icons/centos.gif
new file mode 100644
index 00000000000..b35146cea37
Binary files /dev/null and b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/icons/centos.gif differ
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/icons/centos.jpg b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/icons/centos.jpg
new file mode 100644
index 00000000000..3d1f7d914e2
Binary files /dev/null and b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/icons/centos.jpg differ
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/icons/centos.png b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/icons/centos.png
new file mode 100644
index 00000000000..e626bcf3e9f
Binary files /dev/null and b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/icons/centos.png differ
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/icons/munin-head.gif b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/icons/munin-head.gif
new file mode 100644
index 00000000000..3a08d7f8c48
Binary files /dev/null and b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/icons/munin-head.gif differ
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/icons/ubuntu.gd2 b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/icons/ubuntu.gd2
new file mode 100644
index 00000000000..e05163ba859
Binary files /dev/null and b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/icons/ubuntu.gd2 differ
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/icons/ubuntu.gif b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/icons/ubuntu.gif
new file mode 100644
index 00000000000..0a51c5322e3
Binary files /dev/null and b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/icons/ubuntu.gif differ
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/icons/ubuntu.jpg b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/icons/ubuntu.jpg
new file mode 100644
index 00000000000..0535df9515a
Binary files /dev/null and b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/icons/ubuntu.jpg differ
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/icons/ubuntu.png b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/icons/ubuntu.png
new file mode 100644
index 00000000000..b2d71d93617
Binary files /dev/null and b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/icons/ubuntu.png differ
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/plugins/LICENSE.txt b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/plugins/LICENSE.txt
new file mode 100644
index 00000000000..ef80403f520
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/plugins/LICENSE.txt
@@ -0,0 +1,204 @@
+Applies to RabbitMQ checks:
+From: https://github.com/jamesc/nagios-plugins-rabbitmq
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/plugins/check-mysql-slave.pl b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/plugins/check-mysql-slave.pl
new file mode 100644
index 00000000000..12fce3a4938
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/plugins/check-mysql-slave.pl
@@ -0,0 +1,158 @@
+#!/usr/bin/env perl
+
+#
+# mysql-slave-check.pl
+#
+# Nagios script for checking the replication
+# status of a slave MySQL server.
+#
+# Michal Ludvig (c) 2006
+# http://www.logix.cz/michal
+#
+# Run with --help to get some hints about usage or
+# look at subroutine usage() near the end of this file.
+#
+
+use strict;
+use DBI;
+use Getopt::Long;
+
+my $db_host = "localhost";
+my $db_port = "3306";
+my $db_sock = "";
+my $db_user = "";
+my $db_pass = "";
+my $db_name = "";
+my $warn = 300;
+my $crit = 900;
+
+# Nagios codes
+my %ERRORS=('OK'=>0, 'WARNING'=>1, 'CRITICAL'=>2, 'UNKNOWN'=>3, 'DEPENDENT'=>4);
+
+GetOptions(
+ 'host=s' => \$db_host,
+ 'port=i' => \$db_port,
+ 'user=s' => \$db_user,
+ 'password=s' => \$db_pass,
+ 'socket=s' => \$db_sock,
+ 'warn=i' => \$warn,
+ 'crit=i' => \$crit,
+ 'name|dbname|database=s' => \$db_name,
+ 'help' => sub { &usage(); },
+);
+
+&nagios_return("UNKNOWN", "Either set --host/--port or --sock, not both!") if (($db_port || $db_host ne "localhost") && $db_sock);
+
+my $db_conn_string = "DBI:mysql:";
+$db_conn_string .= "database=$db_name;";
+$db_conn_string .= "host=$db_host;";
+$db_conn_string .= "port=$db_port;";
+$db_conn_string .= "mysql_socket=$db_sock;";
+
+## Connect to the database.
+my $dbh = DBI->connect($db_conn_string, $db_user, $db_pass,
+ {'RaiseError' => 0, 'PrintError' => 0});
+
+&nagios_return("UNKNOWN", "Connect failed: $DBI::errstr") if (!$dbh);
+
+## Now retrieve data from the table.
+my $sth = $dbh->prepare("SHOW SLAVE STATUS");
+&nagios_return("UNKNOWN", "[1] $DBI::errstr") if (!$sth);
+
+$sth->execute();
+
+&nagios_return("UNKNOWN", "[2] $DBI::errstr") if ($sth->err);
+&nagios_return("CRITICAL", "Query returned ".scalar($sth->rows)." rows") if (scalar($sth->rows) < 1);
+
+## Query should return one row only
+my $result = $sth->fetchrow_hashref();
+
+&nagios_return("UNKNOWN", "[3] $DBI::errstr") if (!$result);
+
+## Print all results? No thanks.
+# while (my ($key, $val) = each %$result) {
+# print "$key = $val\n";
+# }
+
+## Check the returned values
+&nagios_return("CRITICAL", "Slave_IO_Running=".$result->{'Slave_IO_Running'}."!") if ($result->{'Slave_IO_Running'} ne "Yes");
+&nagios_return("CRITICAL", "Slave_SQL_Running=".$result->{'Slave_SQL_Running'}."!") if ($result->{'Slave_SQL_Running'} ne "Yes");
+&nagios_return("CRITICAL", "Seconds_Behind_Master=".$result->{'Seconds_Behind_Master'}) if ($result->{'Seconds_Behind_Master'} > $crit);
+&nagios_return("WARNING", "Seconds_Behind_Master=".$result->{'Seconds_Behind_Master'}) if ($result->{'Seconds_Behind_Master'} > $warn);
+$sth->finish();
+
+# Disconnect from the database.
+$dbh->disconnect();
+
+&nagios_return("OK", "$result->{'Slave_IO_State'}, replicating host $result->{'Master_Host'}:$result->{'Master_Port'}");
+exit 0;
+
+###
+
+sub nagios_return($$) {
+ my ($ret, $message) = @_;
+ my ($retval, $retstr);
+ if (defined($ERRORS{$ret})) {
+ $retval = $ERRORS{$ret};
+ $retstr = $ret;
+ } else {
+ $retstr = 'UNKNOWN';
+ $retval = $ERRORS{$retstr};
+ $message = "WTF is return code '$ret'??? ($message)";
+ }
+ $message = "$retstr - $message\n";
+ print $message;
+ exit $retval;
+}
+
+sub usage() {
+ print("
+Nagios script for checking the replication status of a
+slave MySQL server.
+
+Michal Ludvig (c) 2006
+ http://www.logix.cz/michal
+
+ --host= Hostname or IP address to connect to.
+ --port= TCP port where the server listens
+ --socket=
+ Path and filename of the Unix socket
+
+ --user=
+ --password=
+ Username and password of a user with
+ REPLICATION CLIENT privileges. See
+ below for details.
+
+ --dbname=
+ Name od database to open on connect.
+ Should normaly not be needed.
+
+ --warn= Warning threshold in seconds for Seconds_behind_master variable
+
+ --crit= Critical threshold in seconds for Seconds_behind_master variable
+
+ --help Guess what ;-)
+
+The script needs to connect as a MySQL user (say 'monitor')
+with privilege REPLICATION CLIENT. Use this GRANT
+command to create such a user:
+
+mysql> GRANT REPLICATION CLIENT ON *.* \\
+ TO monitor\@localhost IDENTIFIED BY 'SecretPassword';
+
+To access the script over SNMP put the following line
+into your /etc/snmpd.conf:
+
+extend mysql-slave /path/to/mysql-slave-check.pl \\
+ --user monitor --pass 'SecretPassword';
+
+To check retrieve the status over SNMP use check_snmp_extend.sh
+from http://www.logix.cz/michal/devel/nagios
+
+
+
+");
+ exit 0;
+
+}
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/plugins/check_mem.sh b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/plugins/check_mem.sh
new file mode 100644
index 00000000000..6dde99d84c6
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/plugins/check_mem.sh
@@ -0,0 +1,98 @@
+#!/bin/bash
+#
+# evaluate free system memory from Linux based systems
+#
+# Date: 2007-11-12
+# Author: Thomas Borger - ESG
+#
+# the memory check is done with following command line:
+# free -m | grep buffers/cache | awk '{ print $4 }'
+
+# get arguments
+
+while getopts 'w:c:hp' OPT; do
+ case $OPT in
+ w) int_warn=$OPTARG;;
+ c) int_crit=$OPTARG;;
+ h) hlp="yes";;
+ p) perform="yes";;
+ *) unknown="yes";;
+ esac
+done
+
+# usage
+HELP="
+ usage: $0 [ -w value -c value -p -h ]
+
+ syntax:
+
+ -w --> Warning integer value
+ -c --> Critical integer value
+ -p --> print out performance data
+ -h --> print this help screen
+"
+
+if [ "$hlp" = "yes" -o $# -lt 1 ]; then
+ echo "$HELP"
+ exit 0
+fi
+
+# get free memory
+FMEM=`free -m | grep buffers/cache | awk '{ print $4 }'`
+
+# output with or without performance data
+if [ "$perform" = "yes" ]; then
+ OUTPUTP="free system memory: $FMEM MB | free memory="$FMEM"MB;$int_warn;$int_crit;0"
+else
+ OUTPUT="free system memory: $FMEM MB"
+fi
+
+if [ -n "$int_warn" -a -n "$int_crit" ]; then
+
+ err=0
+
+ if (( $FMEM <= $int_warn )); then
+ err=1
+ elif (( $FMEM <= $int_crit )); then
+ err=2
+ fi
+
+ if (( $err == 0 )); then
+
+ if [ "$perform" = "yes" ]; then
+ echo "MEM OK - $OUTPUTP"
+ exit "$err"
+ else
+ echo "MEM OK - $OUTPUT"
+ exit "$err"
+ fi
+
+ elif (( $err == 1 )); then
+ if [ "$perform" = "yes" ]; then
+ echo "MEM WARNING - $OUTPUTP"
+ exit "$err"
+ else
+ echo "MEM WARNING - $OUTOUT"
+ exit "$err"
+ fi
+
+ elif (( $err == 2 )); then
+
+ if [ "$perform" = "yes" ]; then
+ echo "MEM CRITICAL - $OUTPUTP"
+ exit "$err"
+ else
+ echo "MEM CRITICAL - $OUTPUT"
+ exit "$err"
+ fi
+
+ fi
+
+else
+
+ echo "no output from plugin"
+ exit 3
+
+fi
+exit
+
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/plugins/check_mysqlhealth.pl b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/plugins/check_mysqlhealth.pl
new file mode 100644
index 00000000000..f0391d5d779
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/plugins/check_mysqlhealth.pl
@@ -0,0 +1,159 @@
+#!/usr/bin/perl
+# --
+# Check the health of a mysql server.
+#
+# @author Peter Romianowski / optivo GmbH
+# @version 1.0 2005-08-31
+# --
+use Getopt::Long;
+use DBI;
+
+# --
+# Print out the usage message
+# --
+sub usage {
+ print "usage: check_mysqlhealth.pl -H -u -p \n";
+ print " Optional parameters:\n";
+ print " --port \n";
+ print " --Cc \n";
+ print " --Wc \n";
+ print " --Ca \n";
+ print " --Wa \n";
+ print " --sql \n";
+}
+
+$|=1;
+
+# --
+# Parse arguments and read Configuration
+# --
+my ($host, $user, $password, $port, $criticalConnections, $warningConnections, $criticalActive, $warningActive, $sql);
+GetOptions (
+ 'host=s' => \$host,
+ 'H=s' => \$host,
+ 'user=s' => \$user,
+ 'u=s' => \$user,
+ 'password=s' => \$password,
+ 'p:s' => \$password,
+ 'port=i' => \$port,
+ 'Cc=i' => \$criticalConnections,
+ 'Wc=i' => \$warningConnections,
+ 'Ca=i' => \$criticalActive,
+ 'Wa=i' => \$warningActive,
+ 'sql=s'=> \$sql
+);
+
+if (!$host || !$user) {
+ usage();
+ exit(1);
+}
+
+if (!$port) {
+ $port = 3306;
+}
+
+my $totalTime = time();
+
+# --
+# Establish connection
+# --
+my $state = "OK";
+my $dbh;
+eval {
+ $dbh = DBI->connect("DBI:mysql:host=$host;port=$port", $user, $password, {'RaiseError' => 1});
+};
+
+if ($@) {
+ my $status = $@;
+ print 'CRITICAL: Connect failed with reason ' . $status . "\n";
+ exit 2;
+}
+
+# --
+# Count active statements
+# --
+my $connections = 0;
+my $active = 0;
+
+eval {
+ my $sth = $dbh->prepare("SHOW PROCESSLIST");
+ $sth->execute();
+ my $row;
+ do {
+ $row = $sth->fetchrow_hashref();
+ if ($row) {
+ if (!($row->{'Command'} =~ /Sleep/)) {
+ $active++;
+ }
+ $connections++;
+ }
+
+ } while ($row);
+};
+
+if ($@) {
+ my $status = $@;
+ print 'CRITICAL: Error executing SHOW PROCESSLIST, reason ' . $status . "\n";
+ exit 2;
+}
+
+# --
+# Execute optional sql statement if given
+# --
+$sqlResult;
+if ($sql) {
+ eval {
+ my $sth = $dbh->prepare($sql);
+ $sth->execute();
+ my @row = $sth->fetchrow();
+ if (@row) {
+ $sqlResult = join('|', @row);
+ }
+ };
+
+ if ($@) {
+ my $status = $@;
+ print 'CRITICAL: Error executing statement "' . $sql . '", reason ' . $status . "\n";
+ exit 2;
+ }
+
+}
+
+# --
+# Cleanup resources
+# --
+$dbh->disconnect();
+
+# --
+# Check
+# --
+my $statusString = "$connections connections, $active active connections";
+if ($criticalConnections && $criticalConnections < $connections) {
+ print "CRITICAL: Number of connections higher than $criticalConnections ($statusString)\n";
+ exit 2;
+}
+if ($criticalActive && $criticalActive < $active) {
+ print "CRITICAL: Number of ACTIVE connections higher than $criticalActive ($statusString)\n";
+ exit 2;
+}
+if ($warningConnections && $warningConnections < $connections) {
+ print "WARNING: Number of connections higher than $warningConnections ($statusString)\n";
+ exit 1;
+}
+if ($warningActive && $warningActive < $active) {
+ print "WARNING: Number of ACTIVE connections higher than $warningActive ($statusString)\n";
+ exit 1;
+}
+if ($sql) {
+ if ($sqlResult) {
+ $statusString = "Statement '$sql' returned: '$sqlResult', $statusString";
+ } else {
+ print "CRITICAL: Execution of statement '$sql' did not produce any result ($statusString)\n";
+ exit 2;
+ }
+}
+
+print "OK: $statusString\n";
+exit 0;
+
+
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/plugins/check_nova_manage b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/plugins/check_nova_manage
new file mode 100755
index 00000000000..3e78457a606
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/plugins/check_nova_manage
@@ -0,0 +1,94 @@
+#!/bin/bash
+#
+# check to see that nova services are running within options
+#
+
+# get arguments
+
+int_warn=1
+int_crit=2
+int_compute=0
+int_volume=0
+int_network=0
+int_scheduler=0
+
+while getopts 'hS:N:C:V:w:c:' OPT; do
+ case $OPT in
+ w) int_warn=$OPTARG;;
+ c) int_crit=$OPTARG;;
+ C) int_compute=$OPTARG;;
+ V) int_volume=$OPTARG;;
+ N) int_network=$OPTARG;;
+ S) int_scheduler=$OPTARG;;
+ h) hlp="yes";;
+ *) unknown="yes";;
+ esac
+done
+
+# usage
+HELP="
+Usage: $0 [ -w value ] [ -c value ] [ -C value ] [ -N value ] [ -S value ] [ -V value ]
+Options:
+ -w --> Warning threshold of missing components (default: 1)
+ -c --> Critical threshold of missing components (default: 2)
+ -C --> Expected Compute service entries (default: 0)
+ -N --> Expected Network service entries (default: 0)
+ -S --> Expected Scheduler service entries (default: 0)
+ -V --> Expected Volume service entries (default: 0)
+ -h --> print this help screen
+"
+
+if [ "$hlp" = "yes" ]; then
+ echo "$HELP"
+ exit 0
+fi
+
+# Get nova status
+nova-manage service list > /tmp/nova.out.$$
+N_N=`grep nova-network /tmp/nova.out.$$ | grep -v XXX | wc -l`
+N_C=`grep nova-compute /tmp/nova.out.$$ | grep -v XXX | wc -l`
+N_V=`grep nova-volume /tmp/nova.out.$$ | grep -v XXX | wc -l`
+N_S=`grep nova-scheduler /tmp/nova.out.$$ | grep -v XXX | wc -l`
+
+D_C=`expr $int_compute - $N_C`
+if [ $D_C -lt 0 ]; then
+ D_C=0
+fi
+D_N=`expr $int_network - $N_N`
+if [ $D_N -lt 0 ]; then
+ D_N=0
+fi
+D_V=`expr $int_volume - $N_V`
+if [ $D_V -lt 0 ]; then
+ D_V=0
+fi
+D_S=`expr $int_scheduler - $N_S`
+if [ $D_S -lt 0 ]; then
+ D_S=0
+fi
+
+D_Total=`expr $D_N + $D_S + $D_C + $D_V`
+
+err=0
+if (( $D_Total >= $int_crit )); then
+ err=2
+elif (( $D_Total >= $int_warn )); then
+ err=1
+fi
+
+OUTPUTP="scheduler: $N_S ($int_scheduler), network: $N_N ($int_network), compute: $N_C ($int_compute), volume: $N_V ($int_volume)"
+
+if (( $err == 0 )); then
+ echo "Nova OK - $OUTPUTP"
+ exit "$err"
+elif (( $err == 1 )); then
+ echo "Nova WARNING ($D_Total) - $OUTPUTP"
+ exit "$err"
+elif (( $err == 2 )); then
+ echo "Nova CRITICAL ($D_Total) - $OUTPUTP"
+ exit "$err"
+fi
+
+echo "Nova UNKNOWN - Bad Code Path"
+exit -1
+
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/plugins/check_rabbitmq_aliveness b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/plugins/check_rabbitmq_aliveness
new file mode 100755
index 00000000000..b104a6847c9
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/plugins/check_rabbitmq_aliveness
@@ -0,0 +1,222 @@
+#!/usr/bin/env perl
+
+### check_rabbitmq_aliveness.pl
+
+# Use the management aliveness-check to send/receive a message through a vhost
+
+# Originally by Nathan Vonnahme, n8v at users dot sourceforge
+# dot net, July 19 2006
+
+##############################################################################
+# prologue
+use strict;
+use warnings;
+
+use Nagios::Plugin ;
+use LWP::UserAgent;
+use URI::Escape;
+use JSON;
+
+use vars qw($VERSION $PROGNAME $verbose $timeout);
+$VERSION = '1.0';
+
+# get the base name of this script for use in the examples
+use File::Basename;
+$PROGNAME = basename($0);
+
+
+##############################################################################
+# define and get the command line options.
+# see the command line option guidelines at
+# http://nagiosplug.sourceforge.net/developer-guidelines.html#PLUGOPTIONS
+
+
+# Instantiate Nagios::Plugin object (the 'usage' parameter is mandatory)
+my $p = Nagios::Plugin->new(
+ usage => "Usage: %s [options] -H hostname",
+ license => "",
+ version => $VERSION,
+ blurb => 'This plugin uses the RabbitMQ management aliveness-check to send/receive a message through a vhost.',
+);
+
+$p->add_arg(spec => 'host|H=s',
+ help => "Specify the host to connect to",
+ required => 1
+);
+$p->add_arg(spec => 'port=i',
+ help => "Specify the port to connect to (default: %s)",
+ default => 55672
+);
+
+$p->add_arg(spec => 'user|u=s',
+ help => "Username (default: %s)",
+ default => "guest",
+);
+$p->add_arg(spec => 'password|p=s',
+ help => "Password (default: %s)",
+ default => "guest"
+);
+
+$p->add_arg(spec => 'vhost=s',
+ help => "Specify the vhost to test (default: %s)",
+ default => "/"
+);
+# Parse arguments and process standard ones (e.g. usage, help, version)
+$p->getopts;
+
+
+# perform sanity checking on command line options
+
+
+##############################################################################
+# check stuff.
+
+my $hostname=$p->opts->host;
+my $port=$p->opts->port;
+my $vhost=uri_escape($p->opts->vhost);
+
+my $url = "http://$hostname:$port/api/aliveness-test/$vhost";
+
+my $ua = LWP::UserAgent->new(env_proxy=>1);
+$ua->agent($PROGNAME.' ');
+$ua->timeout($p->opts->timeout);
+$ua->credentials("$hostname:$port",
+ "Management: Web UI", $p->opts->user, $p->opts->password);
+my $req = HTTP::Request->new(GET => $url);
+my $res = $ua->request($req);
+
+if (!$res->is_success) {
+ # Deal with standard error conditions - make the messages more sensible
+ if ($res->code == 400) {
+ my $bodyref = decode_json $res->content;
+ $p->nagios_exit(CRITICAL, $bodyref->{'reason'});
+ }
+ $res->code == 404 and $p->nagios_die("Not found: ".$p->opts->vhost);
+ $res->code == 401 and $p->nagios_die("Access refused: ".$p->opts->vhost);
+ if ($res->code < 200 or $res->code > 400 ) {
+ $p->nagios_exit(CRITICAL, "Received ".$res->status_line." for vhost: ".$p->opts->vhost);
+ }
+}
+
+my $bodyref = decode_json $res->content;
+$bodyref->{'status'} eq "ok" or $p->nagios_exit(CRITICAL, $res->content);
+my($code, $message) = (OK, "vhost: ".$p->opts->vhost);
+$p->nagios_exit(
+ return_code => $code,
+ message => $message
+);
+
+=head1 NAME
+
+check_rabbitmq_aliveness - Nagios plugin using RabbitMQ management API to
+check liveness by send/receive a message through a vhost
+
+=head1 SYNOPSIS
+
+check_rabbitmq_aliveness [options] -H hostname
+
+=head1 DESCRIPTION
+
+Use the management interface of RabbitMQ to check that the server is alive.
+It declares a test queue, then publishes and consumes a message.
+
+It uses Nagios::Plugin and accepts all standard Nagios options.
+
+=head1 OPTIONS
+
+=over
+
+=item -h | --help
+
+Display help text
+
+=item -v | --verbose
+
+Verbose output
+
+=item -t | --timeout
+
+Set a timeout for the check in seconds
+
+=item -H | --host
+
+The host to connect to
+
+=item --port
+
+The port to connect to (default: 55672)
+
+=item --vhost
+
+The vhost to create the test queue within (default: /)
+
+=item --user
+
+The user to connect as (default: guest)
+
+=item --pass
+
+The password for the user (default: guest)
+
+=back
+
+=head1 EXAMPLES
+
+The defaults all work with a standard fresh install of RabbitMQ, and all that
+is needed is to specify the host to connect to:
+
+ check_rabbitmq_aliveness -H rabbit.example.com
+
+This returns a standard Nagios result:
+
+ RABBITMQ_ALIVENESS OK - vhost: /
+
+You can choose a different vhost to use for the check also:
+
+ check_rabbitmq_aliveness -H rabbit.example.com --vhost /foo
+
+=head1 ERRORS
+
+The check tries to provide useful error messages on the status line for
+standard error conditions.
+
+Otherwise it returns the HTTP Error message returned by the management
+interface.
+
+=head1 EXIT STATUS
+
+Returns zero if check is OK otherwise returns standard Nagios exit codes to
+signify WARNING, UNKNOWN or CRITICAL state.
+
+=head1 SEE ALSO
+
+See Nagios::Plugin(3)
+
+The RabbitMQ management plugin is described at
+http://www.rabbitmq.com/management.html
+
+=head1 LICENSE
+
+This file is part of nagios-plugins-rabbitmq.
+
+Copyright 2010, Platform 14.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+=head1 AUTHOR
+
+James Casey
+
+=cut
+
+1;
\ No newline at end of file
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/plugins/check_rabbitmq_objects b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/plugins/check_rabbitmq_objects
new file mode 100755
index 00000000000..e11a42ca15d
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/plugins/check_rabbitmq_objects
@@ -0,0 +1,230 @@
+#!/usr/bin/env perl
+#
+# check_rabbitmq_objects
+#
+# Use the management APIs to count various server objects -
+# vhost, exchange, binding, queue, channel
+#
+use strict;
+use warnings;
+
+use Nagios::Plugin ;
+use LWP::UserAgent;
+use URI::Escape;
+use JSON;
+
+use vars qw($VERSION $PROGNAME $verbose $timeout);
+$VERSION = '1.0';
+
+# get the base name of this script for use in the examples
+use File::Basename;
+$PROGNAME = basename($0);
+
+my $p = Nagios::Plugin->new(
+ usage => "Usage: %s [options] -H hostname",
+ license => "",
+ version => $VERSION,
+ blurb => 'This plugin uses the RabbitMQ management to count various objects.',
+);
+
+$p->add_arg(spec => 'host|H=s',
+ help => "Specify the host to connect to",
+ required => 1
+);
+$p->add_arg(spec => 'port=i',
+ help => "Specify the port to connect to (default: %s)",
+ default => 55672
+);
+
+$p->add_arg(spec => 'user|u=s',
+ help => "Username (default: %s)",
+ default => "guest",
+);
+$p->add_arg(spec => 'password|p=s',
+ help => "Password (default: %s)",
+ default => "guest"
+);
+
+
+# Parse arguments and process standard ones (e.g. usage, help, version)
+$p->getopts;
+
+
+# perform sanity checking on command line options
+
+
+##############################################################################
+# check stuff.
+
+my $hostname=$p->opts->host;
+my $port=$p->opts->port;
+
+my $ua = LWP::UserAgent->new(env_proxy=>1);
+$ua->agent($PROGNAME.' ');
+$ua->timeout($p->opts->timeout);
+$ua->credentials("$hostname:$port",
+ "Management: Web UI", $p->opts->user, $p->opts->password);
+
+my @calls = ("vhost", "exchange", "binding", "queue", "channel");
+for my $call (@calls) {
+ my $url = sprintf("http://%s:%d/api/%ss", $hostname, $port, $call);
+ my ($code, $result) = request($url);
+ if ($code != 200) {
+ $p->nagios_exit(CRITICAL, "$result : /api/". $call."s");
+ }
+ # we're always returned a list - count it
+ my $count = $#{$result};
+ $count = 0 if $count == -1;
+ $p->add_message(OK, sprintf("$call (%.2f%%)", $count)) ;
+ $p->add_perfdata(label=>$call, value => $count);
+
+}
+
+$p->nagios_exit(return_code => OK, message => "Gathered Object Counts");
+
+sub request {
+ my ($url) = @_;
+ my $req = HTTP::Request->new(GET => $url);
+ my $res = $ua->request($req);
+
+ if (!$res->is_success) {
+ # Deal with standard error conditions - make the messages more sensible
+ if ($res->code == 400) {
+ my $bodyref = decode_json $res->content;
+ return (400, $bodyref->{'reason'});
+
+ }
+ $res->code == 404 and return (404, "Not Found");
+ $res->code == 401 and return (401, "Access Refused");
+ $res->status_line =~ /Can\'t connect/ and return (500, "Connection Refused : $url");
+ if ($res->code < 200 or $res->code > 400 ) {
+ return ($res->code, "Received ".$res->status_line);
+ }
+ }
+ my $bodyref = decode_json $res->content;
+ return($res->code, $bodyref);
+}
+
+=head1 NAME
+
+check_rabbitmq_objects - Nagios plugin using RabbitMQ management API to
+count the number of various broker objects
+
+=head1 SYNOPSIS
+
+check_rabbitmq_objects [options] -H hostname
+
+=head1 DESCRIPTION
+
+Use the management interface of RabbitMQ to count the number of various
+broker objects. These are published as performance metrics for the check.
+
+Currently the following objects are counted:
+
+=over
+
+=item * vhost
+
+=item * exchange
+
+=item * binding
+
+=item * queue
+
+=item * channel
+
+=back
+
+It uses Nagios::Plugin and accepts all standard Nagios options.
+
+=head1 OPTIONS
+
+=over
+
+=item -h | --help
+
+Display help text
+
+=item -v | --verbose
+
+Verbose output
+
+=item -t | --timeout
+
+Set a timeout for the check in seconds
+
+=item -H | --host
+
+The host to connect to
+
+=item --port
+
+The port to connect to (default: 55672)
+
+=item --user
+
+The user to connect as (default: guest)
+
+=item --pass
+
+The password for the user (default: guest)
+
+=back
+
+=head1 EXAMPLES
+
+The defaults all work with a standard fresh install of RabbitMQ, and all that
+is needed is to specify the host to connect to:
+
+ check_rabbitmq_objects -H rabbit.example.com
+
+This returns a standard Nagios result:
+
+ RABBITMQ_OBJECTS OK - Gathered Object Counts | vhost=1;; exchange=7;;
+ binding=2;; queue=1;; channel=0;;
+
+=head1 ERRORS
+
+The check tries to provide useful error messages on the status line for
+standard error conditions.
+
+Otherwise it returns the HTTP Error message returned by the management
+interface.
+
+=head1 EXIT STATUS
+
+Returns zero if check is OK otherwise returns standard Nagios exit codes to
+signify WARNING, UNKNOWN or CRITICAL state.
+
+=head1 SEE ALSO
+
+See Nagios::Plugin(3)
+
+The RabbitMQ management plugin is described at
+http://www.rabbitmq.com/management.html
+
+=head1 LICENSE
+
+This file is part of nagios-plugins-rabbitmq.
+
+Copyright 2010, Platform 14.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+=head1 AUTHOR
+
+James Casey
+
+=cut
+
+1;
\ No newline at end of file
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/plugins/check_rabbitmq_overview b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/plugins/check_rabbitmq_overview
new file mode 100755
index 00000000000..32f871346e6
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/plugins/check_rabbitmq_overview
@@ -0,0 +1,271 @@
+#!/usr/bin/env perl
+#
+# check_rabbitmq_overview
+#
+# Use the management APIs to count pending messages in broker
+#
+use strict;
+use warnings;
+
+use Nagios::Plugin qw(%STATUS_TEXT OK CRITICAL WARNING UNKNOWN);
+use LWP::UserAgent;
+use URI::Escape;
+use JSON;
+
+use vars qw($VERSION $PROGNAME $verbose $timeout);
+$VERSION = '1.0';
+
+# get the base name of this script for use in the examples
+use File::Basename;
+$PROGNAME = basename($0);
+
+my $p = Nagios::Plugin->new(
+ usage => "Usage: %s [options] -H hostname",
+ license => "",
+ version => $VERSION,
+ blurb => 'This plugin uses the RabbitMQ management to count messages in server.',
+);
+
+$p->add_arg(spec => 'host|H=s',
+ help => "Specify the host to connect to",
+ required => 1
+);
+$p->add_arg(spec => 'port=i',
+ help => "Specify the port to connect to (default: %s)",
+ default => 55672
+);
+
+$p->add_arg(spec => 'user|u=s',
+ help => "Username (default: %s)",
+ default => "guest",
+);
+$p->add_arg(spec => 'password|p=s',
+ help => "Password (default: %s)",
+ default => "guest"
+);
+
+$p->add_arg(
+ spec => 'warning|w=s',
+ help =>
+qq{-w, --warning=INTEGER,INTEGER,INTEGER
+ Warning thresholds specified in order that the metrics are returned.
+ Specify -1 if no warning threshold.},
+
+);
+
+$p->add_arg(
+ spec => 'critical|c=s',
+ help =>
+qq{-c, --critical=INTEGER,INTEGER,INTEGER
+ Critical thresholds specified in order that the metrics are returned.
+ Specify -1 if no critical threshold.},
+);
+
+# Parse arguments and process standard ones (e.g. usage, help, version)
+$p->getopts;
+
+
+# perform sanity checking on command line options
+my %warning;
+if (defined $p->opts->warning) {
+ my @warning = split(',', $p->opts->warning);
+ $p->nagios_die("You should specify three ranges for --warning argument") unless $#warning == 2;
+
+ $warning{'messages'} = shift @warning;
+ $warning{'messages_ready'} = shift @warning;
+ $warning{'messages_unacknowledged'} = shift @warning;
+}
+
+my %critical;
+if (defined $p->opts->critical) {
+ my @critical = split(',', $p->opts->critical);
+ $p->nagios_die("You should specify three ranges for --critical argument") unless $#critical == 2;
+
+ $critical{'messages'} = shift @critical;
+ $critical{'messages_ready'} = shift @critical;
+ $critical{'messages_unacknowledged'} = shift @critical;
+}
+
+
+##############################################################################
+# check stuff.
+
+my $hostname=$p->opts->host;
+my $port=$p->opts->port;
+
+my $ua = LWP::UserAgent->new(env_proxy=>1);
+$ua->agent($PROGNAME.' ');
+$ua->timeout($p->opts->timeout);
+$ua->credentials("$hostname:$port",
+ "Management: Web UI", $p->opts->user, $p->opts->password);
+
+
+my $url = sprintf("http://%s:%d/api/overview", $hostname, $port);
+my ($retcode, $result) = request($url);
+if ($retcode != 200) {
+ $p->nagios_exit(CRITICAL, "$result : /api/overview");
+}
+
+my @metrics = ( "messages", "messages_ready", "messages_unacknowledged");
+for my $metric (@metrics) {
+ my $warning = undef;
+ $warning = $warning{$metric} if (defined $warning{$metric} and $warning{$metric} != -1);
+ my $critical = undef;
+ $critical = $critical{$metric} if (defined $critical{$metric} and $critical{$metric} != -1);
+
+ my $value = $result->{'queue_totals'}->{$metric};
+ my $code = $p->check_threshold(check => $value, warning => $warning, critical=> $critical);
+ $p->add_message($code, sprintf("$metric ".$STATUS_TEXT{$code}." (%d)", $value)) ;
+ $p->add_perfdata(label=>$metric, value => $value, warning=>$warning, critical=> $critical);
+}
+
+my ($code, $message) = $p->check_messages(join_all=>', ');
+$p->nagios_exit(return_code => $code, message => $message);
+
+
+sub request {
+ my ($url) = @_;
+ my $req = HTTP::Request->new(GET => $url);
+ my $res = $ua->request($req);
+
+ if (!$res->is_success) {
+ # Deal with standard error conditions - make the messages more sensible
+ if ($res->code == 400) {
+ my $bodyref = decode_json $res->content;
+ return (400, $bodyref->{'reason'});
+
+ }
+ $res->code == 404 and return (404, "Not Found");
+ $res->code == 401 and return (401, "Access Refused");
+ $res->status_line =~ /Can\'t connect/ and return (500, "Connection Refused : $url");
+ if ($res->code < 200 or $res->code > 400 ) {
+ return ($res->code, "Received ".$res->status_line);
+ }
+ }
+ my $bodyref = decode_json $res->content;
+ return($res->code, $bodyref);
+}
+
+=head1 NAME
+
+check_rabbitmq_overview - Nagios plugin using RabbitMQ management API to
+count the messages pending on the broker
+
+=head1 SYNOPSIS
+
+check_rabbitmq_overview [options] -H hostname
+
+=head1 DESCRIPTION
+
+Use the management interface of RabbitMQ to count the number of pending,
+ready and unacknowledged messages. These are published as performance
+metrics for the check.
+
+Critical and warning thresholds can be set for each of the metrics.
+
+It uses Nagios::Plugin and accepts all standard Nagios options.
+
+=head1 OPTIONS
+
+=over
+
+=item -h | --help
+
+Display help text
+
+=item -v | --verbose
+
+Verbose output
+
+=item -t | --timeout
+
+Set a timeout for the check in seconds
+
+=item -H | --host
+
+The host to connect to
+
+=item --port
+
+The port to connect to (default: 55672)
+
+=item --user
+
+The user to connect as (default: guest)
+
+=item --pass
+
+The password for the user (default: guest)
+
+=item -w | --warning
+
+The warning levels for each count of messages, messages_ready and
+messages_unacknowledged. This field consists of three comma-separated
+integers. Specify -1 if no threshold for a particular count.
+
+=item -c | --critical
+
+The critical levels for each count of messages, messages_ready and
+messages_unacknowledged. This field consists of three comma-separated
+integers. Specify -1 if no threshold for a particular count
+
+=back
+
+=head1 EXAMPLES
+
+The defaults all work with a standard fresh install of RabbitMQ, and all that
+is needed is to specify the host to connect to:
+
+ check_rabbitmq_overview -H rabbit.example.com
+
+This returns a standard Nagios result:
+
+ RABBITMQ_OVERVIEW OK - messages OK (25794) messages_ready OK (22971)
+ messages_unacknowledged OK (2823) | messages=25794;;
+ messages_ready=22971;; messages_unacknowledged=2823;;
+
+=head1 ERRORS
+
+The check tries to provide useful error messages on the status line for
+standard error conditions.
+
+Otherwise it returns the HTTP Error message returned by the management
+interface.
+
+=head1 EXIT STATUS
+
+Returns zero if check is OK otherwise returns standard Nagios exit codes to
+signify WARNING, UNKNOWN or CRITICAL state.
+
+=head1 SEE ALSO
+
+See Nagios::Plugin(3)
+
+The RabbitMQ management plugin is described at
+http://www.rabbitmq.com/management.html
+
+=head1 LICENSE
+
+This file is part of nagios-plugins-rabbitmq.
+
+Copyright 2010, Platform 14.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+=head1 AUTHOR
+
+James Casey
+
+=cut
+
+1;
\ No newline at end of file
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/plugins/check_rabbitmq_server b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/plugins/check_rabbitmq_server
new file mode 100755
index 00000000000..ae1c684cc6d
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/plugins/check_rabbitmq_server
@@ -0,0 +1,288 @@
+#!/usr/bin/env perl
+
+### check_rabbitmq_aliveness.pl
+
+# Use the management overview to check server statistics
+
+##############################################################################
+# prologue
+use strict;
+use warnings;
+
+use Nagios::Plugin qw(%STATUS_TEXT OK CRITICAL WARNING UNKNOWN);
+use LWP::UserAgent;
+use URI::Escape;
+use JSON;
+
+use Data::Dumper;
+
+use vars qw($VERSION $PROGNAME $verbose $timeout $code $message);
+$VERSION = '1.0';
+
+# get the base name of this script for use in the examples
+use File::Basename;
+$PROGNAME = basename($0);
+
+
+##############################################################################
+# define and get the command line options.
+# see the command line option guidelines at
+# http://nagiosplug.sourceforge.net/developer-guidelines.html#PLUGOPTIONS
+
+
+# Instantiate Nagios::Plugin object (the 'usage' parameter is mandatory)
+my $p = Nagios::Plugin->new(
+ usage => "Usage: %s [options] -H hostname",
+ license => "",
+ version => $VERSION,
+ blurb => 'This plugin uses the RabbitMQ management node API to check server process parameters.',
+);
+
+$p->add_arg(spec => 'host|H=s',
+ help => "Specify the host to connect to",
+ required => 1
+);
+$p->add_arg(spec => 'port|p=i',
+ help => "Specify the port to connect to (default: %s)",
+ default => 55672
+);
+
+$p->add_arg(
+ spec => 'warning|w=s',
+
+ help =>
+qq{-w, --warning=INTEGER,INTEGER,INTEGER
+ Warning thresholds specified in order that the metrics are returned.
+ (Default : %s)},
+# required => 1,
+ default => "80,80,80",
+);
+
+$p->add_arg(
+ spec => 'critical|c=s',
+ help =>
+qq{-c, --critical=INTEGER,INTEGER,INTEGER
+ Warning thresholds specified in order that the metrics are returned.
+ (Default: %s) },
+ default => "90,90,90",
+);
+
+$p->add_arg(spec => 'user|u=s',
+ help => "Username (default: %s)",
+ default => "guest",
+);
+$p->add_arg(spec => 'password|p=s',
+ help => "Password (default: %s)",
+ default => "guest"
+);
+
+# Parse arguments and process standard ones (e.g. usage, help, version)
+$p->getopts;
+
+
+# Check we have three values for warning and critical thresholds
+my @warning = split(',', $p->opts->warning);
+$p->nagios_die("You should specify three ranges for --warning argument") unless $#warning == 2;
+
+my @critical = split(',', $p->opts->critical);
+$p->nagios_die("You should specify three ranges for --critical argument") unless $#critical == 2;
+
+##############################################################################
+# check stuff.
+
+my $hostname = $p->opts->host;
+$hostname =~ /^([a-zA-Z0-9-]*)/;
+my $shortname=$1;
+my $port = $p->opts->port;
+
+my $path = "nodes/rabbit\@$shortname";
+my $url = "http://$hostname:$port/api/$path";
+
+my $ua = LWP::UserAgent->new(env_proxy=>1);
+$ua->agent($PROGNAME.' ');
+$ua->timeout($p->opts->timeout);
+$ua->credentials("$hostname:$port",
+ "Management: Web UI", $p->opts->user, $p->opts->password);
+my $req = HTTP::Request->new(GET => $url);
+my $res = $ua->request($req);
+
+if (!$res->is_success) {
+ # Deal with standard error conditions - make the messages more sensible
+ if ($res->code == 400) {
+ my $bodyref = decode_json $res->content;
+ $p->nagios_exit(CRITICAL, $bodyref->{'reason'});
+ }
+ $res->code == 404 and $p->nagios_die("Not found: ".$path);
+ $res->code == 401 and $p->nagios_die("Access refused: ".$path);
+ if ($res->code < 200 or $res->code > 400 ) {
+ $p->nagios_exit(CRITICAL, "Received ".$res->status_line." for path: ".$path);
+ }
+}
+
+my $bodyref = decode_json $res->content;
+check($p, "Memory", $bodyref->{'mem_used'}, $bodyref->{'mem_limit'}, $warning[0], $critical[0]);
+check($p, "Process", $bodyref->{'proc_used'}, $bodyref->{'proc_total'}, $warning[1], $critical[1]);
+check($p, "FD", $bodyref->{'fd_used'}, $bodyref->{'fd_total'}, $warning[2], $critical[2]);
+
+($code, $message) = $p->check_messages(join_all=>', ');
+$p->nagios_exit( return_code=>$code, message=>$message);
+
+
+sub check {
+ my $p = shift;
+ my $label = shift;
+ my $used = shift;
+ my $limit = shift;
+ my $warning = shift;
+ my $critical = shift;
+
+ my $value = percent($used, $limit);
+ my $code = $p->check_threshold(check => $value, warning => $warning, critical => $critical);
+ $p->add_message($code, sprintf("$label ".$STATUS_TEXT{$code}." (%.2f%%)", $value)) ;
+ $p->add_perfdata(label=>$label, value => $value, uom=>"%", warning=>$warning, critical=>$critical);
+}
+
+sub percent {
+ my $num = shift;
+ my $denom = shift;
+ return (10000 * $num/ $denom)%1000/100;
+}
+
+sub structured {
+ my $content = shift;
+ $Data::Dumper::Terse = 1; # don't output names where feasible
+ $Data::Dumper::Indent = 2;
+ return Dumper($content);
+}
+
+=head1 NAME
+
+check_rabbitmq_server - Nagios plugin using RabbitMQ management API to
+check the server resource usage (processes, memory and file descriptors)
+
+=head1 SYNOPSIS
+
+check_rabbitmq_server [options] -H hostname
+
+=head1 DESCRIPTION
+
+Use the management interface of RabbitMQ to check the resource usage of the
+server. This check looks at the node statistics for the rabbit node on
+the host and examines the erlang memory, process and file descriptor usage.
+
+It provides performance data for each of these variables and allows for
+warning and criticality levels to be specified for each.
+
+It uses Nagios::Plugin and accepts all standard Nagios options.
+
+=head1 OPTIONS
+
+=over
+
+=item -h | --help
+
+Display help text
+
+=item -v | --verbose
+
+Verbose output
+
+=item -t | --timeout
+
+Set a timeout for the check in seconds
+
+=item -H | --host
+
+The host to connect to
+
+=item --port
+
+The port to connect to (default: 55672)
+
+=item -w | --warning
+
+The warning levels, expressed as a percentage for each of memory, process
+and file descriptor usage. This field consists of three comma-separated
+integers. (default: 90,90,90)
+
+=item -c | --critical
+
+The critical levels, expressed as a percentage for each of memory, process
+and file descriptor usage. This field consists of three comma-separated
+integers. (default: 90,90,90)
+
+=item --user
+
+The user to connect as (default: guest)
+
+=item --pass
+
+The password for the user (default: guest)
+
+=back
+
+=head1 EXAMPLES
+
+The defaults all work with a standard fresh install of RabbitMQ, and all that
+is needed is to specify the host to connect to:
+
+ check_rabbitmq_server -H rabbit.example.com
+
+This returns a standard Nagios result:
+
+ RABBITMQ_SERVER OK - Memory OK (6.19%) Process OK (0.01%)
+ FD OK (2.53%) | Memory=6.19%;80;90 Process=0.01%;80;90 FD=2.53%;80;90
+
+You can specify different warning and criticality levels. B<-w> and B<-c>
+both accept three comma-separated percentages which represent the
+thresholds for memory, process and file descriptor usage respectively. For
+example, to specify warnings for memory at 60%, process at 80% and file
+descriptors at 95%:
+
+ check_rabbitmq_server -H rabbit.example.com -w 60,80,95
+
+=head1 ERRORS
+
+The check tries to provide useful error messages on the status line for
+standard error conditions.
+
+Otherwise it returns the HTTP Error message returned by the management
+interface.
+
+=head1 EXIT STATUS
+
+Returns zero if check is OK otherwise returns standard Nagios exit codes to
+signify WARNING, UNKNOWN or CRITICAL state.
+
+=head1 SEE ALSO
+
+See Nagios::Plugin(3)
+
+The RabbitMQ management plugin is described at
+http://www.rabbitmq.com/management.html
+
+=head1 LICENSE
+
+This file is part of nagios-plugins-rabbitmq.
+
+Copyright 2010, Platform 14.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+=head1 AUTHOR
+
+James Casey
+
+=cut
+
+1;
\ No newline at end of file
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/plugins/check_solr.rb b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/plugins/check_solr.rb
new file mode 100644
index 00000000000..e2689f0bb15
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/plugins/check_solr.rb
@@ -0,0 +1,117 @@
+#!/usr/bin/env ruby
+#
+# Nagios check for Solr server health
+# Copyright 37signals, 2008
+# Author: Joshua Sierles (joshua@37signals.com)
+
+require 'rubygems'
+require 'xmlsimple'
+require 'net/http'
+require 'uri'
+require 'choice'
+
+EXIT_OK = 0
+EXIT_WARNING = 1
+EXIT_CRITICAL = 2
+EXIT_UNKNOWN = 3
+
+Choice.options do
+ header ''
+ header 'Specific options:'
+
+ option :warn do
+ short '-w'
+ long '--warning=VALUE'
+ desc 'Warning threshold'
+ cast Integer
+ end
+
+ option :crit do
+ short '-c'
+ long '--critical=VALUE'
+ desc 'Critical threshold'
+ cast Integer
+ end
+
+ option :host do
+ short '-h'
+ long '--host=VALUE'
+ desc 'Solr host'
+ end
+
+ option :prefix do
+ short '-p'
+ long '--prefix=VALUE'
+ desc 'App prefix'
+ end
+
+ option :start do
+ short '-s'
+ long '--start=VALUE'
+ desc 'Start index'
+ end
+
+ option :rows do
+ short '-r'
+ long '--rows=VALUE'
+ desc 'Number of rows to check for'
+ default 10
+ end
+
+ option :query do
+ short '-q'
+ long '--query=VALUE'
+ desc 'Query term to search for'
+ default "test%0D%0A"
+ end
+
+ option :version do
+ short '-v'
+ long '--version=VALUE'
+ desc 'Specify version'
+ default "2.2"
+ end
+end
+
+c = Choice.choices
+
+message = "Solr reports %d rows"
+
+if c[:crit]
+
+ value = 0
+ begin
+ url = URI.parse("http://#{c[:host]}:8983/")
+ res = Net::HTTP.start(url.host, url.port) do |http|
+ http.get("/#{c[:prefix]}/select/?q=#{c[:query]}&version=#{c[:version]}&start=#{c[:start]}&rows=#{c[:rows]}&indent=on")
+ end
+
+ solr = XmlSimple.xml_in(res.body, { 'ForceArray' => false, 'KeepRoot' => false })
+ solr['lst']['lst']['str'].each do |str|
+ next unless str['name'] == 'rows'
+ value = str['content'].to_i
+ end
+ rescue Exception => e
+ puts "Error checking Solr: #{e.message}"
+ exit(EXIT_UNKNOWN)
+ end
+
+
+ if value != c[:crit]
+ puts sprintf(message, value)
+ exit(EXIT_CRITICAL)
+ end
+
+ if c[:warn] && value >= c[:warn]
+ puts sprintf(message, value)
+ exit(EXIT_WARNING)
+ end
+
+else
+ puts "Please provide a critical threshold"
+ exit
+end
+
+# if warning nor critical trigger, say OK and return performance data
+
+puts sprintf("Solr is OK, reports %d rows", value)
\ No newline at end of file
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/plugins/db_queues.rb b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/plugins/db_queues.rb
new file mode 100644
index 00000000000..7666b71ed3f
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/plugins/db_queues.rb
@@ -0,0 +1,96 @@
+#!/usr/bin/env ruby
+#
+# Check the size of a database queue
+#
+
+require 'rubygems'
+require 'choice'
+require 'mysql'
+
+EXIT_OK = 0
+EXIT_WARNING = 1
+EXIT_CRITICAL = 2
+EXIT_UNKNOWN = 3
+
+Choice.options do
+ header ''
+ header 'Specific options:'
+
+ option :warn do
+ short '-w'
+ long '--warning=VALUE'
+ desc 'Warning threshold'
+ cast Integer
+ end
+
+ option :crit do
+ short '-c'
+ long '--critical=VALUE'
+ desc 'Critical threshold'
+ cast Integer
+ end
+
+ option :host do
+ short '-H'
+ long '--host=VALUE'
+ desc 'MySQL DB host'
+ end
+
+ option :username do
+ short '-u'
+ long '--username=VALUE'
+ desc 'MySQL DB username'
+ end
+
+ option :password do
+ short '-p'
+ long '--password=VALUE'
+ desc 'MySQL DB password'
+ end
+
+ option :database do
+ short '-d'
+ long '--database=VALUE'
+ desc 'MySQL database'
+ end
+
+ option :query do
+ short '-q'
+ long '--query=VALUE'
+ desc 'MySQL DB count query'
+ end
+
+end
+
+c = Choice.choices
+
+# nagios performance data format: 'label'=value[UOM];[warn];[crit];[min];[max]
+# see http://nagiosplug.sourceforge.net/developer-guidelines.html#AEN203
+
+perfdata = "query_count=%d;#{c[:warn]};#{c[:crit]}"
+message = "Query '#{c[:query]}' result %d exceeds %d|#{perfdata}"
+
+if c[:warn] && c[:crit]
+
+ conn = Mysql::connect(c[:host], c[:username], c[:password], c[:database])
+ res = conn.query(c[:query])
+ value = res.fetch_row
+ value = value.first.to_i
+
+ if value >= c[:crit]
+ puts sprintf(message, value, c[:crit], value)
+ exit(EXIT_CRITICAL)
+ end
+
+ if value >= c[:warn]
+ puts sprintf(message, value, c[:warn], value)
+ exit(EXIT_WARNING)
+ end
+
+else
+ puts "Please provide a warning and critical threshold"
+end
+
+# if warning nor critical trigger, say OK and return performance data
+
+puts sprintf("Query '#{c[:query]}' result %d OK|#{perfdata}", value, value)
\ No newline at end of file
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/plugins/file_queues.rb b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/plugins/file_queues.rb
new file mode 100644
index 00000000000..72609503c6e
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/plugins/file_queues.rb
@@ -0,0 +1,84 @@
+#!/usr/bin/env ruby
+#
+# Nagios check
+# Check 'work queue' directories by file count or age of oldest file
+#
+
+require 'rubygems'
+require 'choice'
+
+EXIT_OK = 0
+EXIT_WARNING = 1
+EXIT_CRITICAL = 2
+EXIT_UNKNOWN = 3
+
+Choice.options do
+ header ''
+ header 'Specific options:'
+
+ option :warn do
+ short '-w'
+ long '--warning=VALUE'
+ desc 'Warning threshold'
+ cast Integer
+ end
+
+ option :crit do
+ short '-c'
+ long '--critical=VALUE'
+ desc 'Critical threshold'
+ cast Integer
+ end
+
+ option :path do
+ short '-p'
+ long '--path=VALUE'
+ desc 'Path to directory'
+ end
+
+ option :type do
+ short '-t'
+ long '--type=VALUE'
+ desc 'Either "age" (threshold of oldest file age in seconds) or "count" (number of files in direcrory)'
+ valid %w(age count)
+ end
+
+end
+
+c = Choice.choices
+
+# nagios performance data format: 'label'=value[UOM];[warn];[crit];[min];[max]
+# see http://nagiosplug.sourceforge.net/developer-guidelines.html#AEN203
+
+
+if c[:warn] && c[:crit]
+
+ if c[:type] == 'count'
+ perfdata = "file_count=%d;#{c[:warn]};#{c[:crit]}"
+ message = "File count %d for #{c[:path]} exceeds %d|#{perfdata}"
+ ok_message = "File count for %d for '#{c[:path]}' OK|#{perfdata}"
+ value = Dir.open(c[:path]).entries.size
+ else
+ perfdata = "oldest_file_age=%ds;#{c[:warn]};#{c[:crit]}"
+ message = "Oldest file age (%d seconds) in #{c[:path]} exceeds %d|#{perfdata}"
+ ok_message = "Oldest file age (%d seconds) for #{c[:path]} OK|#{perfdata}"
+ value = Dir.open(c[:path]).entries.collect {|f| Time.now - File.stat(File.join(c[:path], f)).mtime }.sort.last
+ end
+
+ if value >= c[:crit]
+ puts sprintf(message, value, c[:crit], value)
+ exit(EXIT_CRITICAL)
+ end
+
+ if value >= c[:warn]
+ puts sprintf(message, value, c[:warn], value)
+ exit(EXIT_WARNING)
+ end
+
+else
+ puts "Please provide a warning and critical threshold"
+end
+
+# if warning nor critical trigger, say OK and return performance data
+
+puts sprintf(ok_message, value, value)
\ No newline at end of file
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/plugins/nagios_helper.rb b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/plugins/nagios_helper.rb
new file mode 100644
index 00000000000..46003ab2a23
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/files/default/plugins/nagios_helper.rb
@@ -0,0 +1,26 @@
+require 'rubygems'
+require 'choice'
+
+module NagiosHelper
+ EXIT_OK = 0
+ EXIT_WARNING = 1
+ EXIT_CRITICAL = 2
+ EXIT_UNKNOWN = 3
+
+ def warning(text)
+ puts "WARNING: #{text}"
+ exit EXIT_WARNING
+ end
+
+ def critical(text)
+ puts "CRITICAL: #{text}"
+ exit EXIT_CRITICAL
+ end
+
+ def unknown(text)
+ puts "ERROR #{text}"
+ exit EXIT_UNKNOWN
+ end
+
+end
+
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/libraries/default.rb b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/libraries/default.rb
new file mode 100644
index 00000000000..ab351a67e93
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/libraries/default.rb
@@ -0,0 +1,60 @@
+#
+# Author:: Joshua Sierles
+# Cookbook Name:: nagios
+# Library:: default
+#
+# Copyright 2009, 37signals
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+def nagios_boolean(true_or_false)
+ true_or_false ? "1" : "0"
+end
+
+def nagios_interval(seconds)
+ if seconds.to_i < node[:nagios][:interval_length].to_i
+ raise ArgumentError, "Specified nagios interval of #{seconds} seconds must be equal to or greater than the default interval length of #{node[:nagios][:interval_length]}"
+ end
+ interval = seconds / node[:nagios][:interval_length]
+ interval
+end
+
+def nagios_attr(name)
+ node[:nagios][name]
+end
+
+class Nagios
+class Evaluator
+
+ def initialize(node)
+ @b = binding
+ end
+
+ def eval_with_context(str)
+ eval(str,@b)
+ end
+
+ def log_eval_vars()
+ eval("Chef::Log.info('locals:'+local_variables.join(':') + '\nglobals:'+global_variables.join(':'))")
+ end
+
+ def self.get_value_by_type(node, type)
+ location = node[:nagios][type]
+ e = Evaluator.new(node)
+ val = e.eval_with_context(location)
+ Chef::Log.info("Looking at #{location} for #{type}. Got: #{val}")
+ val
+ end
+
+end
+end
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/metadata.json b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/metadata.json
new file mode 100644
index 00000000000..1a7108bbbc0
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/metadata.json
@@ -0,0 +1,48 @@
+{
+ "platforms": {
+ "debian": [
+
+ ],
+ "ubuntu": [
+
+ ]
+ },
+ "suggestions": {
+
+ },
+ "license": "Apache 2.0",
+ "conflicting": {
+
+ },
+ "long_description": "= DESCRIPTION:\n\nInstalls and configures Nagios 3 for a server and for clients using Chef 0.8 search capabilities.\n\n= REQUIREMENTS:\n\nRequires Chef 0.8+ for search capability of roles and data bags.\n\nA data bag named 'users' should exist, see \"DATA BAG\" below.\n\nThe monitoring server that uses this recipe should have a role named 'monitoring' or similar. A \"per-environment\" role should be created as well. See \"ROLES\" below.\n\nBecause of the heavy use of search, this recipe will not work with Chef Solo, as it cannot do any searches without a server.\n\n== Platform:\n\nTested on Ubuntu 9.04+ and Debian 5+.\n\n== Cookbooks:\n\n* apache2\n\n= ATTRIBUTES:\n\nAttributes under the 'nagios' namespace.\n\n== Client:\n\nThe following attributes are used for the client NRPE checks for warning and critical levels.\n\nchecks.memory.critical\nchecks.memory.warning\nchecks.load.critical\nchecks.load.warning\nchecks.smtp_host - default relayhost to check for connectivity. Default is an empty string, set via an attribute in a role.\nserver_role - the role that the nagios server will have in its run list that the clients can search for.\n\n== Server:\n\ndir - base server configuration directory.\nlog_dir - where the server logs.\ncache_dir - cached directory.\ndocroot - DocumentRoot for webui.\nconfig_subdir - for dropping in configurations as needed.\nnotifications_enabled - set to 1 to enable notification.\ncheck_external_commands\ndefault_contact_groups\nsysadmin_email - default notification email.\nsysadmin_sms_email - default notification sms.\nserver_auth_method - authentication with the server can be done with openid (using apache2::mod_auth_openid), or htauth (basic). The default is openid, any other value will use htauth (basic).\ntemplates\ninterval_length - minimum interval.\ndefault_host.check_interval\ndefault_host.retry_interval\ndefault_host.max_check_attempts\ndefault_host.notification_interval\ndefault_service.check_interval\ndefault_service.retry_interval\ndefault_service.max_check_attempts\ndefault_service.notification_interval\n\n= DATA BAGS:\n\nCreate a `users` data bag that will contain the users that will be able to log into the Nagios webui. Each user can use htauth with a specified password, or an openid. Users that should be able to log in should be in the sysadmin group. Example user data bag item:\n\n {\n \"id\": \"nagiosadmin\",\n \"groups\": \"sysadmin\",\n \"htpasswd\": \"hashed_htpassword\",\n \"openid\": \"http://nagiosadmin.myopenid.com/\",\n \"nagios\": {\n \"pager\": \"nagiosadmin_pager@example.com\",\n \"email\": \"nagiosadmin@example.com\"\n }\n }\n\nWhen using server_auth_method 'openid', use the openid in the data bag item. Any other value for this attribute (e.g., \"htauth\", \"htpasswd\", etc) will use the htpasswd value as the password in `/etc/nagios3/htpasswd.users`.\n\nThe openid must have the http:// and trailing /. The htpasswd must be the hashed value. Get this value with:\n\n % htpasswd -n nagiosadmin\n New password:\n Re-type new password:\n nagiosadmin:mbfzZrHsUUjds\n\nFor example use the \"mbfzZrHsUUjds\" value in the data bag.\n\n= ROLES:\n\nCreate a role to use for the monitoring server. The role name should match the value of the attribute \"nagios[:server_role]\". By default, this is 'monitoring'. For example:\n\n % cat roles/monitoring.rb\n name \"monitoring\"\n description \"Monitoring server\"\n run_list(\n \"recipe[nagios::server]\"\n )\n\n default_attributes(\n \"nagios\" => {\n \"server_auth_method\" => \"htauth\"\n }\n )\n\nAlso create per-environment role. For example, production nodes:\n\n % cat roles/production.rb\n name \"production\"\n description \"Nodes in the production environment.\"\n default_attributes(\n \"app_environment\" => \"production\"\n )\n\nMake sure to apply the production role to all nodes that should be monitored by the production monitoring server.\n\n= USAGE:\n\nFor a Nagios server, create a role named 'monitoring', and add the following recipe to the run_list:\n\n recipe[nagios::server]\n\nThis will allow client nodes to search for the server by this role and add its IP address to the allowed list for NRPE.\n\nTo install Nagios and NRPE on a client node:\n\n include_recipe \"nagios::client\"\n\nThis is a fairly complicated cookbook. We'll describe the components in detail.\n\n== Definitions:\n\nnagios_conf:: This definition is used to drop in a configuration file in the base Nagios configuration directory's conf.d. This can be used for customized configurations for various services.\n\n== Libraries:\n\ndefault:: The library included with the cookbook provides some helper methods used in templates.\n\n* nagios_boolean\n* nagios_interval - calculates interval based on interval length and a given number of seconds.\n* nagios_attr - retrieves a nagios attribute from the node.\n\n== Recipes:\n\n=== Client\n\nThe client recipe searches for allowed servers via a role named 'monitoring'. The recipe will also install the required packages and start the NRPE service. A custom plugin for checking memory is also added.\n\nClient commands for NRPE can be modified by editing the nrpe.cfg.erb template.\n\n=== Server\n\nThe server recipe sets up Apache as the web front end. The nagios::client recipe is also included. This recipe also does a number of searches to dynamically build the hostgroups to monitor, hosts that belong to them and admins to notify of events/alerts.\n\nThe recipe does the following:\n\n1. Searches for members of the sysadmins group by searching through 'users' data bag and adds them to a list for notification/contacts.\n2. Search all nodes for a role matching the app_environment.\n3. Search all available roles and build a list which will be the Nagios hostgroups.\n4. Search for all nodes of each role and add the hostnames to the hostgroups.\n5. Installs various packages required for the server.\n6. Sets up some configuration directories.\n7. Moves the package-installed Nagios configuration to a 'dist' directory.\n8. Disables the 000-default site (present on Debian/Ubuntu Apache2 package installations).\n9. Enables the Nagios web front end configuration.\n10. Sets up the configuration templates for services, contacts, hostgroups and hosts.\n\n*NOTE*: You will probably need to change the services.cfg.erb template for your environment.\n\nTo add custom commands for service checks, these can be done on a per-role basis by editing the 'services.cfg.erb' template. This template has some pre-configured checks that use role names used in an example infrastructure. Here's a brief description:\n\n* monitoring - check_smtp (e.g., postfix relayhost) w/ NRPE and tcp port 514 (e.g., rsyslog)\n* load_balancer - check_nginx with NRPE.\n* appserver - check_unicorn with NRPE, e.g. a Rails application using Unicorn.\n* database_master - check_mysql_server with NRPE for a MySQL database master.\n\n= LICENSE and AUTHOR:\n\nAuthor:: Joshua Sierles \nAuthor:: Nathan Haneysmith \nAuthor:: Joshua Timberman \n\nCopyright 2009, 37signals\nCopyright 2009-2010, Opscode, Inc\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
+ "providing": {
+
+ },
+ "description": "Installs and configures nagios",
+ "version": "0.4.4",
+ "maintainer": "Opscode, Inc.",
+ "replacing": {
+
+ },
+ "attributes": {
+
+ },
+ "maintainer_email": "cookbooks@opscode.com",
+ "name": "nagios",
+ "recipes": {
+ "nagios": "Includes the client recipe.",
+ "nagios::client": "Installs and configures a nagios client with nrpe",
+ "nagios::server": "Installs and configures a nagios server"
+ },
+ "groupings": {
+
+ },
+ "dependencies": {
+ "apache2": [
+
+ ]
+ },
+ "recommendations": {
+
+ }
+}
\ No newline at end of file
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/metadata.rb b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/metadata.rb
new file mode 100644
index 00000000000..15a0e1816bb
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/metadata.rb
@@ -0,0 +1,16 @@
+maintainer "Opscode, Inc."
+maintainer_email "cookbooks@opscode.com"
+license "Apache 2.0"
+description "Installs and configures nagios"
+long_description IO.read(File.join(File.dirname(__FILE__), 'README.rdoc'))
+version "0.4.4"
+
+recipe "nagios", "Includes the client recipe."
+recipe "nagios::client", "Installs and configures a nagios client with nrpe"
+recipe "nagios::server", "Installs and configures a nagios server"
+
+%w{ debian ubuntu }.each do |os|
+ supports os
+end
+
+depends "apache2"
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/recipes/client.rb b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/recipes/client.rb
new file mode 100644
index 00000000000..83c53209fed
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/recipes/client.rb
@@ -0,0 +1,107 @@
+#
+# Author:: Joshua Sierles
+# Author:: Joshua Timberman
+# Author:: Nathan Haneysmith
+# Cookbook Name:: nagios
+# Recipe:: client
+#
+# Copyright 2009, 37signals
+# Copyright 2009-2010, Opscode, Inc
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Base filter for our environment
+env_filter = " AND environment:#{node[:nagios][:config][:environment]}"
+
+# Find the provisioner ip # Assume provisioner is monitored by my nagios server
+nodes = search(:node, "roles:provisioner-server#{env_filter}")
+
+# Get a list of provisioner addresses
+prov_addresses = nodes.map { |n| Nagios::Evaluator.get_value_by_type(n, :admin_ip_eval) }
+
+# The master admin node is the first one in the list
+provisioner_ip = prov_addresses[0]
+admin_interface = Nagios::Evaluator.get_value_by_type(node, :admin_interface_eval)
+
+# Get the DNS domain name (i.e. pod.cloud.openstack.org)
+domain_name = node[:dns][:domain]
+
+# Create a list of monitoring hosts (filter duplicate ip's in the list)
+dup_list = Hash.new
+mon_host = Array.new
+search(:node, "role:nagios-server#{env_filter}") do |n|
+ ip = Nagios::Evaluator.get_value_by_type(n, :admin_ip_eval)
+ next if ip.nil?
+ if (!dup_list.has_key?(ip))
+ mon_host << ip
+ dup_list[ip] = ip
+ end
+end
+
+# Package/plugin install list
+%w{
+ nagios-nrpe-server
+ nagios-plugins
+ nagios-plugins-basic
+ nagios-plugins-standard
+ libjson-perl
+ libmath-calc-units-perl
+ libnagios-plugin-perl
+ libnagios-object-perl
+ libparams-validate-perl
+}.each do |pkg|
+ package pkg
+end
+
+# Service startup definition
+service "nagios-nrpe-server" do
+ action :enable
+ supports :restart => true, :reload => true
+end
+
+# Set directory ownership and permissions
+remote_directory "/usr/lib/nagios/plugins" do
+ source "plugins"
+ owner "nagios"
+ group "nagios"
+ mode 0755
+ files_mode 0755
+end
+
+# NTP server setup
+ntp_servers = node[:ntp][:ntp_servers] unless node[:ntp].nil? or node[:ntp][:ntp_servers].nil? or node[:ntp][:ntp_servers].empty?
+ntp_servers = "127.0.0.1" if node[:ntp].nil? or node[:ntp][:ntp_servers].nil? or node[:ntp][:ntp_servers].empty?
+
+#### setup variables for the different components
+# common
+vars = { :mon_host => mon_host, :provisioner_ip => provisioner_ip, :domain_name => domain_name, :admin_interface => admin_interface}
+# ntp
+vars.merge!({:ntp_servers => ntp_servers})
+
+template "/etc/nagios/nrpe.cfg" do
+ source "nrpe.cfg.erb"
+ owner "nagios"
+ group "nagios"
+ mode "0644"
+ variables(vars)
+ notifies :restart, resources(:service => "nagios-nrpe-server")
+end
+
+# Set file ownership and permissions
+file "/usr/lib/nagios/plugins/check_dhcp" do
+ mode "4755"
+ owner "root"
+ group "root"
+end
+
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/recipes/default.rb b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/recipes/default.rb
new file mode 100644
index 00000000000..ceb1a4ac29f
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/recipes/default.rb
@@ -0,0 +1,23 @@
+#
+# Author:: Joshua Timberman
+# Author:: Joshua Sierles
+# Cookbook Name:: nagios
+# Recipe:: default
+#
+# Copyright 2008-2009, Opscode, Inc
+# Copyright 2009, 37signals
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+include_recipe "nagios::client"
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/recipes/server.rb b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/recipes/server.rb
new file mode 100644
index 00000000000..f2f35f72286
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/recipes/server.rb
@@ -0,0 +1,201 @@
+#
+# Author:: Joshua Sierles
+# Author:: Joshua Timberman
+# Author:: Nathan Haneysmith
+# Cookbook Name:: nagios
+# Recipe:: server
+#
+# Copyright 2009, 37signals
+# Copyright 2009-2010, Opscode, Inc
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+include_recipe "apache2"
+include_recipe "apache2::mod_ssl"
+include_recipe "apache2::mod_rewrite"
+include_recipe "nagios::client"
+
+# Begin recipe transactions
+Chef::Log.debug("BEGIN nagios-server")
+
+# Get the config environment filter
+env_filter = " AND nagios_config_environment:#{node[:nagios][:config][:environment]}"
+Chef::Log.debug("env_filter [" + env_filter.to_s + "]")
+
+# Get the list of nodes
+nodes = search(:node, "roles:nagios-client#{env_filter}")
+Chef::Log.debug("Node query [" + nodes.to_s + "]")
+
+# Deal with an empty node list
+if nodes.empty?
+ Chef::Log.debug("No nodes returned from search, using this node so hosts.cfg has data")
+ nodes = Array.new
+ nodes << node
+ Chef::Log.debug("nodes from hosts.cfg [" + nodes.to_s + "]")
+else
+ # Make sure the server is in the list as well.
+ nodes << node unless nodes.include?(node)
+end
+
+# Remove nodes that are in the process of going away.
+nodes.delete_if { |n| n[:state] == "delete" }
+
+# Get a list of system administration users
+sysadmins = search(:users, 'groups:sysadmin')
+members = Array.new
+sysadmins.each do |s|
+ Chef::Log.debug("Add system admin user [" + s['id'] + "]")
+ members << s['id']
+end
+
+# Make sure that the nodes have a field "ipaddress" that is the admin address
+hosts = {}
+nodes.each do |n|
+ ip = Nagios::Evaluator.get_value_by_type(n, :admin_ip_eval)
+ hosts[ip] = n unless ip.nil?
+end
+
+# Build a hash of service name to the server fulfilling that role (NOT a list )
+role_list = Array.new
+service_hosts = Hash.new
+search(:role, "*:*") do |r|
+ role_list << r.name
+ search(:node, "role:#{r.name} #{env_filter}") do |n|
+ service_hosts[r.name] = n['hostname']
+ end
+end
+
+# Get the public domain name
+if node[:public_domain]
+ public_domain = node[:public_domain]
+else
+ public_domain = node[:domain]
+end
+Chef::Log.debug("Public domain [" + public_domain + "]")
+
+# Package install list
+%w{ nagios3 nagios-nrpe-plugin nagios-images }.each do |pkg|
+ package pkg
+end
+
+service "nagios3" do
+ supports :status => true, :restart => true, :reload => true
+ action [ :enable ]
+end
+
+nagios_conf "nagios" do
+ config_subdir false
+end
+
+# Set directory permissions
+directory "#{node[:nagios][:dir]}/dist" do
+ owner "nagios"
+ group "nagios"
+ mode "0755"
+end
+
+directory node[:nagios][:state_dir] do
+ owner "nagios"
+ group "nagios"
+ mode "0751"
+end
+
+directory "#{node[:nagios][:state_dir]}/rw" do
+ owner "nagios"
+ group node[:apache][:user]
+ mode "2710"
+end
+
+execute "archive default nagios object definitions" do
+ command "mv #{node[:nagios][:dir]}/conf.d/*_nagios*.cfg #{node[:nagios][:dir]}/dist"
+ not_if { Dir.glob(node[:nagios][:dir] + "/conf.d/*_nagios*.cfg").empty? }
+end
+
+file "#{node[:apache][:dir]}/conf.d/nagios3.conf" do
+ action :delete
+end
+
+case node[:nagios][:server_auth_method]
+when "openid"
+ include_recipe "apache2::mod_auth_openid"
+else
+ template "#{node[:nagios][:dir]}/htpasswd.users" do
+ source "htpasswd.users.erb"
+ owner "nagios"
+ group node[:apache][:user]
+ mode 0640
+ variables(
+ :sysadmins => sysadmins
+ )
+ end
+end
+
+apache_site "000-default" do
+ enable false
+end
+
+template "#{node[:apache][:dir]}/sites-available/nagios3.conf" do
+ source "apache2.conf.erb"
+ mode 0644
+ variables :public_domain => public_domain
+ if ::File.symlink?("#{node[:apache][:dir]}/sites-enabled/nagios3.conf")
+ notifies :reload, resources(:service => "apache2")
+ end
+end
+
+apache_site "nagios3.conf"
+
+%w{ nagios cgi }.each do |conf|
+ nagios_conf conf do
+ config_subdir false
+ end
+end
+
+#
+# check_nova_ldap - one day if needed.
+#
+nova_commands = %w{ check_nova_api check_nova_compute check_nova_network check_nova_objectstore check_nova_rabbit check_nova_scheduler check_nova_volume check_nova_manage }
+
+swift_svcs = %w{swift-object swift-object-auditor swift-object-replicator swift-object-updater}
+swift_svcs =swift_svcs + %w{swift-container swift-container-auditor swift-container-replicator swift-container-updater}
+swift_svcs =swift_svcs + %w{swift-account swift-account-reaper swift-account-auditor swift-account-replicator}
+swift_svcs =swift_svcs + ["swift-proxy"]
+
+glance_svcs = %w{glance-api glance-registry}
+
+
+%w{ commands templates timeperiods}.each do |conf|
+ nagios_conf conf do
+ variables :nova_commands => nova_commands, :svcs => swift_svcs + glance_svcs
+ end
+end
+
+nagios_conf "services" do
+ variables :service_hosts => service_hosts
+end
+
+nagios_conf "contacts" do
+ variables :admins => sysadmins, :members => members
+end
+
+nagios_conf "hostgroups" do
+ variables :roles => role_list
+end
+
+nagios_conf "hosts" do
+ variables :hosts => hosts
+end
+
+# End of recipe transactions
+Chef::Log.debug("END nagios-server")
+
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/templates/default/apache2.conf.erb b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/templates/default/apache2.conf.erb
new file mode 100644
index 00000000000..319fd689408
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/templates/default/apache2.conf.erb
@@ -0,0 +1,35 @@
+
+ ServerAdmin <%= node[:nagios][:sysadmin_email] %>
+ ServerName <%= node[:fqdn] %>
+ ServerAlias nagios nagios.<%= node[:app_environment]%>.<%= @public_domain %>
+ DocumentRoot <%= node[:nagios][:docroot] %>
+ CustomLog /var/log/nagios3/apache_access.log combined
+ ErrorLog /var/log/nagios3/apache_error.log
+
+ ScriptAlias /cgi-bin/nagios3 /usr/lib/cgi-bin/nagios3
+ ScriptAlias /nagios3/cgi-bin /usr/lib/cgi-bin/nagios3
+
+ Alias /nagios3/stylesheets /etc/nagios3/stylesheets
+ Alias /nagios3 <%= node[:nagios][:docroot] %>
+
+<% case node[:nagios][:server_auth_method] -%>
+<% when "openid" -%>
+
+ AuthName "Nagios Server"
+ AuthOpenIDEnabled On
+ AuthOpenIDDBLocation /var/cache/apache2/mod_auth_openid.db
+ AuthOpenIDUserProgram /usr/local/bin/mod_auth_openid.rb
+
+<% else -%>
+
+ AuthName "Nagios Server"
+ AuthType Basic
+ AuthUserFile "<%= node[:nagios][:dir] %>/htpasswd.users"
+ require valid-user
+
+<% end -%>
+
+ RewriteEngine On
+ RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /.*index\.html\ HTTP/
+ RewriteRule ^(.*)index\.html$ $1 [R=301,L]
+
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/templates/default/cgi.cfg.erb b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/templates/default/cgi.cfg.erb
new file mode 100644
index 00000000000..3a27490a29a
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/templates/default/cgi.cfg.erb
@@ -0,0 +1,231 @@
+#
+# Autogenerated by Chef.
+#
+# MAIN CONFIGURATION FILE
+# This tells the CGIs where to find your main configuration file.
+# The CGIs will read the main and host config files for any other
+# data they might need.
+
+main_config_file=<%= node[:nagios][:dir] %>/nagios.cfg
+
+# PHYSICAL HTML PATH
+# This is the path where the HTML files for Nagios reside. This
+# value is used to locate the logo images needed by the statusmap
+# and statuswrl CGIs.
+
+physical_html_path=<%= node[:nagios][:docroot] %>
+
+# URL HTML PATH
+# This is the path portion of the URL that corresponds to the
+# physical location of the Nagios HTML files (as defined above).
+# This value is used by the CGIs to locate the online documentation
+# and graphics. If you access the Nagios pages with an URL like
+# http://www.myhost.com/nagios, this value should be '/nagios'
+# (without the quotes).
+
+url_html_path=/nagios3
+
+# CONTEXT-SENSITIVE HELP
+# This option determines whether or not a context-sensitive
+# help icon will be displayed for most of the CGIs.
+# Values: 0 = disables context-sensitive help
+# 1 = enables context-sensitive help
+
+show_context_help=1
+
+# NAGIOS PROCESS CHECK COMMAND
+# This is the full path and filename of the program used to check
+# the status of the Nagios process. It is used only by the CGIs
+# and is completely optional. However, if you don't use it, you'll
+# see warning messages in the CGIs about the Nagios process
+# not running and you won't be able to execute any commands from
+# the web interface. The program should follow the same rules
+# as plugins; the return codes are the same as for the plugins,
+# it should have timeout protection, it should output something
+# to STDIO, etc.
+#
+# Note: The command line for the check_nagios plugin below may
+# have to be tweaked a bit, as different versions of the plugin
+# use different command line arguments/syntaxes.
+
+nagios_check_command=/usr/lib/nagios/plugins/check_nagios <%= node[:nagios][:cache_dir] %>/status.dat 5 '/usr/sbin/nagios3'
+
+# AUTHENTICATION USAGE
+# This option controls whether or not the CGIs will use any
+# authentication when displaying host and service information, as
+# well as committing commands to Nagios for processing.
+#
+# Read the HTML documentation to learn how the authorization works!
+#
+# NOTE: It is a really *bad* idea to disable authorization, unless
+# you plan on removing the command CGI (cmd.cgi)! Failure to do
+# so will leave you wide open to kiddies messing with Nagios and
+# possibly hitting you with a denial of service attack by filling up
+# your drive by continuously writing to your command file!
+#
+# Setting this value to 0 will cause the CGIs to *not* use
+# authentication (bad idea), while any other value will make them
+# use the authentication functions (the default).
+
+use_authentication=1
+
+# DEFAULT USER
+# Setting this variable will define a default user name that can
+# access pages without authentication. This allows people within a
+# secure domain (i.e., behind a firewall) to see the current status
+# without authenticating. You may want to use this to avoid basic
+# authentication if you are not using a secure server since basic
+# authentication transmits passwords in the clear.
+#
+# Important: Do not define a default username unless you are
+# running a secure web server and are sure that everyone who has
+# access to the CGIs has been authenticated in some manner! If you
+# define this variable, anyone who has not authenticated to the web
+# server will inherit all rights you assign to this user!
+
+#default_user_name=guest
+
+# SYSTEM/PROCESS INFORMATION ACCESS
+# This option is a comma-delimited list of all usernames that
+# have access to viewing the Nagios process information as
+# provided by the Extended Information CGI (extinfo.cgi). By
+# default, *no one* has access to this unless you choose to
+# not use authorization. You may use an asterisk (*) to
+# authorize any user who has authenticated to the web server.
+
+authorized_for_system_information=*
+
+# CONFIGURATION INFORMATION ACCESS
+# This option is a comma-delimited list of all usernames that
+# can view ALL configuration information (hosts, commands, etc).
+# By default, users can only view configuration information
+# for the hosts and services they are contacts for. You may use
+# an asterisk (*) to authorize any user who has authenticated
+# to the web server.
+
+authorized_for_configuration_information=*
+
+# SYSTEM/PROCESS COMMAND ACCESS
+# This option is a comma-delimited list of all usernames that
+# can issue shutdown and restart commands to Nagios via the
+# command CGI (cmd.cgi). Users in this list can also change
+# the program mode to active or standby. By default, *no one*
+# has access to this unless you choose to not use authorization.
+# You may use an asterisk (*) to authorize any user who has
+# authenticated to the web server.
+
+authorized_for_system_commands=*
+
+# GLOBAL HOST/SERVICE VIEW ACCESS
+# These two options are comma-delimited lists of all usernames that
+# can view information for all hosts and services that are being
+# monitored. By default, users can only view information
+# for hosts or services that they are contacts for (unless you
+# you choose to not use authorization). You may use an asterisk (*)
+# to authorize any user who has authenticated to the web server.
+
+
+authorized_for_all_services=*
+authorized_for_all_hosts=*
+
+# GLOBAL HOST/SERVICE COMMAND ACCESS
+# These two options are comma-delimited lists of all usernames that
+# can issue host or service related commands via the command
+# CGI (cmd.cgi) for all hosts and services that are being monitored.
+# By default, users can only issue commands for hosts or services
+# that they are contacts for (unless you you choose to not use
+# authorization). You may use an asterisk (*) to authorize any
+# user who has authenticated to the web server.
+
+authorized_for_all_service_commands=*
+authorized_for_all_host_commands=*
+
+# STATUSMAP BACKGROUND IMAGE
+# This option allows you to specify an image to be used as a
+# background in the statusmap CGI. It is assumed that the image
+# resides in the HTML images path (i.e. /usr/local/nagios/share/images).
+# This path is automatically determined by appending "/images"
+# to the path specified by the 'physical_html_path' directive.
+# Note: The image file may be in GIF, PNG, JPEG, or GD2 format.
+# However, I recommend that you convert your image to GD2 format
+# (uncompressed), as this will cause less CPU load when the CGI
+# generates the image.
+
+#statusmap_background_image=smbackground.gd2
+
+# DEFAULT STATUSMAP LAYOUT METHOD
+# This option allows you to specify the default layout method
+# the statusmap CGI should use for drawing hosts. If you do
+# not use this option, the default is to use user-defined
+# coordinates. Valid options are as follows:
+# 0 = User-defined coordinates
+# 1 = Depth layers
+# 2 = Collapsed tree
+# 3 = Balanced tree
+# 4 = Circular
+# 5 = Circular (Marked Up)
+
+default_statusmap_layout=5
+
+# DEFAULT STATUSWRL LAYOUT METHOD
+# This option allows you to specify the default layout method
+# the statuswrl (VRML) CGI should use for drawing hosts. If you
+# do not use this option, the default is to use user-defined
+# coordinates. Valid options are as follows:
+# 0 = User-defined coordinates
+# 2 = Collapsed tree
+# 3 = Balanced tree
+# 4 = Circular
+
+default_statuswrl_layout=4
+
+# STATUSWRL INCLUDE
+# This option allows you to include your own objects in the
+# generated VRML world. It is assumed that the file
+# resides in the HTML path (i.e. /usr/local/nagios/share).
+
+#statuswrl_include=myworld.wrl
+
+# PING SYNTAX
+# This option determines what syntax should be used when
+# attempting to ping a host from the WAP interface (using
+# the statuswml CGI. You must include the full path to
+# the ping binary, along with all required options. The
+# $HOSTADDRESS$ macro is substituted with the address of
+# the host before the command is executed.
+# Please note that the syntax for the ping binary is
+# notorious for being different on virtually ever *NIX
+# OS and distribution, so you may have to tweak this to
+# work on your system.
+
+ping_syntax=/bin/ping -n -U -c 5 $HOSTADDRESS$
+
+# REFRESH RATE
+# This option allows you to specify the refresh rate in seconds
+# of various CGIs (status, statusmap, extinfo, and outages).
+
+refresh_rate=90
+
+# SOUND OPTIONS
+# These options allow you to specify an optional audio file
+# that should be played in your browser window when there are
+# problems on the network. The audio files are used only in
+# the status CGI. Only the sound for the most critical problem
+# will be played. Order of importance (higher to lower) is as
+# follows: unreachable hosts, down hosts, critical services,
+# warning services, and unknown services. If there are no
+# visible problems, the sound file optionally specified by
+# 'normal_sound' variable will be played.
+#
+#
+# =
+#
+# Note: All audio files must be placed in the /media subdirectory
+# under the HTML path (i.e. /usr/local/nagios/share/media/).
+
+#host_unreachable_sound=hostdown.wav
+#host_down_sound=hostdown.wav
+#service_critical_sound=critical.wav
+#service_warning_sound=warning.wav
+#service_unknown_sound=warning.wav
+#normal_sound=noproblem.wav
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/templates/default/commands.cfg.erb b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/templates/default/commands.cfg.erb
new file mode 100644
index 00000000000..edfa2f3c638
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/templates/default/commands.cfg.erb
@@ -0,0 +1,402 @@
+#
+# Automatically generated by Chef
+
+# Host checks
+define command {
+ command_name check-host-alive
+ command_line $USER1$/check_ping -H $HOSTADDRESS$ -w 2000,80% -c 3000,100% -p 1
+}
+
+# Service checks
+define command {
+ command_name check_ec2_count
+ command_line $USER1$/count_ec2_instances.sh
+}
+
+define command {
+ command_name check_solr_proc
+ command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c check_solr_proc -t 20
+}
+
+define command {
+ command_name check_stompserver
+ command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c check_stompserver -t 20
+}
+
+define command {
+ command_name check_chef_client
+ command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c check_chef_client -t 20
+}
+
+define command {
+ command_name check_collectd_client
+ command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c check_collectd_client -t 20
+}
+
+define command {
+ command_name check_rabbitmq
+ command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c check_rabbitmq -t 20
+}
+
+define command {
+ command_name check_authz
+ command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c check_authz -t 20
+}
+
+define command {
+ command_name check_audit
+ command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c check_audit -t 20
+}
+
+define command {
+ command_name check-nagios
+ command_line $USER1$/check_nagios -F <%= node[:nagios][:cache_dir] %>/status.dat -e 4 -C /usr/sbin/nagios3
+}
+
+define command {
+ command_name check_file_age
+ command_line $USER1$/check_by_ssh -H $HOSTADDRESS$ -C "/usr/local/bin/check_file -i -p $ARG1$ -w $ARG2$ -c $ARG3$" -l root
+}
+
+define command {
+ command_name check_file_count
+ command_line $USER1$/check_by_ssh -H $HOSTADDRESS$ -C "/usr/lib/nagios/checks/file_queues.rb -t count -p $ARG1$ -w $ARG2$ -c $ARG3$" -l app
+}
+
+define command {
+ command_name check_log
+ command_line $USER1$/check_by_ssh -H $HOSTADDRESS$ -C "/usr/lib64/nagios/plugins/check_log -F $ARG1$ -O /tmp/nagios.logcheck.processed -q $ARG2$" -l root
+}
+
+define command {
+ command_name check_solr
+ command_line $USER1$/check_solr.rb -c 10 -h $HOSTADDRESS$ -r 10 -p $ARG1$
+
+}
+
+define command {
+ command_name query_solr
+ command_line $USER1$/check_solr.rb -c 10 -h $HOSTADDRESS$ -r 10 -p $ARG1$ -q $ARG2$
+
+}
+
+define command {
+ command_name check_mem
+ command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c check_mem -t 20
+}
+
+
+define command {
+ command_name check_query_count
+ command_line $USER1$/db_queues.rb -H $HOSTADDRESS$ -u $ARG1$ -p $ARG2$ -d $ARG3$ -q $ARG4$ -w $ARG5$ -c $ARG6$
+}
+
+define command {
+ command_name check_local_disk
+ command_line $USER1$/check_disk -w $ARG1$ -c $ARG2$ -p $ARG3$
+}
+
+define command {
+ command_name check_local_load
+ command_line $USER1$/check_load -w $ARG1$ -c $ARG2$
+}
+
+define command {
+ command_name check_local_procs
+ command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c check_total_procs -t 20
+}
+
+define command {
+ command_name check_zombie_procs
+ command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c check_zombie_procs -t 20
+}
+
+define command {
+ command_name check_local_users
+ command_line $USER1$/check_users -w $ARG1$ -c $ARG2$
+}
+
+define command {
+ command_name check_local_log
+ command_line $USER1$/check_log -F $ARG1$ -O /tmp/nagios.logcheck.processed -q $ARG2$
+}
+
+define command {
+ command_name check_dns
+ command_line $USER1$/check_dns -H $ARG1$ -s $HOSTADDRESS$
+}
+
+define command {
+ command_name check_ftp
+ command_line $USER1$/check_ftp -H $HOSTADDRESS$
+}
+
+define command {
+ command_name check_hpjd
+ command_line $USER1$/check_hpjd -H $HOSTADDRESS$ -C public
+}
+
+define command {
+ command_name check_ganglia_web
+ command_line $USER1$/check_http -f follow -a nagiosadmin:password -I $HOSTADDRESS$ -H $HOSTADDRESS$ -u "/ganglia"
+}
+
+define command {
+ command_name check_http
+ command_line $USER1$/check_http -I $HOSTADDRESS$ -H $HOSTADDRESS$
+}
+
+define command {
+ command_name check_http_content
+ command_line $USER1$/check_http -I $HOSTADDRESS$ -H $ARG1$ -u $ARG2$ -s $ARG3$
+}
+
+define command {
+ command_name check_http_port
+ command_line $USER1$/check_http -I $HOSTADDRESS$ -H $HOSTADDRESS$ -p $ARG1$
+}
+
+define command {
+ command_name check_http_port_expect
+ command_line $USER1$/check_http -I $HOSTADDRESS$ -H $HOSTADDRESS$ -p $ARG1$ -e $ARG2$
+}
+
+define command {
+ command_name check_http_ip_port
+ command_line $USER1$/check_http -I $ARG1$ -H $ARG1$ -p $ARG2$
+}
+
+define command {
+ command_name check_mongrel_http_content
+ command_line $USER1$/check_http -I $HOSTADDRESS$ -H $ARG1$ -u $ARG2$ -s $ARG3$ -p $ARG4$
+}
+
+define command {
+ command_name check_nntp
+ command_line $USER1$/check_nntp -H $HOSTADDRESS$
+}
+
+define command {
+ command_name check_ping
+ command_line $USER1$/check_ping -H $HOSTADDRESS$ -w $ARG1$ -c $ARG2$ -p 5
+}
+
+define command {
+ command_name check_pop
+ command_line $USER1$/check_pop -H $HOSTADDRESS$
+}
+
+define command {
+ command_name check_smtp
+ command_line $USER1$/check_smtp -H $HOSTADDRESS$
+}
+
+define command {
+ command_name check_tcp
+ command_line $USER1$/check_tcp -H $HOSTADDRESS$ -p $ARG1$
+}
+
+define command {
+ command_name check_ssh
+ command_line $USER1$/check_ssh $HOSTADDRESS$
+}
+
+define command {
+ command_name check_telnet
+ command_line $USER1$/check_tcp -H $HOSTADDRESS$ -p 23
+}
+
+define command {
+ command_name check_udp
+ command_line $USER1$/check_udp -H $HOSTADDRESS$ -p $ARG1$
+}
+
+# 'check_mysql' check mysql connectivity
+define command {
+ command_name check_mysql
+ command_line $USER1$/check_mysql -H $ARG1$ -u nagios -p $ARG2$
+}
+
+define command {
+ command_name check_mysql_master
+ command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -u $ARG1$ -p $ARG2$
+}
+
+# 'check_mysqlrep' command for mysql replication status
+define command {
+ command_name check_replication
+ command_line $USER1$/check_nrpe -c check_replication -H $HOSTADDRESS$ -t 20
+}
+
+define command {
+ command_name check_mysqlrep
+ command_line $USER1$/check-mysql-slave.pl --host $HOSTADDRESS$ --port $ARG1$ --user replcheck --password $ARG2$ --warn $ARG3$ --crit $ARG4$
+}
+
+# nrpe remote host checks
+define command {
+ command_name check_nrpe_alive
+ command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -t 20
+ }
+
+define command {
+ command_name check_nrpe
+ command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c $ARG1$ -t 20
+ }
+
+define command {
+ command_name check_load
+ command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c check_load -t 20
+}
+
+define command {
+ command_name check_dynomite_proc
+ command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c check_dynomite_proc -t 20
+}
+
+define command {
+ command_name check_couchdb_proc
+ command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c check_couchdb_proc -t 20
+}
+
+define command {
+ command_name check_disk
+ command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c check_$ARG1$ -t 20
+}
+
+define command {
+ command_name check_all_disks
+ command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c check_all_disks -t 20
+}
+
+define command {
+ command_name check_traffic
+ command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c traffic -t 20
+}
+
+define command {
+ command_name check_mysqlhealth
+ command_line $USER1$/check_mysqlhealth.pl -H $HOSTADDRESS$ -u nagios -p $ARG1$ --port 3306 --wa 500 --cc 550
+}
+
+define command {
+ command_name check_iowait_time
+ command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c check_iowait_time -t 20
+}
+
+define command {
+ command_name check_tps
+ command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c check_tps -t 20
+}
+
+define command {
+ command_name check_swap
+ command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c check_swap -t 20
+}
+
+define command {
+ command_name check_solr_index
+ command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c check_$ARG1$_solr_index -t 20
+}
+
+define command {
+ command_name check_gmond
+ command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c check_gmond
+}
+
+define command {
+ command_name check_gmetad
+ command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c check_gmetad
+}
+
+define command {
+ command_name check_local_time
+ command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c check_local_time
+}
+
+define command {
+ command_name check_ntp
+ command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c check_ntp
+}
+
+define command {
+ command_name check_apt
+ command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c check_apt
+}
+
+define command {
+ command_name remote_check_dns
+ command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c check_dns
+}
+
+define command {
+ command_name check_dhcp
+ command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c check_dhcp
+}
+
+# dummy commands for passive checks
+
+define command {
+ command_name no-disk-checks
+ command_line /usr/local/nagios/libexec/check_dummy 2 "CRITICAL: Results of disk checks not coming in!"
+}
+
+define command {
+ command_name no-mem-checks
+ command_line /usr/local/nagios/libexec/check_dummy 2 "CRITICAL: Results of memory checks not coming in!"
+}
+
+# Notification
+define command {
+ command_name host-notify-by-email
+ command_line /usr/bin/printf "%b" "$LONGDATETIME$\n\n$HOSTALIAS$ $NOTIFICATIONTYPE$ $HOSTSTATE$\n\n$HOSTOUTPUT$\n\nLogin: ssh://$HOSTNAME$" | /bin/mail -s "$NOTIFICATIONTYPE$ - $HOSTALIAS$ $HOSTSTATE$!" $CONTACTEMAIL$
+}
+
+define command {
+ command_name host-notify-by-sms-email
+ command_line /usr/bin/printf "%b" "$HOSTALIAS$ $NOTIFICATIONTYPE$ $HOSTSTATE$\n\n$HOSTOUTPUT$" | /bin/mail -s "$HOSTALIAS$ $HOSTSTATE$!" $CONTACTPAGER$
+}
+
+# 'notify-by-email' command definition
+define command {
+ command_name service-notify-by-email
+ command_line /usr/bin/printf "%b" "$LONGDATETIME$ - $SERVICEDESC$ $SERVICESTATE$\n\n$HOSTALIAS$ $NOTIFICATIONTYPE$\n\n$SERVICEOUTPUT$\n\nLogin: ssh://$HOSTNAME$" | /bin/mail -s "** $NOTIFICATIONTYPE$ - $HOSTALIAS$ - $SERVICEDESC$ - $SERVICESTATE$" $CONTACTEMAIL$
+}
+
+#define command {
+# command_name process-service-perfdata
+# command_line /usr/lib/nagios/plugins/process_perfdata.pl
+#}
+
+#define command {
+# command_name process-host-perfdata
+# command_line /usr/lib/nagios/plugins/process_perfdata.pl -d HOSTPERFDATA
+#}
+
+<% @nova_commands.each { |cmd| %>
+define command {
+ command_name <%= cmd %>
+ command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c <%= cmd %>
+}
+<% } %>
+
+define command {
+ command_name check_nova_mysql
+ command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c check_mysql_server
+}
+
+<% @svcs.each { |cmd| %>
+define command {
+ command_name check_<%= cmd %>
+ command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c check_<%= cmd %>
+}
+<% } unless @svcs.nil? %>
+
+<% %w{glance-api glance-registry swift-object swift-container swift-account swift-proxy}.each do |svc| %>
+define command {
+ command_name check_port_<%=svc %>
+ command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c check_port_<%=svc %>
+}
+<% end %>
+
+
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/templates/default/contacts.cfg.erb b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/templates/default/contacts.cfg.erb
new file mode 100644
index 00000000000..844c1d4d823
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/templates/default/contacts.cfg.erb
@@ -0,0 +1,32 @@
+define contact {
+ contact_name root
+ alias Root
+ service_notification_period 24x7
+ host_notification_period 24x7
+ service_notification_options w,u,c,r
+ host_notification_options d,r
+ service_notification_commands service-notify-by-email
+ host_notification_commands host-notify-by-email
+ email root@localhost
+}
+
+define contactgroup {
+ contactgroup_name admins
+ alias Nagios Administrators
+ members <%= @members.join(',') %>
+}
+
+define contactgroup {
+ contactgroup_name admins-sms
+ alias Sysadmin SMS
+ members <%= @members.join(',') %>
+}
+
+<% @admins.each do |a| -%>
+define contact {
+ use default-contact
+ contact_name <%= a['id'] %>
+ email <%= a['nagios']['email'] %>
+}
+
+<% end -%>
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/templates/default/hostgroups.cfg.erb b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/templates/default/hostgroups.cfg.erb
new file mode 100644
index 00000000000..41a3895379a
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/templates/default/hostgroups.cfg.erb
@@ -0,0 +1,16 @@
+# Hostgroup definitions
+# Automatically generated by Chef
+
+define hostgroup {
+ hostgroup_name all
+ alias all
+ members *
+}
+
+<% @roles.each do |r| -%>
+define hostgroup {
+ hostgroup_name <%= r %>
+ alias <%= r %>
+}
+
+<% end -%>
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/templates/default/hosts.cfg.erb b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/templates/default/hosts.cfg.erb
new file mode 100644
index 00000000000..51da59b6358
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/templates/default/hosts.cfg.erb
@@ -0,0 +1,16 @@
+# Generated by Chef
+# host definitions
+
+<% @hosts.each do |ip, n| -%>
+define host {
+ use server
+ address <%= ip %>
+ host_name <%= n["hostname"] %>
+<% if n.run_list.roles.nil? -%>
+ hostgroups all
+<% else -%>
+ hostgroups <%= n.run_list.roles.to_a.join(",") %>
+<% end -%>
+}
+
+<% end -%>
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/templates/default/htpasswd.users.erb b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/templates/default/htpasswd.users.erb
new file mode 100644
index 00000000000..96ee5035608
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/templates/default/htpasswd.users.erb
@@ -0,0 +1,4 @@
+# Generated by Chef.
+<% @sysadmins.each do |sa| -%>
+<%= sa["id"] %>:<%= sa["htpasswd"] %>
+<% end -%>
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/templates/default/nagios.cfg.erb b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/templates/default/nagios.cfg.erb
new file mode 100644
index 00000000000..dc7a0c3ce61
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/templates/default/nagios.cfg.erb
@@ -0,0 +1,156 @@
+# Generated by Chef
+#
+
+log_file=<%= node[:nagios][:log_dir] %>/nagios.log
+
+admin_email=<%= node[:nagios][:sysadmin_email] %>
+admin_pager=<%= node[:nagios][:sysadmin_sms_email] %>
+
+cfg_dir=<%= node[:nagios][:dir] %>/<%= node[:nagios][:config_subdir] %>
+
+object_cache_file=<%= node[:nagios][:cache_dir] %>/objects.cache
+precached_object_file=<%= node[:nagios][:cache_dir] %>/objects.precache
+
+resource_file=/etc/nagios3/resource.cfg
+status_file=<%= node[:nagios][:cache_dir] %>/status.dat
+status_update_interval=10
+nagios_user=nagios
+nagios_group=nagios
+check_external_commands=<%= nagios_boolean(node[:nagios][:check_external_commands]) %>
+
+# NOTE: Setting this value to -1 causes Nagios to check the external command file as often as possible.
+command_check_interval=-1
+
+command_file=<%= node[:nagios][:state_dir] %>/rw/nagios.cmd
+external_command_buffer_slots=4096
+lock_file=/var/run/nagios3/nagios3.pid
+temp_file=<%= node[:nagios][:cache_dir] %>/nagios.tmp
+temp_path=/tmp
+event_broker_options=-1
+
+log_rotation_method=d
+log_archive_path=<%= node[:nagios][:log_dir] %>/archives
+use_syslog=1
+log_notifications=1
+log_service_retries=1
+log_host_retries=1
+log_event_handlers=1
+log_initial_states=0
+log_external_commands=1
+log_passive_checks=1
+
+service_inter_check_delay_method=s
+max_service_check_spread=5
+service_interleave_factor=s
+host_inter_check_delay_method=s
+max_host_check_spread=5
+max_concurrent_checks=0
+check_result_reaper_frequency=10
+max_check_result_reaper_time=30
+check_result_path=<%= node[:nagios][:state_dir] %>/spool/checkresults
+max_check_result_file_age=3600
+cached_host_check_horizon=15
+cached_service_check_horizon=15
+enable_predictive_host_dependency_checks=1
+enable_predictive_service_dependency_checks=1
+soft_state_dependencies=0
+
+auto_reschedule_checks=0
+auto_rescheduling_interval=30
+auto_rescheduling_window=180
+
+sleep_time=0.25
+service_check_timeout=60
+host_check_timeout=30
+event_handler_timeout=30
+notification_timeout=30
+ocsp_timeout=5
+perfdata_timeout=5
+
+retain_state_information=1
+state_retention_file=<%= node[:nagios][:state_dir] %>/retention.dat
+retention_update_interval=60
+use_retained_program_state=1
+use_retained_scheduling_info=1
+retained_host_attribute_mask=0
+retained_service_attribute_mask=0
+retained_process_host_attribute_mask=0
+retained_process_service_attribute_mask=0
+retained_contact_host_attribute_mask=0
+retained_contact_service_attribute_mask=0
+
+interval_length=<%= node[:nagios][:interval_length] %>
+
+use_aggressive_host_checking=0
+
+execute_service_checks=1
+accept_passive_service_checks=1
+execute_host_checks=1
+accept_passive_host_checks=1
+
+enable_notifications=<%= node[:nagios][:notifications_enabled] %>
+enable_event_handlers=1
+
+#process_performance_data=1
+process_performance_data=0
+
+#service_perfdata_command=ngraph-process-service-perfdata-pipe
+#host_perfdata_command=process-host-perfdata
+#service_perfdata_command=process-service-perfdata
+#host_perfdata_file=/tmp/host-perfdata
+#service_perfdata_file=/tmp/service-perfdata
+#host_perfdata_file_template=[HOSTPERFDATA]\t$TIMET$\t$HOSTNAME$\t$HOSTEXECUTIONTIME$\t$HOSTOUTPUT$\t$HOSTPERFDATA$
+#service_perfdata_file_template=[SERVICEPERFDATA]\t$TIMET$\t$HOSTNAME$\t$SERVICEDESC$\t$SERVICEEXECUTIONTIME$\t$SERVICELATENCY$\t$SERVICEOUTPUT$\t$SERVICEPERFDATA$
+#host_perfdata_file_mode=a
+#service_perfdata_file_mode=a
+#host_perfdata_file_processing_interval=0
+#service_perfdata_file_processing_interval=0
+#host_perfdata_file_processing_command=process-host-perfdata-file
+#service_perfdata_file_processing_command=process-service-perfdata-file
+
+obsess_over_services=0
+#ocsp_command=somecommand
+obsess_over_hosts=0
+#ochp_command=somecommand
+translate_passive_host_checks=0
+passive_host_checks_are_soft=0
+check_for_orphaned_services=1
+check_for_orphaned_hosts=1
+check_service_freshness=1
+service_freshness_check_interval=60
+check_host_freshness=0
+host_freshness_check_interval=60
+additional_freshness_latency=15
+
+enable_flap_detection=1
+low_service_flap_threshold=5.0
+high_service_flap_threshold=20.0
+low_host_flap_threshold=5.0
+high_host_flap_threshold=20.0
+
+date_format=iso8601
+
+use_timezone=UTC
+p1_file=/usr/lib/nagios3/p1.pl
+enable_embedded_perl=1
+use_embedded_perl_implicitly=1
+
+illegal_object_name_chars=`~!$%^&*|'"<>?,()=
+illegal_macro_output_chars=`~$&|'"<>
+
+use_regexp_matching=0
+use_true_regexp_matching=0
+
+daemon_dumps_core=0
+
+use_large_installation_tweaks=0
+
+enable_environment_macros=1
+
+#free_child_process_memory=1
+#child_processes_fork_twice=1
+
+debug_level=0
+debug_verbosity=1
+debug_file=<% node[:nagios][:state_dir] %>/nagios.debug
+max_debug_file_size=1000000
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/templates/default/nrpe.cfg.erb b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/templates/default/nrpe.cfg.erb
new file mode 100644
index 00000000000..48c9d2b9a50
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/templates/default/nrpe.cfg.erb
@@ -0,0 +1,47 @@
+pid_file=/var/run/nrpe.pid
+server_port=5666
+nrpe_user=nagios
+nrpe_group=nagios
+dont_blame_nrpe=0
+debug=0
+command_timeout=60
+
+include_dir=/etc/nagios/nrpe.d/
+
+<% unless @mon_host.nil? or @mon_host.empty? -%>
+allowed_hosts=<%= @mon_host.join(',') %>
+<% end -%>
+
+command[check_users]=/usr/lib/nagios/plugins/check_users -w 20 -c 30
+command[check_load]=/usr/lib/nagios/plugins/check_load -w <%= node[:nagios][:checks][:load][:warning] %> -c <%= node[:nagios][:checks][:load][:critical] %>
+command[check_all_disks]=/usr/lib/nagios/plugins/check_disk -w 8% -c 5% -A -x /dev/shm -X nfs -i /boot
+command[check_zombie_procs]=/usr/lib/nagios/plugins/check_procs -w 5 -c 10 -s Z
+command[check_total_procs]=/usr/lib/nagios/plugins/check_procs -w 500 -c 800
+command[check_swap]=/usr/lib/nagios/plugins/check_swap -w '50%' -c '25%'
+command[check_mem]=/usr/lib/nagios/plugins/check_mem.sh -w <%= node[:nagios][:checks][:memory][:warning] %> -c <%= node[:nagios][:checks][:memory][:critical] %> -p
+command[check_chef_client]=/usr/lib/nagios/plugins/check_procs -w 1:2 -c 1:2 -C chef-client
+command[check_smtp]=/usr/lib/nagios/plugins/check_smtp -H <%= node[:nagios][:checks][:smtp_host] %>
+command[check_nginx]=/usr/lib/nagios/plugins/check_procs -w 2:3 -c 1:5 -C nginx
+command[check_sphinx]=/usr/lib/nagios/plugins/check_procs -c 1:1 -C searchd
+<% unless node[:mysql].nil? -%>
+command[check_mysql_server]=/usr/lib/nagios/plugins/check_mysql -H localhost -u debian-sys-maint -p <%= node[:mysql][:server_debian_password] %>
+<% end -%>
+#command[check_unicorn]=/usr/lib/nagios/plugins/check_procs -c 4:8 -C unicorn_rails
+#
+# memcached checks require cpan modules, "Cache::Memcached" and "Nagios::Plugins::Memcached"
+#command[check_memcached_response]=/usr/local/bin/check_memcached -H <%= node[:ipaddress] %> -w 3 -c 5
+#command[check_memcached_size]=/usr/local/bin/check_memcached -H <%= node[:ipaddress] %> --size-warning 60 --size-critical 80
+#command[check_memcached_hit]=/usr/local/bin/check_memcached -H <%= node[:ipaddress] %> --hit-warning 40 --hit-critical 20
+
+command[check_gmond]=/usr/lib/nagios/plugins/check_procs -w 1:2 -c 1:2 -C gmond
+command[check_gmetad]=/usr/lib/nagios/plugins/check_procs -w 1:2 -c 1:2 -C gmetad
+
+command[check_local_time]=/usr/lib/nagios/plugins/check_ntp_time -H 127.0.0.1
+
+command[check_ntp]=/usr/lib/nagios/plugins/check_ntp -H <%= @ntp_servers %>
+
+command[check_dhcp]=/usr/lib/nagios/plugins/check_dhcp -s <%= @provisioner_ip %> -u -i <%= @admin_interface %>
+command[check_dns]=/usr/lib/nagios/plugins/check_dns -H <%= @domain_name %>
+
+command[check_apt]=/usr/lib/nagios/plugins/check_apt
+
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/templates/default/services.cfg.erb b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/templates/default/services.cfg.erb
new file mode 100644
index 00000000000..67c028d042b
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/templates/default/services.cfg.erb
@@ -0,0 +1,373 @@
+# Nagios Service Definitions.
+#
+# Automatically generated by Chef.
+
+define service {
+ use default-service
+ host_name *
+ service_description ping
+ check_command check_ping!200.0,20%!500.0,60%
+}
+
+# monitoring service checks
+<% unless @service_hosts['nagios-server'].nil? -%>
+define service {
+ service_description Nagios
+ hostgroup_name nagios-server
+ check_command check-nagios
+ contact_groups admins
+ use default-service
+}
+<% end -%>
+
+# default checks for all hosts
+define service {
+ service_description Chef Client
+ hostgroup_name all
+ check_command check_chef_client
+ use default-service
+}
+
+define service {
+ service_description Free Space All Disks
+ hostgroup_name all
+ check_command check_all_disks
+ use default-service
+}
+
+define service {
+ service_description Load Average
+ hostgroup_name all
+ check_command check_load
+ use default-service
+}
+
+define service {
+ service_description Free Memory
+ hostgroup_name all
+ check_command check_mem
+ use default-service
+}
+
+define service {
+ service_description SSH
+ hostgroup_name all
+ check_command check_ssh
+ use default-service
+}
+
+define service {
+ service_description Local Processes
+ hostgroup_name all
+ check_command check_local_procs
+ use default-service
+}
+
+define service {
+ service_description Zombie Processes
+ hostgroup_name all
+ check_command check_zombie_procs
+ use default-service
+}
+
+<% unless @service_hosts['ganglia-client'].nil? and @service_hosts['ganglia-server'].nil? -%>
+define service {
+ service_description Ganglia
+ hostgroup_name all
+ check_command check_gmond
+ use default-service
+}
+<% end -%>
+
+define service {
+ service_description Check local ntp daemon
+ hostgroup_name all
+ check_command check_local_time
+ use default-service
+}
+
+define service {
+ service_description Check ntp server daemon
+ hostgroup_name all
+ check_command check_ntp
+ use default-service
+}
+
+define service {
+ service_description Check SWAP level
+ hostgroup_name all
+ check_command check_swap
+ use default-service
+}
+
+define service {
+ service_description Check APT update state
+ hostgroup_name all
+ check_command check_apt
+ use default-service
+}
+
+define service {
+ service_description Check DNS Resolver
+ hostgroup_name all
+ check_command remote_check_dns
+ use default-service
+}
+
+<% unless @service_hosts['ganglia-server'].nil? -%>
+define service {
+ service_description GMetad
+ hostgroup_name ganglia-server
+ check_command check_gmetad
+ use default-service
+}
+
+define service {
+ service_description Ganglia Web
+ hostgroup_name ganglia-server
+ check_command check_ganglia_web
+ use default-service
+}
+<% end -%>
+<% unless @service_hosts['provisioner-server'].nil? -%>
+# These are the services to watch on an admin node
+define service {
+ service_description Crowbar Web Server
+ hostgroup_name provisioner-server
+ check_command check_tcp!3000
+ use default-service
+}
+define service {
+ service_description Install Web Server
+ hostgroup_name provisioner-server
+ check_command check_http_port!8091
+ use default-service
+}
+define service {
+ service_description DHCP Server
+ hostgroup_name provisioner-server
+ check_command check_dhcp
+ use default-service
+}
+<% end -%>
+
+<% unless @service_hosts['nova-single-machine'].nil? -%>
+# These are the services to watch on a nova-single-machine
+define service {
+ service_description Single Nova Object Store
+ hostgroup_name nova-single-machine
+ check_command check_nova_objectstore
+ use default-service
+}
+define service {
+ service_description Single Nova API
+ hostgroup_name nova-single-machine
+ check_command check_nova_api
+ use default-service
+}
+define service {
+ service_description Single Nova Scheduler
+ hostgroup_name nova-single-machine
+ check_command check_nova_scheduler
+ use default-service
+}
+define service {
+ service_description Single Nova Network
+ hostgroup_name nova-single-machine
+ check_command check_nova_network
+ use default-service
+}
+define service {
+ service_description Single Nova Compute
+ hostgroup_name nova-single-machine
+ check_command check_nova_compute
+ use default-service
+}
+#define service {
+# service_description Single Nova Volume
+# hostgroup_name nova-single-machine
+# check_command check_nova_volume
+# use default-service
+#}
+define service {
+ service_description Single Nova System
+ hostgroup_name nova-single-machine
+ check_command check_nova_manage
+ use default-service
+}
+define service {
+ service_description Single Nova Mysql
+ hostgroup_name nova-single-machine
+ check_command check_nova_mysql
+ use default-service
+}
+define service {
+ service_description Single Nova RabbitMQ
+ hostgroup_name nova-single-machine
+ check_command check_nova_rabbit
+ use default-service
+}
+# Until needed
+#define service {
+# service_description Single Nova LDAP
+# hostgroup_name nova-single-machine
+# check_command check_nova_ldap
+# use default-service
+#}
+<% end -%>
+
+<% unless @service_hosts['nova-multi-controller'].nil? -%>
+# These are the services to watch on a nova-single-machine
+define service {
+ service_description Multi Nova Object Store
+ hostgroup_name nova-multi-controller
+ check_command check_nova_objectstore
+ use default-service
+}
+define service {
+ service_description Multi Nova Scheduler
+ hostgroup_name nova-multi-controller
+ check_command check_nova_scheduler
+ use default-service
+}
+define service {
+ service_description Multi Nova Network
+ hostgroup_name nova-multi-controller
+ check_command check_nova_network
+ use default-service
+}
+define service {
+ service_description Multi Nova System
+ hostgroup_name nova-multi-controller
+ check_command check_nova_manage
+ use default-service
+}
+define service {
+ service_description Multi Nova Mysql
+ hostgroup_name nova-multi-controller
+ check_command check_nova_mysql
+ use default-service
+}
+define service {
+ service_description Multi Nova RabbitMQ
+ hostgroup_name nova-multi-controller
+ check_command check_nova_rabbit
+ use default-service
+}
+# Until needed
+#define service {
+# service_description Multi Nova LDAP
+# hostgroup_name nova-multi-controller
+# check_command check_nova_ldap
+# use default-service
+#}
+<% end -%>
+
+<% unless @service_hosts['nova-multi-compute'].nil? -%>
+# These are the services to watch on a nova-multi-compute
+define service {
+ service_description Multi Nova Compute
+ hostgroup_name nova-multi-compute
+ check_command check_nova_compute
+ use default-service
+}
+#define service {
+# service_description Multi Nova Volume
+# hostgroup_name nova-multi-compute
+# check_command check_nova_volume
+# use default-service
+#}
+<% end -%>
+
+#### Services to watch for swift-compoents
+<% if !@service_hosts['swift-proxy'].nil? or !@service_hosts['swift-proxy-acct'].nil? then %>
+
+# check the proxy
+define service {
+ service_description swift proxy process
+ hostgroup_name swift-proxy-acct
+ check_command check_swift-proxy
+ use default-service
+}
+
+<% %w{ object container }.each do |svc| %>
+define service {
+ service_description swift <%= svc%> process
+ hostgroup_name swift-storage
+ check_command check_swift-<%= svc%>
+ use default-service
+}
+
+define service {
+ service_description swift <%= svc%> replicator process
+ hostgroup_name swift-storage
+ check_command check_swift-<%= svc%>-replicator
+ use default-service
+}
+
+define service {
+ service_description swift <%= svc%> updater process
+ hostgroup_name swift-storage
+ check_command check_swift-<%= svc%>-updater
+ use default-service
+}
+
+define service {
+ service_description swift process <%= svc%> auditor
+ hostgroup_name swift-storage
+ check_command check_swift-<%= svc%>-auditor
+ use default-service
+}
+
+define service {
+ service_description swift http port for <%= svc%> server
+ hostgroup_name swift-storage
+ check_command check_port_swift-<%= svc%>
+ use default-service
+}
+
+<% end %>
+
+define service {
+ service_description swift http port for account server
+ hostgroup_name swift-storage
+ check_command check_port_swift-account
+ use default-service
+}
+
+define service {
+ service_description swift http port for proxy server
+ hostgroup_name swift-proxy-acct
+ check_command check_port_swift-proxy
+ use default-service
+}
+
+
+<% %w{swift-account swift-account-reaper swift-account-auditor swift-account-replicator}.each do |svc| %>
+define service {
+ service_description swift process <%= svc %>
+ hostgroup_name swift-storage
+ check_command check_<%= svc %>
+ use default-service
+}
+<% end %>
+
+<% end ## end of swift-proxy present condition %>
+
+
+<% unless @service_hosts['glance-server'].nil? then %>
+<% %w{glance-api glance-registry}.each do |svc| %>
+define service {
+ service_description Glance process <%= svc %>
+ hostgroup_name glance-server
+ check_command check_<%= svc %>
+ use default-service
+}
+define service {
+ service_description Port check for <%= svc%> server
+ hostgroup_name glance-server
+ check_command check_port_<%= svc%>
+ use default-service
+}
+<% end %>
+<% end ## end of glance present condition %>
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/templates/default/templates.cfg.erb b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/templates/default/templates.cfg.erb
new file mode 100644
index 00000000000..91cc04df354
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/templates/default/templates.cfg.erb
@@ -0,0 +1,78 @@
+define contact {
+ name default-contact
+ service_notification_period 24x7
+ host_notification_period 24x7
+ service_notification_options w,u,c,r,f,s
+ host_notification_options d,u,r,f,s
+# service_notification_commands service-notify-by-email, service-notify-by-jabber
+ service_notification_commands service-notify-by-email
+# host_notification_commands host-notify-by-email, host-notify-by-sms-gateway, host-notify-by-jabber
+ host_notification_commands host-notify-by-email
+ register 0
+}
+
+define contact {
+ name sms-contact
+ service_notification_period 24x7
+ host_notification_period 24x7
+ service_notification_options w,u,c,r,f,s
+ host_notification_options d,u,r,f,s
+ service_notification_commands service-notify-by-sms-gateway
+ host_notification_commands host-notify-by-sms-gateway
+ register 0
+}
+
+define host {
+ name default-host
+ notifications_enabled 1
+ event_handler_enabled 1
+ flap_detection_enabled 1
+ failure_prediction_enabled 1
+# process_perf_data 1
+ process_perf_data 0
+ retain_status_information 1
+ retain_nonstatus_information 1
+ notification_period 24x7
+ register 0
+}
+
+define host {
+ name server
+ use default-host
+ check_period 24x7
+ check_interval <%= nagios_interval(nagios_attr(:default_host)[:check_interval]) %>
+ retry_interval <%= nagios_interval(nagios_attr(:default_host)[:retry_interval]) %>
+ max_check_attempts <%= nagios_attr(:default_host)[:max_check_attempts] %>
+ check_command check-host-alive
+ notification_interval <%= nagios_interval(nagios_attr(:default_host)[:notification_interval]) %>
+ notification_options d,u,r
+ contact_groups <%= nagios_attr(:default_contact_groups).join(",") %>
+ register 0
+}
+
+define service {
+ name default-service
+ active_checks_enabled 1
+ passive_checks_enabled 1
+ parallelize_check 1
+ obsess_over_service 1
+ check_freshness 0
+ notifications_enabled 1
+ event_handler_enabled 1
+ flap_detection_enabled 1
+ failure_prediction_enabled 1
+# process_perf_data 1
+ process_perf_data 0
+ retain_status_information 1
+ retain_nonstatus_information 1
+ is_volatile 0
+ check_period 24x7
+ max_check_attempts <%= nagios_attr(:default_service)[:max_check_attempts] %>
+ check_interval <%= nagios_interval(nagios_attr(:default_service)[:check_interval]) %>
+ retry_interval <%= nagios_interval(nagios_attr(:default_service)[:retry_interval]) %>
+ contact_groups <%= nagios_attr(:default_contact_groups).join(",") %>
+ notification_options w,u,c,r
+ notification_interval <%= nagios_interval(nagios_attr(:default_service)[:notification_interval]) %>
+ notification_period 24x7
+ register 0
+}
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/templates/default/timeperiods.cfg.erb b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/templates/default/timeperiods.cfg.erb
new file mode 100644
index 00000000000..24adc00da66
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/chef/cookbooks/nagios/templates/default/timeperiods.cfg.erb
@@ -0,0 +1,14 @@
+# Time period definitions
+# Automatically generated by Chef
+
+define timeperiod {
+ timeperiod_name 24x7
+ alias 24 Hours A Day, 7 Days A Week
+ sunday 00:00-24:00
+ monday 00:00-24:00
+ tuesday 00:00-24:00
+ wednesday 00:00-24:00
+ thursday 00:00-24:00
+ friday 00:00-24:00
+ saturday 00:00-24:00
+}
\ No newline at end of file
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/data_bags/crowbar/bc-template-nagios.json b/crowbar/change-image/dell/barclamps/nagios/chef/data_bags/crowbar/bc-template-nagios.json
new file mode 100644
index 00000000000..95fec746822
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/chef/data_bags/crowbar/bc-template-nagios.json
@@ -0,0 +1,28 @@
+{
+ "id": "bc-template-nagios",
+ "description": "common monitoring service for the cluster that can be used by other barclamps",
+ "attributes": {
+ "nagios": {
+ "admin_ip_eval": "Chef::Recipe::Barclamp::Inventory.get_network_by_type(node, \"admin\").address",
+ "admin_interface_eval": "Chef::Recipe::Barclamp::Inventory.get_network_by_type(node, \"admin\").interface"
+ }
+ },
+ "deployment": {
+ "nagios": {
+ "crowbar-revision": 0,
+ "elements": {},
+ "element_order": [
+ [ "nagios-server", "nagios-client" ]
+ ],
+ "config": {
+ "environment": "nagios-base-config",
+ "mode": "full",
+ "transitions": true,
+ "transition_list": [
+ "discovered"
+ ]
+ }
+ }
+ }
+}
+
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/data_bags/crowbar/bc-template-nagios.schema b/crowbar/change-image/dell/barclamps/nagios/chef/data_bags/crowbar/bc-template-nagios.schema
new file mode 100644
index 00000000000..5435dfd548f
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/chef/data_bags/crowbar/bc-template-nagios.schema
@@ -0,0 +1,70 @@
+{
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "id": { "type": "str", "required": true, "pattern": "/^bc-nagios-|^bc-template-nagios$/" },
+ "description": { "type": "str", "required": true },
+ "attributes": {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "nagios": {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "admin_ip_eval": { "type": "str", "required": true },
+ "admin_interface_eval": { "type": "str", "required": true }
+ }
+ }
+ }
+ },
+ "deployment": {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "nagios": {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "crowbar-revision": { "type": "int", "required": true },
+ "crowbar-committing": { "type": "bool" },
+ "crowbar-queued": { "type": "bool" },
+ "elements": {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ = : {
+ "type": "seq",
+ "required": true,
+ "sequence": [ { "type": "str" } ]
+ }
+ }
+ },
+ "element_order": {
+ "type": "seq",
+ "required": true,
+ "sequence": [ {
+ "type": "seq",
+ "sequence": [ { "type": "str" } ]
+ } ]
+ },
+ "config": {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "environment": { "type": "str", "required": true },
+ "mode": { "type": "str", "required": true },
+ "transitions": { "type": "bool", "required": true },
+ "transition_list": {
+ "type": "seq",
+ "required": true,
+ "sequence": [ { "type": "str" } ]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/data_bags/users/nagiosadmin.json b/crowbar/change-image/dell/barclamps/nagios/chef/data_bags/users/nagiosadmin.json
new file mode 100644
index 00000000000..99be9d7a517
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/chef/data_bags/users/nagiosadmin.json
@@ -0,0 +1,11 @@
+{
+ "id": "nagiosadmin",
+ "groups": "sysadmin",
+ "htpasswd": "Ah4LiEWT3GBMs",
+ "openid": "",
+ "nagios": {
+ "pager": "nagiosadmin_pager@example.com",
+ "email": "nagiosadmin@example.com"
+ }
+}
+
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/data_bags/users/nagiosadmin.schema b/crowbar/change-image/dell/barclamps/nagios/chef/data_bags/users/nagiosadmin.schema
new file mode 100644
index 00000000000..aad271bb6f3
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/chef/data_bags/users/nagiosadmin.schema
@@ -0,0 +1,18 @@
+{
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "id": { "type": "str", "required": true, "assert": "val == 'nagiosadmin'" },
+ "groups": { "type": "str", "required": true },
+ "htpasswd": { "type": "str", "required": true },
+ "openid": { "type": "str" },
+ "nagios": {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "pager": { "type": "str", "required": true },
+ "email": { "type": "str", "required": true, "name": "Email" }
+ }
+ }
+ }
+}
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/roles/nagios-client.rb b/crowbar/change-image/dell/barclamps/nagios/chef/roles/nagios-client.rb
new file mode 100644
index 00000000000..ea68134d736
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/chef/roles/nagios-client.rb
@@ -0,0 +1,8 @@
+
+name "nagios-client"
+description "NAGIOS Client Role - Nodes in the environment that should be monitored"
+run_list(
+ "recipe[nagios::client]"
+)
+default_attributes()
+override_attributes()
diff --git a/crowbar/change-image/dell/barclamps/nagios/chef/roles/nagios-server.rb b/crowbar/change-image/dell/barclamps/nagios/chef/roles/nagios-server.rb
new file mode 100644
index 00000000000..f85d1eddcac
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/chef/roles/nagios-server.rb
@@ -0,0 +1,13 @@
+
+name "nagios-server"
+description "NAGIOS Server Role - NAGIOS master for the cloud"
+run_list(
+ "recipe[nagios::server]"
+)
+default_attributes(
+ "nagios" => {
+ "server_auth_method" => "htauth"
+ }
+)
+override_attributes()
+
diff --git a/crowbar/change-image/dell/barclamps/nagios/command_line/crowbar_nagios b/crowbar/change-image/dell/barclamps/nagios/command_line/crowbar_nagios
new file mode 100755
index 00000000000..556a79a2638
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/command_line/crowbar_nagios
@@ -0,0 +1,6 @@
+#!/usr/bin/env ruby
+
+require File.join(File.expand_path(File.dirname(__FILE__)), "barclamp_lib")
+@barclamp = "nagios"
+
+main
diff --git a/crowbar/change-image/dell/barclamps/nagios/debian/changelog.tmpl b/crowbar/change-image/dell/barclamps/nagios/debian/changelog.tmpl
new file mode 100644
index 00000000000..42694be8134
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/debian/changelog.tmpl
@@ -0,0 +1,5 @@
+CHANGE_LOG_LINE
+
+ * Initial Release.
+
+ -- unknown Thu, 19 May 2011 15:50:02 -0500
diff --git a/crowbar/change-image/dell/barclamps/nagios/debian/compat b/crowbar/change-image/dell/barclamps/nagios/debian/compat
new file mode 100644
index 00000000000..7f8f011eb73
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/debian/compat
@@ -0,0 +1 @@
+7
diff --git a/crowbar/change-image/dell/barclamps/nagios/debian/control b/crowbar/change-image/dell/barclamps/nagios/debian/control
new file mode 100644
index 00000000000..e887a4c260f
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/debian/control
@@ -0,0 +1,13 @@
+Source: barclamp-nagios
+Section: unknown
+Priority: extra
+Maintainer: Dell Openstack
+Build-Depends: debhelper (>= 7.0.50~)
+Standards-Version: 3.9.1
+Homepage: http://openstack.dell.com/
+
+Package: barclamp-nagios
+Architecture: all
+Depends: barclamp-crowbar
+Description: Ganglia Barclamp for Crowbar
+ Provides the nagios barclamp for crowbar
diff --git a/crowbar/change-image/dell/barclamps/nagios/debian/copyright b/crowbar/change-image/dell/barclamps/nagios/debian/copyright
new file mode 100644
index 00000000000..ef293d897c8
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/debian/copyright
@@ -0,0 +1,26 @@
+This work was packaged for Debian by:
+
+ Dell Openstack Team on Thu, 19 May 2011 15:50:02 -0500
+
+It was downloaded from:
+
+
+
+Upstream Author(s):
+
+ Openstack Dell Team
+
+Copyright:
+
+ Copyright (C) 2011 Dell, Inc.
+
+License:
+
+GREG: Fill in Apache 2.0
+
+The Debian packaging is:
+
+ Copyright (C) 2011 Dell
+
+and is licensed under Apache 2.0, see above.
+
diff --git a/crowbar/change-image/dell/barclamps/nagios/debian/postinst b/crowbar/change-image/dell/barclamps/nagios/debian/postinst
new file mode 100644
index 00000000000..becf273afea
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/debian/postinst
@@ -0,0 +1,53 @@
+#!/bin/sh
+# postinst script for #PACKAGE#
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+# * `configure'
+# * `abort-upgrade'
+# * `abort-remove' `in-favour'
+#
+# * `abort-remove'
+# * `abort-deconfigure' `in-favour'
+# `removing'
+#
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+
+case "$1" in
+ configure)
+ cd /usr/share/barclamp-nagios/chef/cookbooks
+ knife cookbook upload -o . -a -u chef-webui -k /etc/chef/webui.pem
+
+ cd /usr/share/barclamp-nagios/chef/data_bags/crowbar
+ for i in *.json; do
+ knife data bag from file crowbar $i
+ done
+
+ cd /usr/share/barclamp-nagios/chef/roles
+ for i in *.rb; do
+ knife role from file $i
+ done
+
+ service apache2 graceful
+ ;;
+
+ abort-upgrade|abort-remove|abort-deconfigure)
+ ;;
+
+ *)
+ echo "postinst called with unknown argument \`$1'" >&2
+ exit 1
+ ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
diff --git a/crowbar/change-image/dell/barclamps/nagios/debian/rules b/crowbar/change-image/dell/barclamps/nagios/debian/rules
new file mode 100755
index 00000000000..79fd842dcae
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/debian/rules
@@ -0,0 +1,8 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+%:
+ dh $@
diff --git a/crowbar/change-image/dell/barclamps/nagios/debian/source/format b/crowbar/change-image/dell/barclamps/nagios/debian/source/format
new file mode 100644
index 00000000000..89ae9db8f88
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/debian/source/format
@@ -0,0 +1 @@
+3.0 (native)
diff --git a/crowbar/change-image/dell/barclamps/nagios/version.sh b/crowbar/change-image/dell/barclamps/nagios/version.sh
new file mode 100644
index 00000000000..7ade0263e47
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/nagios/version.sh
@@ -0,0 +1,7 @@
+BARCLAMP_NAME=nagios
+MAJOR_VERSION=0
+MINOR_VERSION=8
+SVN_REVISION=${SVN_REVISION:-custom}
+BUILD_NUMBER=${BUILD_NUMBER:-custom}
+RPM_CONTEXT_NUMBER=${SVN_REVISION}_${BUILD_NUMBER}
+DEB_CONTEXT_NUMBER=${SVN_REVISION}-${BUILD_NUMBER}
diff --git a/crowbar/change-image/dell/barclamps/network/Makefile b/crowbar/change-image/dell/barclamps/network/Makefile
new file mode 100644
index 00000000000..f704a64b5db
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/network/Makefile
@@ -0,0 +1,21 @@
+
+clean:
+ @echo "Cleaning barclamp-network"
+
+distclean:
+ @echo "Dist-Cleaning barclamp-network"
+
+all: clean build install
+
+build:
+ @echo "Building barclamp-network"
+
+install:
+ @echo "Installing barclamp-network"
+ mkdir -p ${DESTDIR}/opt/crowbar/openstack_manager
+ cp -r app ${DESTDIR}/opt/crowbar/openstack_manager
+ mkdir -p ${DESTDIR}/usr/share/barclamp-network
+ cp -r chef ${DESTDIR}/usr/share/barclamp-network
+ mkdir -p ${DESTDIR}/usr/bin
+ cp -r command_line/* ${DESTDIR}/usr/bin
+
diff --git a/crowbar/change-image/dell/barclamps/network/app/controllers/network_controller.rb b/crowbar/change-image/dell/barclamps/network/app/controllers/network_controller.rb
new file mode 100644
index 00000000000..7be4fd6353b
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/network/app/controllers/network_controller.rb
@@ -0,0 +1,49 @@
+# Copyright 2011, Dell
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+class NetworkController < BarclampController
+ # Make a copy of the barclamp controller help
+ self.help_contents = Array.new(superclass.help_contents)
+ def initialize
+ @service_object = NetworkService.new logger
+ end
+
+ # Below here handles ip address assignment.
+ add_help(:allocate_ip,[:id,:network,:range,:name],[:post])
+ def allocate_ip
+ id = params[:id] # Network id
+ network = params[:network]
+ range = params[:range]
+ name = params[:name]
+
+ ret = @service_object.allocate_ip(id, network, range, name)
+ return render :text => ret[1], :status => ret[0] if ret[0] != 200
+ render :json => ret[1]
+ end
+
+ # Below here handles ip address assignment.
+ add_help(:enable_interface,[:id,:network,:name],[:post])
+ def enable_interface
+ id = params[:id] # Network id
+ network = params[:network]
+ name = params[:name]
+
+ ret = @service_object.enable_interface(id, network, name)
+ return render :text => ret[1], :status => ret[0] if ret[0] != 200
+ render :json => ret[1]
+ end
+
+end
+
diff --git a/crowbar/change-image/dell/barclamps/network/app/models/network_service.rb b/crowbar/change-image/dell/barclamps/network/app/models/network_service.rb
new file mode 100644
index 00000000000..42c9bec6768
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/network/app/models/network_service.rb
@@ -0,0 +1,349 @@
+# Copyright 2011, Dell
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+class NetworkService < ServiceObject
+
+ def initialize(thelogger)
+ @bc_name = "network"
+ @logger = thelogger
+ end
+
+ def acquire_ip_lock
+ acquire_lock "ip"
+ end
+
+ def release_ip_lock(f)
+ release_lock f
+ end
+
+ def allocate_ip(bc_instance, network, range, name)
+ @logger.debug("Network allocate_ip: entering #{name} #{network} #{range}")
+
+ return [404, "No network specified"] if network.nil?
+ return [404, "No range specified"] if range.nil?
+ return [404, "No name specified"] if name.nil?
+
+ # Find the node
+ node = NodeObject.find_node_by_name name
+ @logger.error("Network allocate_ip: return node not found: #{name} #{network} #{range}") if node.nil?
+ return [404, "No node found"] if node.nil?
+
+ # Find an interface based upon config
+ role = RoleObject.find_role_by_name "network-config-#{bc_instance}"
+ @logger.error("Network allocate_ip: No network data found: #{name} #{network} #{range}") if role.nil?
+ return [404, "No network data found"] if role.nil?
+
+ mode = role.default_attributes["network"]["mode"]
+
+ # If we already have on allocated, return success
+ net_info = node.get_network_by_type(network)
+ unless net_info.nil? or net_info["address"].nil?
+ intf = net_info["interface"]
+ net_info = fix_interface(node, net_info, mode)
+ unless net_info.nil?
+ node["crowbar"]["network"][intf] = nil
+ node["crowbar"]["network"][net_info["interface"]] = net_info
+ node.save
+ end
+ @logger.error("Network allocate_ip: node already has address: #{name} #{network} #{range}")
+ return [200, net_info]
+ end
+
+ found = false
+ begin # Rescue block
+ f = acquire_ip_lock
+ db = ProposalObject.find_data_bag_item "crowbar/#{network}_network"
+
+ subnet = db["network"]["subnet"]
+ vlan = db["network"]["vlan"]
+ use_vlan = db["network"]["use_vlan"]
+ add_bridge = db["network"]["add_bridge"]
+ broadcast = db["network"]["broadcast"]
+ router = db["network"]["router"]
+ netmask = db["network"]["netmask"]
+ rangeH = db["network"]["ranges"][range]
+ rangeH = db["network"]["ranges"]["host"] if rangeH.nil?
+
+ tanswer = get_interface_info node, network, mode, use_vlan, vlan
+ if !tanswer
+ @logger.info("Network allocate_ip: return failed to find interface: #{name} #{network} #{range}")
+ return [404, "Failed to find interface"]
+ end
+ interface, interface_list, mac = tanswer
+
+ index = IPAddr.new(rangeH["start"]) & ~IPAddr.new(netmask)
+ index = index.to_i
+ stop_address = IPAddr.new(rangeH["end"]) & ~IPAddr.new(netmask)
+ stop_address = IPAddr.new(subnet) | (stop_address.to_i + 1)
+ address = IPAddr.new(subnet) | index
+
+ # Did we already allocate this, but the node lose it?
+ unless db["allocated_by_name"][node.name].nil?
+ found = true
+ address = db["allocated_by_name"][node.name]["address"]
+ end
+
+ # Let's search for an empty one.
+ while !found do
+ if db["allocated"][address.to_s].nil?
+ found = true
+ break
+ end
+ index = index + 1
+ address = IPAddr.new(subnet) | index
+ break if address == stop_address
+ end
+
+ if found
+ db["allocated_by_name"][node.name] = { "machine" => node.name, "interface" => interface, "address" => address.to_s }
+ db["allocated"][address.to_s] = { "machine" => node.name, "interface" => interface, "address" => address.to_s }
+ db.save
+ end
+ rescue Exception => e
+ @logger.error("Error finding address: #{e.message}")
+ ensure
+ release_ip_lock(f)
+ end
+
+ @logger.info("Network allocate_ip: no address available: #{name} #{network} #{range}") if !found
+ return [404, "No Address Available"] if !found
+
+ # Save the information.
+ net_info = { "interface" => interface, "address" => address.to_s, "netmask" => netmask, "mac" => mac, "node" => name, "router" => router, "subnet" => subnet, "broadcast" => broadcast, "usage" => network, "interface_list" => interface_list, "use_vlan" => use_vlan, "vlan" => vlan, "add_bridge" => add_bridge }
+ node["crowbar"]["network"][interface] = net_info
+ node.save
+
+ @logger.info("Network allocate_ip: Assigned: #{name} #{network} #{range} #{net_info["address"]}")
+ [200, net_info]
+ end
+
+ def create_proposal
+ @logger.debug("Network create_proposal: entering")
+ base = super
+
+ base["attributes"]["network"]["networks"].each do |k,net|
+ @logger.debug("Network: creating #{k} in the network")
+ bc = Chef::DataBagItem.new
+ bc.data_bag "crowbar"
+ bc["id"] = "#{k}_network"
+ bc["network"] = net
+ bc["allocated"] = {}
+ bc["allocated_by_name"] = {}
+ db = ProposalObject.new bc
+ db.save
+ end
+
+ @logger.debug("Network create_proposal: exiting")
+ base
+ end
+
+ def transition(inst, name, state)
+ @logger.debug("Network transition: Entering #{name} for #{state}")
+
+ if state == "discovered"
+ db = ProposalObject.find_proposal "network", inst
+ role = RoleObject.find_role_by_name "network-config-#{inst}"
+
+ @logger.debug("Network transition: make sure that network role is on all nodes: #{name} for #{state}")
+ result = add_role_to_instance_and_node("network", inst, name, db, role, "network")
+
+ @logger.debug("Network transition: Exiting #{name} for #{state} discovered path")
+ return [200, {}] if result
+ return [400, "Failed to add role to node"] unless result
+ end
+
+ @logger.debug("Network transition: Exiting #{name} for #{state}")
+ [200, NodeObject.find_node_by_name(name).to_hash ]
+ end
+
+ def apply_role_pre_chef_call(old_role, role, all_nodes)
+ @logger.debug("Network apply_role_pre_chef_call: entering #{all_nodes.inspect}")
+ return if all_nodes.empty?
+
+ old_mode = nil
+ old_mode = old_role.default_attributes["network"]["mode"] unless old_role.nil? or old_role.default_attributes["network"].nil?
+ new_mode = nil
+ new_mode = role.default_attributes["network"]["mode"] unless role.nil? or role.default_attributes["network"].nil?
+
+ return if old_mode == new_mode
+
+ all_nodes.each do |n|
+ node = NodeObject.find_node_by_name n
+
+ save_it = false
+ new_hash = {}
+ node["crowbar"]["network"].each do |intf, o_net_info|
+ net_info = fix_interface(node, o_net_info, new_mode)
+ unless net_info.nil?
+ save_it = true
+ new_hash[net_info["interface"]] = net_info
+ else
+ new_hash[intf] = o_net_info
+ end
+ end
+ node["crowbar"]["network"] = new_hash
+
+ @logger.debug("Network apply_role_pre_chef_call: saving node") if save_it
+ node.save if save_it
+ end
+ @logger.debug("Network apply_role_pre_chef_call: leaving")
+ end
+
+ def fix_interface(node, net_info, new_mode)
+ @logger.debug("Network fix_interface: #{node.name} #{net_info.inspect} #{new_mode}")
+ tanswer = get_interface_info node, net_info["usage"], new_mode, net_info["use_vlan"], net_info["vlan"]
+ if !tanswer
+ @logger.info("fix_interface: return failed to find interface: #{node.name}")
+ return nil
+ end
+ interface, interface_list, mac = tanswer
+
+ if interface != net_info["interface"]
+ address = net_info["address"]
+
+ begin # Rescue block
+ f = acquire_ip_lock
+ db = ProposalObject.find_data_bag_item "crowbar/#{net_info["usage"]}_network"
+ db["allocated_by_name"][node.name] = { "machine" => node.name, "interface" => interface, "address" => address }
+ db["allocated"][address] = { "machine" => node.name, "interface" => interface, "address" => address }
+ db.save
+ rescue Exception => e
+ @logger.error("Error finding address: #{e.message}")
+ ensure
+ release_ip_lock(f)
+ end
+
+ net_info["interface"] = interface
+ net_info["mac"] = mac
+ net_info["interface_list"] = interface_list
+
+ @logger.debug("Network fix_interface: leaving true: #{node.name} #{net_info.inspect} #{new_mode}")
+ return net_info
+ end
+
+ @logger.debug("Network fix_interface: leaving false: #{node.name} #{net_info.inspect} #{new_mode}")
+ return nil
+ end
+
+ def get_interface_info(node, network, mode, use_vlan, vlan)
+ @logger.debug("Network get_interface_info: entering #{node.name} #{network} #{mode} #{use_vlan} #{vlan}")
+ single = mode == "single"
+ dual = mode == "dual"
+ team = mode == "team"
+ interface_list = node.interface_list
+
+ if network == "bmc"
+ interface = "bmc"
+ mac = "bmc"
+ else
+ if single or ((network == "admin" or network == "bmc_vlan") and dual) or interface_list.size == 1
+ linterface = interface = interface_list.first
+ interface_list = [ interface ]
+ if use_vlan
+ interface = "#{interface}.#{vlan}"
+ end
+ elsif dual
+ linterface = interface = interface_list[1]
+ interface_list = [ interface ]
+ if use_vlan
+ interface = "#{interface}.#{vlan}"
+ end
+ elsif team
+ interface = "bond0"
+ linterface = interface_list.first
+ if use_vlan
+ interface = "#{interface}.#{vlan}"
+ interface_list = [ "bond0" ]
+ end
+ else
+ return false
+ end
+
+ mac = ""
+ node["network"]["interfaces"][linterface]["addresses"].each do |k,addr|
+ mac = k.downcase
+ break if addr[:family] == "lladdr"
+ end
+ end
+
+ answer = [ interface, interface_list, mac ]
+ @logger.debug("Network get_interface_info: leaving #{answer.inspect}")
+ answer
+ end
+
+ def enable_interface(bc_instance, network, name)
+ @logger.debug("Network enable_interface: entering #{name} #{network}")
+
+ return [404, "No network specified"] if network.nil?
+ return [404, "No name specified"] if name.nil?
+
+ # Find the node
+ node = NodeObject.find_node_by_name name
+ @logger.error("Network enable_interface: return node not found: #{name} #{network}") if node.nil?
+ return [404, "No node found"] if node.nil?
+
+ # Find an interface based upon config
+ role = RoleObject.find_role_by_name "network-config-#{bc_instance}"
+ @logger.error("Network enable_interface: No network data found: #{name} #{network}") if role.nil?
+ return [404, "No network data found"] if role.nil?
+
+ mode = role.default_attributes["network"]["mode"]
+
+ # If we already have on allocated, return success
+ net_info = node.get_network_by_type(network)
+ unless net_info.nil?
+ intf = net_info["interface"]
+ net_info = fix_interface(node, net_info, mode)
+ unless net_info.nil?
+ node["crowbar"]["network"][intf] = nil
+ node["crowbar"]["network"][net_info["interface"]] = net_info
+ node.save
+ end
+ @logger.error("Network enable_interface: node already has address: #{name} #{network}")
+ return [200, net_info]
+ end
+
+ begin # Rescue block
+ db = ProposalObject.find_data_bag_item "crowbar/#{network}_network"
+
+ subnet = db["network"]["subnet"]
+ vlan = db["network"]["vlan"]
+ use_vlan = db["network"]["use_vlan"]
+ add_bridge = db["network"]["add_bridge"]
+ broadcast = db["network"]["broadcast"]
+ router = db["network"]["router"]
+ netmask = db["network"]["netmask"]
+
+ tanswer = get_interface_info node, network, mode, use_vlan, vlan
+ if !tanswer
+ @logger.info("Network enable_interface: return failed to find interface: #{name} #{network} #{range}")
+ return [404, "Failed to find interface"]
+ end
+ interface, interface_list, mac = tanswer
+ rescue Exception => e
+ @logger.error("Error finding address: #{e.message}")
+ ensure
+ end
+
+ # Save the information.
+ net_info = { "interface" => interface, "netmask" => netmask, "mac" => mac, "node" => name, "router" => router, "subnet" => subnet, "broadcast" => broadcast, "usage" => network, "interface_list" => interface_list, "use_vlan" => use_vlan, "vlan" => vlan, "add_bridge" => add_bridge }
+ node["crowbar"]["network"][interface] = net_info
+ node.save
+
+ @logger.info("Network enable_interface: Assigned: #{name} #{network}")
+ [200, net_info]
+ end
+
+end
diff --git a/crowbar/change-image/dell/barclamps/network/barclamp-network.spec b/crowbar/change-image/dell/barclamps/network/barclamp-network.spec
new file mode 100644
index 00000000000..02066e96228
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/network/barclamp-network.spec
@@ -0,0 +1,52 @@
+
+%define _topdir BUILD_DIR
+%define name barclamp-network
+%define release RPM_CONTEXT_NUMBER
+%define version MAJOR_VERSION.MINOR_VERSION
+%define buildroot %{_topdir}/%{name}-%{version}-root
+
+BuildRoot: %{buildroot}
+Summary: Instantiates network interfaces on the crowbar managed systems. Also manages the address pool
+License: Apache 2.0
+Name: %{name}
+BuildArch: noarch
+Version: %{version}
+Release: %{release}
+Source: %{name}-%{version}.tar.gz
+Prefix: /
+Group: Development/Tools
+
+%description
+A Crowbar Barclamp that manages network deployments within a Crowbar environment.
+
+%prep
+%setup -q
+
+%build
+
+%install
+make install DESTDIR=${RPM_BUILD_ROOT}
+
+%post
+cd /usr/share/barclamp-network/chef/cookbooks
+knife cookbook upload -o . -a -u chef-webui -k /etc/chef/webui.pem
+
+cd /usr/share/barclamp-network/chef/data_bags/crowbar
+for i in *.json; do
+ knife data bag from file crowbar $i
+done
+
+cd /usr/share/barclamp-network/chef/roles
+for i in *.rb; do
+ knife role from file $i
+done
+
+service httpd graceful
+
+
+%files
+%defattr(-,root,root)
+/usr/bin
+/usr/share
+/opt
+
diff --git a/crowbar/change-image/dell/barclamps/network/build_deb.sh b/crowbar/change-image/dell/barclamps/network/build_deb.sh
new file mode 100755
index 00000000000..79bf21d2ba7
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/network/build_deb.sh
@@ -0,0 +1,17 @@
+#
+# Must have tools:
+# apt-get install dpkg-dev debhelper devscripts fakeroot linda dh-make
+#
+
+. ./version.sh
+
+sed -e "s/CHANGE_LOG_LINE/barclamp-${BARCLAMP_NAME} (${MAJOR_VERSION}.${MINOR_VERSION}-${DEB_CONTEXT_NUMBER}) unstable; urgency=low/" debian/changelog.tmpl > debian/changelog
+
+
+yes | debuild -us -uc
+
+mkdir -p bin
+mv ../barclamp-${BARCLAMP_NAME}_*.deb bin
+mv ../barclamp-${BARCLAMP_NAME}_*gz bin
+rm ../barclamp-${BARCLAMP_NAME}_*
+
diff --git a/crowbar/change-image/dell/barclamps/network/build_rpm.sh b/crowbar/change-image/dell/barclamps/network/build_rpm.sh
new file mode 100755
index 00000000000..c15d9be527a
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/network/build_rpm.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+
+#
+# Needs sudo apt-get install rpm
+#
+
+. ./version.sh
+
+BUILD_DIR="/tmp/build.$$"
+rm -rf ${BUILD_DIR}
+mkdir -p ${BUILD_DIR}/BUILD
+mkdir -p ${BUILD_DIR}/RPMS
+mkdir -p ${BUILD_DIR}/SOURCES
+mkdir -p ${BUILD_DIR}/SPECS
+mkdir -p ${BUILD_DIR}/SRPMS
+
+FULL_NAME="barclamp-${BARCLAMP_NAME}-${MAJOR_VERSION}.${MINOR_VERSION}"
+
+mkdir $FULL_NAME
+cp -r Makefile app chef command_line $FULL_NAME
+tar -zcf ${BUILD_DIR}/SOURCES/${FULL_NAME}.tar.gz ${FULL_NAME}
+rm -rf ${FULL_NAME}
+
+sed -e "s%BUILD_DIR%$BUILD_DIR%" barclamp-${BARCLAMP_NAME}.spec > ${BUILD_DIR}/SPECS/barclamp-${BARCLAMP_NAME}.spec
+sed -ie "s%MAJOR_VERSION%${MAJOR_VERSION}%" ${BUILD_DIR}/SPECS/barclamp-${BARCLAMP_NAME}.spec
+sed -ie "s%MINOR_VERSION%${MINOR_VERSION}%" ${BUILD_DIR}/SPECS/barclamp-${BARCLAMP_NAME}.spec
+sed -ie "s%RPM_CONTEXT_NUMBER%${RPM_CONTEXT_NUMBER}%" ${BUILD_DIR}/SPECS/barclamp-${BARCLAMP_NAME}.spec
+
+rpmbuild -v -ba --clean ${BUILD_DIR}/SPECS/barclamp-${BARCLAMP_NAME}.spec
+
+mkdir -p bin
+cp ${BUILD_DIR}/RPMS/noarch/* bin
+cp ${BUILD_DIR}/SRPMS/* bin
+#rm -rf ${BUILD_DIR}
diff --git a/crowbar/change-image/dell/barclamps/network/chef/cookbooks/network/metadata.json b/crowbar/change-image/dell/barclamps/network/chef/cookbooks/network/metadata.json
new file mode 100644
index 00000000000..2d2fc46fc02
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/network/chef/cookbooks/network/metadata.json
@@ -0,0 +1,36 @@
+{
+ "providing": {
+ },
+ "attributes": {
+ },
+ "replacing": {
+ },
+ "dependencies": {
+ },
+ "groupings": {
+ },
+ "recommendations": {
+ },
+ "platforms": {
+ "debian": [
+
+ ],
+ "ubuntu": [
+
+ ]
+ },
+ "license": "Apache 2.0",
+ "version": "0.9.5",
+ "maintainer": "Dell, Inc.",
+ "suggestions": {
+ },
+ "recipes": {
+ "network": "Installs network"
+ },
+ "maintainer_email": "crowbar@dell.com",
+ "name": "network",
+ "conflicting": {
+ },
+ "description": "Installs network",
+ "long_description": ""
+ }
diff --git a/crowbar/change-image/dell/barclamps/network/chef/cookbooks/network/recipes/default.rb b/crowbar/change-image/dell/barclamps/network/chef/cookbooks/network/recipes/default.rb
new file mode 100644
index 00000000000..b06ba68e823
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/network/chef/cookbooks/network/recipes/default.rb
@@ -0,0 +1,145 @@
+
+include_recipe 'utils'
+
+nova_network = node[:nova][:flat_interface] if !node[:nova].nil? and !node[:nova][:network_type].nil?
+nova_found = false
+
+interfaces = Array.new
+if_map = {}
+node["crowbar"]["network"].each do |intf, network|
+ nova_found = true if !nova_network.nil? and nova_network == intf
+ if network["add_bridge"]
+ # Add base interface
+ interfaces << {
+ :interface => intf,
+ :ipaddress => "0.0.0.0",
+ :vlan => network["vlan"],
+ :use_vlan => network["use_vlan"],
+ :interface_list => network["interface_list"]
+ }
+
+ # Add bridge
+ interfaces << {
+ :interface => "br#{network["vlan"]}",
+ :ipaddress => network["address"],
+ :subnet => network["subnet"],
+ :netmask => network["netmask"],
+ :broadcast => network["broadcast"],
+ :router => network["router"],
+ :interface_list => [ intf ]
+ }
+
+ if_map[intf] = true
+ if_map["br#{network["vlan"]}"] = true
+ else
+ interfaces << {
+ :interface => intf,
+ :ipaddress => network["address"],
+ :subnet => network["subnet"],
+ :netmask => network["netmask"],
+ :broadcast => network["broadcast"],
+ :router => network["router"],
+ :vlan => network["vlan"],
+ :use_vlan => network["use_vlan"],
+ :interface_list => network["interface_list"]
+ }
+ if_map[intf] = true
+ end
+end unless node["crowbar"].nil? or node["crowbar"]["network"].nil?
+
+if !nova_network.nil? and !nova_found
+ Chef::Log.fatal("Failed to define an interface with IP address for Nova!")
+ interfaces << {
+ :interface => nova_network
+ }
+end
+
+links = `ip -o link`.split("\n")
+remove_if = []
+links.each do |link|
+ if link =~ /^[0-9]+: (.*): /
+ intf = $1.split("@")[0]
+ next if if_map[intf]
+ next if intf == "lo"
+ next if intf =~ /^vnet/
+ if node["crowbar"]["network"][intf].nil?
+ remove_if << intf
+ end
+ end
+end
+
+package "bridge-utils"
+package "vlan"
+package "ifenslave-2.6"
+
+# Make sure that the /etc/network/if-up.d/upstart file is gone
+# We manage apache2 (and others), it shouldn't
+file "/etc/network/if-up.d/upstart" do
+ action :delete
+end
+
+utils_line "8021q" do
+ action :add
+ file "/etc/modules"
+end
+
+bash "load 8021q module" do
+ code "/sbin/modprobe 8021q"
+ not_if "lsmod | grep -q 8021q"
+end
+
+if node["network"]["mode"] == "team"
+ utils_line "bonding mode=6 miimon=100" do
+ action :add
+ file "/etc/modules"
+ end
+
+ bash "load bonding module" do
+ code "/sbin/modprobe bonding mode=6 miimon=100"
+ not_if "lsmod | grep -q bonding"
+ end
+end
+
+bash "ensure no dhclient" do
+ code "killall dhclient3"
+ only_if "ps -ef | grep -v grep | grep -q dhclient"
+end
+
+template "/etc/network/interfaces" do
+ source "interfaces.erb"
+ variables :interfaces => interfaces
+ notifies :run, "execute[restart-networking]", :immediately
+end
+
+execute "restart-networking" do
+ command "/etc/init.d/networking restart"
+ action :nothing
+ notifies :run, "execute[delay-networking]", :immediately
+end
+
+execute "delay-networking" do
+ command "sleep 30"
+ action :nothing
+end
+
+remove_if = remove_if.sort!{ |a, b| b <=> a }
+remove_if.each do |link|
+ bash "remove #{link} interface" do
+ code "ifconfig #{link} inet 0.0.0.0 ; ip link delete #{link} ; true"
+ only_if "ip link show #{link}"
+ end
+end
+
+if node["network"]["mode"] != "team"
+ utils_line "bonding mode=6 miimon=100" do
+ action :remove
+ file "/etc/modules"
+ end
+
+ bash "remove bonding module" do
+ code "/sbin/rmmod bonding"
+ only_if "lsmod | grep -q bonding"
+ notifies :run, "execute[restart-networking]", :immediately
+ end
+end
+
diff --git a/crowbar/change-image/dell/barclamps/network/chef/cookbooks/network/templates/default/interfaces.erb b/crowbar/change-image/dell/barclamps/network/chef/cookbooks/network/templates/default/interfaces.erb
new file mode 100644
index 00000000000..aecd5e2fde1
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/network/chef/cookbooks/network/templates/default/interfaces.erb
@@ -0,0 +1,48 @@
+
+auto lo
+iface lo inet loopback
+
+<% @interfaces.each do |interface| -%>
+<% next if interface[:interface] == "bmc" -%>
+
+<% if interface[:interface] =~ /^br/ %>
+
+auto <%= interface[:interface] %>
+iface <%= interface[:interface] %> inet static
+ bridge_ports <%= interface[:interface_list].first %>
+ bridge_stp off
+ bridge_maxwait 0
+ bridge_fd 0
+
+<% else # nova part -%>
+
+auto <%= interface[:interface] %>
+iface <%= interface[:interface] %> inet static
+
+<% end # if nova -%>
+
+<% if !interface[:ipaddress].nil? -%>
+ address <%= interface[:ipaddress] %>
+<% else -%>
+ address 0.0.0.0
+<% end -%>
+<% if !interface[:netmask].nil? -%>
+ netmask <%= interface[:netmask] %>
+<% end -%>
+<% if !interface[:broadcast].nil? -%>
+ broadcast <%= interface[:broadcast] %>
+<% end -%>
+<% if !interface[:router].nil? -%>
+ gateway <%= interface[:router] %>
+<% end -%>
+
+<% unless interface[:interface_list].nil? or interface[:interface_list].size <= 1 -%>
+ down /sbin/ifenslave -d <%= interface[:interface] %> <%= interface[:interface_list].join(" ") %>
+ up /sbin/ifenslave <%= interface[:interface] %> <%= interface[:interface_list].join(" ") %>
+<% end -%>
+<% if interface[:use_vlan] and interface[:vlan] -%>
+ vlan_raw_device <%= interface[:interface_list].first %>
+<% end -%>
+
+<% end # loop -%>
+
diff --git a/crowbar/change-image/dell/barclamps/network/chef/data_bags/crowbar/bc-template-network.json b/crowbar/change-image/dell/barclamps/network/chef/data_bags/crowbar/bc-template-network.json
new file mode 100644
index 00000000000..9b3d3e051b8
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/network/chef/data_bags/crowbar/bc-template-network.json
@@ -0,0 +1,116 @@
+{
+ "id": "bc-template-network",
+ "description": "Instantiates network interfaces on the crowbar managed systems. Also manages the address pool",
+ "attributes": {
+ "network": {
+ "mode": "single",
+ "teaming": {
+ "mode": 6
+ },
+ "networks": {
+ "storage": {
+ "vlan": 200,
+ "use_vlan": true,
+ "add_bridge": false,
+ "subnet": "192.168.125.0",
+ "netmask": "255.255.255.0",
+ "broadcast": "192.168.125.255",
+ "ranges": {
+ "host": { "start": "192.168.125.10", "end": "192.168.125.239" }
+ }
+ },
+ "public": {
+ "vlan": 300,
+ "use_vlan": true,
+ "add_bridge": false,
+ "subnet": "192.168.122.0",
+ "netmask": "255.255.255.0",
+ "broadcast": "192.168.122.255",
+ "router": "192.168.122.1",
+ "ranges": {
+ "host": { "start": "192.168.122.2", "end": "192.168.122.49" },
+ "dhcp": { "start": "192.168.122.50", "end": "192.168.122.254" },
+ "router": { "start": "192.168.122.1", "end": "192.168.122.1" }
+ }
+ },
+ "nova_fixed": {
+ "vlan": 500,
+ "use_vlan": true,
+ "add_bridge": true,
+ "subnet": "192.168.123.0",
+ "netmask": "255.255.255.0",
+ "broadcast": "192.168.123.255",
+ "router": "192.168.123.1",
+ "ranges": {
+ "host": { "start": "192.168.123.2", "end": "192.168.123.49" },
+ "dhcp": { "start": "192.168.123.50", "end": "192.168.123.254" }
+ }
+ },
+ "nova_floating": {
+ "vlan": 400,
+ "use_vlan": true,
+ "add_bridge": false,
+ "subnet": "192.168.126.0",
+ "netmask": "255.255.255.0",
+ "broadcast": "192.168.126.255",
+ "ranges": {
+ "host": { "start": "192.168.126.2", "end": "192.168.126.255" }
+ }
+ },
+ "bmc": {
+ "vlan": 100,
+ "use_vlan": false,
+ "add_bridge": false,
+ "subnet": "192.168.124.0",
+ "netmask": "255.255.255.0",
+ "broadcast": "192.168.124.255",
+ "ranges": {
+ "host": { "start": "192.168.124.162", "end": "192.168.124.240" }
+ }
+ },
+ "bmc_vlan": {
+ "vlan": 100,
+ "use_vlan": true,
+ "add_bridge": false,
+ "subnet": "192.168.124.0",
+ "netmask": "255.255.255.0",
+ "broadcast": "192.168.124.255",
+ "ranges": {
+ "host": { "start": "192.168.124.161", "end": "192.168.124.161" }
+ }
+ },
+ "admin": {
+ "vlan": 100,
+ "use_vlan": false,
+ "add_bridge": false,
+ "subnet": "192.168.124.0",
+ "netmask": "255.255.255.0",
+ "broadcast": "192.168.124.255",
+ "router": "192.168.124.1",
+ "ranges": {
+ "admin": { "start": "192.168.124.10", "end": "192.168.124.11" },
+ "dhcp": { "start": "192.168.124.21", "end": "192.168.124.80" },
+ "host": { "start": "192.168.124.81", "end": "192.168.124.160" },
+ "switch": { "start": "192.168.124.241", "end": "192.168.124.250" }
+ }
+ }
+ }
+ }
+ },
+ "deployment": {
+ "network": {
+ "crowbar-revision": 0,
+ "elements": {},
+ "element_order": [
+ [ "network" ]
+ ],
+ "config": {
+ "environment": "network-base-config",
+ "mode": "full",
+ "transitions": true,
+ "transition_list": [ "discovered" ]
+ }
+ }
+ }
+}
+
diff --git a/crowbar/change-image/dell/barclamps/network/chef/data_bags/crowbar/bc-template-network.schema b/crowbar/change-image/dell/barclamps/network/chef/data_bags/crowbar/bc-template-network.schema
new file mode 100644
index 00000000000..e5fa8caf5b3
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/network/chef/data_bags/crowbar/bc-template-network.schema
@@ -0,0 +1,109 @@
+{
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "id": { "type": "str", "required": true, "pattern": "/^bc-network-|^bc-template-network$/" },
+ "description": { "type": "str", "required": true },
+ "attributes": {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "network": {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "mode": { "type": "str", "required": true, "pattern": "/^single$|^dual$|^team$/" },
+ "teaming": {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "mode": { "type": "int", "required": true }
+ }
+ },
+ "networks": {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ = : {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "vlan": { "type": "int", "required": true },
+ "use_vlan": { "type": "bool", "required": true },
+ "add_bridge": { "type": "bool", "required": true },
+ "subnet": { "type": "str", "required": true, "name": "IpAddress" },
+ "netmask": { "type": "str", "required": true, "name": "IpAddress" },
+ "broadcast": { "type": "str", "required": true, "name": "IpAddress" },
+ "router": { "type": "str", "name": "IpAddress" },
+ "ranges": {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ = : {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "start": { "type": "str", "required": true, "name": "IpAddress" },
+ "end": { "type": "str", "required": true, "name": "IpAddress" }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "deployment": {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "network": {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "crowbar-revision": { "type": "int", "required": true },
+ "crowbar-committing": { "type": "bool" },
+ "crowbar-queued": { "type": "bool" },
+ "elements": {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ = : {
+ "type": "seq",
+ "required": true,
+ "sequence": [ { "type": "str" } ]
+ }
+ }
+ },
+ "element_order": {
+ "type": "seq",
+ "required": true,
+ "sequence": [ {
+ "type": "seq",
+ "sequence": [ { "type": "str" } ]
+ } ]
+ },
+ "config": {
+ "type": "map",
+ "required": true,
+ "mapping": {
+ "environment": { "type": "str", "required": true },
+ "mode": { "type": "str", "required": true },
+ "transitions": { "type": "bool", "required": true },
+ "transition_list": {
+ "type": "seq",
+ "required": true,
+ "sequence": [ { "type": "str" } ]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/crowbar/change-image/dell/barclamps/network/chef/roles/network.rb b/crowbar/change-image/dell/barclamps/network/chef/roles/network.rb
new file mode 100644
index 00000000000..9ea75c47abb
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/network/chef/roles/network.rb
@@ -0,0 +1,7 @@
+
+name "network"
+description "Network role - Setups the network"
+run_list("recipe[network]")
+default_attributes()
+override_attributes()
+
diff --git a/crowbar/change-image/dell/barclamps/network/command_line/crowbar_network b/crowbar/change-image/dell/barclamps/network/command_line/crowbar_network
new file mode 100755
index 00000000000..06a007a4be3
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/network/command_line/crowbar_network
@@ -0,0 +1,49 @@
+#!/usr/bin/env ruby
+
+require File.join(File.expand_path(File.dirname(__FILE__)), "barclamp_lib")
+@barclamp = "network"
+
+
+@commands["allocate_ip"] = [ "allocate_ip(ARGV.shift,ARGV.shift,ARGV.shift,ARGV.shift)", "allocate_ip - Allocate an ip for a name on a network from a range" ]
+@commands["enable_interface"] = [ "enable_interface(ARGV.shift,ARGV.shift,ARGV.shift)", "enable_interface - Ensure that an interface is present for the specified network" ]
+
+def enable_interface(name, node, network)
+ usage -1 if name.nil? or name == ""
+ usage -1 if node.nil? or node == ""
+ usage -1 if network.nil? or network == ""
+
+ @data = { "name" => node, "network" => network }.to_json
+ struct = post_json("/enable_interface/#{name}", @data)
+
+ if struct[1] == 200
+ [ "Edited #{name} #{struct[0].inspect}", 0 ]
+ elsif struct[1] == 404
+ [ "Failed to edit: #{name} : Not Found", 1 ]
+ elsif struct[1] == 400
+ [ "Failed to edit: #{name} : Errors in data\n#{struct[0]}", 1 ]
+ else
+ [ "Failed to talk to service enable_interface: #{struct[1]}: #{struct[0]}", 1 ]
+ end
+end
+
+def allocate_ip(name, node, network, range)
+ usage -1 if name.nil? or name == ""
+ usage -1 if network.nil? or network == ""
+ usage -1 if node.nil? or node == ""
+ usage -1 if range.nil? or range == ""
+
+ @data = { "name" => node, "network" => network, "range" => range }.to_json
+ struct = post_json("/allocate_ip/#{name}", @data)
+
+ if struct[1] == 200
+ [ "Edited #{name} #{struct[0].inspect}", 0 ]
+ elsif struct[1] == 404
+ [ "Failed to edit: #{name} : Not Found", 1 ]
+ elsif struct[1] == 400
+ [ "Failed to edit: #{name} : Errors in data\n#{struct[0]}", 1 ]
+ else
+ [ "Failed to talk to service allocate_ip: #{struct[1]}: #{struct[0]}", 1 ]
+ end
+end
+
+main
diff --git a/crowbar/change-image/dell/barclamps/network/debian/changelog.tmpl b/crowbar/change-image/dell/barclamps/network/debian/changelog.tmpl
new file mode 100644
index 00000000000..42694be8134
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/network/debian/changelog.tmpl
@@ -0,0 +1,5 @@
+CHANGE_LOG_LINE
+
+ * Initial Release.
+
+ -- unknown Thu, 19 May 2011 15:50:02 -0500
diff --git a/crowbar/change-image/dell/barclamps/network/debian/compat b/crowbar/change-image/dell/barclamps/network/debian/compat
new file mode 100644
index 00000000000..7f8f011eb73
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/network/debian/compat
@@ -0,0 +1 @@
+7
diff --git a/crowbar/change-image/dell/barclamps/network/debian/control b/crowbar/change-image/dell/barclamps/network/debian/control
new file mode 100644
index 00000000000..f891f172e63
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/network/debian/control
@@ -0,0 +1,13 @@
+Source: barclamp-network
+Section: unknown
+Priority: extra
+Maintainer: Dell Openstack
+Build-Depends: debhelper (>= 7.0.50~)
+Standards-Version: 3.9.1
+Homepage: http://openstack.dell.com/
+
+Package: barclamp-network
+Architecture: all
+Depends: barclamp-crowbar
+Description: Ganglia Barclamp for Crowbar
+ Provides the network barclamp for crowbar
diff --git a/crowbar/change-image/dell/barclamps/network/debian/copyright b/crowbar/change-image/dell/barclamps/network/debian/copyright
new file mode 100644
index 00000000000..ef293d897c8
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/network/debian/copyright
@@ -0,0 +1,26 @@
+This work was packaged for Debian by:
+
+ Dell Openstack Team on Thu, 19 May 2011 15:50:02 -0500
+
+It was downloaded from:
+
+
+
+Upstream Author(s):
+
+ Openstack Dell Team
+
+Copyright:
+
+ Copyright (C) 2011 Dell, Inc.
+
+License:
+
+GREG: Fill in Apache 2.0
+
+The Debian packaging is:
+
+ Copyright (C) 2011 Dell
+
+and is licensed under Apache 2.0, see above.
+
diff --git a/crowbar/change-image/dell/barclamps/network/debian/postinst b/crowbar/change-image/dell/barclamps/network/debian/postinst
new file mode 100644
index 00000000000..0e820597d27
--- /dev/null
+++ b/crowbar/change-image/dell/barclamps/network/debian/postinst
@@ -0,0 +1,53 @@
+#!/bin/sh
+# postinst script for #PACKAGE#
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+# * `configure'
+# * `abort-upgrade'
+# * `abort-remove' `in-favour'
+#
+# * `abort-remove'
+# * `abort-deconfigure' `in-favour'
+# `removing'
+#