| # functions - Common functions used by DevStack components | 
 | # | 
 | # ENABLED_SERVICES is used by is_service_enabled() | 
 |  | 
 |  | 
 | # Save trace setting | 
 | XTRACE=$(set +o | grep xtrace) | 
 | set +o xtrace | 
 |  | 
 |  | 
 | # apt-get wrapper to set arguments correctly | 
 | # apt_get operation package [package ...] | 
 | function apt_get() { | 
 |     [[ "$OFFLINE" = "True" || -z "$@" ]] && return | 
 |     local sudo="sudo" | 
 |     [[ "$(id -u)" = "0" ]] && sudo="env" | 
 |     $sudo DEBIAN_FRONTEND=noninteractive \ | 
 |         http_proxy=$http_proxy https_proxy=$https_proxy \ | 
 |         apt-get --option "Dpkg::Options::=--force-confold" --assume-yes "$@" | 
 | } | 
 |  | 
 |  | 
 | # Gracefully cp only if source file/dir exists | 
 | # cp_it source destination | 
 | function cp_it { | 
 |     if [ -e $1 ] || [ -d $1 ]; then | 
 |         cp -pRL $1 $2 | 
 |     fi | 
 | } | 
 |  | 
 |  | 
 | # Prints "message" and exits | 
 | # die "message" | 
 | function die() { | 
 |     local exitcode=$? | 
 |     set +o xtrace | 
 |     echo $@ | 
 |     exit $exitcode | 
 | } | 
 |  | 
 |  | 
 | # Checks an environment variable is not set or has length 0 OR if the | 
 | # exit code is non-zero and prints "message" and exits | 
 | # NOTE: env-var is the variable name without a '$' | 
 | # die_if_not_set env-var "message" | 
 | function die_if_not_set() { | 
 |     ( | 
 |         local exitcode=$? | 
 |         set +o xtrace | 
 |         local evar=$1; shift | 
 |         if ! is_set $evar || [ $exitcode != 0 ]; then | 
 |             set +o xtrace | 
 |             echo $@ | 
 |             exit -1 | 
 |         fi | 
 |     ) | 
 | } | 
 |  | 
 |  | 
 | # Grab a numbered field from python prettytable output | 
 | # Fields are numbered starting with 1 | 
 | # Reverse syntax is supported: -1 is the last field, -2 is second to last, etc. | 
 | # get_field field-number | 
 | function get_field() { | 
 |     while read data; do | 
 |         if [ "$1" -lt 0 ]; then | 
 |             field="(\$(NF$1))" | 
 |         else | 
 |             field="\$$(($1 + 1))" | 
 |         fi | 
 |         echo "$data" | awk -F'[ \t]*\\|[ \t]*' "{print $field}" | 
 |     done | 
 | } | 
 |  | 
 |  | 
 | # Determine OS Vendor, Release and Update | 
 | # Tested with OS/X, Ubuntu, RedHat, CentOS, Fedora | 
 | # Returns results in global variables: | 
 | # os_VENDOR - vendor name | 
 | # os_RELEASE - release | 
 | # os_UPDATE - update | 
 | # os_PACKAGE - package type | 
 | # os_CODENAME - vendor's codename for release | 
 | # GetOSVersion | 
 | GetOSVersion() { | 
 |     # Figure out which vendor we are | 
 |     if [[ -n "`which sw_vers 2>/dev/null`" ]]; then | 
 |         # OS/X | 
 |         os_VENDOR=`sw_vers -productName` | 
 |         os_RELEASE=`sw_vers -productVersion` | 
 |         os_UPDATE=${os_RELEASE##*.} | 
 |         os_RELEASE=${os_RELEASE%.*} | 
 |         os_PACKAGE="" | 
 |         if [[ "$os_RELEASE" =~ "10.7" ]]; then | 
 |             os_CODENAME="lion" | 
 |         elif [[ "$os_RELEASE" =~ "10.6" ]]; then | 
 |             os_CODENAME="snow leopard" | 
 |         elif [[ "$os_RELEASE" =~ "10.5" ]]; then | 
 |             os_CODENAME="leopard" | 
 |         elif [[ "$os_RELEASE" =~ "10.4" ]]; then | 
 |             os_CODENAME="tiger" | 
 |         elif [[ "$os_RELEASE" =~ "10.3" ]]; then | 
 |             os_CODENAME="panther" | 
 |         else | 
 |             os_CODENAME="" | 
 |         fi | 
 |     elif [[ -x $(which lsb_release 2>/dev/null) ]]; then | 
 |         os_VENDOR=$(lsb_release -i -s) | 
 |         os_RELEASE=$(lsb_release -r -s) | 
 |         os_UPDATE="" | 
 |         if [[ "Debian,Ubuntu" =~ $os_VENDOR ]]; then | 
 |             os_PACKAGE="deb" | 
 |         else | 
 |             os_PACKAGE="rpm" | 
 |         fi | 
 |         os_CODENAME=$(lsb_release -c -s) | 
 |     elif [[ -r /etc/redhat-release ]]; then | 
 |         # Red Hat Enterprise Linux Server release 5.5 (Tikanga) | 
 |         # CentOS release 5.5 (Final) | 
 |         # CentOS Linux release 6.0 (Final) | 
 |         # Fedora release 16 (Verne) | 
 |         os_CODENAME="" | 
 |         for r in "Red Hat" CentOS Fedora; do | 
 |             os_VENDOR=$r | 
 |             if [[ -n "`grep \"$r\" /etc/redhat-release`" ]]; then | 
 |                 ver=`sed -e 's/^.* \(.*\) (\(.*\)).*$/\1\|\2/' /etc/redhat-release` | 
 |                 os_CODENAME=${ver#*|} | 
 |                 os_RELEASE=${ver%|*} | 
 |                 os_UPDATE=${os_RELEASE##*.} | 
 |                 os_RELEASE=${os_RELEASE%.*} | 
 |                 break | 
 |             fi | 
 |             os_VENDOR="" | 
 |         done | 
 |         os_PACKAGE="rpm" | 
 |     fi | 
 |     export os_VENDOR os_RELEASE os_UPDATE os_PACKAGE os_CODENAME | 
 | } | 
 |  | 
 |  | 
 | # git clone only if directory doesn't exist already.  Since ``DEST`` might not | 
 | # be owned by the installation user, we create the directory and change the | 
 | # ownership to the proper user. | 
 | # Set global RECLONE=yes to simulate a clone when dest-dir exists | 
 | # git_clone remote dest-dir branch | 
 | function git_clone { | 
 |     [[ "$OFFLINE" = "True" ]] && return | 
 |  | 
 |     GIT_REMOTE=$1 | 
 |     GIT_DEST=$2 | 
 |     GIT_BRANCH=$3 | 
 |  | 
 |     if echo $GIT_BRANCH | egrep -q "^refs"; then | 
 |         # If our branch name is a gerrit style refs/changes/... | 
 |         if [[ ! -d $GIT_DEST ]]; then | 
 |             git clone $GIT_REMOTE $GIT_DEST | 
 |         fi | 
 |         cd $GIT_DEST | 
 |         git fetch $GIT_REMOTE $GIT_BRANCH && git checkout FETCH_HEAD | 
 |     else | 
 |         # do a full clone only if the directory doesn't exist | 
 |         if [[ ! -d $GIT_DEST ]]; then | 
 |             git clone $GIT_REMOTE $GIT_DEST | 
 |             cd $GIT_DEST | 
 |             # This checkout syntax works for both branches and tags | 
 |             git checkout $GIT_BRANCH | 
 |         elif [[ "$RECLONE" == "yes" ]]; then | 
 |             # if it does exist then simulate what clone does if asked to RECLONE | 
 |             cd $GIT_DEST | 
 |             # set the url to pull from and fetch | 
 |             git remote set-url origin $GIT_REMOTE | 
 |             git fetch origin | 
 |             # remove the existing ignored files (like pyc) as they cause breakage | 
 |             # (due to the py files having older timestamps than our pyc, so python | 
 |             # thinks the pyc files are correct using them) | 
 |             find $GIT_DEST -name '*.pyc' -delete | 
 |             git checkout -f origin/$GIT_BRANCH | 
 |             # a local branch might not exist | 
 |             git branch -D $GIT_BRANCH || true | 
 |             git checkout -b $GIT_BRANCH | 
 |         fi | 
 |     fi | 
 | } | 
 |  | 
 |  | 
 | # Comment an option in an INI file | 
 | # iniset config-file section option | 
 | function inicomment() { | 
 |     local file=$1 | 
 |     local section=$2 | 
 |     local option=$3 | 
 |     sed -i -e "/^\[$section\]/,/^\[.*\]/ s|^\($option[ \t]*=.*$\)|#\1|" $file | 
 | } | 
 |  | 
 |  | 
 | # Get an option from an INI file | 
 | # iniget config-file section option | 
 | function iniget() { | 
 |     local file=$1 | 
 |     local section=$2 | 
 |     local option=$3 | 
 |     local line | 
 |     line=$(sed -ne "/^\[$section\]/,/^\[.*\]/ { /^$option[ \t]*=/ p; }" $file) | 
 |     echo ${line#*=} | 
 | } | 
 |  | 
 |  | 
 | # Set an option in an INI file | 
 | # iniset config-file section option value | 
 | function iniset() { | 
 |     local file=$1 | 
 |     local section=$2 | 
 |     local option=$3 | 
 |     local value=$4 | 
 |     if ! grep -q "^\[$section\]" $file; then | 
 |         # Add section at the end | 
 |         echo -e "\n[$section]" >>$file | 
 |     fi | 
 |     if [[ -z "$(iniget $file $section $option)" ]]; then | 
 |         # Add it | 
 |         sed -i -e "/^\[$section\]/ a\\ | 
 | $option = $value | 
 | " $file | 
 |     else | 
 |         # Replace it | 
 |         sed -i -e "/^\[$section\]/,/^\[.*\]/ s|^\($option[ \t]*=[ \t]*\).*$|\1$value|" $file | 
 |     fi | 
 | } | 
 |  | 
 |  | 
 | # is_service_enabled() checks if the service(s) specified as arguments are | 
 | # enabled by the user in **ENABLED_SERVICES**. | 
 | # | 
 | # If there are multiple services specified as arguments the test performs a | 
 | # boolean OR or if any of the services specified on the command line | 
 | # return true. | 
 | # | 
 | # There is a special cases for some 'catch-all' services:: | 
 | #   **nova** returns true if any service enabled start with **n-** | 
 | #   **glance** returns true if any service enabled start with **g-** | 
 | #   **quantum** returns true if any service enabled start with **q-** | 
 | function is_service_enabled() { | 
 |     services=$@ | 
 |     for service in ${services}; do | 
 |         [[ ,${ENABLED_SERVICES}, =~ ,${service}, ]] && return 0 | 
 |         [[ ${service} == "nova" && ${ENABLED_SERVICES} =~ "n-" ]] && return 0 | 
 |         [[ ${service} == "glance" && ${ENABLED_SERVICES} =~ "g-" ]] && return 0 | 
 |         [[ ${service} == "quantum" && ${ENABLED_SERVICES} =~ "q-" ]] && return 0 | 
 |     done | 
 |     return 1 | 
 | } | 
 |  | 
 |  | 
 | # Distro-agnostic package installer | 
 | # install_package package [package ...] | 
 | function install_package() { | 
 |     if [[ -z "$os_PACKAGE" ]]; then | 
 |         GetOSVersion | 
 |     fi | 
 |     if [[ "$os_PACKAGE" = "deb" ]]; then | 
 |         apt_get install "$@" | 
 |     else | 
 |         yum_install "$@" | 
 |     fi | 
 | } | 
 |  | 
 |  | 
 | # Test if the named environment variable is set and not zero length | 
 | # is_set env-var | 
 | function is_set() { | 
 |     local var=\$"$1" | 
 |     if eval "[ -z $var ]"; then | 
 |         return 1 | 
 |     fi | 
 |     return 0 | 
 | } | 
 |  | 
 |  | 
 | # pip install wrapper to set cache and proxy environment variables | 
 | # pip_install package [package ...] | 
 | function pip_install { | 
 |     [[ "$OFFLINE" = "True" || -z "$@" ]] && return | 
 |     if [[ -z "$os_PACKAGE" ]]; then | 
 |         GetOSVersion | 
 |     fi | 
 |     if [[ "$os_PACKAGE" = "deb" ]]; then | 
 |         CMD_PIP=/usr/bin/pip | 
 |     else | 
 |         CMD_PIP=/usr/bin/pip-python | 
 |     fi | 
 |     sudo PIP_DOWNLOAD_CACHE=/var/cache/pip \ | 
 |         HTTP_PROXY=$http_proxy \ | 
 |         HTTPS_PROXY=$https_proxy \ | 
 |         $CMD_PIP install --use-mirrors $@ | 
 | } | 
 |  | 
 |  | 
 | # Service wrapper to restart services | 
 | # restart_service service-name | 
 | function restart_service() { | 
 |     if [[ -z "$os_PACKAGE" ]]; then | 
 |         GetOSVersion | 
 |     fi | 
 |     if [[ "$os_PACKAGE" = "deb" ]]; then | 
 |         sudo /usr/sbin/service $1 restart | 
 |     else | 
 |         sudo /sbin/service $1 restart | 
 |     fi | 
 | } | 
 |  | 
 |  | 
 | # Service wrapper to start services | 
 | # start_service service-name | 
 | function start_service() { | 
 |     if [[ -z "$os_PACKAGE" ]]; then | 
 |         GetOSVersion | 
 |     fi | 
 |     if [[ "$os_PACKAGE" = "deb" ]]; then | 
 |         sudo /usr/sbin/service $1 start | 
 |     else | 
 |         sudo /sbin/service $1 start | 
 |     fi | 
 | } | 
 |  | 
 |  | 
 | # Service wrapper to stop services | 
 | # stop_service service-name | 
 | function stop_service() { | 
 |     if [[ -z "$os_PACKAGE" ]]; then | 
 |         GetOSVersion | 
 |     fi | 
 |     if [[ "$os_PACKAGE" = "deb" ]]; then | 
 |         sudo /usr/sbin/service $1 stop | 
 |     else | 
 |         sudo /sbin/service $1 stop | 
 |     fi | 
 | } | 
 |  | 
 |  | 
 | # Normalize config values to True or False | 
 | # VAR=`trueorfalse default-value test-value` | 
 | function trueorfalse() { | 
 |     local default=$1 | 
 |     local testval=$2 | 
 |  | 
 |     [[ -z "$testval" ]] && { echo "$default"; return; } | 
 |     [[ "0 no false False FALSE" =~ "$testval" ]] && { echo "False"; return; } | 
 |     [[ "1 yes true True TRUE" =~ "$testval" ]] && { echo "True"; return; } | 
 |     echo "$default" | 
 | } | 
 |  | 
 |  | 
 | # yum wrapper to set arguments correctly | 
 | # yum_install package [package ...] | 
 | function yum_install() { | 
 |     [[ "$OFFLINE" = "True" ]] && return | 
 |     local sudo="sudo" | 
 |     [[ "$(id -u)" = "0" ]] && sudo="env" | 
 |     $sudo http_proxy=$http_proxy https_proxy=$https_proxy \ | 
 |         yum install -y "$@" | 
 | } | 
 |  | 
 |  | 
 | # Restore xtrace | 
 | $XTRACE |