-
Notifications
You must be signed in to change notification settings - Fork 19
/
grenade.sh
executable file
·390 lines (324 loc) · 13.4 KB
/
grenade.sh
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
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
#!/usr/bin/env bash
# ``grenade.sh`` is an OpenStack upgrade test harness to exercise the
# OpenStack upgrade process. It uses DevStack to perform the initial
# OpenStack install.
# Grenade assumes it is running on the system that will be hosting the
# upgrade processes
# ``grenade.sh [-b] [-t] [-s stop-label] [-q]``
#
# ``-b`` Run only the base part
# ``-t`` Run only the target part (assumes a base run is in place)
# ``-q`` Quiet mode
# ``-s stop-label`` is the name of the step after which the script will stop.
# This is useful for debugging upgrades.
# ``GRENADE_DIR`` is set once by the top level grenade.sh and exported
# so that all subsequent scripts can find their way back to the
# grenade root directory. No other scripts should set this variable
export GRENADE_DIR=$(cd $(dirname "$0") && pwd)
# Source the bootstrapping facilities
#
# Grenade attempts to reuse as much content from devstack on the
# target side as possible, but we need enough of our own code to get
# there.
#
# ``grenaderc`` is a set of X=Y declarations that don't need *any* of
# the devstack functions to work
#
# ``inc/bootstrap`` is the most minimal amount of functions that
# grenade needs to get going. This includes things like echo
# functions, trueorfalse, and the functions related to git cloning, so
# that we can get our devstack trees.
export DSTOOLS_VERSION=${DSTOOLS_VERSION:-0.4.0}
source $GRENADE_DIR/grenaderc
source $GRENADE_DIR/inc/bootstrap
while getopts bqs:t c; do
case $c in
b)
RUN_TARGET=False
;;
q)
VERBOSE=False
;;
s)
STOP=$2
;;
t)
RUN_BASE=False
;;
esac
done
shift `expr $OPTIND - 1`
# Create all the base directory structures needed for the rest of the
# environment to run.
#
# This will give you an STACK_ROOT tree that you expect, and that your
# normal user owns for follow on activities.
sudo mkdir -p $BASE_RELEASE_DIR $TARGET_RELEASE_DIR
sudo chown -R `whoami` $STACK_ROOT
# Logging
# =======
# TODO(sdague): should this extract into ``inc/bootstrap``?
#
# Set up logging
# Set ``LOGFILE`` to turn on logging
# Append '.xxxxxxxx' to the given name to maintain history
# where 'xxxxxxxx' is a representation of the date the file was created
if [[ -n "$LOGFILE" ]]; then
LOGDAYS=${LOGDAYS:-7}
TIMESTAMP_FORMAT=${TIMESTAMP_FORMAT:-"%F-%H%M%S"}
CURRENT_LOG_TIME=$(date "+$TIMESTAMP_FORMAT")
# First clean up old log files. Use the user-specified ``LOGFILE``
# as the template to search for, appending '.*' to match the date
# we added on earlier runs.
LOGDIR=$(dirname "$LOGFILE")
LOGNAME=$(basename "$LOGFILE")
echo "Creating $LOGDIR...."
sudo mkdir -p $LOGDIR
sudo chown -R `whoami` $LOGDIR
find $LOGDIR -maxdepth 1 -name $LOGNAME.\* -mtime +$LOGDAYS -exec rm {} \;
LOGFILE=$LOGFILE.${CURRENT_LOG_TIME}
SUMFILE=$LOGFILE.${CURRENT_LOG_TIME}.summary
# Redirect output according to config
# Copy stdout to fd 3
exec 3>&1
if [[ "$VERBOSE" == "True" ]]; then
echo "Running in verbose mode:"
echo " Full logs found at => ${LOGFILE}"
echo " Summary logs at => ${SUMFILE}"
# Redirect stdout/stderr to tee to write the log file
exec 1> >( ./tools/outfilter.py -v -o "${LOGFILE}" ) 2>&1
# Set up a second fd for output
exec 6> >( ./tools/outfilter.py -o "${SUMFILE}" )
else
echo "Running in summary mode:"
echo " Full logs found at => ${LOGFILE}"
echo " Summary logs at => ${SUMFILE}"
# Set fd 1 and 2 to primary logfile
exec 1> >( ./tools/outfilter.py -o "${LOGFILE}") 2>&1
# Set fd 6 to summary logfile and stdout
exec 6> >( ./tools/outfilter.py -v -o "${SUMFILE}" >&3)
fi
echo_summary "grenade.sh log $LOGFILE"
# Specified logfile name always links to the most recent log
ln -sf $LOGFILE $LOGDIR/$LOGNAME
ln -sf $SUMFILE $LOGDIR/$LOGNAME.summary
else
# Set up output redirection without log files
# Copy stdout to fd 3
exec 3>&1
if [[ "$VERBOSE" != "yes" ]]; then
# Throw away stdout and stderr
exec 1>/dev/null 2>&1
fi
# Always send summary fd to original stdout
exec 6> >( ./tools/outfilter.py -v -o "${SUMFILE}" >&3)
fi
# Set up logging of screen windows
# Set ``SCREEN_LOGDIR`` to turn on logging of screen windows to the
# directory specified in ``SCREEN_LOGDIR``, we will log to the file
# ``screen-$SERVICE_NAME-$TIMESTAMP.log`` in that dir and have a link
# ``screen-$SERVICE_NAME.log`` to the latest log file.
# Logs are kept for as long specified in ``LOGDAYS``.
if [[ -n "$SCREEN_LOGDIR" ]]; then
# We make sure the directory is created.
if [[ -d "$SCREEN_LOGDIR" ]]; then
# We cleanup the old logs
find $SCREEN_LOGDIR -maxdepth 1 -name screen-\*.log -mtime +$LOGDAYS -exec rm {} \;
else
sudo mkdir -p $SCREEN_LOGDIR
sudo chown -R `whoami` $SCREEN_LOGDIR
fi
fi
# This script exits on an error so that errors don't compound and you see
# only the first error that occurred.
set -o errexit
# Print the commands being run so that we can see the command that triggers
# an error. It is also useful for following allowing as the install occurs.
set -o xtrace
# Devstack Phase 2 initialization
# ===============================
#
# We now have enough infrastructure in grenade.sh to go and get *both*
# SOURCE and TARGET devstack trees. After which point we 'pivot' onto
# the TARGET devstack functions file, then source the rest of the
# grenade settings. This should let us run the bulk of grenade.
if [ "${GRENADE_USE_EXTERNAL_DEVSTACK}" != "True" ]; then
# Get both devstack trees, so that BASE_DEVSTACK_DIR, and
# TARGET_DEVSTACK_DIR are now fully populated.
fetch_devstacks
else
devstacks_setup_environment
fi
# Source the rest of the Grenade functions. For convenience
# ``$GRENADE_DIR/functions`` implicitly sources
# ``$TARGET_DEVSTACK_DIR/functions``. So this line can't happen until
# we have the devstacks pulled down.
source $GRENADE_DIR/functions
# We now have the 'short_source' function available, so setup our PS4 variable
export PS4='+ $(short_source): '
# Many calls inside of devstack functions reference $TOP_DIR, which is
# the root of devstack. We export $TOP_DIR to all child processes here
# to be the TARGET_DEVSTACK_DIR.
#
# If you want a script to use functions off of BASE_DEVSTACK_DIR (like
# the shutdown phase) you *must* explicitly reset TOP_DIR in those
# scripts.
export TOP_DIR=$TARGET_DEVSTACK_DIR
# Install 'Base' Build of OpenStack
# =================================
source $TARGET_DEVSTACK_DIR/inc/meta-config
# Oh the complexity of bootstrapping. We need to populate enabled
# services from what devstack-gate might have set it as.
extract_localrc_section $BASE_DEVSTACK_DIR/local.conf \
$BASE_DEVSTACK_DIR/localrc \
$BASE_DEVSTACK_DIR/.localrc.auto
# Collect the ENABLED_SERVICES from the base directory, this is what
# we are starting with.
ENABLED_SERVICES=$(set +o xtrace &&
source $BASE_DEVSTACK_DIR/stackrc &&
echo $ENABLED_SERVICES)
# Fetch all the grenade plugins which were registered in ``pluginrc``
# via the ``enable_grenade_plugin`` stanza. This must be done before
# settings are loaded, but has to be this late to give access to all
# the devstack functions.
fetch_grenade_plugins
# Load the ``settings`` files for all the in tree ``projects/``. This
# registers all the projects in order that we're going to be upgrading
# when the time is right.
load_settings
if [ "${GRENADE_USE_EXTERNAL_DEVSTACK}" != "True" ]; then
# Nova should use singleconductor as Grenade doesn't
# setup multi-cell rabbit for now
devstack_localrc base "CELLSV2_SETUP=singleconductor"
devstack_localrc target "CELLSV2_SETUP=singleconductor"
fi
# And ensure that we setup the target localrc.auto, because stack.sh
# isn't run there. This has to be run after load_settings because
# plugins might change the service list during this phase.
extract_localrc_section $TARGET_DEVSTACK_DIR/local.conf \
$TARGET_DEVSTACK_DIR/localrc \
$TARGET_DEVSTACK_DIR/.localrc.auto
# Run the base install of the environment
if [[ "$RUN_BASE" == "True" ]]; then
# Initialize grenade_db local storage, used for resource tracking
init_grenade_db
if [ "${GRENADE_USE_EXTERNAL_DEVSTACK}" != "True" ]; then
echo_summary "Running base stack.sh"
cd $BASE_DEVSTACK_DIR
GIT_BASE=$GIT_BASE ./stack.sh
stop $STOP stack.sh 10
echo_summary "Running post-stack.sh"
if [[ -e $GRENADE_DIR/post-stack.sh ]]; then
cd $GRENADE_DIR
# By the time we get here the sub nodes are already setup with localrc files
# as those are transferred in devstack-gate even before grenade.sh is called
# We hack the ./post-stack.sh to inject what we need. if we don't set
# CELLSV2_SETUP, the default devstack assumes "superconductor" and fails.
export SUB_NODE_ENV_VARS="CELLSV2_SETUP=singleconductor"
sed -i 's/stdbuf/$SUB_NODE_ENV_VARS stdbuf/' ./post-stack.sh
cat ./post-stack.sh
./post-stack.sh
stop $STOP post-stack.sh 15
echo_summary "Completed post-stack.sh"
fi
fi
# Cache downloaded instances
# --------------------------
echo_summary "Caching downloaded images"
mkdir -p $BASE_RELEASE_DIR/images
echo "Images: $IMAGE_URLS"
for image_url in ${IMAGE_URLS//,/ }; do
IMAGE_FNAME=`basename "$image_url"`
if [[ -r $BASE_DEVSTACK_DIR/files/$IMAGE_FNAME ]]; then
rsync -a $BASE_DEVSTACK_DIR/files/$IMAGE_FNAME $BASE_RELEASE_DIR/images
fi
done
# NOTE(sileht): If glance is not enabled the directory cannot exists.
if [[ -d $BASE_DEVSTACK_DIR/files/images ]] ; then
rsync -a $BASE_DEVSTACK_DIR/files/images/ $BASE_RELEASE_DIR/images
fi
stop $STOP image-cache 20
# Operation
# ---------
# Validate the install
if [[ "$BASE_RUN_SMOKE" == "True" ]]; then
echo_summary "Running base smoke test"
run_tempest $BASE_RELEASE_DIR
if [ "${GRENADE_USE_EXTERNAL_DEVSTACK}" != "True" ]; then
# once we are done, copy our created artifacts to the target
if [[ -e $TARGET_RELEASE_DIR/tempest ]]; then
rsync -a $BASE_RELEASE_DIR/tempest/.tox/ $TARGET_RELEASE_DIR/tempest/.tox/
if [[ -d $BASE_RELEASE_DIR/tempest/.testrepository ]]; then
rsync -a $BASE_RELEASE_DIR/tempest/.testrepository/ $TARGET_RELEASE_DIR/tempest/.testrepository/
elif [[ -d $BASE_RELEASE_DIR/tempest/.stestr ]]; then
rsync -a $BASE_RELEASE_DIR/tempest/.stestr/ $TARGET_RELEASE_DIR/tempest/.stestr/
fi
fi
fi
fi
stop $STOP base-smoke 110
# Early Create resources, used largely for network setup
resources early_create
# Create resources
resources create
# Verify the resources were created
resources verify pre-upgrade
# Save some stuff before we shut that whole thing down
echo_summary "Saving current state information"
$GRENADE_DIR/save-state
stop $STOP save-state 130
# Shut down running code
echo_summary "Shutting down all services on base devstack..."
shutdown_services
# Verify the resources still exist after the shutdown
resources verify_noapi pre-upgrade
fi
# Upgrades
# ========
if [[ "$RUN_TARGET" == "True" ]]; then
# Clone all devstack plugins on the new side, because we're not
# running a full stack.sh
fetch_plugins
# Get target devstack tree ready for services to be run from it,
# including trying to reuse any existing files we pulled during
# the base run.
echo_summary "Preparing the target devstack environment"
$GRENADE_DIR/prep-target
# upgrade all the projects in order
echo "Upgrade projects: $UPGRADE_PROJECTS"
for project in $UPGRADE_PROJECTS; do
echo "Upgrading project: $project"
upgrade_service $project
done
# Upgrade Tempest
if [[ "$ENABLE_TEMPEST" == "True" ]]; then
echo_summary "Running upgrade-tempest"
$GRENADE_DIR/upgrade-tempest || die $LINENO "Failure in upgrade-tempest"
stop $STOP upgrade-tempest 290
fi
# Upgrade Tests
# =============
# Verify the resources still exist after the upgrade
resources verify post-upgrade
# Validate the upgrade
# This is used for testing grenade locally, and should not be used in the
# gate. Instead, grenade.sh runs smoke tests on the old cloud above, but
# smoke tests are run on the upgraded cloud by the gate script after
# grenade.sh has finished. If this option is enabled in the gate, tempest
# will be run twice against the new cloud.
if [[ "$TARGET_RUN_SMOKE" == "True" ]]; then
echo_summary "Running tempest smoke tests"
run_tempest $TARGET_RELEASE_DIR
stop $STOP run-smoke 330
fi
# Save databases
# --------------
save_data $TARGET_RELEASE $TARGET_DEVSTACK_DIR
# Cleanup the resources
resources destroy
fi
# Fin
# ===
echo_summary "Grenade has completed the pre-programmed upgrade scripts."
# Indicate how long this took to run (bash maintained variable ``SECONDS``)
echo_summary "grenade.sh completed in $SECONDS seconds."