285 WordPress Sites, upgraded in 11 minutes – and they weren’t MultiSite
A number of our clients run WordPress, but, for some reason, keeping them updated is a problem. Sites are uploaded and run on autopilot and are forgotten… until they are hacked. Last week a client asked why his WordPress 2.8 site was hacked. WordPress 2.8 was released in June 2009 with 25 WordPress releases since. We checked a few of his sites and found a few different versions running, but, how many other clients were running old WordPress versions? The results were shocking.
Finding WordPress sites on shared storage
First, we need to find each of the individual client’s WordPress installations.
find /var/www -type f -wholename \*wp-includes/version.php|awk '{ print "grep -H \"wp_version =\" " $1 }' | sh > /var/tmp/wpversions
From this, with a little cut and sort trickery, we end up with the following histogram:
35 3.1 29 2.8.5 25 3.2.1 24 2.9.2 20 2.8.4 19 3.0.1 16 2.8.2 16 2.1 15 2.6 13 2.7.1 8 3.3.1 6 2.9.1 6 2.8 6 2.3 5 3.3 5 2.7 4 3.1.2 4 2.8.1 3 3.1.1 3 3.0.5 3 3.0.4 3 2.8.6 2 3.1.3 2 3.0 2 2.0.3 1 3.1.4 1 2.9 1 2.6.3 1 2.5.1 1 2.3.3 1 2.3.2 1 2.2.2 1 2.2.1 1 2.2 1 2.1.3 1 2.0.5 1 2.0.4
Yes, we have 2 2.0.3 installations in production use out of 285 sites. Of them, 8, or, less than 3% are running the current version, 3.3.1.
Clearly this is a problem.
We have a few options, one of which is to utilize the upgrade process inside WordPress which requires us to communicate with each client, or, write a quick script to give us admin privileges to do the upgrade. Or, we could use bash.
The magic
Our filesystem structure is set up so that each user has their own UID/GID, and the paths where the domains are located are fairly static. However, the script just takes the path of the wp-content/version.php file, strips off the correct pieces, copies the uncompressed WordPress .tar.gz file, changes ownership from root to the user that owns the directory.
There are two variables that need to be set:
WORDPRESS_TMPDIR – set this to the directory where you have untarred and ungzipped the WordPress archive
BASE_PATH – set this to the machine’s root path.
The script
#!/bin/bash # cd34, 20120212 # # find /var/www -type f -wholename \*wp-includes/version.php|awk '{ print "grep -H \"wp_version =\" " $1 }' | sh > /var/tmp/wpversions # # if you want to really save time: # awk < /var/tmp/wpversion '{ print "/path/to/wpu.sh " $1 }' | sh -x # set this to match your temporary directory location for WordPress WORDPRESS_TMPDIR=/var/tmp/wordpress # wget -O /var/tmp http://wordpress.org/latest.tar.gz # cd /var/tmp # tar xzf latest.tar.gz #set this to signify the base path of your machine's web root BASE_PATH=/var/www if [ "X" == "$1X" ]; then echo "Needs a pathname for the version.php file" echo echo "$0 /var/www/domain.com/wp-includes/version.php" echo echo "You can include data after version.php, i.e. :$version from find command" else WP_INCLUDE_PATH=$1 WP_PATH=${WP_INCLUDE_PATH%%/wp-includes/version.php*} DOMAIN=${WP_PATH##$BASE_PATH/} TMP=`stat $WP_PATH|grep Uid:` TMP_GID=${TMP##*Gid: ( } DGID=${TMP_GID%%/*} TMP_UID=${TMP##*Uid: ( } DUID=${TMP_UID%%/*} `cp -Rp $WORDPRESS_TMPDIR/* $WP_PATH` `chown -R --from=root $DUID.$DGID $WP_PATH` `/usr/bin/wget -q -O /dev/null "http://$DOMAIN/wp-admin/upgrade.php?step=1"` echo "Upgraded: http://$DOMAIN" fi
The code for this and a few other tools that I’ve written can be found at cd34-tools, hosted on code.google.com
February 13th, 2012 at 4:24 pm
How do you deal with clients if the upgrade has broken the site (e.g. depreciated functions or themes)? Where do you draw the line between appeasing clients and server security?
February 13th, 2012 at 4:40 pm
I did a spot check on most of them to make sure things did look right. There were a few where I knew the themes or certain plugins would break so I knew what to look for. I will probably adjust it to look for a few signatures.
For the most part, 99% of them upgraded without any issues, two had problems (reported this morning), both were simple upgrade the plugin causing the problem. One was a tag plugin I had never heard of.
Luckily, the older sites used very generic themes and very few plugins. They were set up, had 10-20 posts and then were probably forgotten – projects that someone would come back and handle later on.
I debated upgrading anyone on 3.x, but, in the end, looked at the changes in 3.x -> 3.3.1 and determined that there would be less breakage there than from 2.0 -> 3.3. Of the older 2.x sites, pre 2.6 were checked a bit more since there were a number of changes.
February 14th, 2012 at 9:21 am
I appreciate your time to write the process as a script and your willingness to share with others.
I never knew that I could upgrade a WordPress from the command line. :(
March 3rd, 2012 at 2:28 pm
If you are using this, the repository on code.google.com contains the most up to date version.
I have made a few modifications that are not reflected in the above post to handle a few different filesystem layouts.