Created
July 10, 2012 13:14
-
-
Save ehowe/3083162 to your computer and use it in GitHub Desktop.
automigrate
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
clear | |
unalias ls 2> /dev/null | |
# | |
# The next section is only functions that are called in other parts of the script | |
# | |
# THIS FUNCTION IS CURRENTLY BROKEN! | |
#errorcheck () { | |
# This function checks the exit status of every other command run in the script | |
#`$@` | |
#if [[ $? != 0 ]]; | |
#then | |
#SUBLOOP=0 | |
#while [ $SUBLOOP -eq 0 ]; | |
#do | |
#echo -n "$1 had an error. Would you like to continue? " | |
#read ERRORCHECK | |
#case $ERRORCHECK in | |
#yes) | |
#SUBLOOP=1 | |
#;; | |
#no) | |
#exit 1; | |
#;; | |
#*) | |
#echo "Please enter 'yes' or 'no'" | |
#SUBLOOP=0 | |
#;; | |
#esac | |
#done | |
#fi | |
#} | |
scripthelp () { | |
echo -e "Automigrate.sh Help: \n" | |
echo "This script can only be run on the server you are migrating from." | |
echo -e "Its goal is to make migrations as automated as possible. \n" | |
echo -e "Usage: \n" | |
echo "sh automigrate.sh [-o [1-9]] [-p PORT] [-i IP] [-u USER] [-h]" | |
echo "Choose the appropriate option from the menu." | |
echo "In most cases this will be option 1, unless " | |
echo "there are already accounts on the server you" | |
echo "are migrating to. If this is the case, " | |
echo "option 2 is for you. You can also choose one " | |
echo -e "of the specialized options if you would like. \n" | |
echo "Options:" | |
echo -e "-h\t\tDisplay this help message" | |
echo -e "-o\t\tWhich option in the menu you would like" | |
echo -e "-i\t\tIP you are migrating to" | |
echo -e "-u\t\tUser on the remote server" | |
echo -e "-p\t\tPort for SSH" | |
echo -e "-P\t\tPassword for Destination" | |
echo -e "-v\t\tView available menu options" | |
exit 0 | |
} | |
serverinfo () { | |
# Read Server Information | |
SUBLOOP=0 | |
while [ $SUBLOOP -eq 0 ]; | |
do | |
if [ -z $IP ]; then | |
echo -n "Remote server IP address: " | |
read IP | |
fi | |
SUBLOOP=1 | |
# IP is required | |
if [ -z $IP ]; then | |
echo "IP is required!" | |
sleep 1 | |
SUBLOOP=0 | |
else | |
validip | |
fi | |
#Find User | |
if [ -z $RUSER ]; then | |
echo -n "Remote User [root]: " | |
read RUSER | |
fi | |
#Get SSH Port | |
if [ -z $PORT ]; then | |
echo -n "SSH Port [22]: " | |
read PORT | |
fi | |
#Get Server password | |
if [ -z $RPASS ]; then | |
echo -n "Destination Server Password: " | |
read RPASS | |
SUBLOOP=1 | |
fi | |
#Password is required | |
if [ -z $RPASS ]; then | |
echo "Destination Password Required!" | |
SUBLOOP=0 | |
fi | |
# 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 | |
} | |
passwordlogin () { | |
KEY=`cat /root/.ssh/id_rsa.pub` | |
expect_output=$(expect -c " | |
send_user \"connecting to $IP\n\" | |
spawn ssh -o StrictHostKeyChecking=no $RUSER@$IP | |
#login handles cases: | |
# login with keys (no user/pass) | |
# user/pass | |
# login with keys (first time verification) | |
expect { | |
\"> \" { } | |
\"$ \" { } | |
\"assword: \" { | |
send \"$RPASS\n\" | |
expect { | |
\"> \" { } | |
\"$ \" { } | |
\"# \" { } | |
} | |
} | |
default { | |
send_user \"Login failed\n\" | |
exit | |
} | |
} | |
send \"mkdir -p ~/.ssh\n\" | |
expect { | |
\"> \" {} | |
\"# \" {} | |
default {} | |
} | |
send \"echo $KEY >> ~/.ssh/authorized_keys\n\" | |
expect { | |
\"> \" {} | |
\"# \" {} | |
default {} | |
} | |
send \"exit\n\" | |
expect { | |
\"> \" {} | |
\"# \" {} | |
default {} | |
} | |
send_user \"finished\n\" | |
") | |
echo "$expect_output" | |
} | |
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_rsa ] | |
then ssh-keygen -t rsa -q -N "" -f ~/.ssh/id_rsa | |
fi | |
} | |
matchsoftware () { | |
# Matches easyapache config and grabs customer package and feature lists | |
REMOTECPANEL=`ssh -p $PORT $RUSER@$IP 'cat /var/cpanel/cpanelsync/repoversions/cpanel | cut -d "." -f1,2'` | |
NEEDEDCPANEL=11.25 | |
if [[ $REMOTECPANEL < $NEEDEDCPANEL ]]; then | |
ssh -p$PORT $RUSER@$IP 'sed -i -e "s/CPANEL=.*/CPANEL=current/g" /etc/cpupdate.conf; /scripts/upcp --force' | |
fi | |
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 | |
} | |
mysqlversions () { | |
# Downgrades mysql | |
REMOTEMYSQL=`ssh -p$PORT $RUSER@$IP 'mysql --version'|grep mysql|cut -d ' ' -f6|cut -d ',' -f1|cut -d 'a' -f1|awk -F"." '{print $1"."$2}'` | |
LOCALMYSQL=`mysql --version|grep mysql|cut -d ' ' -f6|cut -d ',' -f1|cut -d 'a' -f1|awk -F"." '{print $1"."$2}'` | |
# if [[ $REMOTEMYSQL != $LOCALMYSQL ]]; then | |
# ssh -p$PORT $RUSER@$IP "for each in cphulkd eximstats horde leechprotect modsec roundcube; do mysqldump --compatible=mysql40 $each > $each.sql; done" | |
# 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=.*/mysql-version=$LOCALMYSQL/' /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 | |
if [[ $REMOTEMYSQL > $LOCALMYSQL ]]; then | |
echo "The versions of MySQL do not match" | |
echo "Please correct this and run the script again" | |
exit 1 | |
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'` | |
if [[ -z $SKIPHOMEDIR ]]; then | |
echo "/scripts/pkgacct does not accept --skiphomedir" | |
echo "You must update cpanel to use this script" | |
exit 1 | |
fi | |
} | |
pkgacctloop () { | |
# Packages accounts --skiphomedir and scps the results to the remote server | |
mysql -e 'show databases;' | |
if [[ $? != 0 ]]; | |
then | |
SUBLOOP=0 | |
while [ $SUBLOOP -eq 0 ]; | |
do | |
echo "MySQL is not functioning correctly" | |
echo -n "Would you like to continue? " | |
read SQLERR | |
case $SQLERR in | |
yes) | |
SUBLOOP=1; | |
;; | |
no) | |
exit 1; | |
;; | |
*) | |
echo "You must enter 'yes' or 'no'" | |
SUBLOOP=0 | |
;; | |
esac | |
done | |
fi | |
> /home/dedips.txt | |
> /home/didnotrestore.txt | |
MAINIP=`cat /etc/wwwacct.conf|grep ADDR|awk '{print $2}'` | |
for DEDIPACCT in `ls -A /var/cpanel/users/`; do if [[ $MAINIP != `grep IP /var/cpanel/users/$DEDIPACCT|cut -d '=' -f2` ]]; then if [[ $DEDIPACCT != system ]]; then echo $DEDIPACCT >> /home/dedips.txt; fi; fi; done | |
for RUSERS in `ls -A /var/cpanel/users | grep -vf /home/dedips.txt`; do echo $RUSERS >> /home/sharedips.txt; done | |
for RUSERS in `ls -A /var/cpanel/users`; do /scripts/pkgacct --skiphomedir $RUSERS /home cpmove nocompress; done | |
ls -A /var/cpanel/users > /home/users.txt | |
scp -P$PORT /home/cpmove-*.tar $RUSER@$IP:/home | |
scp -P$PORT /home/dedips.txt $RUSER@$IP:/home | |
scp -P$PORT /home/sharedips.txt $RUSER@$IP:/home | |
ssh -p$PORT $RUSER@$IP '> /home/didnotrestore.txt; mkdir /home/cprestoretemp; for RUSERS in `cat /home/dedips.txt`; do mv /home/cpmove-$RUSERS.tar /home/cprestoretemp; /scripts/restorepkg --ip=y /home/cprestoretemp/cpmove-$RUSERS.tar; mv /home/cprestoretemp/cpmove-$RUSERS.tar /home; if ! [ -f /var/cpanel/users/$RUSERS ]; then echo $RUSERS >> /home/didnotrestore.txt; fi; done' | |
ssh -p$PORT $RUSER@$IP 'cat /home/didnotrestore.txt' >> /home/didnotrestore.txt | |
if [ ! -s /home/didnotrestore.txt ]; then | |
echo "All users restored successfully" | |
RESTORED=1 | |
else | |
echo "The following users did not restore" | |
cat /home/didnotrestore.txt | |
RESTORED=0 | |
fi | |
if [ $RESTORED == 0 ]; then | |
echo -n "Would you like to continue? (Failed accounts will not rsync data) (y/n) " | |
read CONTINUE | |
case $CONTINUE in | |
y) ;; | |
n) exit ;; | |
*) echo "Invalid input. Not continuing."; exit ;; | |
esac | |
fi | |
ssh -p$PORT $RUSER@$IP 'for RUSERS in `cat /home/sharedips.txt`; do if [ ! -d "/home/cprestoretemp" ]; then mkdir /home/cprestoretemp; fi; mv /home/cpmove-$RUSERS.tar /home/cprestoretemp; /scripts/restorepkg /home/cprestoretemp/cpmove-$RUSERS.tar; mv /home/cprestoretemp/cpmove-$RUSERS.tar /home; done' | |
for SYNC in `cat /home/dedips.txt | grep -vf /home/didnotrestore.txt`; do rsync -avHle "ssh -p$PORT" /home/$SYNC/ $RUSER@$IP:/home/$SYNC/ --progress; done | |
for SYNC in `cat /home/sharedips.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;' | |
} | |
nolocaldns () { | |
# Checks for list of domains that are using external nameservers | |
counter=1 | |
for ns in `cat /etc/nameserverips | cut -d '=' -f2`; do | |
nsarray[$counter]=`echo $ns | tr "[:upper:]" "[:lower:]"` | |
counter=`expr $counter + 1` | |
done | |
for domain in `cat /etc/userdomains | grep -v \* | cut -d ':' -f1 | egrep "^[a-zA-Z0-9]([-]?[a-zA-Z0-9])+\.[a-z]{2,9}$"`; do | |
nameserver=`dig NS $domain | sed -r -n "/IN\sNS/p" | grep -v "^;" | head -1 | awk '{print $5}' | sed 's/.$//' | tr "[:upper:]" "[:lower:]"` | |
for (( i=1; i <= ${#nsarray[@]}; i++ )); do | |
if [[ ${nsarray[$i]} == $nameserver ]]; then | |
hasnameserver=1 | |
fi | |
done | |
if [[ $hasnameserver -ne 1 ]]; then | |
echo $domain >> /root/not_local_dns.txt | |
fi | |
hasnameserver=0 | |
done | |
echo "Please check /root/not_local_dns.txt for list of domains not using local DNS" | |
sleep 2 | |
} | |
premigrate () { | |
sed -i.lwbak -e 's/14400/300/g' -e 's/86400/300/g' -e "s/[0-9]\{10\}/`date +%Y%m%d%H`/g" /var/named/*.db | |
} | |
rsyncupgrade () { | |
#Optional function to upgrade rsync to V 3.0 | |
LOCALCENT=`cat /etc/redhat-release |awk '{print $3}'|cut -d '.' -f1` | |
REMOTECENT=`ssh -p$PORT $USER@$IP "cat /etc/redhat-release" |awk '{print $3}'|cut -d '.' -f1` | |
LOCALARCH=`uname -i` | |
REMOTEARCH=`ssh -p$PORT $USER@$IP "uname -i"` | |
rpm -Uvh http://migration.sysres.liquidweb.com//rsync/rsync-3.0.0-1.el$LOCALCENT.rf.$LOCALARCH.rpm | |
ssh -p$PORT $USER@$IP "rpm -Uvh http://migration.sysres.liquidweb.com/rsync/rsync-3.0.0-1.el$REMOTECENT.rf.$REMOTEARCH.rpm" | |
} | |
menuoptions () { | |
echo "This should ONLY be run on the server you are migrating FROM!" | |
echo "" | |
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) Single account migration (Shared to VPS/Dedicated)" | |
echo "4) Match software versions only" | |
echo "5) Upgrade rsync" | |
echo "0) Exit" | |
} | |
# | |
# Take care of some options before starting script | |
# | |
# o=Option for Loop | |
# h=server you are migrating to | |
# u=user for remote server | |
# p=port | |
# v=view options | |
optstr=o:i:u:p:P:hv | |
while getopts $optstr var | |
do | |
case $var in | |
o) STATUS=$OPTARG ;; | |
i) IP=$OPTARG ;; | |
u) RUSER=$OPTARG ;; | |
p) PORT=$OPTARG ;; | |
P) RPASS="$OPTARG" ;; | |
h) scripthelp ;; | |
v) menuoptions; exit ;; | |
esac | |
done | |
# | |
# 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. | |
if [ -z $STATUS ]; then | |
menuoptions | |
echo -n "Please enter your choice: " | |
read STATUS | |
fi | |
case $STATUS in | |
1) # This executes the initial Migration | |
source ~/.bash_profile | |
skiphomedir | |
serverinfo | |
sshkeys | |
passwordlogin | |
rsyncupgrade | |
sed -i -e 's/export\ RPASS.*//' ~/.bash_profile | |
premigrate | |
nolocaldns | |
matchsoftware | |
mysqlversions | |
easyapache | |
pkgacctloop | |
echo "Domains not using Local Nameservers" | |
cat /root/not_local_dns.txt | |
echo "Migration Complete" | |
LOOP=1 | |
;; | |
2) #Initial migration with no software version matching | |
source ~/.bash_profile | |
skiphomedir | |
serverinfo | |
sshkeys | |
passwordlogin | |
rsyncupgrade | |
premigrate | |
sed -i -e 's/export\ RPASS.*//' ~/.bash_profile | |
nolocaldns | |
pkgacctloop | |
echo "Domains not using Local Nameservers" | |
cat /root/not_local_dns.txt | |
echo "Migration Complete" | |
LOOP=1 | |
;; | |
3) #Shared to VPS/Dedicated | |
skiphomedir | |
serverinfo | |
sshkeys | |
passwordlogin | |
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/trueuserdomains|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 | |
;; | |
4) #Match software versions | |
#Runs the 4 functions to gather info, set up ssh keys, rsync software, and run easyapache | |
serverinfo | |
sshkeys | |
passwordlogin | |
matchsoftware | |
easyapache | |
LOOP=1 | |
;; | |
5) | |
serverinfo | |
sshkeys | |
passwordlogin | |
rsyncupgrade | |
LOOP=1 | |
;; | |
0) #Exit Gracefully | |
exit 0; | |
;; | |
*) # Default | |
echo "Not a valid choice" | |
sleep 1 | |
clear | |
esac | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment