Posted by vovaodei on July 2, 2009 at 7:24pm
hi all!
i administer a project-server with 500+ Drupal-installations on it.
All these installations have one, collectively used "core installation".
As the websites count was about 100 the updates took a lot of time, i.e. one whole day, and already
that was too much. But now, as there are > 500 sites, it's simply unmanageable...
Now the question: is there another way to do updates or, so to say, simply to klick the "update.php"
on the website? I mean, "update.php" do nothing more then calling some functions and interact with the user.
And can i somehow do a "mass" update? And can it be done unattended??
Or are there maybe other ways to do such mass updates of installations?
Thanks !
Vladimir
Comments
You might want to move
You might want to move frequently used non-core modules to the central installation. That way, those modules only have to be updated once and not for each installation.
Just curious? Is that a shared server or some dedicated business server?
What is the hardware?
-----------------------------------------
Joep
CompuBase, Drupal, websites and webdesign
-----------------------------------------
Joep
CompuBase, Dutch Drupal full service agency
well, the core and the
well, the core and all the modules (and themes) are in the central installation.
No, it's not a shared server :-)
It's a pair of 2U 19" Servers: one as Webserver, one as DB-Server.
Webserver is an IBM xSeries 345, 2x3,06 GHz Xeons, 4 GB RAM, 2x36 GB HDD for system, 2x73 GB for sites.
DB-Server is identical, just the 2x73 GB for are for dbs.
+ Many tweaks and brainwork ;-)
Hm, i googled a lot, and as it seems, the problem identical to mine exists; but only the problem, not the solution :-/
Boah, maybe hire a dosen of students to click "update.php" ? :-) LOL
subscribing
subscribing
DRUSH
http://drupal.org/project/drush
http://drupal.org/node/477684
try writing a script which makes use of DRUSH. I'm thinking that you could script putting the sites into maintenance mode, looping through a DB backup of each site, updating the core then scripting a loop through each site to run the update.php
drush --uri=http://www.domain-one.com updatedb
drush --uri=http://www.domain-two.com updatedb
Then put them back online
Just a half baked idea I'm afraid.
thanks, never heard of the
thanks, never heard of the "drush"-thing but - hey, it seems really to be interesting;
does
drush --uri=http://www.domain-one.com updatedb
works non-interactively?
Just checked, it asks if you
Just checked, it asks if you want to
"Do you wish to run all pending updates? (y/n) :"
But if you run
drush --uri=http://www.domain-one.com --yes update
then it'll get the new modules, backup the old ones and run updatedb as one.
Would be useful to know if the --yes flag also worked on the updatedb command.
Just thinking about your
Just thinking about your update task. I'm guessing these 500 sites are very similar to each other? But this task could take hours even if scripted.
I'm wondering if you could have two drupal installations?
/var/www/drupal-6.12
and
/var/www/drupal-6.13
Then have the script create an array of the directories in /var/www/drupal-6.12/sites.
Then loop doing the following
1: Put site into maintenance mode.
2: Copy site's directory cp -a /var/www/drupal-6.12/sites/www.domain-one.com to
/var/www/drupal-6.13/sites/www.domain-one.com
3: create a db backup
4: run drush --uri=http://www.domain-one.com --yes update
5: change the vhost entry in httpd.conf from /var/www/drupal-6.12/sites/www.domain-one.com to
/var/www/drupal-6.13/sites/www.domain-one.com
6: Reload the server.
7: Put site backonline.
8: Do some test to check all went well.
9: log result.
loop back and do the same on next domain in array
well, the only problem now is
well, the only problem now is to deactivate all non-core modules before
the upgrade... But how i saw, drush can list module status on website, so
im sure, the output can be parsed and then make a kinda loop throug all
enabled modules and deactivate them before update..
Hmm ... well, i think i'll wriite the script in the next days :-)
This is the perl script I use
This is the perl script I use - its based on an apache setup (and needs the Apache::ConfigParser perl module), but I guess it could be modified for other webservers.
It just outputs the drush commands required, rather than executing them - the main reason for this is that drush (AFAIK) can't do the actual core update, but you can copy and paste them into a terminal window or script and execute them that way.
#!/usr/bin/perl
# --------------------------------------------------------------------------------------
#
# Script to generate drush commands required for a core update
#
# Simon Hanmer simon.hanmer@gmail.com
# IntelligentWeb Ltd http://www.intelligentweb.co.uk
#
# --------------------------------------------------------------------------------------
use strict;
use Apache::ConfigParser;
my %server;
my @core_modules = qw( block color comment dblog filter help menu node system taxonomy update user);
my %cmds = (
'disable' => "drush -r %s -l http://%s -y disable %s\n",
'update' => "# << DO MANUAL UPDATE >>\n",
'enable' => "drush -r %s -l http://%s -y enable %s\n",
'cron' => "drush -r %s -l http://%s cron\n",
'refresh' => "drush -r %s -l http://%s refresh\n"
);
# --------------------------------------------------------------------------------------
#
# First step is to parse the apache config to find our hosts.
# Then for each host find the non-core modules
#
# --------------------------------------------------------------------------------------
my $parser = Apache::ConfigParser->new;
my $cf = $parser->parse_file("/usr/local/apache2/conf/httpd.conf"); # Read apache config
foreach my $server ($parser->find_down_directive_names('ServerName')) { # For each server, get document dir
my $serverName = $server->value;
my @root = $parser->find_siblings_and_up_directive_names($server, "DocumentRoot");
if ( -r $root[0]->value."/COPYRIGHT.txt" ) { # Is this a Drupal directory -
$server{$serverName}{'root'} = $root[0]->value; # if so, store root directory
my $drush_cmd = sprintf("drush -r %s -l http://%s -p statusmodules|", $root[0]->value, $serverName);
open DRUSH, $drush_cmd || die "Can't run drush";
my $drush_modules = <DRUSH>;
close DRUSH;
my @module_list = split(/ /, $drush_modules);
my @non_core = grep { my $x = $_; not grep { $x =~ /\Q$_/i } @core_modules } @module_list;
@{$server{$serverName}{'module'}} = @non_core;
}
}
# --------------------------------------------------------------------------------------
#
# Now generate required output for each stage
#
# --------------------------------------------------------------------------------------
foreach my $cmd (qw(disable update enable refresh cron)) {
do_action($cmd);
}
exit;
sub do_action {
my ($opt) = @_;
foreach my $host (keys(%server)) {
my $root_dir = $server{$host}{'root'};
my @module_list = @{$server{$host}{'module'}};
if (scalar(@module_list) > 0) {
printf($cmds{$opt},
$root_dir,
$host,
join( ' ', @module_list)
);
}
}
print "\n\n";
}
An example of the output would be:
depends on the size of your multi site instances.
I have a few multi site instances that I manage. For a couple of smaller ones (less than 20 sites each) I use the following bash script:
#!/bin/sh# Update all sites using drush
# Written by Dave Hall <dave.hall@skwashd.com>
# Copyright (c) 2009 Dave Hall Consulting http://davehall.com.au
# Permission granted to use under the terms of the CC-BY-SA license http://creativecommons.org/licenses/by-sa/3.0/
DRUSH_PATH=/home/bluejube/drush/drush
SITES_PATH=/srv/www/cms/sites
PWD=$(pwd)
cd $SITES_PATH;
for site in `find ./ -maxdepth 1 -type d | cut -d/ -f2 | egrep -v '(.svn|all|default)'`
do
echo updating $site
~/drush/drush updatedb -y -l $site
done
cd $PWD
For a much larger instance (almost 2000 drupal sites and growing), I use aegir as it has better error handling.
It really depends on what your requirements are.
Dave Hall Consulting -
Open Source Business Solutions