Moving From No Control Panel Servers to a cPanel Server

When I first started with my employer as a sysadmin I was given a long term goal:

  • Move email services from our dedicated email server to cPanel
  • Move website services from our dedicated web server to cPanel.

The major inconvenience being that the existing servers did not have a control panel to work with. So how do we go about moving from a non cPanel server to a cPanel server? Well I’m going to zip over some points about it.

Moving Email to cPanel

Let me talk about the existing setup a little. It was a dedicated mail server basically. It ran Exim and dovcat, and a little control panel called VMail VMC. I can’t recall what it stood for. Anyway it was this simple little control panel that our clients could login to to add and remove popboxes and forwarders. The only good thing about this setup was VMail worked on MySQL, so when new email came in it would check if the domain and user existed in the MySQL database. Then we had a branded version of squirrel mail.

The concept was to relocate 180 odd email customers using this server to the control panel cPanel. Here’s how we did it.

Step 1 – The problem with passwords is we don’t know what they are…

For security reasons, the popbox passwords were stored in MD5 in the MySQL database. This meant that we couldn’t reverse them or copy and paste them over to the cPanel server. Basically the passwords either had to be reset or we needed to be given them. Resetting all the passwords would have been a catastrophe. What we really needed was a list of all the passwords – so we made our own.

The POP server we were running was Dovecot. We wrote a script that upon successfully authentication, the login details were inserted in a new table in the database. The following day we took another look at it and realised every login was being recorded multiple times. So we add a new field to the existing table holding the logins and updated it with the plaintext password harvested during the POP login. All we had to do was wait.

A few weeks later I put together a query that joins the domains table and popboxes table together, counting the number of popboxes per domain and the number of popboxes per domain with a plaintext password stored. If these two counts were the same we had a client with all passwords logged that we could transfer.

We found that after the first month, we didn’t really gain any more passwords. Everyone that was going to login had logged in and the list I mentioned above didn’t grow much. So we had to come up with a way that we could reset the passwords too if we didn’t know what it was.

Step 2 – Transferring the popboxes…

Essentially all a popbox (email account with an inbox) was is a configuration that would accept mail. To create a new one on cPanel we needed to know what the email address and password to use. Known the email address was easy. In early days I came up with these script, which was long before we automated the process.

<?php
$content = file_get_contents(‘/root/emailstoadd.txt’);
$lines = explode(“\n”, $content);
foreach ($lines as $line)
{
$line_parts = explode(‘ ‘, trim($line));
exec(“/scripts/addpop “.$line_parts[0].” “.$line_parts[1]);
}
echo “done!\n”;
?>

In the above instance the client had provided me with a list of email addresses and passwords they wanted to use. We basically broke the supplied list up and added a new email address using the cPanel script in /scripts/addpop.

Now afterwards (naturally) I realised I could have just added it using the import feature in cPanel. You just upload a file with everything in it and it does it for you. But by doing the above I build the basic concept of automating adding popboxes. We could run a MySQL query to the old mail server and retrieve both!

The only downside using this method is that a mailbox quota isn’t implemented. Everything else is above board.

Step 3- Moving the email forwarders…

Just like popboxes, essentially all a forwarder is was is a configuration that would accept mail and send it elsewhere. Implementing forwarders was so incredibly easy! There was one catch, and one only. On the hold system, forwarders moved mail, instead of copying email, AND where multiple were sometimes setup as follows:

sales->john@domain.com.au,joan@domain.com.au,james@domain.com.au

As you can very clearly see, they all start with J – but that’s besides the point. The format isn’t compatible for transfer, you may need to make manual modifications later.

In essence to setup a forward, all you do it write to the alias file. In cPanel they’re referred to as virtual aliases. They’re stored at the following path:

/etc/valiases/$domain

Where $domain equals the domain name. They’re stored in the format:

sales@domain.com.au: john@domain.com.au
sales@domain.com.au: joan@domain.com.au
sales@domain.com.au: james@domain.com.au
info@domain.com.au: james@domain.com.au
external@domain.com.au: externalemail@hotmail.com

A very simple format to write to.

Step 4 – Transferring the email…

