Sitting on #drupal-support on IRC, you see people drop by with update problems from time to time. With Drupal 6.21, 6.22, 7.1 and 7.2 released earlier in the week, today was such a day.
The person in question had attempted a Drupal core update via drush, but ran it in the wrong directory. Drupal had picked up this incorrect location for its core modules, so when the drupal-6.22 directory got deleted, it was unable to load any of the core modules. Oops.
This led me to wondering whether the way I manage my Drupal updates is odd and whether sharing it would be useful. Being an open source person, I am of the opinion that sharing is virtual always useful (except when it comes to cheese) so I'll document the way I manage updates here.
There's a few ways to update Drupal core to a new minor version. I'll not discuss major version upgrades, for which it's best to follow the procedure set out in the UPGRADE.txt file that comes with Drupal anyway.
Unpack tarball or zip
I imagine a lot of people follow that UPGRADE.txt file regardless, so an update means down-time for them whilst they move directories out of the way, unpack the tarball or zip and then copy the files directory back. It's also tedious. if you have a large files directory, you'll spend ages waiting for it to copy. On the plus side, you know you have a backup.
The even more tedious version of this involves a server where all you have is FTP access, so you need to unpack the archive locally and then upload it file by file.
Update via git fetch/rebase1
If you've installed Drupal from git, you can simply fetch the new tag from the Drupal git repository and then rebase your local Drupal version. Certainly anyone who hates kittens is already doing this, as it allows you to hack core and keep your changes separate and version controlled.
It's also nice and efficient, as git fetch would download only the changes to the code, not the full Drupal source. Admittedly, that's only 1MB (or 2MB for Drupal 7) which isn't that much of a deal these days.
1 ... because we don't git merge, do we? :-)
Make a patch and apply it
The way I handle Drupal updates is by making a patch file that contains the difference between the versions. It's effectively a combination of the tarball and git ways. I like it because by applying a patch I can see if there are any conflicting changes (changing .htaccess is hacking core too!) and manage them sensibly. In addition, I can apply such a patch to any staging sites I manage via git as well as stand-alone production sites.
Make a patch
Making a patch is trivially easy. First I download a copy of the original and new Drupal versions via drush:
drush dl drupal-6.20 drush dl drupal-6.22
Then I create a patch using the diff utility, where the urN options control the patch file format. By default diff outputs to the screen, so I redirect this output to my patch file instead:
diff -urN drupal-6.20 drupal-6.22 > drupal-620-to-622.patch
If you have a look at the patch file, you'll see that the contents list what gets removed (-) and what gets added (+) at which line numbers. Pretty straighforward.
diff -urN drupal-6.20/CHANGELOG.txt drupal-6.22/CHANGELOG.txt --- drupal-6.20/CHANGELOG.txt 2010-12-16 08:11:22.000000000 +1100 +++ drupal-6.22/CHANGELOG.txt 2011-05-26 06:43:55.000000000 +1000 @@ -1,4 +1,14 @@ -// $Id: CHANGELOG.txt,v 1.253.2.43 2010/12/15 21:11:22 goba Exp $ + +Drupal 6.22, 2011-05-25 +---------------------- +- Made Drupal 6 work better with IIS and Internet Explorer. +- Fixed .po file imports to work better with custom textgroups.
Apply the patch
Now all that remains is to apply the patch to any Drupal instances that need updating, using the patch utility. It reads data from standard input, so I use a redirect2 again:
cd /path/to/drupal/root patch -p1 --dry-run < /path/to/drupal-620-to-622.patch
When you run that, patch will tell you which files it's patching and whether any errors have occurred. The -p1 option tells patch to remove the top level part of the file path from each file that's listed in the patch. In this example, it would strip off "drupal-6.20/" and "drupal-6.22", leaving it to patch the CHANGELOG.txt file in the current directory, which is what we want.
The --dry-run part means patch is not actually modifying the Drupal files yes, but only telling you what it would do. If there are any errors, you can find out what they are and then decide whether or not to apply the patch. To apply the patch for real, use:
patch -p1 < /path/to/drupal-6.20-to-6.22.patch
If there were errors that you decided to ignore during the dry-run, you'll find that patch has created created two copies of all the files it failed to patch successfully. One with the suffix .orig, which is the original unpatched copy of the file and one with the suffix .rej, which contains a listing of the parts of the patch that failed to apply to the file.
Fixing those up is effectively identical to resolving a failed git rebase or merge.
And there you have it, my reasonably fast, reasonably fool-proof and - above all - reasonably lazy way of updating a Drupal installation.
2Because I'm an opponent of the needless use of cat, as in cat drupal-6.20-to-6.22.patch | patch -p1
Comments
Re: How do you update Drupal?
drush up
Re: How do you update Drupal?
I too like the incremental patch approach better, and I've found this site which makes life a little easier:
http://fuerstnet.de/en/drupal-upgrade-easier
It would be great if drupal.org itself provided incremental patches between stable releases.
BTW the point about using "cat" and pipes is that when you recall the command from the shell history you are already at the _end_of_the_line_ and it is easier to edit the patch command options (adding or removing
--dry-run
for example), so yes, it is less efficient, but more usable for some. :)Bye,
Antonio
Re: How do you update Drupal?
Here's a list of patches from any Drupal 6 and Drupal 7 version to 6.22 and 7.2. The list is kept up to date ever since 2007.
http://fuerstnet.de/en/drupal-upgrade-easier
Re: How do you update Drupal?
I take a very lazy approach that is quite foolproof. Instead of making a patch I go the route of finding all changed files and replacing them, not replacing any files that were untouched. It leaves the /sites folder undisturbed among other things too.
1. Navigate to Drupal root
2. wget drupal-x.xx.tar.gz
3. tar -xzvf drupal-x.xx.tar.gz
4. cd drupal-x.xx
5. \cp -Rvupf * ../
The cp command with those flags does all that was said above. Flawless core upgrade every time.
Re: How do you update Drupal?
All of the core files and directories are symlinked to a single version (on machines with mupltiple vhosts),
cron.php -> /var/www/vhosts/drupal/drupal-6.x/cron.php
.htaccess
includes -> /var/www/vhosts/drupal/drupal-6.x/includes
index.php -> /var/www/vhosts/drupal/drupal-6.x/index.php
install.php -> /var/www/vhosts/drupal/drupal-6.x/install.php
misc -> /var/www/vhosts/drupal/drupal-6.x/misc
modules -> /var/www/vhosts/drupal/drupal-6.x/modules
profiles -> /var/www/vhosts/drupal/drupal-6.x/profiles
robots.txt
scripts -> /var/www/vhosts/drupal/drupal-6.x/scripts
sites
themes -> /var/www/vhosts/drupal/drupal-6.x/themes
update.php -> /var/www/vhosts/drupal/drupal-6.x/update.php
xmlrpc.php -> /var/www/vhosts/drupal/drupal-6.x/xmlrpc.php
e.g. drupal-6.x which itself a symlink to the current version. So to update all sites I can run:
drush dl drupal-6.22
rm drupal-6.x; ln -s drupal-6.22 drupal-6.x;
I run the rm and ln on a single line to ensure that there is no gap between removing the old link and recreating the new one.
Re: How do you update Drupal?
This is smart. Using patches to upgrade core. Drupal Project pages should have patches for upgrades in between versions. Although it is quick & easy to build them as you have outlined, if they just provide them by default, that would be great. This would only be for full releases and not dev. version
Re: How do you update Drupal?
I used the drush pm-updatecode, update went fine according to the output. However when i visited my local drupal install and saw admin/report still shows i had drupal 7.0 and requires to be upgraded to drupal 7.2
I think this could be down to me using windows - let me try the update by patching.
downloaded patch for windows, hopefully will work - fingers crossed!
Re: How do you update Drupal?
i have problem with the windows version, how do it?
Re: How do you update Drupal?
I also typically use drush up.
And I believe the canonical phrase is 'useless use of cat'.
Re: How do you update Drupal?
I use a combination of drush and symlinks and also just wrote up a blog post on the very same thing.
I do like the idea of git fetch/rebase since I do have a small D6 patch applied to core (only on local dev machine though, so they're just my kittens).
I used the drush pm-
I used the drush pm-updatecode, update went fine according to the output. However when i visited my local drupal install and saw admin/report still shows i had drupal 7.0 and requires to be upgraded to drupal 7.2
I think this could be down to me using windows - let me try the update by patching.
downloaded patch for windows, hopefully will work - fingers crossed!
_________
grady speer from machine café nespresso
drush up
Can't beat drush, like a few others posted. I updated half a dozen sites last night, both D6 and D7 with the script below. Yeah, I know, csh isn't cool for scripting, so sue me!
#!/bin/csh -f
# update any of my sites, site subdir name is first arg to this script
if (! -e ~/www/$1) then
echo "www/$1 does not exist"
exit
endif
cd ~/www/$1
echo "Backing up files and DB"
tar cfz ~/backup/$1/files-`date +%m%d%Y`.tgz .
drush sql-dump > ~/backup/$1/db-`date +%m%d%Y`.sql
echo
echo "Updating Drupal"
drush up
echo
echo "All done. Please test the site immediately!"
Re: How do you update Drupal?
I used drush on 6 d7 sites and 36 d6 sites across 7 multisite installs for my day.
Here is an example of my commands on an install with 2 sites, I take the sites offline, update the core against the default install, run update.php on a site then run any module updates, manually check site, then finally bring back out of maintenance mode:
sudo cp ./.htaccess ~/
sudrush -l site1.com vset --yes site_offline 1
sudrush -l site2.com vset --yes site_offline 1
sudrush up
sudrush -l site1.com updb
sudrush -l site1.com up
sudrush -l site1.com vset --yes site_offline 0
sudrush -l site2.com updb
sudrush -l site2.com up
sudrush -l site2.com vset --yes site_offline 0
sudo mv ~/.htaccess ./
D7 is almost the same except for putting into maintenance mode:
sudrush -l d7site.com vset --yes maintenance_mode 0
sudrush -l d7site.com cache-clear all
Re: How do you update Drupal?
Though I don't use drush to update the core code directly (too much magic for me) I do use it to process updates and clear cache on multisite installs. I've scripted it a little bit further than you, though. I use a variation of this script to run Drupal crons as well, actually.
Rather than having to specify each site, it'll just process all sites defined via their own directory under /sites/ (but not default).
Re: How do you update Drupal?
Drush aliases are really key for this sort of thing.
You can simply specify:
drush @sites cron --root=/path/to/drupal
to run cron on all mulitsites in the specified root.You can also set groups of sites like @dev or @staging if you want to define some sites, but not all.
Re: How do you update Drupal?
Yes and no - they're handy, but it would mean I'd have to remember to update my drush aliases file whenever I add a new site. The script just finds them without me having to edit a config file.
Re: How do you update Drupal?
I should probably make a note there that I also don't need to update my web server config when I add a site. With mod_vhost_alias Apache will happily serve www.example.com if /var/www/www.example.com exists :-)
Re: How do you update Drupal?
There are a couple of aliases that exist with Drush even without modifying the aliases file. @sites and @self are two that I use. @sites will do all sites with no additional configuration even after you add new sites.
Re: How do you update Drupal?
There is a script that automates this process attached here.
Upgrading Drupal installations security releases using a single patch.
The "Make a patch and apply" method with git
You can use git to make the process of creating the patch even easier. Since the entire history of Drupal is kept in git you won't have to download both the current and previous versions of Drupal to be able to make the patch. It is also faster to just update the git repository than downloading full new copies from drupal.org.
git fetch
If you don't have one yet, fetch it with Drush (or using the git instructions from drupal.org):
drush dl drupal --package-handler=git_drupalorg
git checkout 6.22
git diff 6.20 > drupal-620-to-622.patch
You can apply the patch with:
patch -p1 < drupal-620-to-622.patch
Re: How do you update Drupal?
Do you have to go to http://yoursite/update.php after patching !?
Re: How do you update Drupal?
Yes, or you can use `drush updatedb' instead. If there are pending database updates, you need to process those somehow.
I run a multisite and I've pasted my shell script that runs `drush updatedb' for each site (and produces a log file) a bit further down at http://cafuego.net/2011/05/27/how-do-you-update-drupal#comment-668
Fix for bad CVS $Id tags
I had a few sites in which the old CVS tags were preventing successful application of the patch.
The problem was that the files were starting with a full CVS id string, for example:
// $Id: jquery.js,v 1.12.2.3 2008/06/25 09:38:39 goba Exp $
and the patch was expecting:
// $Id$
This can be fixed with regex. Run this command in the root folder:
perl -pi -e 's/ \$Id: .+Exp \$/ \$Id\$/g' `find . -type f`
Re: How do you update Drupal?
I get a bunch of errors? Help
macbook:dwc mhardy11$ patch -p1 --dry-run < /Users/mhardy11/drupal-620-to-622.patch
patching file .htaccess
Reversed (or previously applied) patch detected! Assume -R? [n] n
Apply anyway? [n] y
Hunk #1 FAILED at 113.
1 out of 1 hunk FAILED -- saving rejects to file .htaccess.rej
patching file CHANGELOG.txt
patching file COPYRIGHT.txt
patching file modules/aggregator/aggregator.info
Hunk #1 FAILED at 1.
1 out of 1 hunk FAILED -- saving rejects to file modules/aggregator/aggregator.info.rej
patching file modules/aggregator/aggregator.install
patching file sites/all/README.txt
Reversed (or previously applied) patch detected! Assume -R? [n] n
Apply anyway? [n] n
Skipping patch.
1 out of 1 hunk ignored -- saving rejects to file sites/all/README.txt.rej
patching file sites/default/default.settings.php
patch: **** Can't rename file /var/folders/x6/x6h0-t1-GMuYoCzerl7ycE+++TI/-Tmp-//poVpxLek to sites/default/default.settings.php : Permission denied
Please help. Thanks
Re: patch failed
There are a few reasons a path might fail. If the version you're patching from does match or if an affected file was modified from the original, you'll see such errors.
In this case, because some parts of the patch succeed and some fail, my guess is that the Drupal you're upgrading is not 6.20 but maybe 6.21 or might be a 6.20 that has had individual fixes applied to it.
The final error, on default.settings.php is due to directory permissions. The user that is running the patch command doesn't have permission to create or write to files in sites/default.
Re: How do you update Drupal?
i think i will ask my webmaster to do this job!.. sounds to complicated for me...
Drupal help
I have installed drupal 6.21 but I can`t install any plugin. Please help me how to setup a plugin on drupl site.
Voodoo magic
Thanks for posting this, I just had the
drush up
voodoo magic fail on me again. Seemed like a good time to give your method a whirl.The advantage of patching is that I get a better understanding of what I'm doing. Another step toward enlightenment...
Removing packaging information from .info-files
When you have downloaded a regular (ie non-git) copy of Drupal core and update it with a patch generated with "git diff" the update status screen will still report the wrong (previous) version. This is caused by the packaging information that is added to the .info files. There is a discrepancy between the packaging information and the actual Drupal version and this confuses the update module.
If you are affected by this you can remove all packaging information from all .info files with this oneliner, to be run from the drupal root folder. Mind that this will also happily remove all packaging information from your contrib and custom themes and modules ;)
grep -lr "; Information added by drupal.org packaging script" * --null | xargs -0 sed -i '/; Information added by drupal.org packaging script/,$d'
I also typically use drush
I also typically use drush up.
And I believe the canonical phrase is 'useless use of cat'.
What's Going down i'm new to
What's Going down i'm new to this, I stumbled upon this I have discovered It positively useful and it has aided me out loads. I am hoping to contribute & assist different customers like its aided me. Good job.
Add new comment