Skip to content

Instantly share code, notes, and snippets.

@dsamojlenko
Last active August 29, 2015 14:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dsamojlenko/60b9e6083066b02d6e5f to your computer and use it in GitHub Desktop.
Save dsamojlenko/60b9e6083066b02d6e5f to your computer and use it in GitHub Desktop.
In place upgrade script for drupal/wetkit distribution
#
# Environment-specific variables
# sourced by wetkit_upgrade.sh
#
# Database settings
DBHOST=[DEV DB HOST]
DBUSER=[DEV DB USER]
DBPASS=[DEV DB PASS]
# Directories
DB_BACKUPS=[DB BACKUPS DIRECTORY] # ex: /var/sites/mysite/backups/database
HTDOCS=[SITE HOME DIRECTORY] # ex: /var/sites/mysite/current
RELEASES=[SITE RELEASES DIRECTORY] # ex: /var/sites/mysite/releases
SHARED=[SITE SHARED DIRECTORY] # ex: /var/sites/mysite/shared
# Number of releases to keep
KEEP=5
# MySQL Clients
MYSQL=/usr/bin/mysql
MYSQLDUMP=/usr/bin/mysqldump
#
# Environment-specific variables
# sourced by wetkit_upgrade.sh
#
# Database settings
DBHOST=[DEV DB HOST]
DBUSER=[DEV DB USER]
DBPASS=[DEV DB PASS]
# Directories
DB_BACKUPS=[DB BACKUPS DIRECTORY] # ex: /var/sites/mysite/backups/database
HTDOCS=[SITE HOME DIRECTORY] # ex: /var/sites/mysite/current
RELEASES=[SITE RELEASES DIRECTORY] # ex: /var/sites/mysite/releases
SHARED=[SITE SHARED DIRECTORY] # ex: /var/sites/mysite/shared
# Number of releases to keep
KEEP=5
# MySQL Clients
MYSQL=/usr/bin/mysql
MYSQLDUMP=/usr/bin/mysqldump
#!/bin/bash
#
# Wetkit in-place upgrade script. Depends on
# environment-specific scripts following the
# naming convention wetkit_[environment].sh
#
# Currently script only configured for two environments:
# development, production
#
# These scripts and the drupal/wetkit release tarball should be
# in the same directory. Call using:
#
# > sudo ./wetkit_upgrade.sh wetkit-7.x-1.4-core.tar.gz
#
# Requires the following folder/symlink structure (names are configurable):
# [sitedir]/backups/database
# [sitedir]/releases
# [sitedir]/shared/sites
# [sitedir]/htdocs -> [sitedir]/releases/[release_datetime] (symlink)
# [sitedir]/releases/[release_datetime]/sites -> [sitedir]/shared/sites (symlink)
#
set -e
# Script name
PROGNAME=$(basename $0)
# Colour codes
RED=$(tput setaf 1)
GREEN=$(tput setaf 2)
YELLOW=$(tput setaf 3)
BLUE=$(tput setaf 4)
WHITE=$(tput setaf 7)
NORMAL=$(tput sgr0)
# Generic error handler - display an error and exit.
function error_exit
{
echo "${RED}[ERROR]${NORMAL} ${1:-"Unknown Error"}" 1>&2
exit 1
}
# Argument check: must pass in tarball
if [ $# -eq 0 ]; then
printf "%s\n" "${RED}[ERROR]${NORMAL} You must supply a file as an argument"
printf "\t%s\n" "USAGE: sudo wetkit_upgrade [wetkit-7.x-1.4-core.tar.gz]"
exit 1
fi
# Permissions check: must be sudo
if [ "$(whoami)" != "root" ]; then
printf "%s\n" "${RED}[ERROR]${NORMAL} You don't have sufficient privileges to run this script."
printf "\t%s\n" "Usage: sudo wetkit_upgrade $1"
exit 1
fi
# Prompt user for current environment
PS3='Please select environment: '
options=("Production" "Development")
select opt in "${options[@]}"
do
case $opt in
"Production")
ENV=production
break
;;
"Development")
ENV=development
break
;;
*) echo invalid option;;
esac
done
printf "%s\n" "${GREEN}[${PROGNAME}]${NORMAL} Environment set: ${ENV}"
# Include ENV specific config
CONF_FILE=wetkit_${ENV}.sh
source ${CONF_FILE}
printf "%s\n" "${GREEN}[${PROGNAME}]${NORMAL} Database set to ${DBHOST}"
# List of databases
DATABASES=`mysql --user=${DBUSER} -p${DBPASS} -h ${DBHOST} -e "SHOW DATABASES;" | grep -Ev "(Database|information_schema|test)"`
# Name for release/backup directories (datetime)
RELEASE_DIR=`date +"%Y%m%d%H%M%S"`
# Execution directory
EXEC_DIR=`pwd`
# Target tarball
TARGET_FILE=$1
# get the top level directory in the tarball
# (ie: wetkit-7.x-1.4) or exit because it's not a tarball
#
TAR_DIR=`tar tfz ${TARGET_FILE} --exclude '*/*'` || error_exit "File provided is not the correct type - should be a tar.gz"
# Confirmation dialog:
# Print a nice big warning and force user to confirm they want to continue
#
printf "\n%s\n" "${RED}[WARNING]${NORMAL} This script will backup the following databases:"
printf "\t%s\n" ${DATABASES}
printf "\n%s\n" "It will then:"
printf "\t%s\n" "- put the site(s) into maintenance mode"
printf "\t%s\n" "- install the new files in the releases folder"
printf "\t%s\n" "- run database updates"
printf "\t%s\n" "- update symbolic links"
printf "\t%s\n\n" "- remove maintenance mode and clear caches"
while true; do
read -p "Are you sure you want to continue? " yn
case $yn in
[Yy]* ) break;;
[Nn]* ) exit 0;;
* ) echo "please answer yes or no";;
esac
done
# Environment check:
# - releases folder exists
# - htdocs folder is a symlink
# - shared folder exists
# - database backups folder exists
#
if [ ! -d ${RELEASES} ] || [ ! -L ${HTDOCS} ] || [ ! -d ${SHARED} ] || [ ! -d ${DB_BACKUPS} ]; then
error_exit "Server not configured correctly (folders are missing)"
fi
# Requirements check:
# Need drush, tar, and mysql client utilities
#
command -v drush >/dev/null 2>&1 || error_exit "Drush is required but not installed."
command -v tar >/dev/null 2>&1 || error_exit "tar is required but not installed."
command -v mysql >/dev/null 2>&1 || error_exit "MySQL Client utilities are required but not installed"
command -v mysqldump >/dev/null 2>&1 || error_exit "I require mysqldump but it's not installed"
printf "%s\n" "${GREEN}[${PROGNAME}]${NORMAL} Checks passed"
printf "%s\n" "${GREEN}[${PROGNAME}]${NORMAL} Target file: ${EXEC_DIR}/${TARGET_FILE}"
printf "%s\n" "${GREEN}[${PROGNAME}]${NORMAL} Release directory: ${RELEASES}/${RELEASE_DIR}"
# Put site into maintenance mode
cd ${HTDOCS}
printf "%s\n" "${GREEN}[${PROGNAME}]${NORMAL} Put site in maintenance mode"
drush @sites variable-set maintenance_mode 1 --yes
printf "%s\n" "${GREEN}[${PROGNAME}]${NORMAL} Clearing cache"
drush @sites cc all --yes
# Create database backup using mysqldump
mkdir ${DB_BACKUPS}/${RELEASE_DIR}
for db in ${DATABASES}; do
$MYSQLDUMP --force --opt --user=$DBUSER -p$DBPASS -h $DBHOST --databases $db > "$DB_BACKUPS/$RELEASE_DIR/$db.sql" || error_exit "There was a problem backing up the database"
done
printf "%s\n" "${GREEN}[${PROGNAME}]${NORMAL} Database backups created in ${DB_BACKUPS}/${RELEASE_DIR}"
# untar the archive to releases folder
cd ${RELEASES}
printf "%s\n" "${GREEN}[${PROGNAME}]${NORMAL} Untar archive"
tar -xf ${EXEC_DIR}/$1
# Rename the output directory to $RELEASE_DIR (datetime)
printf "%s\n" "${GREEN}[${PROGNAME}]${NORMAL} Move files into place"
mv ${TAR_DIR} ./${RELEASE_DIR}
# Create/update symlinks
printf "%s\n" "${GREEN}[${PROGNAME}]${NORMAL} Create symlinks"
# Remove sites directory that came with the release tarball
rm -r ${RELEASES}/${RELEASE_DIR}/sites
# symlink the sites directory from shared
ln -s ${SHARED}/sites ${RELEASES}/${RELEASE_DIR}/sites
# Run db updates (in new release folder)
cd ${RELEASES}/${RELEASE_DIR}
printf "%s\n" "${GREEN}[${PROGNAME}]${NORMAL} Run database updates"
drush @sites updatedb --yes
# Force overwrite of htdocs symlink
ln -sfn ${RELEASES}/$RELEASE_DIR ${HTDOCS}
# All done get site out of maintenance mode
printf "%s\n" "${GREEN}[${PROGNAME}]${NORMAL} Disable maintenance mode"
drush @sites variable-set maintenance_mode 0 --yes
# Clear cache
printf "%s\n" "${GREEN}[${PROGNAME}]${NORMAL} Clear cache"
drush @sites cc all --yes
# Cleanup old releases
printf "%s\n" "${GREEN}[${PROGNAME}]${NORMAL} Cleaning up old releases (keeping the last $KEEP)"
cd ${RELEASES}
COUNTER=0
while [ `ls -1 | wc -l` -gt $KEEP ]; do
let COUNTER=COUNTER=1
(ls -t|head -n $KEEP;ls)|sort|uniq -u|xargs rm -r
done
printf "%s\n" "${GREEN}[${PROGNAME}]${NORMAL} Deleted $COUNTER old releases"
printf "%s\n" "${GREEN}[${PROGNAME}]${NORMAL} Successfully upgraded"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment