diff --git a/tools/info.sh b/tools/info.sh new file mode 100755 index 0000000000..edff617f96 --- /dev/null +++ b/tools/info.sh @@ -0,0 +1,213 @@ +#!/usr/bin/env bash +# info.sh - Produce a report on the state of devstack installs +# +# Output fields are separated with '|' chars +# Output types are git,localrc,os,pip,pkg: +# git||[] +# localtc|= +# os|= +# pip|| +# pkg|| + +function usage { + echo "$0 - Report on the devstack configuration" + echo "" + echo "Usage: $0" + exit 1 +} + +if [ "$1" = "-h" ]; then + usage +fi + +# Keep track of the current directory +TOOLS_DIR=$(cd $(dirname "$0") && pwd) +TOP_DIR=$(cd $TOOLS_DIR/..; pwd) +cd $TOP_DIR + +# Source params +source $TOP_DIR/stackrc + +DEST=${DEST:-/opt/stack} +FILES=$TOP_DIR/files +if [[ ! -d $FILES ]]; then + echo "ERROR: missing devstack/files - did you grab more than just stack.sh?" + exit 1 +fi + +# Repos +# ----- + +# git_report +function git_report() { + local dir=$1 + local proj ref branch head + if [[ -d $dir/.git ]]; then + pushd $dir >/dev/null + proj=$(basename $dir) + ref=$(git symbolic-ref HEAD) + branch=${ref##refs/heads/} + head=$(git show-branch --sha1-name $branch | cut -d' ' -f1) + echo "git|${proj}|${branch}${head}" + popd >/dev/null + fi +} + +for i in $DEST/*; do + if [[ -d $i ]]; then + git_report $i + fi +done + +# OS +# -- + +GetOSInfo() { + # Figure out which vedor we are + if [ -r /etc/lsb-release ]; then + . /etc/lsb-release + VENDORNAME=$DISTRIB_ID + RELEASE=$DISTRIB_RELEASE + else + for r in RedHat CentOS Fedora; do + VENDORPKG="`echo $r | tr [:upper:] [:lower:]`-release" + VENDORNAME=$r + RELEASE=`rpm -q --queryformat '%{VERSION}' $VENDORPKG` + if [ $? = 0 ]; then + break + fi + VENDORNAME="" + done + # Get update level + if [ -n "`grep Update /etc/redhat-release`" ]; then + # Get update + UPDATE=`cat /etc/redhat-release | sed s/.*Update\ // | sed s/\)$//` + else + # Assume update 0 + UPDATE=0 + fi + fi + + echo "os|vendor=$VENDORNAME" + echo "os|release=$RELEASE" + if [ -n "$UPDATE" ]; then + echo "os|version=$UPDATE" + fi +} + +GetOSInfo + +# Packages +# -------- + +# - We are going to check packages only for the services needed. +# - We are parsing the packages files and detecting metadatas. +# - If we have the meta-keyword dist:DISTRO or +# dist:DISTRO1,DISTRO2 it will be installed only for those +# distros (case insensitive). +function get_packages() { + local file_to_parse="general" + local service + + for service in ${ENABLED_SERVICES//,/ }; do + # Allow individual services to specify dependencies + if [[ -e $FILES/apts/${service} ]]; then + file_to_parse="${file_to_parse} $service" + fi + if [[ $service == n-* ]]; then + if [[ ! $file_to_parse =~ nova ]]; then + file_to_parse="${file_to_parse} nova" + fi + elif [[ $service == g-* ]]; then + if [[ ! $file_to_parse =~ glance ]]; then + file_to_parse="${file_to_parse} glance" + fi + elif [[ $service == key* ]]; then + if [[ ! $file_to_parse =~ keystone ]]; then + file_to_parse="${file_to_parse} keystone" + fi + fi + done + + for file in ${file_to_parse}; do + local fname=${FILES}/apts/${file} + local OIFS line package distros distro + [[ -e $fname ]] || { echo "missing: $fname"; exit 1; } + + OIFS=$IFS + IFS=$'\n' + for line in $(<${fname}); do + if [[ $line =~ (.*)#.*dist:([^ ]*) ]]; then # We are using BASH regexp matching feature. + package=${BASH_REMATCH[1]} + distros=${BASH_REMATCH[2]} + for distro in ${distros//,/ }; do #In bash ${VAR,,} will lowecase VAR + [[ ${distro,,} == ${DISTRO,,} ]] && echo $package + done + continue + fi + + echo ${line%#*} + done + IFS=$OIFS + done +} + +for p in $(get_packages); do + ver=$(dpkg -s $p 2>/dev/null | grep '^Version: ' | cut -d' ' -f2) + echo "pkg|${p}|${ver}" +done + +# Pips +# ---- + +function get_pips() { + cat $FILES/pips/* | uniq +} + +# Pip tells us what is currently installed +FREEZE_FILE=$(mktemp --tmpdir freeze.XXXXXX) +pip freeze >$FREEZE_FILE 2>/dev/null + +# Loop through our requirements and look for matches +for p in $(get_pips); do + [[ "$p" = "-e" ]] && continue + if [[ "$p" =~ \+?([^#]*)#? ]]; then + # Get the URL from a remote reference + p=${BASH_REMATCH[1]} + fi + line="`grep -i $p $FREEZE_FILE`" + if [[ -n "$line" ]]; then + if [[ "$line" =~ \+(.*)@(.*)#egg=(.*) ]]; then + # Handle URLs + p=${BASH_REMATCH[1]} + ver=${BASH_REMATCH[2]} + elif [[ "$line" =~ (.*)[=\<\>]=(.*) ]]; then + # Normal pip packages + p=${BASH_REMATCH[1]} + ver=${BASH_REMATCH[2]} + else + # Unhandled format in freeze file + #echo "unknown: $p" + continue + fi + echo "pip|${p}|${ver}" + else + # No match in freeze file + #echo "unknown: $p" + continue + fi +done + +rm $FREEZE_FILE + +# localrc +# ------- + +# Dump localrc with 'localrc|' prepended and comments and passwords left out +if [[ -r $TOP_DIR/localrc ]]; then + sed -e ' + /PASSWORD/d; + /^#/d; + s/^/localrc\|/; + ' $TOP_DIR/localrc | sort +fi