#!/bin/bash # Copyright 2017 VMware, Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # source $PWD/db/util/mysql.sh source $PWD/db/util/pgsql.sh source $PWD/db/util/mysql_pgsql_1_5_0.sh source $PWD/db/util/alembic.sh set -e ISMYSQL=false ISPGSQL=false ISNOTARY=false ISCLAIR=false cur_version="" PGSQL_USR="postgres" function init { if [ "$(ls -A /var/lib/mysql)" ]; then # As after the first success run, the data will be migrated to pgsql, # the PG_VERSION should be in /var/lib/mysql if user repeats the UP command. if [ -e '/var/lib/mysql/PG_VERSION' ]; then ISPGSQL=true elif [ -d '/var/lib/mysql/mysql' ]; then ISMYSQL=true if [ -d '/var/lib/mysql/notaryserver' ]; then ISNOTARY=true fi fi fi if [ "$(ls -A /var/lib/postgresql/data)" ]; then ISPGSQL=true fi if [ -d "/clair-db" ]; then ISCLAIR=true fi if [ $ISMYSQL == false ] && [ $ISPGSQL == false ]; then echo "No database has been mounted for the migration. Use '-v' to set it in 'docker run'." exit 1 fi if [ $ISMYSQL == true ]; then # as for UP notary, user does not need to provide username and pwd. # the check works for harbor DB only. if [ $ISNOTARY == false ]; then if [ -z "$DB_USR" -o -z "$DB_PWD" ]; then echo "DB_USR or DB_PWD not set, exiting..." exit 1 fi launch_mysql $DB_USR $DB_PWD else launch_mysql root fi fi if [ $ISPGSQL == true ]; then if [ $ISCLAIR == true ]; then launch_pgsql $PGSQL_USR "/clair-db" else launch_pgsql $PGSQL_USR fi fi } function get_version { if [ $ISMYSQL == true ]; then result=$(get_version_mysql) fi if [ $ISPGSQL == true ]; then result=$(get_version_pgsql $PGSQL_USR) fi cur_version=$result } # first version is less than or equal to second version. function version_le { ## if no version specific, see it as larger then 1.5.0 if [ $1 = "head" ];then return 1 fi test "$(printf '%s\n' "$@" | sort -V | head -n 1)" = "$1"; } function backup { echo "Performing backup..." if [ $ISMYSQL == true ]; then backup_mysql fi if [ $ISPGSQL == true ]; then backup_pgsql fi rc="$?" echo "Backup performed." exit $rc } function restore { echo "Performing restore..." if [ $ISMYSQL == true ]; then restore_mysql fi if [ $ISPGSQL == true ]; then restore_pgsql fi rc="$?" echo "Restore performed." exit $rc } function validate { echo "Performing test..." if [ $ISMYSQL == true ]; then test_mysql $DB_USR $DB_PWD fi if [ $ISPGSQL == true ]; then test_pgsql $PGSQL_USR fi rc="$?" echo "Test performed." exit $rc } function upgrade { if [ $ISNOTARY == true ];then up_notary $PGSQL_USR elif [ $ISCLAIR == true ];then up_clair $PGSQL_USR else up_harbor $1 fi } function up_harbor { local target_version="$1" if [ -z $target_version ]; then target_version="head" echo "Version is not specified. Default version is head." fi get_version if [ "$cur_version" = "$target_version" ]; then echo "It has always running the $target_version, no longer need to upgrade." exit 0 fi # $cur_version <='1.5.0', $target_version <='1.5.0', it needs to call mysql upgrade. if version_le $cur_version '1.5.0' && version_le $target_version '1.5.0'; then if [ $ISMYSQL != true ]; then echo "Please mount the database volume to /var/lib/mysql, then to run the upgrade again." return 1 else alembic_up mysql $target_version return $? fi fi # $cur_version > '1.5.0', $target_version > '1.5.0', it needs to call pgsql upgrade. if ! version_le $cur_version '1.5.0' && ! version_le $target_version '1.5.0'; then if [ $ISPGSQL != true ]; then echo "Please mount the database volume to /var/lib/postgresql/data, then to run the upgrade again." return 1 else alembic_up pgsql $target_version return $? fi fi # $cur_version <='1.5.0', $target_version >'1.5.0', it needs to upgrade to $cur_version.mysql => 1.5.0.mysql => 1.5.0.pgsql => target_version.pgsql. if version_le $cur_version '1.5.0' && ! version_le $target_version '1.5.0'; then if [ $ISMYSQL != true ]; then echo "Please make sure to mount the correct the data volume." return 1 else launch_pgsql $PGSQL_USR mysql_2_pgsql_1_5_0 $PGSQL_USR # Pgsql won't run the init scripts as the migration script has already created the PG_VERSION, # which is a flag that used by entrypoint.sh of pgsql to define whether to run init scripts to create harbor DBs. # Here to force init notary DBs just align with new harbor launch process. # Otherwise, user could get db failure when to launch harbor with notary as no data was created. psql -U $PGSQL_USR -f /harbor-migration/db/schema/notaryserver_init.pgsql psql -U $PGSQL_USR -f /harbor-migration/db/schema/notarysigner_init.pgsql stop_mysql $DB_USR $DB_PWD ## it needs to call the alembic_up to target, disable it as it's now unsupported. alembic_up pgsql $target_version stop_pgsql $PGSQL_USR rm -rf /var/lib/mysql/* cp -rf $PGDATA/* /var/lib/mysql ## Chmod 700 to DB data directory chmod 700 /var/lib/mysql return 0 fi fi echo "Unsupported DB upgrade from $cur_version to $target_version, please check the inputs." return 1 } function main { if [[ $1 = "help" || $1 = "h" || $# = 0 ]]; then echo "Usage:" echo "backup perform database backup" echo "restore perform database restore" echo "up, upgrade perform database schema upgrade" echo "test test database connection" echo "h, help usage help" exit 0 fi init local key="$1" case $key in up|upgrade) upgrade $2 ;; backup) backup ;; restore) restore ;; test) validate ;; *) echo "unknown option" exit 0 ;; esac } main "$@"