This caused a bit of a stir. Most of the clients had a very simple mail setup. They used POP3, they downloaded their mail to Microsoft Outlook and that was it. Others, used a complex IMAP setup and stored all their emails on the server with a heap of sub folders.

For the simple POP users with barely any mail on the server we used fetchmail. We would write to the .fetchmailrc file which was stored locally on each of the cPanel servers (fetchmail is easy to install too just yum install fetchmail). For those new to fetchmail, it polls other mail servers. If it finds email, it can act as a client and receive those emails – effectively transferring email between servers. The downside is it rewrote the time on every email message to the time we did the transfer. I’m sure there is a parameter you can use though to turn that off, but we never bothered.

As I mentioned, people that used IMAP or webmail a lot had subfolders filled with emails. When using fetchmail, it would wreck all that structure. Using fetchmail, because is acts as a normal client acting as POP it removed the emails on the server after downloading. This tested our backups a few times! Because the mail storage methods were identical, in the end we just rsync’ed the mail folders over – it didn’t rewrite times, it maintained storage structure and with just one rsync command everything was just there and ready to use again.

My Script

Noting all of these factors I wrote a script to automate the migration progress. I chose to write it in PHP because I prefer using the MySQL functions in it, plus I’m very familiar with PHP.

If you’re thinking that you can copy this script, run it and expect it to work – wrong! We had a customised setup, and you’ll need to adjusts it to work on your own setup if infact you decide to use it. The reason I’m posting this is to give some ideas, whether you integrate them with your own or otherwise.

The code is licensed as follows.

Creative Commons License
Email Migration Script by Simplec Services is licensed under a Creative Commons Attribution 2.5 Australia License.

<?php

/*

This should run on the destination server.

Thought process:

– ./importmail.php domain.com.au
– check if domain.com.au account is setup on new server
– connect to mysql on remote server
– check if domain exists in vmail
– build record set of popboxes (select * from popbox where domain_name = “domain.com.au”)
– add popbox on new server – system(‘/scripts/addpop ‘.$email.’ ‘.$password.’ ‘.$quota);
– where $password is blank make one up
– create forwarders too
– print to screen
– add to fetchmail file in appropriate format

*/

$domain = $argv[1];

if ($domain == “”)
{
die(“No domain selected. You must use syntax \”command domain.com.au\”.”);
}

// Mail server – mysql details
$mail_host = “mail.domain.com.au”;
$mail_user = “vmail_user”;
$mail_password = “securepassword”;
$mail_database = “vmail_database”;

echo “\nThis script will connect to $mail_host in an attempt to migrate popboxes\nand forwarders to this server for the domain $domain.\n\n”;

echo “Attempting database connection… “;

// connect to database
$connection = mysql_connect($mail_host, $mail_user, $mail_password);
if (!$connection)
{
die(mysql_error());
}

$database = mysql_select_db($mail_database, $connection);
if (!$database)
{
die(mysql_error());
}

echo “Connectetd.\n\n”;

// check domain exists… num_rows… select * from domain where domain_name = “”

$get_domain = mysql_query(“SELECT domain_name FROM domain WHERE domain_name = ‘$domain’ LIMIT 1”) or die(mysql_error());

