#!/bin/bash clear unalias ls 2> /dev/null # # The next section is only functions that are called in other parts of the script # serverinfo () { # Read Server Information SUBLOOP=0 while [ $SUBLOOP -eq 0 ]; do echo -n "Remote server IP address: " read IP SUBLOOP=1 # IP is required if [ -z $IP ]; then echo "IP is required!" sleep 1 SUBLOOP=0 else validip sleep 1 fi echo -n "Remote User: " read RUSER echo -n "SSH Port: " read PORT # Assign port 22 if no value was assigned if [ -z $PORT ]; then echo "No port given, assuming 22" sleep 1 PORT=22 fi # Assume root user if none was given if [ -z $RUSER ]; then echo "No user given, assuming root" sleep 1 RUSER=root fi done } validip () { valid=1 count=0 for field in $(echo "$IP" | cut -d. --output-delimiter=$'\012' -f1-); do count=$[count+1] if [ "$field" -eq $[field+0] -a "$field" -le 256 -a "$field" -ge 0 ]; then : yay else valid=0 fi done if [ "$valid" -a "$count" -eq 4 ]; then echo "Valid IP address!" else echo "Invalid IP address!" SUBLOOP=0 fi } sshkeys () { # Generate SSH keys if ! [ -f ~/.ssh/id_dsa ] then ssh-keygen -t dsa -q -N "" -f ~/.ssh/id_dsa fi cat ~/.ssh/id_dsa.pub | ssh -p$PORT $RUSER@$IP "mkdir /root/.ssh; cat >> /root/.ssh/authorized_keys" } matchsoftware () { # Matches easyapache config and grabs customer package and feature lists rsync -avHle "ssh -p$PORT" /var/cpanel/easy/apache/ $RUSER@$IP:/var/cpanel/easy/apache/ rsync -avHle "ssh -p$PORT" /var/cpanel/packages/ $RUSER@$IP:/var/cpanel/packages/ rsync -avHle "ssh -p$PORT" /var/cpanel/features/ $RUSER@$IP:/var/cpanel/features } mysqldowngrade () { # Downgrades mysql REMOTEMYSQL=`ssh -p$PORT $RUSER@$IP 'mysql --version'|grep mysql|cut -d ' ' -f6|cut -d ',' -f1|cut -d 'a' -f1|cut -d '.' -f1` LOCALMYSQL=`mysql --version|grep mysql|cut -d ' ' -f6|cut -d ',' -f1|cut -d 'a' -f1|cut -d '.' -f1` if [[ "$REMOTEMYSQL" -gt "$LOCALMYSQL" ]]; then ssh -p$PORT $RUSER@$IP "for each in cphulkd eximstats horde leechprotect modsec roundcube; do mysqldump --compatible=mysql40 $each > $each.sql;" ssh -p$PORT $RUSER@$IP "mysql -e 'drop database horde'; mysql -e 'drop database roundcube'" ssh -p$PORT $RUSER@$IP "perl -pi -e 's/mysql-version=5.0/mysql-version=4.1/g' /var/cpanel/cpanel.config" ssh -p$PORT $RUSER@$IP '/scripts/mysqlup --force' ssh -p$PORT $RUSER@$IP 'for each in horde roundcube; do mysql -e "create database $each"; done' ssh -p$PORT $RUSER@$IP 'for each in horde roundcube cphulkd eximstats leechprotect modsec; do mysql $each < $each.sql; done' fi } easyapache () { #Runs easyapache ssh -p$PORT $RUSER@$IP '/scripts/easyapache --build' } skiphomedir () { #Checks to see if skiphomedir is valid switch to pkgacct SKIPHOMEDIR=`cat /scripts/pkgacct|grep skiphomedir|cut -d ' ' -f2|grep -v "("` if [ -z $SKIPHOMEDIR ]; then echo "/scripts/pkgacct does not accept --skiphomedir" echo "You must update cpanel to use this script" exit fi } pkgacctloop () { # Packages accounts --skiphomedir and scps the results to the remote server for RUSERS in `ls -A /var/cpanel/users`; do /scripts/pkgacct --skiphomedir $RUSERS; done ls -A /var/cpanel/users > /home/users.txt scp -P$PORT /home/cpmove-* $RUSER@$IP:/home ssh -p$PORT $RUSER@$IP 'cd /home; for RUSERS in `ls|grep cpmove|cut -d "-" -f2|cut -d "." -f1`; do /scripts/restorepkg $RUSERS; done' for SYNC in `cat /home/users.txt`; do rsync -avHle "ssh -p$PORT" /home/$SYNC/ $RUSER@$IP:/home/$SYNC/ --progress; done ssh -p$PORT $RUSER@$IP 'cp /usr/local/apache/conf/httpd.conf /usr/local/apache/conf/httpd.conf.bak`date +%Y%m%d`; /scripts/rebuildhttpdconf; /etc/init.d/httpd stop; sleep 2; /etc/init.d/httpd startssl;' } finalrsync () { # Stops services on remote server and runs a final rsync of data ssh -p$PORT $RUSER@$IP '/etc/init.d/cpanel stop' ssh -p$PORT $RUSER@$IP '/etc/init.d/mysql stop' ssh -p$PORT $RUSER@$IP '/etc/init.d/httpd stop' /etc/init.d/cpanel stop /etc/init.d/mysql stop /etc/init.d/httpd stop ls -A /var/cpanel/users > /home/users.txt rsync -avHle "ssh -p$PORT" /var/lib/mysql/ $RUSER@$IP:/var/lib/mysql/ --progress for SYNC in `cat /home/users.txt`; do rsync -avHle "ssh -p$PORT" /home/$SYNC/ $RUSER@$IP:/home/$SYNC/ --progress; done } nolocaldns () { # Checks for list of domains that are using external nameservers hostname=`hostname`;for each in `cat /etc/trueuserdomains | sed -e 's/:.*//'`;do dig NS $each | grep --silent "ns..${hostname#*\.}"; if [[ $? == 1 ]];then echo $each;fi;done > /root/not_local_dns.txt echo "Please check /root/not_local_dns.txt for list of domains not using local DNS" sleep 2 } premigrate () { # Duh; Lower TTLs and restart named wget http://layer3.example.com/migrations/premigrate.sh sh premigrate.sh } # # Start script # # Start while loop for fault tolerance LOOP=0 while [ $LOOP == 0 ] ; do # Prompt the admin with some choices for the appropriate stage # of the migration. echo "Please select the type of migration from the list below" echo "1) Full Initial Migration" echo "2) Initial Migration (No Software Version Matching)" echo "3) Final Rsync" echo "4) Single account migration (Shared to VPS/Dedicated)" echo "5) Single account final sync" echo "6) Downgrade MySQL only (NEW SERVERS ONLY!)" echo "7) Match software versions only" echo "8) Match software and downgrade MySQL (no migration)" echo "0) Exit" echo -n "Please enter your choice: " read STATUS case $STATUS in 1) # This executes the initial Migration # Checks for --skiphomedir validity skiphomedir # Run serverinfo/sshkeys function serverinfo sshkeys # Run premigrate.sh premigrate # Find which domains are not using locally configured DNS and dump to file nolocaldns # Match Software Versions and get all customer packages matchsoftware # Check MySQL version and downgrade if necessary mysqldowngrade # Runs easyapache easyapache # Package accounts and perform initial sync of data pkgacctloop LOOP=1 ;; 2) #Initial migration with no software version matching #Check for --skiphomedir validity skiphomedir # Run serverinfo/sshkeys function serverinfo sshkeys # Run premigrate.sh premigrate # Find which domains are not using locally configured DNS and dump to file nolocaldns # Package accounts and perform inital sync of data pkgacctloop LOOP=1 ;; 3) # Runs the final rsync. # Run serverinfo/sshkeys function serverinfo sshkeys # Do final rsync finalrsync LOOP=1 ;; 4) #Shared to VPS/Dedicated # Check for --skiphomedir validity skiphomedir # Run serverinfo/sshkeys function serverinfo sshkeys #Get rest of Migration info SUBLOOP=0 while [ $SUBLOOP -eq 0 ]; do echo -n "Domain name to be migrated (without www): " read DOMAIN echo "DNS will need to be updated for $DOMAIN at the nameservers!" SHARED=`cat /etc/userdomains|grep $DOMAIN|cut -d ' ' -f2|uniq` SUBLOOP=1 if [ -z $SHARED ] then echo "That domain does not exist on the server" sleep 2 clear SUBLOOP=0 fi done echo "The account has the following subdomains/addon\n domains configured that should be accounted for as well:\n" echo "Outputting addon domains to /root/addon_domains.txt" cat /etc/userdomains|grep $SHARED|cut -d ':' -f1|grep -v $DOMAIN > /root/addon_domains.txt cat /root/addon_domains.txt # Sleep for a few NAP=10 while [ $NAP -eq 10 ] ; do echo -n "Continuing in 10..." let NAP=$NAP-1 sleep 1 done while [ $NAP -gt 1 ] ; do echo -n "$NAP..." let NAP=$NAP-1 sleep 1 done while [ $NAP -eq 1 ] ; do echo "$NAP" sleep 1 let NAP=$NAP-1 done /scripts/pkgacct --skiphomedir $SHARED scp -P$PORT /home/cpmove-$SHARED.tar.gz $RUSER@$IP:/home/ scp -P$PORT /home{1..9}/cpmove-$SHARED.tar.gz $RUSER@$IP:/home/ ssh -p$PORT $RUSER@$IP "/scripts/restorepkg $SHARED" rsync -avHle "ssh -p$PORT" /home/$SHARED/ $RUSER@$IP:/home/$SHARED --progress --exclude=mail/new --exclude=mail/cur LOOP=1 ;; 5) #Single account final sync # Run serverinfo/sshkeys function serverinfo sshkeys #Get rest of Migration info SUBLOOP=0 while [ $SUBLOOP -eq 0 ]; do echo -n "Domain name to be migrated (without www): " read DOMAIN SHARED=`cat /etc/userdomains|grep $DOMAIN|cut -d ' ' -f2|uniq` SUBLOOP=1 if [ -z $SHARED ] then echo "That domain does not exist on the server" sleep 2 clear SUBLOOP=0 fi done rsync -avHle "ssh -p$PORT" /home/$SHARED/ $RUSER@$IP:/home/$SHARED --progress --exclude=mail/new --exclude=mail/cur for each in `ls /var/lib/mysql/|grep $SHARED|cut -d '/' -f1`; do mysqldump $each > /home/$SHARED/$each.sql; done scp -P$PORT /home/$SHARED/$SHARED*.sql $RUSER@$IP:/home/$SHARED/ ssh -p$PORT $RUSER@$IP "for each in `ls /home/$SHARED/|grep $SHARED*sql|cut -d '.' -f1`; do mysql -e 'drop database $each'; mysql -e 'create database $each'; mysql $each < /home/$SHARED/$each.sql; done" LOOP=1 ;; 6) #Downgrade MySQL only #Runs the 4 functions to gather info, set up ssh keys, downgrade mysql and run easyapache serverinfo sshkeys mysqldowngrade if [ $REMOTEMYSQL -lt $LOCALMYSQL ]; then clear echo "Remote MySQL version is lower than local MySQL." echo "MySQL not downgraded" else easyapache fi LOOP=1 ;; 7) #Match software versions #Runs the 4 functions to gather info, set up ssh keys, rsync software, and run easyapache serverinfo sshkeys matchsoftware easyapache LOOP=1 ;; 8) #Match software and downgrade mysql, no migration serverinfo sshkeys matchsoftware mysqldowngrade easyapache LOOP=1 ;; 0) #Exit Gracefully LOOP=1 ;; *) # Default echo "Not a valid choice" sleep 1 clear esac done