Joshua Hesketh | 648f74b | 2015-07-13 23:49:18 +1000 | [diff] [blame] | 1 | #!/bin/bash |
| 2 | # |
| 3 | # Copyright 2014 Rackspace Australia |
| 4 | # |
| 5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may |
| 6 | # not use this file except in compliance with the License. You may obtain |
| 7 | # a copy of the License at |
| 8 | # |
| 9 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | # |
| 11 | # Unless required by applicable law or agreed to in writing, software |
| 12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| 13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| 14 | # License for the specific language governing permissions and limitations |
| 15 | # under the License. |
| 16 | |
| 17 | # A tool to update a given dataset to a given version. Used to keep datasets |
| 18 | # somewhat fresh rather than over-exercising old migrations. |
| 19 | |
| 20 | |
| 21 | # Usage: ./update_datasets.sh VENV_NAME WORKING_DIR GIT_PATH DB_USER DB_PASS DB_NAME SEED_DATA OUTPUT_DATA |
| 22 | # apt-get install git virtualenvwrapper python-pip mysql-server python-lxml build-essential libffi-dev |
| 23 | |
| 24 | # $1 is the unique job id |
| 25 | # $2 is the working dir path |
| 26 | # $3 is the path to the git repo path |
| 27 | # $4 is the nova db user |
| 28 | # $5 is the nova db password |
| 29 | # $6 is the nova db name |
| 30 | # $7 is the path to the seed dataset to test against |
| 31 | # $8 is the logging.conf for openstack |
| 32 | # $9 is the pip cache dir |
| 33 | |
| 34 | UNIQUE_ID=$1 |
| 35 | WORKING_DIR_PATH=`realpath $2` |
| 36 | GIT_REPO_PATH=`realpath $3` |
| 37 | DB_USER=$4 |
| 38 | DB_PASS=$5 |
| 39 | DB_NAME=$6 |
| 40 | DATASET_SEED_SQL=`realpath $7` |
| 41 | DATASET_OUTPUT_SQL=$8 |
| 42 | |
| 43 | SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) |
| 44 | |
| 45 | # We also support the following environment variables to tweak our behavour: |
| 46 | # NOCLEANUP: if set to anything, don't cleanup at the end of the run |
| 47 | |
| 48 | pip_requires() { |
| 49 | pip install -q mysql-python |
| 50 | pip install -q eventlet |
| 51 | requires="tools/pip-requires" |
| 52 | if [ ! -e $requires ] |
| 53 | then |
| 54 | requires="requirements.txt" |
| 55 | fi |
| 56 | echo "Install pip requirements from $requires" |
| 57 | pip install -q -r $requires |
| 58 | echo "Requirements installed" |
| 59 | } |
| 60 | |
| 61 | db_sync() { |
| 62 | # $1 is the test target (ie branch name) |
| 63 | # $2 is an (optional) destination version number |
| 64 | |
| 65 | # Create a nova.conf file |
| 66 | cat - > $WORKING_DIR_PATH/nova-$1.conf <<EOF |
| 67 | [DEFAULT] |
| 68 | sql_connection = mysql://$DB_USER:$DB_PASS@localhost/$DB_NAME?charset=utf8 |
| 69 | #log_config = $LOG_CONF_FILE |
| 70 | EOF |
| 71 | |
| 72 | # Silently return git to a known good state (delete untracked files) |
| 73 | git clean -xfdq |
| 74 | |
| 75 | echo "***** Start DB upgrade to state of $1 *****" |
| 76 | echo "HEAD of branch under test is:" |
| 77 | git log -n 1 |
| 78 | |
| 79 | echo "Setting up the nova-manage entry point" |
| 80 | python setup.py -q clean |
| 81 | python setup.py -q develop |
| 82 | python setup.py -q install |
| 83 | |
| 84 | # Log the migrations present |
| 85 | echo "Migrations present:" |
| 86 | ls $GIT_REPO_PATH/nova/db/sqlalchemy/migrate_repo/versions/*.py | sed 's/.*\///' | egrep "^[0-9]+_" |
| 87 | |
| 88 | # Flush innodb's caches |
| 89 | echo "Restarting mysql" |
| 90 | sudo service mysql stop |
| 91 | sudo service mysql start |
| 92 | |
| 93 | start_version=`mysql -u $DB_USER --password=$DB_PASS $DB_NAME -e "select * from migrate_version \G" | grep version | sed 's/.*: //'` |
| 94 | |
| 95 | if [ "%$2%" == "%%" ] |
| 96 | then |
| 97 | end_version=`ls $GIT_REPO_PATH/nova/db/sqlalchemy/migrate_repo/versions/*.py | sed 's/.*\///' | egrep "^[0-9]+_" | tail -1 | cut -f 1 -d "_"` |
| 98 | else |
| 99 | end_version=$2 |
| 100 | fi |
| 101 | |
| 102 | echo "Test will migrate from $start_version to $end_version" |
| 103 | if [ $end_version -lt $start_version ] |
| 104 | then |
| 105 | increment=-1 |
| 106 | end_version=$(( $end_version + 1 )) |
| 107 | else |
| 108 | increment=1 |
| 109 | start_version=$(( $start_version + 1)) |
| 110 | fi |
| 111 | |
| 112 | for i in `seq $start_version $increment $end_version` |
| 113 | do |
| 114 | set -x |
| 115 | $SCRIPT_DIR/nova-manage-wrapper.sh $VENV_PATH --config-file $WORKING_DIR_PATH/nova-$1.conf --verbose db sync --version $i |
| 116 | manage_exit=$? |
| 117 | set +x |
| 118 | |
| 119 | echo "nova-manage returned exit code $manage_exit" |
| 120 | if [ $manage_exit -gt 0 ] |
| 121 | then |
| 122 | echo "Aborting early" |
| 123 | exit $manage_exit |
| 124 | fi |
| 125 | done |
| 126 | |
| 127 | echo "***** Finished DB upgrade to state of $1 *****" |
| 128 | } |
| 129 | |
| 130 | stable_release_db_sync() { |
| 131 | version=`mysql -u $DB_USER --password=$DB_PASS $DB_NAME -e "select * from migrate_version \G" | grep version | sed 's/.*: //'` |
| 132 | |
| 133 | # Some databases are from Folsom |
| 134 | echo "Schema version is $version" |
| 135 | if [ $version -lt "161" ] |
| 136 | then |
| 137 | echo "Database is from Folsom! Upgrade via Grizzly" |
| 138 | git branch -D eol/grizzly || true |
| 139 | git remote update |
| 140 | git checkout -b eol/grizzly |
| 141 | # Use tag |
| 142 | git reset --hard grizzly-eol |
| 143 | pip_requires |
| 144 | db_sync "grizzly" |
| 145 | fi |
| 146 | |
| 147 | version=`mysql -u $DB_USER --password=$DB_PASS $DB_NAME -e "select * from migrate_version \G" | grep version | sed 's/.*: //'` |
| 148 | # Some databases are from Grizzly |
| 149 | echo "Schema version is $version" |
| 150 | if [ $version -lt "216" ] |
| 151 | then |
| 152 | echo "Database is from Grizzly! Upgrade via Havana" |
| 153 | git branch -D eol/havana || true |
| 154 | git remote update |
| 155 | git checkout -b eol/havana |
| 156 | # Use tag |
| 157 | git reset --hard havana-eol |
| 158 | pip_requires |
| 159 | db_sync "havana" |
| 160 | fi |
| 161 | |
| 162 | version=`mysql -u $DB_USER --password=$DB_PASS $DB_NAME -e "select * from migrate_version \G" | grep version | sed 's/.*: //'` |
| 163 | # Some databases are from Havana |
| 164 | echo "Schema version is $version" |
| 165 | if [ $version -lt "234" ] |
| 166 | then |
| 167 | echo "Database is from Havana! Upgrade via Icehouse" |
| 168 | git branch -D eol/icehouse || true |
| 169 | git remote update |
| 170 | git checkout -b eol/icehouse |
| 171 | # Use tag |
| 172 | git reset --hard icehouse-eol |
| 173 | pip_requires |
| 174 | db_sync "icehouse" |
| 175 | fi |
| 176 | |
| 177 | version=`mysql -u $DB_USER --password=$DB_PASS $DB_NAME -e "select * from migrate_version \G" | grep version | sed 's/.*: //'` |
| 178 | # Some databases are from Icehouse |
| 179 | echo "Schema version is $version" |
| 180 | if [ $version -lt "254" ] |
| 181 | then |
| 182 | echo "Database is from Icehouse! Upgrade via Juno" |
| 183 | git branch -D stable/juno || true |
| 184 | git remote update |
| 185 | git checkout -b stable/juno |
| 186 | git reset --hard remotes/origin/stable/juno |
| 187 | pip_requires |
| 188 | db_sync "juno" |
| 189 | fi |
| 190 | |
| 191 | version=`mysql -u $DB_USER --password=$DB_PASS $DB_NAME -e "select * from migrate_version \G" | grep version | sed 's/.*: //'` |
| 192 | # Some databases are from Juno |
| 193 | echo "Schema version is $version" |
| 194 | if [ $version -lt "280" ] |
| 195 | then |
| 196 | echo "Database is from Juno! Upgrade via Kilo" |
| 197 | git branch -D stable/kilo || true |
| 198 | git remote update |
| 199 | git checkout -b stable/kilo |
| 200 | git reset --hard remotes/origin/stable/kilo |
| 201 | pip_requires |
| 202 | db_sync "kilo" |
| 203 | |
| 204 | # TODO(jhesketh): This is a bit of a hack until we update our datasets to |
| 205 | # have the flavour data migrated. We have to do this before upgrading from |
| 206 | set -x |
| 207 | $SCRIPT_DIR/nova-manage-wrapper.sh $VENV_PATH --config-file $WORKING_DIR_PATH/nova-kilo.conf --verbose db migrate_flavor_data --force |
| 208 | set +x |
| 209 | fi |
| 210 | |
| 211 | # TODO(jhesketh): Add in Liberty here once released |
| 212 | |
| 213 | # TODO(jhesketh): Make this more DRY and/or automatically match migration |
| 214 | # numbers to releases. |
| 215 | } |
| 216 | |
| 217 | echo "Test running on "`hostname`" as "`whoami`" ("`echo ~`", $HOME)" |
| 218 | echo "To execute this script manually, run this:" |
| 219 | echo "$0 $@" |
| 220 | |
| 221 | # Setup the environment |
| 222 | set -x |
| 223 | export PATH=/usr/lib/ccache:$PATH |
| 224 | #export PIP_INDEX_URL="http://www.rcbops.com/pypi/mirror" |
| 225 | export PIP_INDEX_URL="http://pypi.openstack.org/simple/" |
| 226 | export PIP_EXTRA_INDEX_URL="https://pypi.python.org/simple/" |
| 227 | which pip |
| 228 | pip --version |
| 229 | which virtualenv |
| 230 | virtualenv --version |
| 231 | which mkvirtualenv |
| 232 | set +x |
| 233 | |
| 234 | # Restore database to known good state |
| 235 | echo "Restoring test database $DB_NAME" |
| 236 | set -x |
| 237 | mysql -u $DB_USER --password=$DB_PASS -e "drop database $DB_NAME" |
| 238 | mysql -u $DB_USER --password=$DB_PASS -e "create database $DB_NAME" |
| 239 | mysql -u $DB_USER --password=$DB_PASS $DB_NAME < $DATASET_SEED_SQL |
| 240 | set +x |
| 241 | |
| 242 | echo "Build test environment" |
| 243 | cd $GIT_REPO_PATH |
| 244 | |
| 245 | echo "Setting up virtual env" |
| 246 | source ~/.bashrc |
| 247 | export WORKON_HOME=`pwd`/envs |
| 248 | mkdir -p $WORKON_HOME |
| 249 | VENV_PATH=$WORKON_HOME/$UNIQUE_ID |
| 250 | rm -rf $VENV_PATH |
| 251 | source /usr/local/bin/virtualenvwrapper.sh |
| 252 | source /etc/bash_completion.d/virtualenvwrapper |
| 253 | mkvirtualenv --no-site-packages $UNIQUE_ID |
| 254 | #toggleglobalsitepackages |
| 255 | export PYTHONPATH=$PYTHONPATH:$GIT_REPO_PATH |
| 256 | |
| 257 | if [ ! -e $VENV_PATH ] |
| 258 | then |
| 259 | echo "Error: making the virtual env failed" |
| 260 | exit 1 |
| 261 | fi |
| 262 | |
| 263 | stable_release_db_sync |
| 264 | |
| 265 | # Determine the final schema version |
| 266 | version=`mysql -u $DB_USER --password=$DB_PASS $DB_NAME -e "select * from migrate_version \G" | grep version | sed 's/.*: //'` |
| 267 | echo "Final schema version is $version" |
| 268 | |
| 269 | if [ "%$NOCLEANUP%" == "%%" ] |
| 270 | then |
| 271 | # Cleanup virtual env |
| 272 | echo "Cleaning up virtual env" |
| 273 | deactivate |
| 274 | rmvirtualenv $UNIQUE_ID |
| 275 | fi |
| 276 | |
| 277 | cd $SCRIPT_DIR |
| 278 | mysqldump -u $DB_USER --password=$DB_PASS $DB_NAME > $DATASET_OUTPUT_SQL |