forked from openstack/devstack
-
Notifications
You must be signed in to change notification settings - Fork 1
/
functions
335 lines (290 loc) · 9.5 KB
/
functions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
# 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
# optset 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
# optget 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
# This is NOT a complete option setter, it assumes that the section and
# option already exist in the INI file. If the section does not exist,
# nothing happens.
# optset config-file section option value
function iniset() {
local file=$1
local section=$2
local option=$3
local value=$4
sed -i -e "/^\[$section\]/,/^\[.*\]/ s|^\($option[ \t]*=[ \t]*\).*$|\1$value|" $file
}
# 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() {
sudo /usr/sbin/service $1 restart
}
# Service wrapper to start services
# start_service service-name
function start_service() {
sudo /usr/sbin/service $1 start
}
# Service wrapper to stop services
# stop_service service-name
function stop_service() {
sudo /usr/sbin/service $1 stop
}
# 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