| Dean Troyer | dec00f6 | 2011-12-30 17:43:20 -0600 | [diff] [blame] | 1 | #!/usr/bin/env bash | 
|  | 2 | # info.sh - Produce a report on the state of devstack installs | 
|  | 3 | # | 
|  | 4 | # Output fields are separated with '|' chars | 
|  | 5 | # Output types are git,localrc,os,pip,pkg: | 
|  | 6 | #   git|<project>|<branch>[<shaq>] | 
|  | 7 | #   localtc|<var>=<value> | 
|  | 8 | #   os|<var>=<value> | 
|  | 9 | #   pip|<package>|<version> | 
|  | 10 | #   pkg|<package>|<version> | 
|  | 11 |  | 
|  | 12 | function usage { | 
|  | 13 | echo "$0 - Report on the devstack configuration" | 
|  | 14 | echo "" | 
|  | 15 | echo "Usage: $0" | 
|  | 16 | exit 1 | 
|  | 17 | } | 
|  | 18 |  | 
|  | 19 | if [ "$1" = "-h" ]; then | 
|  | 20 | usage | 
|  | 21 | fi | 
|  | 22 |  | 
|  | 23 | # Keep track of the current directory | 
|  | 24 | TOOLS_DIR=$(cd $(dirname "$0") && pwd) | 
|  | 25 | TOP_DIR=$(cd $TOOLS_DIR/..; pwd) | 
|  | 26 | cd $TOP_DIR | 
|  | 27 |  | 
|  | 28 | # Source params | 
|  | 29 | source $TOP_DIR/stackrc | 
|  | 30 |  | 
|  | 31 | DEST=${DEST:-/opt/stack} | 
|  | 32 | FILES=$TOP_DIR/files | 
|  | 33 | if [[ ! -d $FILES ]]; then | 
|  | 34 | echo "ERROR: missing devstack/files - did you grab more than just stack.sh?" | 
|  | 35 | exit 1 | 
|  | 36 | fi | 
|  | 37 |  | 
|  | 38 | # Repos | 
|  | 39 | # ----- | 
|  | 40 |  | 
|  | 41 | # git_report <dir> | 
|  | 42 | function git_report() { | 
|  | 43 | local dir=$1 | 
|  | 44 | local proj ref branch head | 
|  | 45 | if [[ -d $dir/.git ]]; then | 
|  | 46 | pushd $dir >/dev/null | 
|  | 47 | proj=$(basename $dir) | 
|  | 48 | ref=$(git symbolic-ref HEAD) | 
|  | 49 | branch=${ref##refs/heads/} | 
|  | 50 | head=$(git show-branch --sha1-name $branch | cut -d' ' -f1) | 
|  | 51 | echo "git|${proj}|${branch}${head}" | 
|  | 52 | popd >/dev/null | 
|  | 53 | fi | 
|  | 54 | } | 
|  | 55 |  | 
|  | 56 | for i in $DEST/*; do | 
|  | 57 | if [[ -d $i ]]; then | 
|  | 58 | git_report $i | 
|  | 59 | fi | 
|  | 60 | done | 
|  | 61 |  | 
|  | 62 | # OS | 
|  | 63 | # -- | 
|  | 64 |  | 
|  | 65 | GetOSInfo() { | 
|  | 66 | # Figure out which vedor we are | 
|  | 67 | if [ -r /etc/lsb-release ]; then | 
|  | 68 | . /etc/lsb-release | 
|  | 69 | VENDORNAME=$DISTRIB_ID | 
|  | 70 | RELEASE=$DISTRIB_RELEASE | 
|  | 71 | else | 
|  | 72 | for r in RedHat CentOS Fedora; do | 
|  | 73 | VENDORPKG="`echo $r | tr [:upper:] [:lower:]`-release" | 
|  | 74 | VENDORNAME=$r | 
|  | 75 | RELEASE=`rpm -q --queryformat '%{VERSION}' $VENDORPKG` | 
|  | 76 | if [ $? = 0 ]; then | 
|  | 77 | break | 
|  | 78 | fi | 
|  | 79 | VENDORNAME="" | 
|  | 80 | done | 
|  | 81 | # Get update level | 
|  | 82 | if [ -n "`grep Update /etc/redhat-release`" ]; then | 
|  | 83 | # Get update | 
|  | 84 | UPDATE=`cat /etc/redhat-release | sed s/.*Update\ // | sed s/\)$//` | 
|  | 85 | else | 
|  | 86 | # Assume update 0 | 
|  | 87 | UPDATE=0 | 
|  | 88 | fi | 
|  | 89 | fi | 
|  | 90 |  | 
|  | 91 | echo "os|vendor=$VENDORNAME" | 
|  | 92 | echo "os|release=$RELEASE" | 
|  | 93 | if [ -n "$UPDATE" ]; then | 
|  | 94 | echo "os|version=$UPDATE" | 
|  | 95 | fi | 
|  | 96 | } | 
|  | 97 |  | 
|  | 98 | GetOSInfo | 
|  | 99 |  | 
|  | 100 | # Packages | 
|  | 101 | # -------- | 
|  | 102 |  | 
|  | 103 | # - We are going to check packages only for the services needed. | 
|  | 104 | # - We are parsing the packages files and detecting metadatas. | 
|  | 105 | #  - If we have the meta-keyword dist:DISTRO or | 
|  | 106 | #    dist:DISTRO1,DISTRO2 it will be installed only for those | 
|  | 107 | #    distros (case insensitive). | 
|  | 108 | function get_packages() { | 
|  | 109 | local file_to_parse="general" | 
|  | 110 | local service | 
|  | 111 |  | 
|  | 112 | for service in ${ENABLED_SERVICES//,/ }; do | 
|  | 113 | # Allow individual services to specify dependencies | 
|  | 114 | if [[ -e $FILES/apts/${service} ]]; then | 
|  | 115 | file_to_parse="${file_to_parse} $service" | 
|  | 116 | fi | 
|  | 117 | if [[ $service == n-* ]]; then | 
|  | 118 | if [[ ! $file_to_parse =~ nova ]]; then | 
|  | 119 | file_to_parse="${file_to_parse} nova" | 
|  | 120 | fi | 
|  | 121 | elif [[ $service == g-* ]]; then | 
|  | 122 | if [[ ! $file_to_parse =~ glance ]]; then | 
|  | 123 | file_to_parse="${file_to_parse} glance" | 
|  | 124 | fi | 
|  | 125 | elif [[ $service == key* ]]; then | 
|  | 126 | if [[ ! $file_to_parse =~ keystone ]]; then | 
|  | 127 | file_to_parse="${file_to_parse} keystone" | 
|  | 128 | fi | 
|  | 129 | fi | 
|  | 130 | done | 
|  | 131 |  | 
|  | 132 | for file in ${file_to_parse}; do | 
|  | 133 | local fname=${FILES}/apts/${file} | 
|  | 134 | local OIFS line package distros distro | 
|  | 135 | [[ -e $fname ]] || { echo "missing: $fname"; exit 1; } | 
|  | 136 |  | 
|  | 137 | OIFS=$IFS | 
|  | 138 | IFS=$'\n' | 
|  | 139 | for line in $(<${fname}); do | 
|  | 140 | if [[ $line =~ (.*)#.*dist:([^ ]*) ]]; then # We are using BASH regexp matching feature. | 
|  | 141 | package=${BASH_REMATCH[1]} | 
|  | 142 | distros=${BASH_REMATCH[2]} | 
|  | 143 | for distro in ${distros//,/ }; do  #In bash ${VAR,,} will lowecase VAR | 
|  | 144 | [[ ${distro,,} == ${DISTRO,,} ]] && echo $package | 
|  | 145 | done | 
|  | 146 | continue | 
|  | 147 | fi | 
|  | 148 |  | 
|  | 149 | echo ${line%#*} | 
|  | 150 | done | 
|  | 151 | IFS=$OIFS | 
|  | 152 | done | 
|  | 153 | } | 
|  | 154 |  | 
|  | 155 | for p in $(get_packages); do | 
|  | 156 | ver=$(dpkg -s $p 2>/dev/null | grep '^Version: ' | cut -d' ' -f2) | 
|  | 157 | echo "pkg|${p}|${ver}" | 
|  | 158 | done | 
|  | 159 |  | 
|  | 160 | # Pips | 
|  | 161 | # ---- | 
|  | 162 |  | 
|  | 163 | function get_pips() { | 
|  | 164 | cat $FILES/pips/* | uniq | 
|  | 165 | } | 
|  | 166 |  | 
|  | 167 | # Pip tells us what is currently installed | 
|  | 168 | FREEZE_FILE=$(mktemp --tmpdir freeze.XXXXXX) | 
|  | 169 | pip freeze >$FREEZE_FILE 2>/dev/null | 
|  | 170 |  | 
|  | 171 | # Loop through our requirements and look for matches | 
|  | 172 | for p in $(get_pips); do | 
|  | 173 | [[ "$p" = "-e" ]] && continue | 
|  | 174 | if [[ "$p" =~ \+?([^#]*)#? ]]; then | 
|  | 175 | # Get the URL from a remote reference | 
|  | 176 | p=${BASH_REMATCH[1]} | 
|  | 177 | fi | 
|  | 178 | line="`grep -i $p $FREEZE_FILE`" | 
|  | 179 | if [[ -n "$line" ]]; then | 
|  | 180 | if [[ "$line" =~ \+(.*)@(.*)#egg=(.*) ]]; then | 
|  | 181 | # Handle URLs | 
|  | 182 | p=${BASH_REMATCH[1]} | 
|  | 183 | ver=${BASH_REMATCH[2]} | 
|  | 184 | elif [[ "$line" =~ (.*)[=\<\>]=(.*) ]]; then | 
|  | 185 | # Normal pip packages | 
|  | 186 | p=${BASH_REMATCH[1]} | 
|  | 187 | ver=${BASH_REMATCH[2]} | 
|  | 188 | else | 
|  | 189 | # Unhandled format in freeze file | 
|  | 190 | #echo "unknown: $p" | 
|  | 191 | continue | 
|  | 192 | fi | 
|  | 193 | echo "pip|${p}|${ver}" | 
|  | 194 | else | 
|  | 195 | # No match in freeze file | 
|  | 196 | #echo "unknown: $p" | 
|  | 197 | continue | 
|  | 198 | fi | 
|  | 199 | done | 
|  | 200 |  | 
|  | 201 | rm $FREEZE_FILE | 
|  | 202 |  | 
|  | 203 | # localrc | 
|  | 204 | # ------- | 
|  | 205 |  | 
|  | 206 | # Dump localrc with 'localrc|' prepended and comments and passwords left out | 
|  | 207 | if [[ -r $TOP_DIR/localrc ]]; then | 
|  | 208 | sed -e ' | 
|  | 209 | /PASSWORD/d; | 
|  | 210 | /^#/d; | 
|  | 211 | s/^/localrc\|/; | 
|  | 212 | ' $TOP_DIR/localrc | sort | 
|  | 213 | fi |