
Fixed bug #1136964. 1. Added 3 ini functions to support MultiStrOpt: Function "iniset_multiline config-file section option value1 value2 value3 ..." sets a MultiStrOpt option in an ini file. Function "iniget_multiline config-file section option" gets the MultiStrOpt option values. Function "iniadd config-file section option value1 value2 value3..." appends an option without relacing the old values, which would result the option to be MultiStrOpt. 2. Modified the nova configuation to correctly enable notification for ceilometer. Change-Id: I1c27db1a6e58b35bc4428e761f40627988f69e37
1254 lines
39 KiB
Bash
1254 lines
39 KiB
Bash
# functions - Common functions used by DevStack components
|
|
#
|
|
# The following variables are assumed to be defined by certain functions:
|
|
# ``ENABLED_SERVICES``
|
|
# ``EROR_ON_CLONE``
|
|
# ``FILES``
|
|
# ``GLANCE_HOSTPORT``
|
|
# ``OFFLINE``
|
|
# ``PIP_DOWNLOAD_CACHE``
|
|
# ``PIP_USE_MIRRORS``
|
|
# ``RECLONE``
|
|
# ``TRACK_DEPENDS``
|
|
# ``http_proxy``, ``https_proxy``, ``no_proxy``
|
|
|
|
|
|
# Save trace setting
|
|
XTRACE=$(set +o | grep xtrace)
|
|
set +o xtrace
|
|
|
|
|
|
# Exit 0 if address is in network or 1 if address is not in
|
|
# network or netaddr library is not installed.
|
|
# address_in_net ip-address ip-range
|
|
function address_in_net() {
|
|
python -c "
|
|
import netaddr
|
|
import sys
|
|
sys.exit(netaddr.IPAddress('$1') not in netaddr.IPNetwork('$2'))
|
|
"
|
|
}
|
|
|
|
|
|
# Wrapper for ``apt-get`` to set cache and proxy environment variables
|
|
# Uses globals ``OFFLINE``, ``*_proxy`
|
|
# 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 \
|
|
no_proxy=$no_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=$?
|
|
if [ $exitcode == 0 ]; then
|
|
exitcode=1
|
|
fi
|
|
set +o xtrace
|
|
local msg="[ERROR] $0:$1 $2"
|
|
echo $msg 1>&2;
|
|
if [[ -n ${SCREEN_LOGDIR} ]]; then
|
|
echo $msg >> "${SCREEN_LOGDIR}/error.log"
|
|
fi
|
|
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=$2; shift
|
|
if ! is_set $evar || [ $exitcode != 0 ]; then
|
|
die $@
|
|
fi
|
|
)
|
|
}
|
|
|
|
|
|
# HTTP and HTTPS proxy servers are supported via the usual environment variables [1]
|
|
# ``http_proxy``, ``https_proxy`` and ``no_proxy``. They can be set in
|
|
# ``localrc`` or on the command line if necessary::
|
|
#
|
|
# [1] http://www.w3.org/Daemon/User/Proxies/ProxyClients.html
|
|
#
|
|
# http_proxy=http://proxy.example.com:3128/ no_proxy=repo.example.net ./stack.sh
|
|
|
|
function export_proxy_variables() {
|
|
if [[ -n "$http_proxy" ]]; then
|
|
export http_proxy=$http_proxy
|
|
fi
|
|
if [[ -n "$https_proxy" ]]; then
|
|
export https_proxy=$https_proxy
|
|
fi
|
|
if [[ -n "$no_proxy" ]]; then
|
|
export no_proxy=$no_proxy
|
|
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
|
|
}
|
|
|
|
|
|
function _get_package_dir() {
|
|
local pkg_dir
|
|
if is_ubuntu; then
|
|
pkg_dir=$FILES/apts
|
|
elif is_fedora; then
|
|
pkg_dir=$FILES/rpms
|
|
elif is_suse; then
|
|
pkg_dir=$FILES/rpms-suse
|
|
else
|
|
exit_distro_not_supported "list of packages"
|
|
fi
|
|
echo "$pkg_dir"
|
|
}
|
|
|
|
# get_packages() collects a list of package names of any type from the
|
|
# prerequisite files in ``files/{apts|rpms}``. The list is intended
|
|
# to be passed to a package installer such as apt or yum.
|
|
#
|
|
# Only packages required for the services in 1st argument will be
|
|
# included. Two bits of metadata are recognized in the prerequisite files:
|
|
# - ``# NOPRIME`` defers installation to be performed later in stack.sh
|
|
# - ``# dist:DISTRO`` or ``dist:DISTRO1,DISTRO2`` limits the selection
|
|
# of the package to the distros listed. The distro names are case insensitive.
|
|
function get_packages() {
|
|
local services=$1
|
|
local package_dir=$(_get_package_dir)
|
|
local file_to_parse
|
|
local service
|
|
|
|
if [[ -z "$package_dir" ]]; then
|
|
echo "No package directory supplied"
|
|
return 1
|
|
fi
|
|
if [[ -z "$DISTRO" ]]; then
|
|
GetDistro
|
|
fi
|
|
for service in general ${services//,/ }; do
|
|
# Allow individual services to specify dependencies
|
|
if [[ -e ${package_dir}/${service} ]]; then
|
|
file_to_parse="${file_to_parse} $service"
|
|
fi
|
|
# NOTE(sdague) n-api needs glance for now because that's where
|
|
# glance client is
|
|
if [[ $service == n-api ]]; then
|
|
if [[ ! $file_to_parse =~ nova ]]; then
|
|
file_to_parse="${file_to_parse} nova"
|
|
fi
|
|
if [[ ! $file_to_parse =~ glance ]]; then
|
|
file_to_parse="${file_to_parse} glance"
|
|
fi
|
|
elif [[ $service == c-* ]]; then
|
|
if [[ ! $file_to_parse =~ cinder ]]; then
|
|
file_to_parse="${file_to_parse} cinder"
|
|
fi
|
|
elif [[ $service == ceilometer-* ]]; then
|
|
if [[ ! $file_to_parse =~ ceilometer ]]; then
|
|
file_to_parse="${file_to_parse} ceilometer"
|
|
fi
|
|
elif [[ $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
|
|
elif [[ $service == q-* ]]; then
|
|
if [[ ! $file_to_parse =~ quantum ]]; then
|
|
file_to_parse="${file_to_parse} quantum"
|
|
fi
|
|
fi
|
|
done
|
|
|
|
for file in ${file_to_parse}; do
|
|
local fname=${package_dir}/${file}
|
|
local OIFS line package distros distro
|
|
[[ -e $fname ]] || continue
|
|
|
|
OIFS=$IFS
|
|
IFS=$'\n'
|
|
for line in $(<${fname}); do
|
|
if [[ $line =~ "NOPRIME" ]]; then
|
|
continue
|
|
fi
|
|
|
|
if [[ $line =~ (.*)#.*dist:([^ ]*) ]]; then
|
|
# We are using BASH regexp matching feature.
|
|
package=${BASH_REMATCH[1]}
|
|
distros=${BASH_REMATCH[2]}
|
|
# In bash ${VAR,,} will lowecase VAR
|
|
[[ ${distros,,} =~ ${DISTRO,,} ]] && echo $package
|
|
continue
|
|
fi
|
|
|
|
echo ${line%#*}
|
|
done
|
|
IFS=$OIFS
|
|
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=""
|
|
os_PACKAGE="rpm"
|
|
if [[ "Debian,Ubuntu" =~ $os_VENDOR ]]; then
|
|
os_PACKAGE="deb"
|
|
elif [[ "SUSE LINUX" =~ $os_VENDOR ]]; then
|
|
lsb_release -d -s | grep -q openSUSE
|
|
if [[ $? -eq 0 ]]; then
|
|
os_VENDOR="openSUSE"
|
|
fi
|
|
elif [[ $os_VENDOR =~ Red.*Hat ]]; then
|
|
os_VENDOR="Red Hat"
|
|
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"
|
|
elif [[ -r /etc/SuSE-release ]]; then
|
|
for r in openSUSE "SUSE Linux"; do
|
|
if [[ "$r" = "SUSE Linux" ]]; then
|
|
os_VENDOR="SUSE LINUX"
|
|
else
|
|
os_VENDOR=$r
|
|
fi
|
|
|
|
if [[ -n "`grep \"$r\" /etc/SuSE-release`" ]]; then
|
|
os_CODENAME=`grep "CODENAME = " /etc/SuSE-release | sed 's:.* = ::g'`
|
|
os_RELEASE=`grep "VERSION = " /etc/SuSE-release | sed 's:.* = ::g'`
|
|
os_UPDATE=`grep "PATCHLEVEL = " /etc/SuSE-release | sed 's:.* = ::g'`
|
|
break
|
|
fi
|
|
os_VENDOR=""
|
|
done
|
|
os_PACKAGE="rpm"
|
|
fi
|
|
export os_VENDOR os_RELEASE os_UPDATE os_PACKAGE os_CODENAME
|
|
}
|
|
|
|
# git update using reference as a branch.
|
|
# git_update_branch ref
|
|
function git_update_branch() {
|
|
|
|
GIT_BRANCH=$1
|
|
|
|
git checkout -f origin/$GIT_BRANCH
|
|
# a local branch might not exist
|
|
git branch -D $GIT_BRANCH || true
|
|
git checkout -b $GIT_BRANCH
|
|
}
|
|
|
|
|
|
# git update using reference as a tag. Be careful editing source at that repo
|
|
# as working copy will be in a detached mode
|
|
# git_update_tag ref
|
|
function git_update_tag() {
|
|
|
|
GIT_TAG=$1
|
|
|
|
git tag -d $GIT_TAG
|
|
# fetching given tag only
|
|
git fetch origin tag $GIT_TAG
|
|
git checkout -f $GIT_TAG
|
|
}
|
|
|
|
|
|
# git update using reference as a branch.
|
|
# git_update_remote_branch ref
|
|
function git_update_remote_branch() {
|
|
|
|
GIT_BRANCH=$1
|
|
|
|
git checkout -b $GIT_BRANCH -t origin/$GIT_BRANCH
|
|
}
|
|
|
|
|
|
# Translate the OS version values into common nomenclature
|
|
# Sets ``DISTRO`` from the ``os_*`` values
|
|
function GetDistro() {
|
|
GetOSVersion
|
|
if [[ "$os_VENDOR" =~ (Ubuntu) ]]; then
|
|
# 'Everyone' refers to Ubuntu releases by the code name adjective
|
|
DISTRO=$os_CODENAME
|
|
elif [[ "$os_VENDOR" =~ (Fedora) ]]; then
|
|
# For Fedora, just use 'f' and the release
|
|
DISTRO="f$os_RELEASE"
|
|
elif [[ "$os_VENDOR" =~ (openSUSE) ]]; then
|
|
DISTRO="opensuse-$os_RELEASE"
|
|
elif [[ "$os_VENDOR" =~ (SUSE LINUX) ]]; then
|
|
# For SLE, also use the service pack
|
|
if [[ -z "$os_UPDATE" ]]; then
|
|
DISTRO="sle${os_RELEASE}"
|
|
else
|
|
DISTRO="sle${os_RELEASE}sp${os_UPDATE}"
|
|
fi
|
|
else
|
|
# Catch-all for now is Vendor + Release + Update
|
|
DISTRO="$os_VENDOR-$os_RELEASE.$os_UPDATE"
|
|
fi
|
|
export DISTRO
|
|
}
|
|
|
|
|
|
# Determine if current distribution is an Ubuntu-based distribution.
|
|
# It will also detect non-Ubuntu but Debian-based distros; this is not an issue
|
|
# since Debian and Ubuntu should be compatible.
|
|
# is_ubuntu
|
|
function is_ubuntu {
|
|
if [[ -z "$os_PACKAGE" ]]; then
|
|
GetOSVersion
|
|
fi
|
|
|
|
[ "$os_PACKAGE" = "deb" ]
|
|
}
|
|
|
|
|
|
# Determine if current distribution is a Fedora-based distribution
|
|
# (Fedora, RHEL, CentOS).
|
|
# is_fedora
|
|
function is_fedora {
|
|
if [[ -z "$os_VENDOR" ]]; then
|
|
GetOSVersion
|
|
fi
|
|
|
|
[ "$os_VENDOR" = "Fedora" ] || [ "$os_VENDOR" = "Red Hat" ] || [ "$os_VENDOR" = "CentOS" ]
|
|
}
|
|
|
|
|
|
# Determine if current distribution is a SUSE-based distribution
|
|
# (openSUSE, SLE).
|
|
# is_suse
|
|
function is_suse {
|
|
if [[ -z "$os_VENDOR" ]]; then
|
|
GetOSVersion
|
|
fi
|
|
|
|
[ "$os_VENDOR" = "openSUSE" ] || [ "$os_VENDOR" = "SUSE LINUX" ]
|
|
}
|
|
|
|
|
|
# Exit after outputting a message about the distribution not being supported.
|
|
# exit_distro_not_supported [optional-string-telling-what-is-missing]
|
|
function exit_distro_not_supported {
|
|
if [[ -z "$DISTRO" ]]; then
|
|
GetDistro
|
|
fi
|
|
|
|
if [ $# -gt 0 ]; then
|
|
die $LINENO "Support for $DISTRO is incomplete: no support for $@"
|
|
else
|
|
die $LINENO "Support for $DISTRO is incomplete."
|
|
fi
|
|
}
|
|
|
|
|
|
# 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
|
|
# Set global ERROR_ON_CLONE=True to abort execution with an error if the git repo
|
|
# does not exist (default is False, meaning the repo will be cloned).
|
|
# Uses global ``OFFLINE``
|
|
# git_clone remote dest-dir branch
|
|
function git_clone {
|
|
[[ "$OFFLINE" = "True" ]] && return
|
|
|
|
GIT_REMOTE=$1
|
|
GIT_DEST=$2
|
|
GIT_REF=$3
|
|
|
|
if echo $GIT_REF | egrep -q "^refs"; then
|
|
# If our branch name is a gerrit style refs/changes/...
|
|
if [[ ! -d $GIT_DEST ]]; then
|
|
[[ "$ERROR_ON_CLONE" = "True" ]] && exit 1
|
|
git clone $GIT_REMOTE $GIT_DEST
|
|
fi
|
|
cd $GIT_DEST
|
|
git fetch $GIT_REMOTE $GIT_REF && git checkout FETCH_HEAD
|
|
else
|
|
# do a full clone only if the directory doesn't exist
|
|
if [[ ! -d $GIT_DEST ]]; then
|
|
[[ "$ERROR_ON_CLONE" = "True" ]] && exit 1
|
|
git clone $GIT_REMOTE $GIT_DEST
|
|
cd $GIT_DEST
|
|
# This checkout syntax works for both branches and tags
|
|
git checkout $GIT_REF
|
|
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
|
|
|
|
# handle GIT_REF accordingly to type (tag, branch)
|
|
if [[ -n "`git show-ref refs/tags/$GIT_REF`" ]]; then
|
|
git_update_tag $GIT_REF
|
|
elif [[ -n "`git show-ref refs/heads/$GIT_REF`" ]]; then
|
|
git_update_branch $GIT_REF
|
|
elif [[ -n "`git show-ref refs/remotes/origin/$GIT_REF`" ]]; then
|
|
git_update_remote_branch $GIT_REF
|
|
else
|
|
echo $GIT_REF is neither branch nor tag
|
|
exit 1
|
|
fi
|
|
|
|
fi
|
|
fi
|
|
}
|
|
|
|
|
|
# Comment an option in an INI file
|
|
# inicomment config-file section option
|
|
function inicomment() {
|
|
local file=$1
|
|
local section=$2
|
|
local option=$3
|
|
sed -i -e "/^\[$section\]/,/^\[.*\]/ s|^\($option[ \t]*=.*$\)|#\1|" "$file"
|
|
}
|
|
|
|
# Uncomment an option in an INI file
|
|
# iniuncomment config-file section option
|
|
function iniuncomment() {
|
|
local file=$1
|
|
local section=$2
|
|
local option=$3
|
|
sed -i -e "/^\[$section\]/,/^\[.*\]/ s|[^ \t]*#[ \t]*\($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#*=}
|
|
}
|
|
|
|
# Determinate is the given option present in the INI file
|
|
# ini_has_option config-file section option
|
|
function ini_has_option() {
|
|
local file=$1
|
|
local section=$2
|
|
local option=$3
|
|
local line
|
|
line=$(sed -ne "/^\[$section\]/,/^\[.*\]/ { /^$option[ \t]*=/ p; }" "$file")
|
|
[ -n "$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 ! ini_has_option "$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
|
|
}
|
|
|
|
# Get a multiple line option from an INI file
|
|
# iniget_multiline config-file section option
|
|
function iniget_multiline() {
|
|
local file=$1
|
|
local section=$2
|
|
local option=$3
|
|
local values
|
|
values=$(sed -ne "/^\[$section\]/,/^\[.*\]/ { s/^$option[ \t]*=[ \t]*//gp; }" "$file")
|
|
echo ${values}
|
|
}
|
|
|
|
# Set a multiple line option in an INI file
|
|
# iniset_multiline config-file section option value1 value2 valu3 ...
|
|
function iniset_multiline() {
|
|
local file=$1
|
|
local section=$2
|
|
local option=$3
|
|
shift 3
|
|
local values
|
|
for v in $@; do
|
|
# The later sed command inserts each new value in the line next to
|
|
# the section identifier, which causes the values to be inserted in
|
|
# the reverse order. Do a reverse here to keep the original order.
|
|
values="$v ${values}"
|
|
done
|
|
if ! grep -q "^\[$section\]" "$file"; then
|
|
# Add section at the end
|
|
echo -e "\n[$section]" >>"$file"
|
|
else
|
|
# Remove old values
|
|
sed -i -e "/^\[$section\]/,/^\[.*\]/ { /^$option[ \t]*=/ d; }" "$file"
|
|
fi
|
|
# Add new ones
|
|
for v in $values; do
|
|
sed -i -e "/^\[$section\]/ a\\
|
|
$option = $v
|
|
" "$file"
|
|
done
|
|
}
|
|
|
|
# Append a new option in an ini file without replacing the old value
|
|
# iniadd config-file section option value1 value2 value3 ...
|
|
function iniadd() {
|
|
local file=$1
|
|
local section=$2
|
|
local option=$3
|
|
shift 3
|
|
local values="$(iniget_multiline $file $section $option) $@"
|
|
iniset_multiline $file $section $option $values
|
|
}
|
|
|
|
# is_service_enabled() checks if the service(s) specified as arguments are
|
|
# enabled by the user in ``ENABLED_SERVICES``.
|
|
#
|
|
# Multiple services specified as arguments are ``OR``'ed together; the test
|
|
# is a short-circuit boolean, i.e it returns on the first match.
|
|
#
|
|
# There are special cases for some 'catch-all' services::
|
|
# **nova** returns true if any service enabled start with **n-**
|
|
# **cinder** returns true if any service enabled start with **c-**
|
|
# **ceilometer** returns true if any service enabled start with **ceilometer**
|
|
# **glance** returns true if any service enabled start with **g-**
|
|
# **quantum** returns true if any service enabled start with **q-**
|
|
#
|
|
# Uses global ``ENABLED_SERVICES``
|
|
# is_service_enabled service [service ...]
|
|
function is_service_enabled() {
|
|
services=$@
|
|
for service in ${services}; do
|
|
[[ ,${ENABLED_SERVICES}, =~ ,${service}, ]] && return 0
|
|
[[ ${service} == "nova" && ${ENABLED_SERVICES} =~ "n-" ]] && return 0
|
|
[[ ${service} == "cinder" && ${ENABLED_SERVICES} =~ "c-" ]] && return 0
|
|
[[ ${service} == "ceilometer" && ${ENABLED_SERVICES} =~ "ceilometer-" ]] && return 0
|
|
[[ ${service} == "glance" && ${ENABLED_SERVICES} =~ "g-" ]] && return 0
|
|
[[ ${service} == "quantum" && ${ENABLED_SERVICES} =~ "q-" ]] && return 0
|
|
done
|
|
return 1
|
|
}
|
|
|
|
|
|
# remove extra commas from the input string (i.e. ``ENABLED_SERVICES``)
|
|
# _cleanup_service_list service-list
|
|
function _cleanup_service_list () {
|
|
echo "$1" | sed -e '
|
|
s/,,/,/g;
|
|
s/^,//;
|
|
s/,$//
|
|
'
|
|
}
|
|
|
|
|
|
# enable_service() adds the services passed as argument to the
|
|
# ``ENABLED_SERVICES`` list, if they are not already present.
|
|
#
|
|
# For example:
|
|
# enable_service qpid
|
|
#
|
|
# This function does not know about the special cases
|
|
# for nova, glance, and quantum built into is_service_enabled().
|
|
# Uses global ``ENABLED_SERVICES``
|
|
# enable_service service [service ...]
|
|
function enable_service() {
|
|
local tmpsvcs="${ENABLED_SERVICES}"
|
|
for service in $@; do
|
|
if ! is_service_enabled $service; then
|
|
tmpsvcs+=",$service"
|
|
fi
|
|
done
|
|
ENABLED_SERVICES=$(_cleanup_service_list "$tmpsvcs")
|
|
disable_negated_services
|
|
}
|
|
|
|
|
|
# disable_service() removes the services passed as argument to the
|
|
# ``ENABLED_SERVICES`` list, if they are present.
|
|
#
|
|
# For example:
|
|
# disable_service rabbit
|
|
#
|
|
# This function does not know about the special cases
|
|
# for nova, glance, and quantum built into is_service_enabled().
|
|
# Uses global ``ENABLED_SERVICES``
|
|
# disable_service service [service ...]
|
|
function disable_service() {
|
|
local tmpsvcs=",${ENABLED_SERVICES},"
|
|
local service
|
|
for service in $@; do
|
|
if is_service_enabled $service; then
|
|
tmpsvcs=${tmpsvcs//,$service,/,}
|
|
fi
|
|
done
|
|
ENABLED_SERVICES=$(_cleanup_service_list "$tmpsvcs")
|
|
}
|
|
|
|
|
|
# disable_all_services() removes all current services
|
|
# from ``ENABLED_SERVICES`` to reset the configuration
|
|
# before a minimal installation
|
|
# Uses global ``ENABLED_SERVICES``
|
|
# disable_all_services
|
|
function disable_all_services() {
|
|
ENABLED_SERVICES=""
|
|
}
|
|
|
|
|
|
# Remove all services starting with '-'. For example, to install all default
|
|
# services except rabbit (rabbit) set in ``localrc``:
|
|
# ENABLED_SERVICES+=",-rabbit"
|
|
# Uses global ``ENABLED_SERVICES``
|
|
# disable_negated_services
|
|
function disable_negated_services() {
|
|
local tmpsvcs="${ENABLED_SERVICES}"
|
|
local service
|
|
for service in ${tmpsvcs//,/ }; do
|
|
if [[ ${service} == -* ]]; then
|
|
tmpsvcs=$(echo ${tmpsvcs}|sed -r "s/(,)?(-)?${service#-}(,)?/,/g")
|
|
fi
|
|
done
|
|
ENABLED_SERVICES=$(_cleanup_service_list "$tmpsvcs")
|
|
}
|
|
|
|
|
|
# Distro-agnostic package installer
|
|
# install_package package [package ...]
|
|
function install_package() {
|
|
if is_ubuntu; then
|
|
[[ "$NO_UPDATE_REPOS" = "True" ]] || apt_get update
|
|
NO_UPDATE_REPOS=True
|
|
|
|
apt_get install "$@"
|
|
elif is_fedora; then
|
|
yum_install "$@"
|
|
elif is_suse; then
|
|
zypper_install "$@"
|
|
else
|
|
exit_distro_not_supported "installing packages"
|
|
fi
|
|
}
|
|
|
|
|
|
# Distro-agnostic function to tell if a package is installed
|
|
# is_package_installed package [package ...]
|
|
function is_package_installed() {
|
|
if [[ -z "$@" ]]; then
|
|
return 1
|
|
fi
|
|
|
|
if [[ -z "$os_PACKAGE" ]]; then
|
|
GetOSVersion
|
|
fi
|
|
|
|
if [[ "$os_PACKAGE" = "deb" ]]; then
|
|
dpkg -l "$@" > /dev/null
|
|
elif [[ "$os_PACKAGE" = "rpm" ]]; then
|
|
rpm --quiet -q "$@"
|
|
else
|
|
exit_distro_not_supported "finding if a package is installed"
|
|
fi
|
|
}
|
|
|
|
|
|
# Test if the named environment variable is set and not zero length
|
|
# is_set env-var
|
|
function is_set() {
|
|
local var=\$"$1"
|
|
eval "[ -n \"$var\" ]" # For ex.: sh -c "[ -n \"$var\" ]" would be better, but several exercises depends on this
|
|
}
|
|
|
|
|
|
# Wrapper for ``pip install`` to set cache and proxy environment variables
|
|
# Uses globals ``OFFLINE``, ``PIP_DOWNLOAD_CACHE``, ``PIP_USE_MIRRORS``,
|
|
# ``TRACK_DEPENDS``, ``*_proxy`
|
|
# pip_install package [package ...]
|
|
function pip_install {
|
|
[[ "$OFFLINE" = "True" || -z "$@" ]] && return
|
|
if [[ -z "$os_PACKAGE" ]]; then
|
|
GetOSVersion
|
|
fi
|
|
if [[ $TRACK_DEPENDS = True ]] ; then
|
|
source $DEST/.venv/bin/activate
|
|
CMD_PIP=$DEST/.venv/bin/pip
|
|
SUDO_PIP="env"
|
|
else
|
|
SUDO_PIP="sudo"
|
|
CMD_PIP=$(get_pip_command)
|
|
fi
|
|
if [[ "$PIP_USE_MIRRORS" != "False" ]]; then
|
|
PIP_MIRROR_OPT="--use-mirrors"
|
|
fi
|
|
$SUDO_PIP PIP_DOWNLOAD_CACHE=${PIP_DOWNLOAD_CACHE:-/var/cache/pip} \
|
|
HTTP_PROXY=$http_proxy \
|
|
HTTPS_PROXY=$https_proxy \
|
|
NO_PROXY=$no_proxy \
|
|
$CMD_PIP install $PIP_MIRROR_OPT $@
|
|
}
|
|
|
|
|
|
# Service wrapper to restart services
|
|
# restart_service service-name
|
|
function restart_service() {
|
|
if is_ubuntu; then
|
|
sudo /usr/sbin/service $1 restart
|
|
else
|
|
sudo /sbin/service $1 restart
|
|
fi
|
|
}
|
|
|
|
|
|
# Helper to launch a service in a named screen
|
|
# screen_it service "command-line"
|
|
function screen_it {
|
|
SCREEN_NAME=${SCREEN_NAME:-stack}
|
|
SERVICE_DIR=${SERVICE_DIR:-${DEST}/status}
|
|
SCREEN_DEV=`trueorfalse True $SCREEN_DEV`
|
|
|
|
if is_service_enabled $1; then
|
|
# Append the service to the screen rc file
|
|
screen_rc "$1" "$2"
|
|
|
|
screen -S $SCREEN_NAME -X screen -t $1
|
|
|
|
if [[ -n ${SCREEN_LOGDIR} ]]; then
|
|
screen -S $SCREEN_NAME -p $1 -X logfile ${SCREEN_LOGDIR}/screen-${1}.${CURRENT_LOG_TIME}.log
|
|
screen -S $SCREEN_NAME -p $1 -X log on
|
|
ln -sf ${SCREEN_LOGDIR}/screen-${1}.${CURRENT_LOG_TIME}.log ${SCREEN_LOGDIR}/screen-${1}.log
|
|
fi
|
|
|
|
if [[ "$SCREEN_DEV" = "True" ]]; then
|
|
# sleep to allow bash to be ready to be send the command - we are
|
|
# creating a new window in screen and then sends characters, so if
|
|
# bash isn't running by the time we send the command, nothing happens
|
|
sleep 1.5
|
|
|
|
NL=`echo -ne '\015'`
|
|
screen -S $SCREEN_NAME -p $1 -X stuff "$2 || touch \"$SERVICE_DIR/$SCREEN_NAME/$1.failure\"$NL"
|
|
else
|
|
screen -S $SCREEN_NAME -p $1 -X exec /bin/bash -c "$2 || touch \"$SERVICE_DIR/$SCREEN_NAME/$1.failure\""
|
|
fi
|
|
fi
|
|
}
|
|
|
|
|
|
# Screen rc file builder
|
|
# screen_rc service "command-line"
|
|
function screen_rc {
|
|
SCREEN_NAME=${SCREEN_NAME:-stack}
|
|
SCREENRC=$TOP_DIR/$SCREEN_NAME-screenrc
|
|
if [[ ! -e $SCREENRC ]]; then
|
|
# Name the screen session
|
|
echo "sessionname $SCREEN_NAME" > $SCREENRC
|
|
# Set a reasonable statusbar
|
|
echo "hardstatus alwayslastline '$SCREEN_HARDSTATUS'" >> $SCREENRC
|
|
echo "screen -t shell bash" >> $SCREENRC
|
|
fi
|
|
# If this service doesn't already exist in the screenrc file
|
|
if ! grep $1 $SCREENRC 2>&1 > /dev/null; then
|
|
NL=`echo -ne '\015'`
|
|
echo "screen -t $1 bash" >> $SCREENRC
|
|
echo "stuff \"$2$NL\"" >> $SCREENRC
|
|
fi
|
|
}
|
|
|
|
# Helper to remove the *.failure files under $SERVICE_DIR/$SCREEN_NAME
|
|
# This is used for service_check when all the screen_it are called finished
|
|
# init_service_check
|
|
function init_service_check() {
|
|
SCREEN_NAME=${SCREEN_NAME:-stack}
|
|
SERVICE_DIR=${SERVICE_DIR:-${DEST}/status}
|
|
|
|
if [[ ! -d "$SERVICE_DIR/$SCREEN_NAME" ]]; then
|
|
mkdir -p "$SERVICE_DIR/$SCREEN_NAME"
|
|
fi
|
|
|
|
rm -f "$SERVICE_DIR/$SCREEN_NAME"/*.failure
|
|
}
|
|
|
|
# Helper to get the status of each running service
|
|
# service_check
|
|
function service_check() {
|
|
local service
|
|
local failures
|
|
SCREEN_NAME=${SCREEN_NAME:-stack}
|
|
SERVICE_DIR=${SERVICE_DIR:-${DEST}/status}
|
|
|
|
|
|
if [[ ! -d "$SERVICE_DIR/$SCREEN_NAME" ]]; then
|
|
echo "No service status directory found"
|
|
return
|
|
fi
|
|
|
|
# Check if there is any falure flag file under $SERVICE_DIR/$SCREEN_NAME
|
|
failures=`ls "$SERVICE_DIR/$SCREEN_NAME"/*.failure 2>/dev/null`
|
|
|
|
for service in $failures; do
|
|
service=`basename $service`
|
|
service=${service::-8}
|
|
echo "Error: Service $service is not running"
|
|
done
|
|
|
|
if [ -n "$failures" ]; then
|
|
echo "More details about the above errors can be found with screen, with ./rejoin-stack.sh"
|
|
fi
|
|
}
|
|
|
|
# ``pip install`` the dependencies of the package before ``setup.py develop``
|
|
# so pip and not distutils processes the dependency chain
|
|
# Uses globals ``TRACK_DEPENDES``, ``*_proxy`
|
|
# setup_develop directory
|
|
function setup_develop() {
|
|
if [[ $TRACK_DEPENDS = True ]] ; then
|
|
SUDO_CMD="env"
|
|
else
|
|
SUDO_CMD="sudo"
|
|
fi
|
|
(cd $1; \
|
|
python setup.py egg_info; \
|
|
raw_links=$(awk '/^.+/ {print "-f " $1}' *.egg-info/dependency_links.txt); \
|
|
depend_links=$(echo $raw_links | xargs); \
|
|
require_file=$([ ! -r *-info/requires.txt ] || echo "-r *-info/requires.txt"); \
|
|
pip_install $require_file $depend_links; \
|
|
$SUDO_CMD \
|
|
HTTP_PROXY=$http_proxy \
|
|
HTTPS_PROXY=$https_proxy \
|
|
NO_PROXY=$no_proxy \
|
|
python setup.py develop \
|
|
)
|
|
}
|
|
|
|
|
|
# Service wrapper to start services
|
|
# start_service service-name
|
|
function start_service() {
|
|
if is_ubuntu; 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 is_ubuntu; then
|
|
sudo /usr/sbin/service $1 stop
|
|
else
|
|
sudo /sbin/service $1 stop
|
|
fi
|
|
}
|
|
|
|
|
|
# Normalize config values to True or False
|
|
# Accepts as False: 0 no false False FALSE
|
|
# Accepts as True: 1 yes true True TRUE
|
|
# 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"
|
|
}
|
|
|
|
|
|
# Retrieve an image from a URL and upload into Glance
|
|
# Uses the following variables:
|
|
# ``FILES`` must be set to the cache dir
|
|
# ``GLANCE_HOSTPORT``
|
|
# upload_image image-url glance-token
|
|
function upload_image() {
|
|
local image_url=$1
|
|
local token=$2
|
|
|
|
# Create a directory for the downloaded image tarballs.
|
|
mkdir -p $FILES/images
|
|
|
|
# Downloads the image (uec ami+aki style), then extracts it.
|
|
IMAGE_FNAME=`basename "$image_url"`
|
|
if [[ ! -f $FILES/$IMAGE_FNAME || "$(stat -c "%s" $FILES/$IMAGE_FNAME)" = "0" ]]; then
|
|
wget -c $image_url -O $FILES/$IMAGE_FNAME
|
|
if [[ $? -ne 0 ]]; then
|
|
echo "Not found: $image_url"
|
|
return
|
|
fi
|
|
fi
|
|
|
|
# OpenVZ-format images are provided as .tar.gz, but not decompressed prior to loading
|
|
if [[ "$image_url" =~ 'openvz' ]]; then
|
|
IMAGE="$FILES/${IMAGE_FNAME}"
|
|
IMAGE_NAME="${IMAGE_FNAME%.tar.gz}"
|
|
glance --os-auth-token $token --os-image-url http://$GLANCE_HOSTPORT image-create --name "$IMAGE_NAME" --is-public=True --container-format ami --disk-format ami < "${IMAGE}"
|
|
return
|
|
fi
|
|
|
|
# XenServer-ovf-format images are provided as .vhd.tgz as well
|
|
# and should not be decompressed prior to loading
|
|
if [[ "$image_url" =~ '.vhd.tgz' ]]; then
|
|
IMAGE="$FILES/${IMAGE_FNAME}"
|
|
IMAGE_NAME="${IMAGE_FNAME%.vhd.tgz}"
|
|
glance --os-auth-token $token --os-image-url http://$GLANCE_HOSTPORT image-create --name "$IMAGE_NAME" --is-public=True --container-format=ovf --disk-format=vhd < "${IMAGE}"
|
|
return
|
|
fi
|
|
|
|
KERNEL=""
|
|
RAMDISK=""
|
|
DISK_FORMAT=""
|
|
CONTAINER_FORMAT=""
|
|
UNPACK=""
|
|
case "$IMAGE_FNAME" in
|
|
*.tar.gz|*.tgz)
|
|
# Extract ami and aki files
|
|
[ "${IMAGE_FNAME%.tar.gz}" != "$IMAGE_FNAME" ] &&
|
|
IMAGE_NAME="${IMAGE_FNAME%.tar.gz}" ||
|
|
IMAGE_NAME="${IMAGE_FNAME%.tgz}"
|
|
xdir="$FILES/images/$IMAGE_NAME"
|
|
rm -Rf "$xdir";
|
|
mkdir "$xdir"
|
|
tar -zxf $FILES/$IMAGE_FNAME -C "$xdir"
|
|
KERNEL=$(for f in "$xdir/"*-vmlinuz* "$xdir/"aki-*/image; do
|
|
[ -f "$f" ] && echo "$f" && break; done; true)
|
|
RAMDISK=$(for f in "$xdir/"*-initrd* "$xdir/"ari-*/image; do
|
|
[ -f "$f" ] && echo "$f" && break; done; true)
|
|
IMAGE=$(for f in "$xdir/"*.img "$xdir/"ami-*/image; do
|
|
[ -f "$f" ] && echo "$f" && break; done; true)
|
|
if [[ -z "$IMAGE_NAME" ]]; then
|
|
IMAGE_NAME=$(basename "$IMAGE" ".img")
|
|
fi
|
|
;;
|
|
*.img)
|
|
IMAGE="$FILES/$IMAGE_FNAME";
|
|
IMAGE_NAME=$(basename "$IMAGE" ".img")
|
|
format=$(qemu-img info ${IMAGE} | awk '/^file format/ { print $3; exit }')
|
|
if [[ ",qcow2,raw,vdi,vmdk,vpc," =~ ",$format," ]]; then
|
|
DISK_FORMAT=$format
|
|
else
|
|
DISK_FORMAT=raw
|
|
fi
|
|
CONTAINER_FORMAT=bare
|
|
;;
|
|
*.img.gz)
|
|
IMAGE="$FILES/${IMAGE_FNAME}"
|
|
IMAGE_NAME=$(basename "$IMAGE" ".img.gz")
|
|
DISK_FORMAT=raw
|
|
CONTAINER_FORMAT=bare
|
|
UNPACK=zcat
|
|
;;
|
|
*.qcow2)
|
|
IMAGE="$FILES/${IMAGE_FNAME}"
|
|
IMAGE_NAME=$(basename "$IMAGE" ".qcow2")
|
|
DISK_FORMAT=qcow2
|
|
CONTAINER_FORMAT=bare
|
|
;;
|
|
*) echo "Do not know what to do with $IMAGE_FNAME"; false;;
|
|
esac
|
|
|
|
if [ "$CONTAINER_FORMAT" = "bare" ]; then
|
|
if [ "$UNPACK" = "zcat" ]; then
|
|
glance --os-auth-token $token --os-image-url http://$GLANCE_HOSTPORT image-create --name "$IMAGE_NAME" --public --container-format=$CONTAINER_FORMAT --disk-format $DISK_FORMAT < <(zcat --force "${IMAGE}")
|
|
else
|
|
glance --os-auth-token $token --os-image-url http://$GLANCE_HOSTPORT image-create --name "$IMAGE_NAME" --public --container-format=$CONTAINER_FORMAT --disk-format $DISK_FORMAT < "${IMAGE}"
|
|
fi
|
|
else
|
|
# Use glance client to add the kernel the root filesystem.
|
|
# We parse the results of the first upload to get the glance ID of the
|
|
# kernel for use when uploading the root filesystem.
|
|
KERNEL_ID=""; RAMDISK_ID="";
|
|
if [ -n "$KERNEL" ]; then
|
|
KERNEL_ID=$(glance --os-auth-token $token --os-image-url http://$GLANCE_HOSTPORT image-create --name "$IMAGE_NAME-kernel" --public --container-format aki --disk-format aki < "$KERNEL" | grep ' id ' | get_field 2)
|
|
fi
|
|
if [ -n "$RAMDISK" ]; then
|
|
RAMDISK_ID=$(glance --os-auth-token $token --os-image-url http://$GLANCE_HOSTPORT image-create --name "$IMAGE_NAME-ramdisk" --public --container-format ari --disk-format ari < "$RAMDISK" | grep ' id ' | get_field 2)
|
|
fi
|
|
glance --os-auth-token $token --os-image-url http://$GLANCE_HOSTPORT image-create --name "${IMAGE_NAME%.img}" --public --container-format ami --disk-format ami ${KERNEL_ID:+--property kernel_id=$KERNEL_ID} ${RAMDISK_ID:+--property ramdisk_id=$RAMDISK_ID} < "${IMAGE}"
|
|
fi
|
|
}
|
|
|
|
# Set the database backend to use
|
|
# When called from stackrc/localrc DATABASE_BACKENDS has not been
|
|
# initialized yet, just save the configuration selection and call back later
|
|
# to validate it.
|
|
# $1 The name of the database backend to use (mysql, postgresql, ...)
|
|
function use_database {
|
|
if [[ -z "$DATABASE_BACKENDS" ]]; then
|
|
# No backends registered means this is likely called from ``localrc``
|
|
# This is now deprecated usage
|
|
DATABASE_TYPE=$1
|
|
DEPRECATED_TEXT="$DEPRECATED_TEXT\nThe database backend needs to be properly set in ENABLED_SERVICES; use_database is deprecated localrc\n"
|
|
else
|
|
# This should no longer get called...here for posterity
|
|
use_exclusive_service DATABASE_BACKENDS DATABASE_TYPE $1
|
|
fi
|
|
}
|
|
|
|
# Toggle enable/disable_service for services that must run exclusive of each other
|
|
# $1 The name of a variable containing a space-separated list of services
|
|
# $2 The name of a variable in which to store the enabled service's name
|
|
# $3 The name of the service to enable
|
|
function use_exclusive_service {
|
|
local options=${!1}
|
|
local selection=$3
|
|
out=$2
|
|
[ -z $selection ] || [[ ! "$options" =~ "$selection" ]] && return 1
|
|
for opt in $options;do
|
|
[[ "$opt" = "$selection" ]] && enable_service $opt || disable_service $opt
|
|
done
|
|
eval "$out=$selection"
|
|
return 0
|
|
}
|
|
|
|
# Wait for an HTTP server to start answering requests
|
|
# wait_for_service timeout url
|
|
function wait_for_service() {
|
|
local timeout=$1
|
|
local url=$2
|
|
timeout $timeout sh -c "while ! http_proxy= https_proxy= curl -s $url >/dev/null; do sleep 1; done"
|
|
}
|
|
|
|
# Wrapper for ``yum`` to set proxy environment variables
|
|
# Uses globals ``OFFLINE``, ``*_proxy`
|
|
# 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 \
|
|
no_proxy=$no_proxy \
|
|
yum install -y "$@"
|
|
}
|
|
|
|
# ping check
|
|
# Uses globals ``ENABLED_SERVICES``
|
|
function ping_check() {
|
|
if is_service_enabled quantum; then
|
|
_ping_check_quantum "$1" $2 $3 $4
|
|
return
|
|
fi
|
|
_ping_check_novanet "$1" $2 $3 $4
|
|
}
|
|
|
|
# ping check for nova
|
|
# Uses globals ``MULTI_HOST``, ``PRIVATE_NETWORK``
|
|
function _ping_check_novanet() {
|
|
local from_net=$1
|
|
local ip=$2
|
|
local boot_timeout=$3
|
|
local expected=${4:-"True"}
|
|
local check_command=""
|
|
MULTI_HOST=`trueorfalse False $MULTI_HOST`
|
|
if [[ "$MULTI_HOST" = "True" && "$from_net" = "$PRIVATE_NETWORK_NAME" ]]; then
|
|
sleep $boot_timeout
|
|
return
|
|
fi
|
|
if [[ "$expected" = "True" ]]; then
|
|
check_command="while ! ping -c1 -w1 $ip; do sleep 1; done"
|
|
else
|
|
check_command="while ping -c1 -w1 $ip; do sleep 1; done"
|
|
fi
|
|
if ! timeout $boot_timeout sh -c "$check_command"; then
|
|
if [[ "$expected" = "True" ]]; then
|
|
die $LINENO "[Fail] Couldn't ping server"
|
|
else
|
|
die $LINENO "[Fail] Could ping server"
|
|
fi
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# ssh check
|
|
|
|
function ssh_check() {
|
|
if is_service_enabled quantum; then
|
|
_ssh_check_quantum "$1" $2 $3 $4 $5
|
|
return
|
|
fi
|
|
_ssh_check_novanet "$1" $2 $3 $4 $5
|
|
}
|
|
|
|
function _ssh_check_novanet() {
|
|
local NET_NAME=$1
|
|
local KEY_FILE=$2
|
|
local FLOATING_IP=$3
|
|
local DEFAULT_INSTANCE_USER=$4
|
|
local ACTIVE_TIMEOUT=$5
|
|
local probe_cmd=""
|
|
if ! timeout $ACTIVE_TIMEOUT sh -c "while ! ssh -o StrictHostKeyChecking=no -i $KEY_FILE ${DEFAULT_INSTANCE_USER}@$FLOATING_IP echo success ; do sleep 1; done"; then
|
|
die $LINENO "server didn't become ssh-able!"
|
|
fi
|
|
}
|
|
|
|
|
|
# zypper wrapper to set arguments correctly
|
|
# zypper_install package [package ...]
|
|
function zypper_install() {
|
|
[[ "$OFFLINE" = "True" ]] && return
|
|
local sudo="sudo"
|
|
[[ "$(id -u)" = "0" ]] && sudo="env"
|
|
$sudo http_proxy=$http_proxy https_proxy=$https_proxy \
|
|
zypper --non-interactive install --auto-agree-with-licenses "$@"
|
|
}
|
|
|
|
|
|
# Add a user to a group.
|
|
# add_user_to_group user group
|
|
function add_user_to_group() {
|
|
local user=$1
|
|
local group=$2
|
|
|
|
if [[ -z "$os_VENDOR" ]]; then
|
|
GetOSVersion
|
|
fi
|
|
|
|
# SLE11 and openSUSE 12.2 don't have the usual usermod
|
|
if ! is_suse || [[ "$os_VENDOR" = "openSUSE" && "$os_RELEASE" != "12.2" ]]; then
|
|
sudo usermod -a -G "$group" "$user"
|
|
else
|
|
sudo usermod -A "$group" "$user"
|
|
fi
|
|
}
|
|
|
|
|
|
# Get the path to the direcotry where python executables are installed.
|
|
# get_python_exec_prefix
|
|
function get_python_exec_prefix() {
|
|
if is_fedora; then
|
|
echo "/usr/bin"
|
|
else
|
|
echo "/usr/local/bin"
|
|
fi
|
|
}
|
|
|
|
# Get the location of the $module-rootwrap executables, where module is cinder
|
|
# or nova.
|
|
# get_rootwrap_location module
|
|
function get_rootwrap_location() {
|
|
local module=$1
|
|
|
|
echo "$(get_python_exec_prefix)/$module-rootwrap"
|
|
}
|
|
|
|
# Get the path to the pip command.
|
|
# get_pip_command
|
|
function get_pip_command() {
|
|
if is_fedora; then
|
|
which pip-python
|
|
else
|
|
which pip
|
|
fi
|
|
}
|
|
|
|
# Restore xtrace
|
|
$XTRACE
|
|
|
|
|
|
# Local variables:
|
|
# -*- mode: Shell-script -*-
|
|
# End:
|