grenade.sh |
|
|---|---|
|
grenade.sh是一个 OpenStack 升级测试框架,用于执行 OpenStack 升级过程。它使用 DevStack 执行初始的 OpenStack 安装。 # DIVIDER #!/usr/bin/env bash # DIVIDER # DIVIDER # DIVIDER export GRENADE_DIR=$(cd $(dirname "$0") && pwd) # DIVIDER 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` # DIVIDER sudo mkdir -p $BASE_RELEASE_DIR $TARGET_RELEASE_DIR sudo chown -R `whoami` $STACK_ROOT # DIVIDER # DIVIDER if [[ -n "$LOGFILE" ]]; then LOGDAYS=${LOGDAYS:-7} TIMESTAMP_FORMAT=${TIMESTAMP_FORMAT:-"%F-%H%M%S"} CURRENT_LOG_TIME=$(date "+$TIMESTAMP_FORMAT") # DIVIDER 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 # DIVIDER exec 3>&1 if [[ "$VERBOSE" == "True" ]]; then echo "Running in verbose mode:" echo " Full logs found at => ${LOGFILE}" echo " Summary logs at => ${SUMFILE}" # DIVIDER exec 1> >( ./tools/outfilter.py -v -o "${LOGFILE}" ) 2>&1 # DIVIDER exec 6> >( ./tools/outfilter.py -o "${SUMFILE}" ) else echo "Running in summary mode:" echo " Full logs found at => ${LOGFILE}" echo " Summary logs at => ${SUMFILE}" # DIVIDER exec 1> >( ./tools/outfilter.py -o "${LOGFILE}") 2>&1 # DIVIDER exec 6> >( ./tools/outfilter.py -v -o "${SUMFILE}" >&3) fi echo_summary "grenade.sh log $LOGFILE" # DIVIDER ln -sf $LOGFILE $LOGDIR/$LOGNAME ln -sf $SUMFILE $LOGDIR/$LOGNAME.summary else # DIVIDER exec 3>&1 if [[ "$VERBOSE" != "yes" ]]; then # DIVIDER exec 1>/dev/null 2>&1 fi # DIVIDER exec 6> >( ./tools/outfilter.py -v -o "${SUMFILE}" >&3) fi # DIVIDER if [[ -n "$SCREEN_LOGDIR" ]]; then # DIVIDER if [[ -d "$SCREEN_LOGDIR" ]]; then # DIVIDER 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 # DIVIDER set -o errexit # DIVIDER set -o xtrace # DIVIDER if [ "${GRENADE_USE_EXTERNAL_DEVSTACK}" != "True" ]; then # DIVIDER fetch_devstacks else devstacks_setup_environment fi # DIVIDER source $GRENADE_DIR/functions # DIVIDER export PS4='+ $(short_source): ' # DIVIDER export TOP_DIR=$TARGET_DEVSTACK_DIR # DIVIDER source $TARGET_DEVSTACK_DIR/inc/meta-config # DIVIDER extract_localrc_section $BASE_DEVSTACK_DIR/local.conf \ $BASE_DEVSTACK_DIR/localrc \ $BASE_DEVSTACK_DIR/.localrc.auto # DIVIDER ENABLED_SERVICES=$(set +o xtrace && source $BASE_DEVSTACK_DIR/stackrc && echo $ENABLED_SERVICES) # DIVIDER fetch_grenade_plugins # DIVIDER load_settings if [ "${GRENADE_USE_EXTERNAL_DEVSTACK}" != "True" ]; then # DIVIDER devstack_localrc base "CELLSV2_SETUP=singleconductor" devstack_localrc target "CELLSV2_SETUP=singleconductor" fi # DIVIDER extract_localrc_section $TARGET_DEVSTACK_DIR/local.conf \ $TARGET_DEVSTACK_DIR/localrc \ $TARGET_DEVSTACK_DIR/.localrc.auto # DIVIDER if [[ "$RUN_BASE" == "True" ]]; then # DIVIDER 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 # DIVIDER 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 # DIVIDER 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 # DIVIDER 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 # DIVIDER # DIVIDER if [[ "$BASE_RUN_SMOKE" == "True" ]]; then echo_summary "Running base smoke test" run_tempest $BASE_RELEASE_DIR if [ "${GRENADE_USE_EXTERNAL_DEVSTACK}" != "True" ]; then # DIVIDER 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 # DIVIDER resources early_create # DIVIDER resources create # DIVIDER resources verify pre-upgrade # DIVIDER echo_summary "Saving current state information" $GRENADE_DIR/save-state stop $STOP save-state 130 # DIVIDER echo_summary "Shutting down all services on base devstack..." shutdown_services # DIVIDER resources verify_noapi pre-upgrade fi # DIVIDER if [[ "$RUN_TARGET" == "True" ]]; then # DIVIDER fetch_plugins # DIVIDER echo_summary "Preparing the target devstack environment" $GRENADE_DIR/prep-target # DIVIDER echo "Upgrade projects: $UPGRADE_PROJECTS" for project in $UPGRADE_PROJECTS; do echo "Upgrading project: $project" upgrade_service $project done # DIVIDER 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 # DIVIDER # DIVIDER resources verify post-upgrade # DIVIDER if [[ "$TARGET_RUN_SMOKE" == "True" ]]; then echo_summary "Running tempest smoke tests" run_tempest $TARGET_RELEASE_DIR stop $STOP run-smoke 330 fi # DIVIDER save_data $TARGET_RELEASE $TARGET_DEVSTACK_DIR # DIVIDER resources destroy fi # DIVIDER echo_summary "Grenade has completed the pre-programmed upgrade scripts." # DIVIDER echo_summary "grenade.sh completed in $SECONDS seconds." # DIVIDER | |
|
Grenade 假定它正在运行于将托管升级流程的系统上 | |
|
grenade.sh [-b] [-t] [-s stop-label] [-q] -b仅运行基础部分-t仅运行目标部分(假定已进行基础运行)-q静默模式-s stop-label是脚本停止执行的步骤名称。这对于调试升级非常有用。 | |
|
GRENADE_DIR由顶层 grenade.sh 设置一次并导出,以便所有后续脚本可以找到返回 grenade 根目录的路径。其他脚本不应设置此变量 | |
|
加载引导设施 Grenade 尝试尽可能地重用来自 devstack 的内容到目标侧,但我们需要足够自己的代码来实现这一点。 grenaderc是一组 X=Y 声明,不需要任何 devstack 函数来工作 inc/bootstrap是 grenade 启动所需的最小函数集。这包括诸如 echo 函数、trueorfalse 以及与 git 克隆相关的函数,以便我们可以获取我们的 devstack 树。 | |
|
创建其余环境运行所需的所有基础目录结构。 这将为您提供一个预期的 STACK_ROOT 树,并且您的普通用户拥有它以进行后续活动。 | |
日志记录 | |
|
TODO(sdague): 是否应该提取到inc/bootstrap? 设置日志记录LOGFILE以开启日志记录。将“xxxxxxxx”附加到给定的名称以维护历史记录,其中“xxxxxxxx”是文件创建日期的表示形式 | |
|
首先清理旧的日志文件。使用用户指定的LOGFILE作为模板进行搜索,并附加“.*”以匹配之前运行中添加的日期。 | |
|
根据配置重定向输出。将 stdout 复制到 fd 3 | |
|
将 stdout/stderr 重定向到 tee 以写入日志文件 | |
|
设置第二个 fd 用于输出 | |
|
将 fd 1 和 2 设置为主要日志文件 | |
|
将 fd 6 设置为摘要日志文件和 stdout | |
|
指定的日志文件名始终链接到最新的日志 | |
|
设置不带日志文件的输出重定向。将 stdout 复制到 fd 3 | |
|
丢弃 stdout 和 stderr | |
|
始终将摘要 fd 发送到原始 stdout | |
|
设置屏幕窗口的日志记录。设置SCREEN_LOGDIR以开启屏幕窗口的日志记录到SCREEN_LOGDIR中指定的目录,我们将记录到文件screen-$SERVICE_NAME-$TIMESTAMP.log在该目录中,并有一个链接screen-$SERVICE_NAME.log到最新的日志文件。日志会保留LOGDAYS. | |
|
指定的时间长。我们确保目录已创建。 | |
|
我们清理旧日志 | |
|
此脚本在发生错误时退出,以便错误不会累积,并且您只会看到发生的第一个错误。 | |
|
打印正在运行的命令,以便我们可以看到触发错误的命令。在安装过程中,它也对跟踪有所帮助。 | |
Devstack Phase 2 初始化现在我们拥有足够的 grenade.sh 基础设施来获取SOURCE 和 TARGET devstack 树。之后,我们“枢轴”到 TARGET devstack 函数文件,然后加载其余的 grenade 设置。这应该让我们运行大部分 grenade。 | |
|
获取两个 devstack 树,以便 BASE_DEVSTACK_DIR 和 TARGET_DEVSTACK_DIR 现在已完全填充。 | |
|
加载其余的 Grenade 函数。为了方便起见$GRENADE_DIR/functions隐式加载$TARGET_DEVSTACK_DIR/functions。因此,在拉取 devstack 之前,不能发生此行。 | |
|
现在我们拥有“short_source”函数,因此设置我们的 PS4 变量 | |
|
devstack 函数中的许多调用引用 $TOP_DIR,这是 devstack 的根目录。我们在此将 $TOP_DIR 导出到所有子进程,使其成为 TARGET_DEVSTACK_DIR。 如果您希望脚本使用来自 BASE_DEVSTACK_DIR 的函数(例如关闭阶段),您必须在这些脚本中显式重置 TOP_DIR。 | |
安装 'Base' 构建的 OpenStack | |
|
哦,引导的复杂性。我们需要从 devstack-gate 可能将其设置为的内容中填充启用的服务。 | |
|
从基础目录收集 ENABLED_SERVICES,这是我们开始使用的内容。 | |
|
获取在pluginrc中注册的所有 grenade 插件,通过enable_grenade_plugin段落。这必须在加载设置之前完成,但必须在此晚些时候完成才能访问所有 devstack 函数。 | |
|
加载settings文件中所有树内projects/。这会按我们要升级的时间顺序注册所有项目。 | |
|
Nova 应该使用 singleconductor,因为 Grenade 目前未设置多单元 rabbit | |
|
并确保我们设置目标 localrc.auto,因为 stack.sh 并没有在那里运行。这必须在 load_settings 之后运行,因为插件可能会在此阶段更改服务列表。 | |
|
运行环境的基础安装 | |
|
初始化 grenade_db 本地存储,用于资源跟踪 | |
|
到我们这里时,子节点已经使用 localrc 文件设置好了,因为这些文件在调用 grenade.sh 之前就已经在 devstack-gate 中传输了。我们修改 ./post-stack.sh 以注入我们需要的内容。如果我们不设置 CELLSV2_SETUP,默认 devstack 会假定“superconductor”并失败。 | |
缓存下载的实例 | |
|
注意(sileht):如果未启用 glance,则目录不能存在。 | |
操作 | |
|
验证安装 | |
|
完成之后,将我们创建的工件复制到目标 | |
|
提前创建资源,主要用于网络设置 | |
|
创建资源 | |
|
验证资源是否已创建 | |
|
在关闭之前保存一些内容 | |
|
关闭正在运行的代码 | |
|
验证关闭后资源是否仍然存在 | |
升级 | |
|
克隆新的所有 devstack 插件,因为我们没有运行完整的 stack.sh。 | |
|
准备目标 devstack 树以供服务从中运行,包括尝试重用在基础运行期间拉取的任何现有文件。 | |
|
按顺序升级所有项目 | |
|
升级 Tempest | |
升级 Tests | |
|
验证升级后资源是否仍然存在 | |
|
验证升级。这用于在本地测试 grenade,不应在 gate 中使用。相反,grenade.sh 在旧云上运行烟雾测试,但 gate 脚本在 grenade.sh 完成后在升级后的云上运行烟雾测试。如果此选项在 gate 中启用,tempest 将对新云运行两次。 | |
保存数据库 | |
|
清理资源 | |
结束 | |
|
指示运行此操作所花费的时间(bash 维护的变量SECONDS) | |