if (mysql_num_rows($get_domain) < 1)
{
// error domain doesn’t exist
die(“$domain was not found in the domain table.”);
}
else
{
while ($domain_data = mysql_fetch_array($get_domain))
{

echo “Starting popbox migration\n\n”;

// get popboxes to migrate
$get_popboxes = mysql_query(“SELECT CONCAT(local_part, ‘@’, domain_name) AS username, plain_pass AS password FROM popbox WHERE domain_name = ‘$domain'”) or die(mysql_error());

$data_stream = fopen(“/root/.fetchmailrc”, a);

while ($popbox_data = mysql_fetch_array($get_popboxes))
{

if ($popbox_data[username] != “”)
{
// hopefully email is valid

echo “Creating account $popbox_data[username] … “;

if ($popbox_data[password] == “”)
{
$password_length = 9;
$popbox_data[password] = substr(md5($popbox_data[username] . strlen($popbox_data[username])),0,$password_length);
echo “No password found – generating password… “;
}

echo “Using password $popbox_data[password] … “;

$create_result = system(‘/scripts/addpop ‘.$popbox_data[username].’ ‘.$popbox_data[password].’ 250 > /dev/null’);

// write to fetchmail file
$fetchmail_content = “user $popbox_data[username] with password $popbox_data[password] is $popbox_data[username] here\n”;

fwrite($data_stream, $fetchmail_content);   ///// **** Comment this line out to disable writing to fetchmail. To do rsync data migration
echo “Written to fetchmail… “;
}
else
{
// error, dont write to fetchmail
echo “Error. Fetchmail not written to… “;
}

echo “Popbox migration done.\n\n”;

}

fclose($data_stream);

// get forwarders to migrate
$get_forwarders = mysql_query(“SELECT CONCAT(local_part, ‘@’, domain_name) AS emailfrom, remote_name AS emailto FROM forwarder WHERE domain_name = ‘$domain'”) or die(mysql_error());

$data_stream = fopen(“/etc/valiases/$domain”, a);

while ($forwarders_data = mysql_fetch_array($get_forwarders))
{

echo “Starting forwarder migration\n\n”;

echo “Creating forwarder from $forwarders_data[emailfrom] to $forwarders_data[emailto]… “;

if ($forwarders_data[emailfrom] != “” || $forwarders_data[emailto] != “”)
{

// write to fetchmail file
$valias_content = “$forwarders_data[emailfrom]: $forwarders_data[emailto]\n”;

fwrite($data_stream, $valias_content);
echo “Written to valias… \n”;
}
else
{
// error, dont write to fetchmail
echo “Error. valias not written to… \n”;
} // if

} // while

echo “Forwarder migration done.\n\n”;

fclose($data_stream);

} // while domains
} // else – if domain exists

mysql_close($connection);

?>

And that was it. That’s what we moved. I went from moving one email domain every 20-45 minutes to one every 2-10 minutes (this is including contacting the client and talking to them). It is the job of a system administrator to automate as much of the work as possible – because lets face it, we have better things to do.

Moving Websites to cPanel

Now, like our email setup we used a customised web setup; a propriety content management systems called SnapCMS, originally developed by Snapfrozen Australia. About 90% of all clients on that server used SnapCMS so the transfer process for each was going to be very similar. If you have a server now that has the same thing installed on it 100-200 times, the transfer will be similar. You can adapt the script below to do whatever you need to do.

To make this script, I basically made a list of everything I needed to do in order to move a website. The intention was to then get that script to do all of it. I got most of the way, and I’ll likely develop it further to finish everything.

Some things this script does not do! It does NOT create a cPanel account for you. I toyed with it, and I got over it very quickly. It is easier for me to create the account via WHM, select the predefine plan I want to use and click submit. If I used the script I would have to define all the plan specs manually and I didn’t want to do that. Maybe that is something you can add yourself.

The script doesn’t create the MySQL database on the destination server for you. It could, and probably will in the future – but I need time to sit down and determine how to safely create a database for a cPanel user. I tried something and it failed, so I commented it out and will come back for it later. Feel free to modify it.

At the end of the migration, the script forwards the database connections from the source to the destination server. This saves data loss while waiting for DNS propagation. We ran our TTL at 10 minutes but it was just easier for testing and to be able to say to customers “there wouldn’t be any downtime”.

I use the MySQL setup wizard to add the new database in cPanel. The wizard flow reduces clicking and the workflow is good. I would never have used it in the past because of the term “wizard” but it actually is better. THEN I added the source server hostname/ip into the remote connections (so you can forward the DB connections). Also make sure that skip-networking isn’t enabled or you won’t get an external db connection in.

Beyond the stuff I have already mentioned, I know for a fact there is a bug in the logic asking Y/n for a database. You’ll have to fix that. Shouldn’t be hard. Alternatively if anyone is reading this and enough time has passed, I’m sure if you contacted me I would have a version later than 7. Depending on what you want I might be able to help you modify it or give tips.

So a brief checklist for moving websites:

  • Lower TTL on the DNS zone to reduce propagation (I went for 300 seconds or 10 minutes). I set every zone on the server to 300 seconds to avoid the stuffing around with it one at a time. Meant on a good day we could just keep transferring.
  • Create cPanel account
  • CSV and SVN
  • Website files
    • Check for old hard coded paths
  • Database
    • Check for old hard coded path references in database
  • Permissions and stats
  • DNS
    • Transfer subdomains
    • Special MX records, etc
  • Cron
  • MIME

DNS

Let’s talk about the pain that DNS is!! Firstly, the domain name must have nameservers pointing to DNS servers you control. If you don’t, it gets difficult. You need to contact the client, teach them how to change it themselves or remind them their DNS hosting is at dnsmadeeasy.com or similar.

Most of our clients are businesses or companies, so some of them prefer to manage their own DNS to point to difference offices and servers, etc. If you manage their DNS though it is much easier. If you don’t, try and get access to make the change yourself.

Our old nameservers point to the source server, so my script modifies the zone file directly.

Make sure you setup DNS records of subdomains and so on or you’ll break the sites. Don’t forget to adjust the TTL for these too!

Create cPanel Account

As I said earlier I haven’t automated this and likely won’t. There isn’t a demand for me so I’ll unlikely waste time on it. I prefer to create the accounts manually and supply the values to the script. Nothing more to say on this.

CSV and SVN

Our old system used both CSV and SVN. We don’t use it anymore. We remove these folders to reduce the space transferred and stored on the destination server.

Website Files

SnapCMS uses centralised library files stored elsewhere on the server. It also uses separate library, includes and page template files to build the page. These all sit outside the document root. So if the main directory is /var/www/html/domain.com.au/ most of the other folders sit there, including the document root folder html (you might also use htdocs, public, etc).

We search all the files for specific references to /var/www/tools/ so we know if it references a central source that doesn’t exist on the new server. This is encountered when there are additional scripts installed that reference phpmailer or similar – they usually point to SnapCore.

That side, just because I search for that doesn’t mean you have nothing to search for. You may need to search and replace old document root paths, old usernames, etc.

The transfer of the website files is pretty easy. My script uses rsync to move them over.

SSH / Authentication

I mention SSH because the last line above this section mentions rsync. My script is run on the destination server and pulls the files across. We use SSH keys on the root user between the servers to make the process as smooth as possible – no entering passwords each time you want to rsync something over or SSH over to the other server to execute a command.

Database

As mentioned, my script asks you if you want to transfer over one database. Typically our SnapCMS sites only have one. It uses mysqldump to save a .sql file to the /docroot/sql/ directory. You may need to adjust the sql path. I don’t check if it exists or not, I know it’s always there.

You could compress the database over before transferring it. I personally found this a waste of time, and would prefer to burn the bandwidth than time.

The database .sql file is transferred over with the rest of the website files (it is actually done first, then the files are transferred over). One pull across only, much easier.

Once I get the .sql file to the destination server I check it for references to /var/www/ and other paths that won’t exist on the new server. Most of the time it returns nothing but sometimes it catching something and stops a lot of head scratching.

Permissions and Stats

Because we’re switching between non-control panel servers and cPanel, the user typically changes. You know, we go from nobody or apache owner/group to the new cPanel username. My method of fixing this isn’t the best, but I wanted to avoid breaking the existing permissions by doing a chown -R * on everything, which can potentially break email, etc. Effectively what I do is search for the files I’ve transferred over and then rechown, etc.

One thing I should point out is if you are search to fix this, or any of my other search methods, if your file or folder name has a character that requires delimited under normal conditions… mine doesn’t fix this. It will return file not found. Keep this in mind.

We previously used awstats on the old server. Its really old, most of it is broken but some clients really really love it and can’t live without it. So we had to come up with a way to not break stats. I have no idea where this came from, so I can’t reference the source sorry, but it links to webalizer! Most snapCMS sites have a /usage directory to access stats. We use this:

cd /home/username/
mv public_html/usage public_html/usage.old
ln -s ../tmp/webalizer public_html/usage
chmod 755 tmp
chmod 755 tmp/webalizer

Now when I go to /usage I can see the webalizer. You could throw a .htaccess file in the webalizer folder to password protect it if you want. We do that on demand if a client requests it.

Cron

Now my script doesn’t check for cron entries yet. It might later because I always forget to check. Check it yourself before closing a migration off:

crontab -e -u username
crontab -e

You don’t want to break anything.

MIME

Another thing I constantly forget. Most of the pages are .html but they contain PHP. So I have to add a custom MIME entry using cPanel. I might insert this into the .htaccess automatically later. Undecided. Check this before completing the transfer though. Usually I noticed it after I test with my local hosts file.

The Script

Drum roll, you’ve been very patient. I know I ramble a lot sorry – I think you can skip over reading it if you want to, but the info is there if you need it.

The script…

The code is licensed as follows.

Creative Commons License
Email Migration Script by Simplec Services is licensed under a Creative Commons Attribution 2.5 Australia License.

echo
echo “Version 7”
echo “This script will guide you moving websites from OLDSERVER to NEWSERVERS.”
echo
echo “Please ensure that the new hosting account is setup on the new server before continuing.”
echo “A MySQL user, database and accepting remote connection must also be setup prior.”
echo
# =========================================================================
# check user

foobar=`whoami`

if [ “$foobar” != “root” ] ; then
echo “This script can only be run as root.”
echo
exit;
fi

# =========================================================================

# =========================================================================
# domainName

echo -n “What is the domain name you’ll be moving? ”
read domainName

# =========================================================================

# =========================================================================
# sourceServer

defaultSourceServer=`host www.${domainName} | grep ‘has address’ | awk ‘{print $4}’`
echo -n “What IP address is the website currently running on? [$defaultSourceServer] ”
read sourceServer

if [ “$sourceServer” == “” ] ; then
sourceServer=$defaultSourceServer
fi

# =========================================================================

# =========================================================================
# sourceDocumentRoot

defaultSourceDocumentRoot=/var/www/html/$domainName
echo -n “What is the document root on OLDSERVER? [$defaultSourceDocumentRoot] ”
read sourceDocumentRoot

if [ “$sourceDocumentRoot” == “” ] ; then
sourceDocumentRoot=$defaultSourceDocumentRoot
fi

# =========================================================================

# =========================================================================
# sourceExistingDatabase

defaultSourceExistingDatabase=Y
echo -n “Is there a snap database to move? [Y/n] ”
read sourceExistingDatabase

if [ “$sourceExistingDatabase” == “” ] ; then
sourceExistingDatabase=$defaultSourceExistingDatabase
fi

# =========================================================================

if [ “$sourceExistingDatabase” == “Y” ] ; then

# =========================================================================
# sourceDatabaseName

echo -n “What is the database name used by the website? ”
read sourceDatabaseName

# =========================================================================

# =========================================================================
# sourceDatabaseUserName

defaultSourceDatabaseUserName=snapuser
echo -n “What is the remote database username? [$defaultSourceDatabaseUserName] ”
read sourceDatabaseUserName

if [ “$sourceDatabaseUserName” == “” ] ; then
sourceDatabaseUserName=$defaultSourceDatabaseUserName
fi

# =========================================================================

# =========================================================================
# sourceDatabasePassword

defaultSourceDatabasePassword=SnApDeFaultPassWord # This isn’t really the password 😛
echo -n “What is the remote database password? [$defaultSourceDatabasePassword] ”
read sourceDatabasePassword

if [ “$sourceDatabasePassword” == “” ] ; then
sourceDatabasePassword=$defaultSourceDatabasePassword
fi

# =========================================================================

fi

# =========================================================================

# =========================================================================
# sourcePathToBind

defaultSourcePathToBind=/var/named/chroot/var/named/
echo -n “What is the remote path to BIND zone file directory? [$defaultSourcePathToBind] ”
read sourcePathToBind

if [ “$sourcePathToBind” == “” ] ; then
sourcePathToBind=$defaultSourcePathToBind
fi

# =========================================================================

# =========================================================================
# destinationServer

defaultDestinationServer=`hostname`
echo -n “What server is the website being moved to? [$defaultDestinationServer] ”
read destinationServer

if [ “$destinationServer” == “” ] ; then
destinationServer=$defaultDestinationServer
fi

# =========================================================================

# =========================================================================
# destinationUserName

echo -n “What is the cPanel username? ”
read destinationUserName

# =========================================================================

# =========================================================================
# destinationPassword

echo -n “What is the cPanel password? ”
read destinationPassword

# =========================================================================

# =========================================================================
# destinationDatabaseName

defaultDestinationDatabaseName=${destinationUserName}_snapcms
echo -n “What database name/username would you like to use? [$defaultDestinationDatabaseName] ”
read destinationDatabaseName

if [ “$destinationDatabaseName” == “” ] ; then
destinationDatabaseName=$defaultDestinationDatabaseName
fi

# =========================================================================

# =========================================================================
# destinationDatabasePassword

defaultDestinationDatabasePassword=`head -c 10 < /dev/random | uuencode -m – | tail -n 2 | head -c 14`
echo -n “What database destinationPassword? [$defaultDestinationDatabasePassword] ”
read destinationDatabasePassword

if [ “$destinationDatabasePassword” == “” ] ; then
destinationDatabasePassword=$defaultDestinationDatabasePassword
fi

# =========================================================================

# =========================================================================

echo
echo Domain Name: domainName = ${domainName}
echo Source Server: sourceServer = ${sourceServer}
echo Source Server Path: sourceDocumentRoot = ${sourceDocumentRoot}
echo Source Database Exists: sourceExistingDatabase = ${sourceExistingDatabase}
echo Source Database Name: sourceDatabaseName = ${sourceDatabaseName}
echo Source Database destinationUserName: sourceDatabaseUserName = ${sourceDatabaseUserName}
echo Source Database destinationPassword: sourceDatabasePassword = ${sourceDatabasePassword}
echo Source Path to BIND: sourcePathToBind = ${sourcePathToBind}
echo Destination Server: destinationServer = ${destinationServer}
echo Destination Server cPanel destinationUserName: destinationUserName = ${destinationUserName}
echo Destination Server cPanel destinationPassword: destinationPassword = ${destinationPassword}
echo Destination Server Database Name / destinationUserName: destinationDatabaseName = ${destinationDatabaseName}
echo Destination Server Database destinationPassword: destinationDatabasePassword = ${destinationDatabasePassword}
echo

# =========================================================================

# =========================================================================

echo “Check the above details are correct. They’ll be used to trasfer the website.”
echo
echo -n “Press enter to proceed with the transfer… ”
read foobar

# =========================================================================

# =========================================================================
# Source Server

echo
echo
echo “== Remote Server ==”

if [ “$sourceExistingDatabase” == “Y” ] ; then

echo
echo “Connecting to MySQL and dumping database…”
echo
workingPath=${sourceDocumentRoot}/sql/
databaseDumpFilename=${domainName}-dump.sql

ssh root@${sourceServer} “mysqldump -u${sourceDatabaseUserName} -p${sourceDatabasePassword} ${sourceDatabaseName} > ${workingPath}${databaseDumpFilename}; tail ${workingPath}${databaseDumpFilename};”

fi

# ————————-

echo
echo “Removing SVN and CVS folders…”
echo

ssh root@${sourceServer} “find ${sourceDocumentRoot} -iname ‘.svn’ | xargs rm -rf”
ssh root@${sourceServer} “find ${sourceDocumentRoot} -iname ‘CVS’ | xargs rm -rf”

# ————————-

echo
echo “Transferring files from source to destination server…”
echo

rsync -avz root@${sourceServer}:${sourceDocumentRoot}/ /home/${destinationUserName}/

# =========================================================================

# =========================================================================
# Destination Server

echo
echo
echo “== Destination Server ==”

if [ “$sourceExistingDatabase” == “Y” ] ; then

# This doesn’t work, disabled
#  echo
#  echo “Setting up new database…”
#  echo
#  mysql -u${destinationUserName} -p${destinationPassword} -e “CREATE DATABASE ${destinationDatabaseName}”
#  mysql -u${destinationUserName} -p${destinationPassword} -e “GRANT ALL ON ${destinationDatabaseName}.* TO ${destinationDatabaseName}@’localhost’ IDENTIFIED BY ‘${destinationDatabasePassword}’;
#  mysql -u${destinationUserName} -p${destinationPassword} -e “GRANT ALL ON ${destinationDatabaseName}.* TO ${destinationDatabaseName}@’%’ IDENTIFIED BY ‘${destinationDatabasePassword}’;

# ————————-

echo
echo “Importing database…”
echo
workingPath=/home/${destinationUserName}/sql

cd ${workingPath}
mysql -u${destinationDatabaseName} -p${destinationDatabasePassword} ${destinationDatabaseName} -e “source ${databaseDumpFilename}”

# ————————-

echo
echo “Replace database name in config files (${sourceDatabaseName} / ${destinationDatabaseName})…”
echo
workingPath=/home/${destinationUserName}/lib/config

find ${workingPath} -name ‘*config*’ -type f | xargs grep -l DB_NAME | xargs replace “$CONFIG[‘DB_NAME’]           = ‘${sourceDatabaseName}’;” “$CONFIG[‘DB_NAME’]           = ‘${destinationDatabaseName}’;” —

# ————————-

echo
echo “Replace database logins (${destinationDatabaseName} / ${destinationDatabasePassword})…”
echo
workingPath=/home/${destinationUserName}/lib/config

keyword=${sourceDatabaseUserName}
find ${workingPath} -type f | xargs grep -l ${keyword} | xargs replace “${keyword}” “${destinationDatabaseName}” —

keyword=${sourceDatabasePassword}
find ${workingPath} -type f | xargs grep -l ${keyword} | xargs replace “${keyword}” “${destinationDatabasePassword}” —

fi

# ————————-

echo
echo “Moving files to new document root…”
echo
workingPath=/home/${destinationUserName}

cd ${workingPath}
rm -rf pubic_html/*
cp -rf html/* public_html/
cp -f html/.htaccess public_html/.htaccess
rm -rf html/
ln -s public_html html
chmod -R 777 logs

# ————————-

echo
echo “Fixing statistics and usage…”
echo
workingPath=/home/${destinationUserName}

cd ${workingPath}
mv public_html/usage public_html/usage.old
ln -s ../tmp/webalizer public_html/usage
chmod 755 tmp
chmod 755 tmp/webalizer

# ————————-

echo
echo “Fixing permissions…”
echo
workingPath=/home/${destinationUserName}

cd ${workingPath}
chmod -R 777 logs
find ${workingPath} -group root | xargs chown ${destinationUserName}:${destinationUserName}
find ${workingPath} -group apache | xargs chown ${destinationUserName}:${destinationUserName}
chown ${destinationUserName}:nobody public_html

# =========================================================================

# =========================================================================
# Testing

echo
echo
echo “== Testing ==”

if [ “$sourceExistingDatabase” == “Y” ] ; then

echo
echo “Checking for other database logins…”
workingPath=/home/${destinationUserName}

keyword=${sourceDatabaseUserName}
result=`find ${workingPath} -type f | xargs grep -l ‘${keyword}’ `

if [ “$result” == “” ] ; then
echo “Check OK”
else
echo “Check FAILED! POSSIBLE PROBLEM DETECTED”
echo
echo When checking for ${keyword}, it was found to still exist in the following locations:
echo —————————
echo $result
echo —————————
fi

echo

# ————————-

echo
echo “Checking database dump for references to /var/www/…”
workingPath=/home/${destinationUserName}/sql/

keyword=”/var/www/”
result=`find ${workingPath} -name ‘${databaseDumpFilename}’ -type f | xargs grep -l ‘${keyword}’ `

if [ “$result” == “” ] ; then
echo “Check OK”
else
echo “Check FAILED! POSSIBLE PROBLEM DETECTED”
echo
echo When checking for ${keyword}, it was found to be present in the database dump exported from the source server.
echo This could indicate that the database references paths that no longer exist on the destination server.
echo —————————
echo $result
echo —————————
fi

echo

fi

# ————————-

echo
echo “Checking for files referring to /var/www/…”
workingPath=/home/${destinationUserName}

keyword=”/var/www/”
result=`find ${workingPath} -type f | xargs grep -l ‘${keyword}’ `

if [ “$result” == “” ] ; then
echo “Check OK”
else
echo “Check FAILED! POSSIBLE PROBLEM DETECTED”
echo
echo When checking for ${keyword}, it was found to still exist in the following locations:
echo —————————
echo $result
echo —————————
fi

echo

# ————————-

echo
echo “Host file output for testing…”
websiteIP=`cat /var/cpanel/users/${destinationUserName} | grep ‘IP=’ | cut -d’=’ -f2`

echo “————————-
${websiteIP}    ${domainName}
${websiteIP}    www.${domainName}
————————-”

echo

# ————————-

echo
echo “This script will now halt to allow testing and resolution of potential errors mentioned above. Modify your local”
echo “host file, ping the domain and check the transferred website loads properly in either a 1) separate browser”
echo “or 2) clean cached browser.”
echo
echo -n “Press enter if you are ready to continue with the transfer… ”
read foobar

# =========================================================================

# =========================================================================
# Source Server

echo
echo
echo “== Source Server ==”

echo
echo “Forwarding remote database connections…”
workingPath=${sourceDocumentRoot}/lib/config/

keyword=”localhost”
ssh root@${sourceServer} “find ${workingPath} -name ‘*config*’ -type f | xargs grep -l ${keyword} | xargs replace ‘${keyword}’ ‘${destinationServer}’ — ”

ssh root@${sourceServer} “find ${workingPath} -name ‘*config*’ -type f | xargs grep -l DB_NAME | xargs replace \”$CONFIG[‘DB_NAME’]           = ‘${sourceDatabaseName}’;\” \”$CONFIG[‘DB_NAME’]           = ‘${destinationDatabaseName}’;\” — ”

keyword=${sourceDatabaseUserName}
ssh root@${sourceServer} “find ${workingPath} -name ‘*config*’ -type f | xargs grep -l ${keyword} | xargs replace ‘${keyword}’ ‘${destinationDatabaseName}’ — ”

keyword=${sourceDatabasePassword}
ssh root@${sourceServer} “find ${workingPath} -name ‘*config*’ -type f | xargs grep -l ${keyword} | xargs replace ‘${keyword}’ ‘${destinationDatabasePassword}’ — ”

# ————————-

echo
echo “Updating DNS zone file source server…”
workingPath=${sourcePathToBind}

keyword=${sourceServer}
echo “*** BEFORE ***”
ssh root@${sourceServer} “find ${workingPath} -name ‘${domainName}.hosts’ -type f | xargs cat ”
echo
echo “*** CHANGING NOW ***”
ssh root@${sourceServer} “find ${workingPath} -name ‘${domainName}.hosts’ -type f | xargs grep -l ${keyword} | xargs replace ‘${keyword}’ ‘${websiteIP}’ — ”
echo
echo “*** AFTER ***”
ssh root@${sourceServer} “find ${workingPath} -name ‘${domainName}.hosts’ -type f | xargs cat ”
echo “*** FINISHED ***”
echo
echo -n “The above output represents the changes made on Gecko. Confirm accuracy and press enter to reload BIND… ”
read foobar

# ————————-

echo
echo “Reloading BIND on source server…”
result=`ssh root@${sourceServer} “/etc/init.d/named reload”`

echo ${result}

# ————————-

echo
echo
echo “#—————————————-”
echo “# Transfer Complete!”
echo “#—————————————-”
echo “# Remaining tasks:”
echo “#    – Check root and apache crontab”
echo “#—————————————-”
echo

And there we have it!

This is the script I use to move websites. This will NOT work for everything. This is a custom designed script for MY needs. You will NEED to CUSTOMISE it to suit your own needs. But my hope is that it helps some people out.

Similar Posts:

VN:F [1.9.22_1171]
Rating: 0.0/5 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)
Tags: , , , , , .

What are your thoughts?