#!/bin/bash # ============================================================================= # - title : Migrating Servers Using RSYNC # - description : This Script Will Migrate Data From one Instance to another # - License : GPLv3 # - author : Kevin Carter # - date : 2013-11-16 # - version : 2.0.1 # - usage : bash rsrsyncLive.sh # - OS Supported : Ubuntu, Debian, SUSE, Gentoo, RHEL, CentOS, Scientific, Arch # ============================================================================= # Trap Errors and or Exits trap "CONTROL_C" SIGINT trap "EXIT_ERROR Line Number: ${LINENO} Exit Code: $?" ERR # Set modes set -u set -e # Root user check for install # ============================================================================= function CHECKFORROOT() { USERCHECK=$( whoami ) if [ "$(id -u)" != "0" ]; then echo -e "This script must be run as ROOT You have attempted to run this as ${USERCHECK} use sudo $0 or change to root. " exit 1 fi } # Root user check for install # ============================================================================= function CREATE_SWAP() { cat > /tmp/swap.sh < /tmp/swappiness.sh < /tmp/intsalldeps.sh < /dev/null 2>&1 echo "Installing rsync Package." apt-get -y install rsync > /dev/null 2>&1 cat > /tmp/intsalldeps.sh < /dev/null 2>&1 apt-get -y install rsync > /dev/null 2>&1 EOF if [ "${INFLAMMATORY}" == "True" ];then echo -e "Great choice by choosing a Debian Based Distro. The Debian way is by far the best way."; sleep 1 fi } # When SUSE # ============================================================================= function WHENSUSE() { echo -e "\033[1;31mSUSE Based System Detected\033[0m" zypper in rsync cat > /tmp/intsalldeps.sh <= 2.0.0 but < 3.0.0 Flags." fi } # Dep Scripts # ============================================================================= function KEYANDDEPSEND() { echo -e "\033[1;36mBuilding Key Based Access for the target host\033[0m" ssh-keygen -t rsa -f ${SSH_KEY_TEMP} -N '' # Making backup of known_host if [ -f "/root/.ssh/known_hosts" ];then cp /root/.ssh/known_hosts /root/.ssh/known_hosts.${DATE}.bak fi echo -e "Please Enter the Password of the \033[1;33mTARGET\033[0m Server." ssh-copy-id -i ${SSH_KEY_TEMP} root@${TIP} if [ -f /tmp/intsalldeps.sh ];then echo -e "Passing RSYNC Dependencies to the \033[1;33mTARGET\033[0m Server." scp -i ${SSH_KEY_TEMP} /tmp/intsalldeps.sh root@${TIP}:/root/ fi if [ -f /tmp/swap.sh ];then echo -e "Passing Swap script to the \033[1;33mTARGET\033[0m Server." scp -i ${SSH_KEY_TEMP} /tmp/swap.sh root@${TIP}:/root/ fi if [ -f /tmp/swappiness.sh ];then echo -e "Passing Swappiness script to the \033[1;33mTARGET\033[0m Server." scp -i ${SSH_KEY_TEMP} /tmp/swappiness.sh root@${TIP}:/root/ fi } # Commands # ============================================================================= function RUNPREPROCESS() { echo -e "Running Dependency Scripts on the \033[1;33mTARGET\033[0m Server." SCRIPTS='[ -f "swap.sh" ] && bash swap.sh; [ -f "swappiness.sh" ] && bash swappiness.sh; [ -f "intsalldeps.sh" ] && bash intsalldeps.sh' ssh -i ${SSH_KEY_TEMP} -o UserKnownHostsFile=/dev/null \ -o StrictHostKeyChecking=no root@${TIP} \ "${SCRIPTS}" > /dev/null 2>&1 } function RUNRSYNCCOMMAND() { set +e MAX_RETRIES=${MAX_RETRIES:-5} RETRY_COUNT=0 # Set the initial return value to failure false while [ $? -ne 0 -a ${RETRY_COUNT} -lt ${MAX_RETRIES} ];do RETRY_COUNT=$((${RETRY_COUNT}+1)) ${RSYNC} -e "${RSSH}" -${RSYNC_FLAGS} --progress \ --exclude-from="${EXCLUDE_FILE}" \ --exclude "${SSHAUTHKEYFILE}" \ / root@${TIP}:/ echo "Resting for 5 seconds..." sleep 5 done if [ ${RETRY_COUNT} -ge ${MAX_RETRIES} ];then EXIT_ERROR "Hit maximum number of retries, giving up." fi unset MAX_RETRIES set -e } function RUNMAINPROCESS() { echo -e "\033[1;36mNow performing the Copy\033[0m" RSYNC="$(which rsync)" RSSH_OPTIONS="-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" RSSH="ssh -i ${SSH_KEY_TEMP} ${RSSH_OPTIONS}" RUNRSYNCCOMMAND echo -e "\033[1;36mNow performing Final Sweep\033[0m" RSYNC_FLAGS="${RSYNC_FLAGS} --checksum" RUNRSYNCCOMMAND } # Run Script # ============================================================================= INFLAMMATORY=${INFLAMMATORY:-"False"} VERBOSE=${VERBOSE:-"False"} DEBUG=${DEBUG:-"False"} # The Date as generated by the Source System DATE=$(date +%y%m%d%H) # The Temp Working Directory TEMPDIR='/tmp' # Name of the Temp SSH Key we will be using. SSH_KEY_TEMP="${TEMPDIR}/tempssh.${DATE}" # ROOT SSH Key File SSHAUTHKEYFILE='/root/.ssh/authorized_keys' # General Exclude List; The exclude list is space Seperated EXCLUDE_LIST='/boot /dev/ /etc/conf.d/net /etc/fstab /etc/hostname /etc/HOSTNAME /etc/hosts /etc/issue /etc/init.d/nova-agent* /etc/mdadm* /etc/mtab /etc/network* /etc/network/* /etc/networks* /etc/network.d/* /etc/rc.conf /etc/resolv.conf /etc/selinux/config /etc/sysconfig/network* /etc/sysconfig/network-scripts/* /etc/ssh/ssh_host_dsa_key /etc/ssh/ssh_host_rsa_key /etc/ssh/ssh_host_dsa_key.pub /etc/ssh/ssh_host_rsa_key.pub /etc/udev/rules.d/* /lock /net /sys /tmp /usr/sbin/nova-agent* /usr/share/nova-agent* /var/cache/yum/* ' # Allow the user to add excludes to the general Exclude list USER_EXCLUDES=${USER_EXCLUDES:-""} # Amazon Exclude List; The exclude list is space Seperated AMAZONEXCLUDE_LIST='/etc/sysctl.conf /etc/yum.repos.d/amzn-*' # Extra Exclude File EXCLUDE_FILE='/tmp/excludeme.file' # Building Exclude File - DONT TOUCH UNLESS YOU KNOW WHAT YOU ARE DOING # ============================================================================= if [ "${VERBOSE}" == "True" ];then set -v fi if [ "${DEBUG}" == "True" ];then set -x fi if [ "${USER_EXCLUDES}" ];then EXCLUDE_LIST+=${USER_EXCLUDES} fi EXCLUDEVAR=$(echo ${EXCLUDE_LIST} | sed 's/\ /\\n/g') if [ -f ${EXCLUDE_FILE} ];then rm ${EXCLUDE_FILE} fi echo -e "${EXCLUDEVAR}" | tee -a ${EXCLUDE_FILE} # Check that we are the root User CHECKFORROOT # Clear the screen to get ready for work clear if [ "${INFLAMMATORY}" == "True" ];then echo -e "Inflammatory mode has been enabled... The application will now be really opinionated... \033[1;33mYOU\033[0m have been warned... " fi echo -e "This Utility Moves a \033[1;36mLIVE\033[0m System to an other System. This application will work on \033[1;36mAll\033[0m Linux systems using RSYNC. Before performing this action you \033[1;35mSHOULD\033[0m be in a screen session. " sleep 1 echo -e "This Utility does an \033[1;32mRSYNC\033[0m copy of instances over the network. As such, I recommend that you perform this Migration Action on SNET (Internal IP), however any Network will work. Here is why I make this recommendation: Service Net = \033[1;32mFREE\033[0m Bandwidth. Public Net = \033[1;35mNOT FREE\033[0m Bandwidth " # Run the Amazon Check ISTHISAMAZON # If the Target IP is not set, ask for it GETTIP # Allow the user to specify the source drive GETDRIVE1 GETDRIVE2 # check what distro we are running on DISTROCHECK # Make sure we can swap CREATE_SWAP # Check RSYNC version and set the in use flags RSYNCCHECKANDSET # Create a Key for target access and send over a dependency script KEYANDDEPSEND # If this is an amazon AMI linux Distro send over a post processing script AMAZONPOSTPROCESSES # Removing known_host entry made by script if [ -f "/root/.ssh/known_hosts" ];then cp /root/.ssh/known_hosts /tmp/known_hosts sed '$ d' /tmp/known_hosts > /root/.ssh/known_hosts fi RUNPREPROCESS RUNMAINPROCESS AMAZONPROCESSES echo -e "\033[1;36mThe target Instance is being rebooted\033[0m" ssh -i ${SSH_KEY_TEMP} -o UserKnownHostsFile=/dev/null \ -o StrictHostKeyChecking=no root@${TIP} \ "shutdown -r now" echo -e "If you were copying something that was not a Rackspace Cloud Server, You may need to ensure that your setting are correct, and the target is healthy " AMAZONWARNING echo -e "Other wise you are good to go, and the target server should have been rebooted. If all is well, you should now be able to enjoy your newly cloned Virtual Instance. " # Say something nice ALLDONE # Teardown what I setup on the source node and exit QUIT exit 0