Skip to content

Instantly share code, notes, and snippets.

@fstrube
Last active December 20, 2015 12:49
Show Gist options
  • Save fstrube/6134493 to your computer and use it in GitHub Desktop.
Save fstrube/6134493 to your computer and use it in GitHub Desktop.
BETA: A shell script for copying a Magento instance on the same server. Useful for quickly spinning up a new staging environment on a shared host.
#!/bin/sh
#/ Usage: magento-cp [options] <source> <destination>
#/
#/ Options
#/ --no-anon WARNING: do not anonymize customer data
#/ --db-host=<host|socket> the new database info
#/ --db-name=<name>
#/ --db-user=<user>
#/ --db-password=<password>
#/ --exclude=<pattern> exclude specific directories during copy (can occur multiple)
#/ --with-cache copy the cache (for some reason, if you want to)
#/ --with-session copy the session (for some reason, if you want to)
#/ --without-extensions do not copy third-party (community) and local extensions
#/ --without-extension=<name> exclude a specific extension from the copy
#/ --without-themes do not copy any themes
#/ --without-data do not copy any additional data, only run the Magento installer
#/ --without-media do not copy over the media folder
function usage() {
grep ^#/ $0 | cut -c4-
}
function error() {
echo ${red}$@${reset} >&2
}
function warn() {
echo ${yellow}$@${reset} >&2
}
function info() {
echo ${blue}$@${reset} >&2
}
#====================================================
# defaults
#====================================================
SRC=""
DEST=""
ANONYMIZE="yes"
EXCLUDE="--exclude=/var/cache --exclude=/var/session"
WITHOUT_DATA=""
#====================================================
# colorize some shit
#====================================================
red=$(tput setaf 1)
green=$(tput setaf 2)
yellow=$(tput setaf 3)
blue=$(tput setaf 4)
reset=$(tput sgr0)
#====================================================
# parse options
#====================================================
if [ -z "$1" ]; then
usage >&2
exit
fi
while [ -n "$1" ]; do
case "$1" in
--no-anon)
ANONYMIZE="no"
;;
--db-host*)
DB_HOST="${1#*=}"
;;
--db-name*)
DB_NAME="${1#*=}"
;;
--db-user*)
DB_USER="${1#*=}"
;;
--db-password*)
DB_PASSWORD="${1#*=}"
;;
--exclude=*)
EXCLUDE="$EXCLUDE --exclude=${1#*=}"
EXCLUDE="${EXCLUDE# }"
;;
--with-cache)
EXCLUDE="$EXCLUDE --include=/var/cache"
EXCLUDE="${EXCLUDE# }"
;;
--with-session)
EXCLUDE="$EXCLUDE --include=/var/session"
EXCLUDE="${EXCLUDE# }"
;;
--without-extensions)
EXCLUDE="$EXCLUDE --exclude=/app/code/community"
EXCLUDE="$EXCLUDE --include=/app/code/community/Phoenix"
EXCLUDE="$EXCLUDE --exclude=/app/code/local"
EXCLUDE="${EXCLUDE# }"
;;
--without-extension=*)
EXCLUDE="$EXCLUDE --exclude=/app/code/community/${1#*=}"
EXCLUDE="$EXCLUDE --exclude=/app/code/local/${1#*=}"
EXCLUDE="${EXCLUDE# }"
;;
--without-themes)
EXCLUDE="$EXCLUDE --exclude=/app/design/frontend/default/*"
EXCLUDE="$EXCLUDE --exclude=/skin/frontend/default/*"
EXCLUDE="$EXCLUDE --include=/app/design/frontend/default/blank"
EXCLUDE="$EXCLUDE --include=/app/design/frontend/default/default"
EXCLUDE="$EXCLUDE --include=/app/design/frontend/default/iphone"
EXCLUDE="$EXCLUDE --include=/app/design/frontend/default/modern"
EXCLUDE="$EXCLUDE --include=/skin/frontend/default/blank"
EXCLUDE="$EXCLUDE --include=/skin/frontend/default/blue"
EXCLUDE="$EXCLUDE --include=/skin/frontend/default/default"
EXCLUDE="$EXCLUDE --include=/skin/frontend/default/french"
EXCLUDE="$EXCLUDE --include=/skin/frontend/default/german"
EXCLUDE="$EXCLUDE --include=/skin/frontend/default/iphone"
EXCLUDE="$EXCLUDE --include=/skin/frontend/default/modern"
EXCLUDE="${EXCLUDE# }"
;;
--without-theme=*)
EXCLUDE="$EXCLUDE --exclude=/app/design/frontend/${1#*=}"
EXCLUDE="${EXCLUDE# }"
;;
--without-data)
WITHOUT_DATA="yes"
;;
--without-media)
EXCLUDE="$EXCLUDE --exclude=/media/**"
EXCLUDE="${EXCLUDE# }"
;;
#====================================================
# show usage
#====================================================
--help)
usage
exit
;;
--*)
error "$0: $1: unknown command"
usage >&2
exit 1
;;
*)
if [ -z "$SRC" ]; then
SRC="$1"
elif [ -z "$DEST" ]; then
DEST="$1"
else
error "$0: $1: unknown command"
usage >&2
exit 1
fi
;;
esac
shift
done;
#====================================================
# don't allow destination to exists
#====================================================
if [ -d $DEST ]; then
error "$0: destination $DEST already exists!"
exit 1
fi
#====================================================
# check for required commands (rsync, xpath)
#====================================================
if ! which rsync > /dev/null 2>&1 ; then
error "$0: missing rsync command" >&2
exit 1
fi
if ! which xpath > /dev/null 2>&1 ; then
error "$0: missing xpath command" >&2
exit 1
fi
#====================================================
# copy files using rsync
#====================================================
RSYNC="rsync --archive --itemize-changes $EXCLUDE $SRC $DEST"
info The following command will be run
echo $RSYNC
read -p "${blue}Press enter to continue...${reset}"
$RSYNC
#====================================================
# touch up configs and anything else
#====================================================
info Prepare to edit the magento config file
read -p "Press enter to continue..."
vi ${DEST}/app/etc/local.xml
#====================================================
# copy database?
#====================================================
if [ "$WITHOUT_DATA" = "" ]; then
# parse database config from original magento
orig_socket=$(xpath -q -e '//connection/socket/text()' ${SRC}/app/etc/local.xml)
orig_host=$(xpath -q -e '//connection/host/text()' ${SRC}/app/etc/local.xml)
orig_user=$(xpath -q -e '//connection/username/text()' ${SRC}/app/etc/local.xml)
orig_password=$(xpath -q -e '//connection/password/text()' ${SRC}/app/etc/local.xml)
orig_database=$(xpath -q -e '//connection/dbname/text()' ${SRC}/app/etc/local.xml)
new_socket=$(xpath -q -e '//connection/socket/text()' ${DEST}/app/etc/local.xml)
new_host=$(xpath -q -e '//connection/host/text()' ${DEST}/app/etc/local.xml)
new_user=$(xpath -q -e '//connection/username/text()' ${DEST}/app/etc/local.xml)
new_password=$(xpath -q -e '//connection/password/text()' ${DEST}/app/etc/local.xml)
new_database=$(xpath -q -e '//connection/dbname/text()' ${DEST}/app/etc/local.xml)
MYSQLDUMP_OPTS="-u $orig_user --password=$orig_password"
if [ -n "$orig_socket" ]; then
MYSQLDUMP_OPTS="-S $orig_socket $MYSQLDUMP_OPTS"
fi
if [ -n "$orig_host" ]; then
MYSQLDUMP_OPTS="-h $orig_host $MYSQLDUMP_OPTS"
fi
MYSQL_OPTS="-u $new_user --password=$new_password"
if [ -n "$new_socket" ]; then
MYSQL_OPTS="-S $new_socket $MYSQL_OPTS"
fi
if [ -n "$new_host" ]; then
MYSQL_OPTS="-h $new_host $MYSQL_OPTS"
fi
MYSQLDUMP="mysqldump $MYSQLDUMP_OPTS $orig_database"
MYSQL="mysql $MYSQL_OPTS $new_database"
info The following command will be run
echo "$MYSQLDUMP | $MYSQL"
read -p "${blue}Press enter to continue...${reset}"
# Create new database and run the dump
if mysql $MYSQL_OPTS -e "CREATE DATABASE \`$new_database\`"; then
$MYSQLDUMP | $MYSQL
else
warn "Database $new_database already exists!"
read -p "${blue}Press enter to overwrite the database...${reset}"
$MYSQLDUMP | $MYSQL
fi
else
warn "Skipping database copy!"
fi
#====================================================
# cleanse emails in database?
#====================================================
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment