285 WordPress Sites, upgraded in 11 minutes – and they weren’t MultiSite
Sunday, February 12th, 2012A 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