mostly complete upgrade system
This commit is contained in:
parent
cf92cb5a4f
commit
1a79d607af
13 changed files with 399 additions and 698 deletions
64
lib/WebGUI/Middleware/Maintenance.pm
Normal file
64
lib/WebGUI/Middleware/Maintenance.pm
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
package WebGUI::Middleware::Maintenance;
|
||||||
|
|
||||||
|
=head1 LEGAL
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
WebGUI is Copyright 2001-2009 Plain Black Corporation.
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Please read the legal notices (docs/legal.txt) and the license
|
||||||
|
(docs/license.txt) that came with this distribution before using
|
||||||
|
this software.
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
http://www.plainblack.com info@plainblack.com
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use parent qw(Plack::Middleware);
|
||||||
|
|
||||||
|
|
||||||
|
=head1 NAME
|
||||||
|
|
||||||
|
Package WebGUI::Content::Maintenance;
|
||||||
|
|
||||||
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
|
A content handler that displays a maintenance page while upgrading.
|
||||||
|
|
||||||
|
=head1 SYNOPSIS
|
||||||
|
|
||||||
|
enable '+WebGUI::Middleware::Maintenance';
|
||||||
|
|
||||||
|
=head1 SUBROUTINES
|
||||||
|
|
||||||
|
These subroutines are available from this package:
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------
|
||||||
|
|
||||||
|
=head2 handler ( session )
|
||||||
|
|
||||||
|
The content handler for this package.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
sub call {
|
||||||
|
my $self = shift;
|
||||||
|
my $env = shift;
|
||||||
|
my $session = $env->{'webgui.session'};
|
||||||
|
my $upgradeState = $session->setting->get('upgradeState');
|
||||||
|
if ($upgradeState) {
|
||||||
|
if ($upgradeState eq WebGUI->VERSION) {
|
||||||
|
$session->setting->remove('upgradeState');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return [ 503, ['Content-Type' => 'text/plain'], [ 'Service Unavailable' ] ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $self->app->($env);
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
|
|
@ -1,27 +1,57 @@
|
||||||
package WebGUI::Upgrade;
|
package WebGUI::Upgrade;
|
||||||
use strict;
|
|
||||||
use warnings;
|
|
||||||
|
|
||||||
|
use Moose;
|
||||||
use WebGUI::Paths;
|
use WebGUI::Paths;
|
||||||
use WebGUI::Pluggable;
|
use WebGUI::Pluggable;
|
||||||
use WebGUI::Config;
|
use WebGUI::Config;
|
||||||
|
use WebGUI::SQL;
|
||||||
use Try::Tiny;
|
use Try::Tiny;
|
||||||
use DBI;
|
use File::Spec;
|
||||||
|
use File::Path qw(make_path);
|
||||||
|
use namespace::autoclean;
|
||||||
|
|
||||||
|
has quiet => (
|
||||||
|
is => 'rw',
|
||||||
|
default => undef,
|
||||||
|
);
|
||||||
|
has mysql => (
|
||||||
|
is => 'rw',
|
||||||
|
default => 'mysql',
|
||||||
|
);
|
||||||
|
has mysqldump => (
|
||||||
|
is => 'rw',
|
||||||
|
default => 'mysqldump',
|
||||||
|
);
|
||||||
|
has clearCache => (
|
||||||
|
is => 'rw',
|
||||||
|
default => 1,
|
||||||
|
);
|
||||||
|
has createBackups => (
|
||||||
|
is => 'rw',
|
||||||
|
default => 1,
|
||||||
|
);
|
||||||
|
has useMaintenanceMode => (
|
||||||
|
is => 'rw',
|
||||||
|
default => 1,
|
||||||
|
);
|
||||||
|
has backupPath => (
|
||||||
|
is => 'rw',
|
||||||
|
default => File::Spec->catdir(File::Spec->tmpdir, 'backups'),
|
||||||
|
);
|
||||||
|
|
||||||
sub upgradeSites {
|
sub upgradeSites {
|
||||||
my $class = shift;
|
my $self = shift;
|
||||||
my $quiet = shift;
|
|
||||||
my @configs = WebGUI::Paths->siteConfigs;
|
my @configs = WebGUI::Paths->siteConfigs;
|
||||||
for my $configFile (@configs) {
|
for my $configFile (@configs) {
|
||||||
my $bareFilename = $configFile;
|
my $bareFilename = $configFile;
|
||||||
$bareFilename =~ s{.*/}{};
|
$bareFilename =~ s{.*/}{};
|
||||||
print "Upgrading $bareFilename:\n";
|
print "Upgrading $bareFilename:\n";
|
||||||
try {
|
try {
|
||||||
$class->upgradeSite($configFile, $quiet);
|
$self->upgradeSite($configFile);
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
print "Error upgrading $bareFilename: $_\n";
|
print "Error upgrading $bareFilename: $_\n";
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -32,13 +62,17 @@ sub getCodeVersion {
|
||||||
}
|
}
|
||||||
|
|
||||||
sub upgradeSite {
|
sub upgradeSite {
|
||||||
my $class = shift;
|
my $self = shift;
|
||||||
my ($configFile, $quiet) = @_;
|
my ($configFile) = @_;
|
||||||
my $fromVersion = $class->getCurrentVersion($configFile);
|
my $fromVersion = $self->getCurrentVersion($configFile);
|
||||||
my $toVersion = $class->getCodeVersion;
|
my $toVersion = $self->getCodeVersion;
|
||||||
my @steps = $class->calcUpgradePath($fromVersion, $toVersion);
|
my @steps = $self->calcUpgradePath($fromVersion, $toVersion);
|
||||||
|
if ( $self->useMaintenanceMode ) {
|
||||||
|
my $dbh = $self->dbhForConfig( $configFile );
|
||||||
|
$dbh->do('REPLACE INTO settings (name, value) VALUES (?, ?)', {}, 'upgradeState', 'started');
|
||||||
|
}
|
||||||
for my $step ( @steps ) {
|
for my $step ( @steps ) {
|
||||||
$class->runUpgradeStep($configFile, $step, $quiet);
|
$self->runUpgradeStep($configFile, $step);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -90,8 +124,8 @@ sub calcUpgradePath {
|
||||||
}
|
}
|
||||||
|
|
||||||
sub runUpgradeStep {
|
sub runUpgradeStep {
|
||||||
my $class = shift;
|
my $self = shift;
|
||||||
my ($configFile, $step, $quiet) = @_;
|
my ($configFile, $step) = @_;
|
||||||
|
|
||||||
my ($version) = $step =~ /-(\d+\.\d+\.\d+)$/;
|
my ($version) = $step =~ /-(\d+\.\d+\.\d+)$/;
|
||||||
print "Running upgrades for $step.\n";
|
print "Running upgrades for $step.\n";
|
||||||
|
|
@ -103,14 +137,14 @@ sub runUpgradeStep {
|
||||||
my $filename = File::Spec->catfile($upgradesDir, $upgradeFile);
|
my $filename = File::Spec->catfile($upgradesDir, $upgradeFile);
|
||||||
next
|
next
|
||||||
unless -f $filename;
|
unless -f $filename;
|
||||||
$class->runUpgradeFile($configFile, $version, $filename, $quiet);
|
$self->runUpgradeFile($configFile, $version, $filename);
|
||||||
}
|
}
|
||||||
closedir $dh;
|
closedir $dh;
|
||||||
$class->markVersionUpgrade($configFile, $version);
|
$self->markVersionUpgrade($configFile, $version);
|
||||||
}
|
}
|
||||||
|
|
||||||
sub runUpgradeFile {
|
sub runUpgradeFile {
|
||||||
my $class = shift;
|
my $self = shift;
|
||||||
my ($configFile, $version, $filename, $quiet) = @_;
|
my ($configFile, $version, $filename, $quiet) = @_;
|
||||||
|
|
||||||
my ($extension) = $filename =~ /\.([^.]+)$/;
|
my ($extension) = $filename =~ /\.([^.]+)$/;
|
||||||
|
|
@ -119,31 +153,64 @@ sub runUpgradeFile {
|
||||||
|
|
||||||
my $package = 'WebGUI::Upgrade::File::' . $extension;
|
my $package = 'WebGUI::Upgrade::File::' . $extension;
|
||||||
if ( try { WebGUI::Pluggable::load($package) } && $package->can('run') ) {
|
if ( try { WebGUI::Pluggable::load($package) } && $package->can('run') ) {
|
||||||
return $package->run($configFile, $version, $filename, $quiet);
|
return $package->run($configFile, $version, $filename, $self->quiet);
|
||||||
}
|
}
|
||||||
warn "Don't know how to use $extension upgrade file\n";
|
warn "Don't know how to use $extension upgrade file\n";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub markVersionUpgrade {
|
sub markVersionUpgrade {
|
||||||
my $class = shift;
|
my $self = shift;
|
||||||
my $configFile = shift;
|
my $configFile = shift;
|
||||||
my $version = shift;
|
my $version = shift;
|
||||||
|
|
||||||
my $config = WebGUI::Config->new($configFile, 1);
|
my $dbh = $self->dbhForConfig($configFile);
|
||||||
my $dbh = $class->dbhForConfig($config);
|
|
||||||
|
|
||||||
$dbh->do(
|
$dbh->do(
|
||||||
'INSERT INTO webguiVersion (webguiVersion, versionType, dateApplied) VALUES (?,?,?)', {},
|
'INSERT INTO webguiVersion (webguiVersion, versionType, dateApplied) VALUES (?,?,?)', {},
|
||||||
$version, 'upgrade', time,
|
$version, 'upgrade', time,
|
||||||
);
|
);
|
||||||
|
if ( $self->useMaintenanceMode ) {
|
||||||
|
$dbh->do('REPLACE INTO settings (name, value) VALUES (?, ?)', {}, 'upgradeState', $version);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub createBackup {
|
||||||
|
my $self = shift;
|
||||||
|
my $config = shift;
|
||||||
|
|
||||||
|
make_path($self->backupPath);
|
||||||
|
my $configFile = ( File::Spec->splitpath($config->pathToFile) )[2];
|
||||||
|
my $resultFile = File::Spec->catfile(
|
||||||
|
$self->backupPath,
|
||||||
|
$configFile . '_' . $self->getCurrentVersion($config) . '_' . time . '.sql',
|
||||||
|
);
|
||||||
|
my @command_line = (
|
||||||
|
$self->mysql,
|
||||||
|
$self->mysqlCommandLine($config),
|
||||||
|
'--add-drop-table',
|
||||||
|
'--result-file=' . $resultFile,
|
||||||
|
);
|
||||||
|
system { $command_line[0] } @command_line
|
||||||
|
and die "$!";
|
||||||
|
}
|
||||||
|
|
||||||
|
sub siteHistory {
|
||||||
|
my $class = shift;
|
||||||
|
my $config = shift;
|
||||||
|
my $dbh = $class->dbhForConfig($config);
|
||||||
|
my $sth = $dbh->prepare('SELECT webguiVersion, dateApplies, versionType FROM webguiVersion ORDER BY dateApplied ASC, webguiVersion ASC');
|
||||||
|
$sth->execute;
|
||||||
|
while ( my @data = $sth->fetchrow_array ) {
|
||||||
|
printf "\t%-8s %-15s %-15s\n", $data[0], POSIX::strftime('%D %T', $data[1]), $data[2];
|
||||||
|
}
|
||||||
|
$sth->finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub getCurrentVersion {
|
sub getCurrentVersion {
|
||||||
my $class = shift;
|
my $class = shift;
|
||||||
my $configFile = shift;
|
my $configFile = shift;
|
||||||
my $config = WebGUI::Config->new($configFile, 1);
|
my $dbh = $class->dbhForConfig($configFile);
|
||||||
my $dbh = $class->dbhForConfig($config);
|
|
||||||
|
|
||||||
my $sth = $dbh->prepare('SELECT webguiVersion FROM webguiVersion');
|
my $sth = $dbh->prepare('SELECT webguiVersion FROM webguiVersion');
|
||||||
$sth->execute;
|
$sth->execute;
|
||||||
|
|
@ -158,19 +225,44 @@ sub getCurrentVersion {
|
||||||
sub dbhForConfig {
|
sub dbhForConfig {
|
||||||
my $class = shift;
|
my $class = shift;
|
||||||
my $config = shift;
|
my $config = shift;
|
||||||
|
if (! ref $config) {
|
||||||
|
$config = WebGUI::Config->new($config, 1);
|
||||||
|
}
|
||||||
|
return WebGUI::SQL->connect($config);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub mysqlCommandLine {
|
||||||
|
my $class = shift;
|
||||||
|
my $config = shift;
|
||||||
|
|
||||||
my $dsn = $config->get('dsn');
|
my $dsn = $config->get('dsn');
|
||||||
my $user = $config->get('dbuser');
|
my $username = $config->get('dbuser');
|
||||||
my $pass = $config->get('dbpass');
|
my $password = $config->get('dbpass');
|
||||||
|
my $database = ( split /[:;]/msx, $dsn )[2];
|
||||||
|
my $hostname = 'localhost';
|
||||||
|
my $port = '3306';
|
||||||
|
while ( $dsn =~ /([^=;:]+)=([^;:]+)/msxg ) {
|
||||||
|
if ( $1 eq 'host' || $1 eq 'hostname' ) {
|
||||||
|
$hostname = $2;
|
||||||
|
}
|
||||||
|
elsif ( $1 eq 'db' || $1 eq 'database' || $1 eq 'dbname' ) {
|
||||||
|
$database = $2;
|
||||||
|
}
|
||||||
|
elsif ( $1 eq 'port' ) {
|
||||||
|
$port = $2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
my (undef, $driver) = DBI->parse_dsn($dsn);
|
my @command_line = (
|
||||||
my $dbh = DBI->connect($dsn, $user, $pass, {
|
'-h' . $hostname,
|
||||||
RaiseError => 1,
|
'-P' . $port,
|
||||||
AutoCommit => 1,
|
$database,
|
||||||
PrintError => 0,
|
'-u' . $username,
|
||||||
$driver eq 'mysql' ? (mysql_enable_utf8 => 1) : (),
|
( $password ? '-p' . $password : () ),
|
||||||
});
|
'--default-character-set=utf8',
|
||||||
return $dbh;
|
'--batch',
|
||||||
|
);
|
||||||
|
return @command_line;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub numericVersion {
|
sub numericVersion {
|
||||||
|
|
@ -184,5 +276,6 @@ sub numericVersion {
|
||||||
return $decVersion;
|
return $decVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__PACKAGE__->meta->make_immutable;
|
||||||
1;
|
1;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,40 +3,18 @@ use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
|
|
||||||
use WebGUI::Config;
|
use WebGUI::Config;
|
||||||
|
use WebGUI::Upgrade;
|
||||||
|
|
||||||
sub run {
|
sub run {
|
||||||
my ($class, $configFile, $version, $file, $quiet) = @_;
|
my ($class, $configFile, $version, $file, $quiet) = @_;
|
||||||
|
|
||||||
my $config = WebGUI::Config->new($configFile, 1);
|
my $config = WebGUI::Config->new($configFile, 1);
|
||||||
my $dsn = $config->get('dsn');
|
|
||||||
my $username = $config->get('dbuser');
|
|
||||||
my $password = $config->get('dbpass');
|
|
||||||
my $database = ( split /[:;]/msx, $dsn )[2];
|
|
||||||
my $hostname = 'localhost';
|
|
||||||
my $port = '3306';
|
|
||||||
while ( $dsn =~ /([^=;:]+)=([^;:]+)/msxg ) {
|
|
||||||
if ( $1 eq 'host' || $1 eq 'hostname' ) {
|
|
||||||
$hostname = $2;
|
|
||||||
}
|
|
||||||
elsif ( $1 eq 'db' || $1 eq 'database' || $1 eq 'dbname' ) {
|
|
||||||
$database = $2;
|
|
||||||
}
|
|
||||||
elsif ( $1 eq 'port' ) {
|
|
||||||
$port = $2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
my @command_line = (
|
my @command_line = (
|
||||||
'mysql',
|
'mysql',
|
||||||
'-h' . $hostname,
|
WebGUI::Upgrade->mysqlCommandLine($config),
|
||||||
'-P' . $port,
|
|
||||||
$database,
|
|
||||||
'-u' . $username,
|
|
||||||
( $password ? '-p' . $password : () ),
|
|
||||||
'--default-character-set=utf8',
|
|
||||||
'--batch',
|
|
||||||
'--execute=source ' . $file,
|
'--execute=source ' . $file,
|
||||||
);
|
);
|
||||||
|
|
||||||
system { $command_line[0] } @command_line
|
system { $command_line[0] } @command_line
|
||||||
and die "$!";
|
and die "$!";
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
||||||
|
|
@ -104,6 +104,12 @@ sub _build_exports {
|
||||||
$dbh = WebGUI::Upgrade->dbhForConfig($subs->{config}->());
|
$dbh = WebGUI::Upgrade->dbhForConfig($subs->{config}->());
|
||||||
return $dbh;
|
return $dbh;
|
||||||
},
|
},
|
||||||
|
sql => sub (@) {
|
||||||
|
my $sql = shift;
|
||||||
|
my $dbh = $subs->{dbh}->();
|
||||||
|
my $sth = $dbh->prepare($sql);
|
||||||
|
$sth->execute(@_);
|
||||||
|
},
|
||||||
version_tag => sub (;$) {
|
version_tag => sub (;$) {
|
||||||
my $name = shift;
|
my $name = shift;
|
||||||
$check_cleanup->();
|
$check_cleanup->();
|
||||||
|
|
@ -161,7 +167,7 @@ sub _build_exports {
|
||||||
},
|
},
|
||||||
asset => sub ($) {
|
asset => sub ($) {
|
||||||
require WebGUI::Asset;
|
require WebGUI::Asset;
|
||||||
my $session = $subs->session->();
|
my $session = $subs->{session}->();
|
||||||
my $assetId = shift;
|
my $assetId = shift;
|
||||||
my $asset;
|
my $asset;
|
||||||
if ($session->id->valid($assetId)) {
|
if ($session->id->valid($assetId)) {
|
||||||
|
|
@ -174,6 +180,11 @@ sub _build_exports {
|
||||||
}
|
}
|
||||||
return $asset;
|
return $asset;
|
||||||
},
|
},
|
||||||
|
clear_cache => sub () {
|
||||||
|
my $session = $subs->{session}->();
|
||||||
|
my $cache = $session->cache;
|
||||||
|
$cache->clear;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
return $subs;
|
return $subs;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
438
sbin/upgrade.pl
438
sbin/upgrade.pl
|
|
@ -11,47 +11,38 @@
|
||||||
#-------------------------------------------------------------------
|
#-------------------------------------------------------------------
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use Cwd ();
|
use warnings;
|
||||||
use File::Path ();
|
use WebGUI::Paths -inc;
|
||||||
use File::Spec;
|
use WebGUI::Upgrade;
|
||||||
use Getopt::Long ();
|
use Getopt::Long ();
|
||||||
use Pod::Usage ();
|
use Pod::Usage ();
|
||||||
use WebGUI::Paths -inc;
|
|
||||||
|
|
||||||
use WebGUI::Config;
|
|
||||||
use WebGUI::Session;
|
|
||||||
|
|
||||||
my $help;
|
|
||||||
my $history;
|
|
||||||
my $override;
|
|
||||||
my $quiet;
|
|
||||||
my $mysql = "mysql";
|
|
||||||
my $mysqldump = "mysqldump";
|
|
||||||
my $backupDir = "/tmp/backups";
|
|
||||||
my $skipBackup;
|
|
||||||
my $skipDelete;
|
|
||||||
my $skipMaintenance;
|
|
||||||
my $doit;
|
|
||||||
|
|
||||||
Getopt::Long::GetOptions(
|
Getopt::Long::GetOptions(
|
||||||
'help'=>\$help,
|
'help' => \( my $help ),
|
||||||
'history'=>\$history,
|
'history' => \( my $history ),
|
||||||
'override'=>\$override,
|
'override' => \( my $override ),
|
||||||
'quiet'=>\$quiet,
|
'quiet' => \( my $quiet ),
|
||||||
'mysql=s'=>\$mysql,
|
'doit' => \( my $doit ),
|
||||||
'doit'=>\$doit,
|
'skipDelete' => \( my $skipDelete ),
|
||||||
'skipDelete' =>\$skipDelete,
|
'skipMaintenance' => \( my $skipMaintenance ),
|
||||||
'skipMaintenance' =>\$skipMaintenance,
|
'skipbackup' => \( my $skipBackup ),
|
||||||
'mysqldump=s'=>\$mysqldump,
|
'backupDir=s' => \( my $backupDir ),
|
||||||
'backupDir=s'=>\$backupDir,
|
'mysql=s' => \( my $mysql ),
|
||||||
'skipbackup'=>\$skipBackup
|
'mysqldump=s' => \( my $mysqldump ),
|
||||||
);
|
) or Pod::Usage::pod2usage(2);
|
||||||
|
|
||||||
Pod::Usage::pod2usage( verbose => 2 ) if $help;
|
if ($help) {
|
||||||
Pod::Usage::pod2usage() unless $doit;
|
Pod::Usage::pod2usage(
|
||||||
|
-verbosity => 1,
|
||||||
unless ($doit) {
|
-exitval => 1,
|
||||||
print <<STOP;
|
);
|
||||||
|
}
|
||||||
|
elsif ($history) {
|
||||||
|
print "print site history\n";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
elsif ( ! $doit ) {
|
||||||
|
my $message = <<'END_MESSAGE';
|
||||||
|
|
||||||
+--------------------------------------------------------------------+
|
+--------------------------------------------------------------------+
|
||||||
| |
|
| |
|
||||||
|
|
@ -75,197 +66,38 @@ unless ($doit) {
|
||||||
| |
|
| |
|
||||||
+--------------------------------------------------------------------+
|
+--------------------------------------------------------------------+
|
||||||
|
|
||||||
STOP
|
END_MESSAGE
|
||||||
exit;
|
Pod::Usage::pod2usage($message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( $^O ne 'MSWin32' && $> != 0 && !$override ) {
|
||||||
if (!($^O =~ /^Win/i) && $> != 0 && !$override) {
|
print "You must be the super user to use this utility.\n";
|
||||||
print "You must be the super user to use this utility.\n";
|
exit;
|
||||||
exit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
## Globals
|
## Globals
|
||||||
|
|
||||||
$| = 1;
|
$| = 1;
|
||||||
our $perl = $^X;
|
|
||||||
our $slash;
|
|
||||||
if ($^O =~ /^Win/i) {
|
|
||||||
$slash = "\\";
|
|
||||||
} else {
|
|
||||||
$slash = "/";
|
|
||||||
}
|
|
||||||
our $upgradesPath = WebGUI::Paths->upgrades;
|
|
||||||
our (%upgrade, %config);
|
|
||||||
|
|
||||||
|
my $upgrade = WebGUI::Upgrade->new(
|
||||||
|
quiet => $quiet,
|
||||||
|
clearCache => !$skipDelete,
|
||||||
|
createBackups => !$skipBackup,
|
||||||
|
useMaintenanceMode => !$skipMaintenance,
|
||||||
|
$mysql ? (
|
||||||
|
mysql => $mysql,
|
||||||
|
) : (),
|
||||||
|
$mysqldump ? (
|
||||||
|
mysqldump => $mysqldump,
|
||||||
|
) : (),
|
||||||
|
$backupDir ? (
|
||||||
|
backupPath => $backupDir,
|
||||||
|
) : (),
|
||||||
|
);
|
||||||
|
|
||||||
## Find site configs.
|
$upgrade->upgradeSites;
|
||||||
|
|
||||||
print "\nGetting site configs...\n" unless ($quiet);
|
print <<STOP;
|
||||||
my $configs = WebGUI::Config->readAllConfigs;
|
|
||||||
foreach my $filename (keys %{$configs}) {
|
|
||||||
print "\tProcessing $filename.\n" unless ($quiet);
|
|
||||||
$config{$filename}{configFile} = $filename;
|
|
||||||
$config{$filename}{dsn} = $configs->{$filename}->get("dsn");
|
|
||||||
my $temp = _parseDSN($config{$filename}{dsn}, ['database', 'host', 'port']);
|
|
||||||
if ($temp->{'driver'} eq "mysql") {
|
|
||||||
$config{$filename}{db} = $temp->{'database'};
|
|
||||||
$config{$filename}{host} = $temp->{'host'};
|
|
||||||
$config{$filename}{port} = $temp->{'port'};
|
|
||||||
$config{$filename}{dbuser} = $configs->{$filename}->get("dbuser");
|
|
||||||
$config{$filename}{dbpass} = $configs->{$filename}->get("dbpass");
|
|
||||||
$config{$filename}{mysqlCLI} = $configs->{$filename}->get("mysqlCLI");
|
|
||||||
$config{$filename}{mysqlDump} = $configs->{$filename}->get("mysqlDump");
|
|
||||||
$config{$filename}{backupPath} = $configs->{$filename}->get("backupPath");
|
|
||||||
my $session = WebGUI::Session->open($filename);
|
|
||||||
($config{$filename}{version}) = $session->db->quickArray("select webguiVersion from webguiVersion order by
|
|
||||||
dateApplied desc, length(webguiVersion) desc, webguiVersion desc limit 1");
|
|
||||||
unless ($history) {
|
|
||||||
print "\tPreparing site for upgrade.\n" unless ($quiet);
|
|
||||||
unless ($skipMaintenance) {
|
|
||||||
$session->setting->remove('specialState');
|
|
||||||
$session->setting->add('specialState','upgrading');
|
|
||||||
}
|
|
||||||
unless ($skipDelete) {
|
|
||||||
print "\tDeleting temp files.\n" unless ($quiet);
|
|
||||||
my $path = File::Spec->catdir($configs->{$filename}->get("uploadsPath"), 'temp');
|
|
||||||
File::Path::rmtree($path) unless ($path eq "" || $path eq "/" || $path eq "/data");
|
|
||||||
print "\tDeleting file cache.\n" unless ($quiet);
|
|
||||||
$path = $configs->{$filename}->get("fileCacheRoot") || "/tmp/WebGUICache";
|
|
||||||
File::Path::rmtree($path) unless ($path eq "" || $path eq "/" || $path eq "/data");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$session->close();
|
|
||||||
} else {
|
|
||||||
delete $config{$filename};
|
|
||||||
print "\tSkipping non-MySQL database.\n" unless ($quiet);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($history) {
|
|
||||||
print "\nDisplaying upgrade history for each site.\n";
|
|
||||||
foreach my $file (keys %config) {
|
|
||||||
print "\n".$file."\n";
|
|
||||||
my $session = WebGUI::Session->open($file);
|
|
||||||
my $sth = $session->db->read("select * from webguiVersion order by dateApplied asc, webguiVersion asc");
|
|
||||||
while (my $data = $sth->hashRef) {
|
|
||||||
print "\t".sprintf("%-8s %-15s %-15s",
|
|
||||||
$data->{webguiVersion},
|
|
||||||
$session->datetime->epochToHuman($data->{dateApplied},"%y-%m-%d"),
|
|
||||||
$data->{versionType})."\n";
|
|
||||||
}
|
|
||||||
$sth->finish;
|
|
||||||
$session->close;
|
|
||||||
}
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
## Find upgrade files.
|
|
||||||
|
|
||||||
print "\nLooking for upgrade files...\n" unless ($quiet);
|
|
||||||
opendir(DIR,$upgradesPath) or die "Couldn't open $upgradesPath\n";
|
|
||||||
my @files = readdir(DIR);
|
|
||||||
closedir(DIR);
|
|
||||||
foreach my $file (@files) {
|
|
||||||
if ($file =~ /^upgrade_(\d+\.\d+\.\d+)-(\d+\.\d+\.\d+)\.(pl|sql)$/) {
|
|
||||||
if (checkVersion($1)) {
|
|
||||||
if ($3 eq "sql") {
|
|
||||||
print "\tFound upgrade script from $1 to $2.\n" unless ($quiet);
|
|
||||||
$upgrade{$1}{sql} = $file;
|
|
||||||
} elsif ($3 eq "pl") {
|
|
||||||
print "\tFound upgrade executable from $1 to $2.\n" unless ($quiet);
|
|
||||||
$upgrade{$1}{pl} = $file;
|
|
||||||
}
|
|
||||||
$upgrade{$1}{from} = $1;
|
|
||||||
$upgrade{$1}{to} = $2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
print "\nREADY TO BEGIN UPGRADES\n" unless ($quiet);
|
|
||||||
|
|
||||||
my $notRun = 1;
|
|
||||||
|
|
||||||
|
|
||||||
my $currentPath = Cwd::getcwd();
|
|
||||||
my $totalConfigs = scalar keys %config;
|
|
||||||
my $configCounter = 0;
|
|
||||||
foreach my $filename (keys %config) {
|
|
||||||
chdir($upgradesPath);
|
|
||||||
my $clicmd = $config{$filename}{mysqlCLI} || $mysql;
|
|
||||||
my $dumpcmd = $config{$filename}{mysqlDump} || $mysqldump;
|
|
||||||
my $backupTo = $config{$filename}{backupPath} || $backupDir;
|
|
||||||
mkdir($backupTo);
|
|
||||||
++$configCounter;
|
|
||||||
while ($upgrade{$config{$filename}{version}}{sql} ne "" || $upgrade{$config{$filename}{version}}{pl} ne "") {
|
|
||||||
my $upgrade = $upgrade{$config{$filename}{version}}{from};
|
|
||||||
print "\n".$config{$filename}{db}." ".$upgrade{$upgrade}{from}."-".$upgrade{$upgrade}{to}."\n" unless ($quiet);
|
|
||||||
print "Processing $configCounter out of $totalConfigs configs\n" unless ($quiet);
|
|
||||||
unless ($skipBackup) {
|
|
||||||
print "\tBacking up $config{$filename}{db} ($upgrade{$upgrade}{from})..." unless ($quiet);
|
|
||||||
my $cmd = qq!$dumpcmd -u"$config{$filename}{dbuser}" -p"$config{$filename}{dbpass}"!;
|
|
||||||
$cmd .= " --host=".$config{$filename}{host} if ($config{$filename}{host});
|
|
||||||
$cmd .= " --port=".$config{$filename}{port} if ($config{$filename}{port});
|
|
||||||
$cmd .= " --add-drop-table ".$config{$filename}{db}." --result-file="
|
|
||||||
.File::Spec->catfile($backupTo, $config{$filename}{db}."_".$upgrade{$upgrade}{from}."_".time.".sql");
|
|
||||||
unless (system($cmd)) {
|
|
||||||
print "OK\n" unless ($quiet);
|
|
||||||
} else {
|
|
||||||
print "Failed!\n" unless ($quiet);
|
|
||||||
fatalError();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($upgrade{$upgrade}{sql} ne "") {
|
|
||||||
print "\tUpgrading to ".$upgrade{$upgrade}{to}."..." unless ($quiet);
|
|
||||||
my $cmd = qq!$clicmd -u"$config{$filename}{dbuser}" -p"$config{$filename}{dbpass}"!;
|
|
||||||
$cmd .= " --host=".$config{$filename}{host} if ($config{$filename}{host});
|
|
||||||
$cmd .= " --port=".$config{$filename}{port} if ($config{$filename}{port});
|
|
||||||
$cmd .= " --database=".$config{$filename}{db}." < ".$upgrade{$upgrade}{sql};
|
|
||||||
unless (system($cmd)) {
|
|
||||||
print "OK\n" unless ($quiet);
|
|
||||||
} else {
|
|
||||||
print "Failed!\n" unless ($quiet);
|
|
||||||
fatalError();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($upgrade{$upgrade}{pl} ne "") {
|
|
||||||
my $pid = fork;
|
|
||||||
if (!$pid) {
|
|
||||||
local @ARGV = ("--configFile=$filename", $quiet ? ('--quiet') : ());
|
|
||||||
local $0 = $upgrade{$upgrade}{pl};
|
|
||||||
local $@;
|
|
||||||
do $0;
|
|
||||||
if ($@) {
|
|
||||||
warn $@;
|
|
||||||
exit 255;
|
|
||||||
};
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
waitpid $pid, 0;
|
|
||||||
if ($?) {
|
|
||||||
print "\tProcessing upgrade executable failed!\n";
|
|
||||||
fatalError();
|
|
||||||
}
|
|
||||||
##Do a dummy load of the config
|
|
||||||
WebGUI::Config->clearCache();
|
|
||||||
}
|
|
||||||
$config{$filename}{version} = $upgrade{$upgrade}{to};
|
|
||||||
$notRun = 0;
|
|
||||||
sleep 1; # Sleep a second to avoid adding asset revisions too quickly
|
|
||||||
}
|
|
||||||
chdir($currentPath);
|
|
||||||
my $session = WebGUI::Session->open($filename);
|
|
||||||
print "\tSetting site upgrade completed..." unless ($quiet);
|
|
||||||
$session->setting->remove('specialState');
|
|
||||||
$session->close();
|
|
||||||
print "OK\n" unless ($quiet);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($notRun) {
|
|
||||||
print "\nNO UPGRADES NECESSARY\n\n" unless ($quiet);
|
|
||||||
} else {
|
|
||||||
unless ($quiet) {
|
|
||||||
print <<STOP;
|
|
||||||
|
|
||||||
UPGRADES COMPLETE
|
UPGRADES COMPLETE
|
||||||
Please restart your web server and test your sites.
|
Please restart your web server and test your sites.
|
||||||
|
|
@ -278,111 +110,6 @@ NOTE: If you have not already done so, please consult
|
||||||
docs/gotcha.txt for possible upgrade complications.
|
docs/gotcha.txt for possible upgrade complications.
|
||||||
|
|
||||||
STOP
|
STOP
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#-----------------------------------------
|
|
||||||
# checkVersion($versionNumber)
|
|
||||||
#-----------------------------------------
|
|
||||||
# Version number must be 7.3.22 or greater
|
|
||||||
# in order to be upgraded by this utility.
|
|
||||||
#-----------------------------------------
|
|
||||||
sub checkVersion {
|
|
||||||
$_[0] =~ /(\d+)\.(\d+)\.(\d+)/;
|
|
||||||
my $goal = 7;
|
|
||||||
my $feature = 3;
|
|
||||||
my $fix = 22;
|
|
||||||
if ($1 > $goal) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
elsif ($1 == $goal) {
|
|
||||||
if ($2 > $feature) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
elsif ($2 == $feature) {
|
|
||||||
if ($3 >= $fix) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#-----------------------------------------
|
|
||||||
sub fatalError {
|
|
||||||
print <<STOP;
|
|
||||||
|
|
||||||
The upgrade process failed and has stopped so you can either restore
|
|
||||||
from backup, or attempt to fix the problem and continue.
|
|
||||||
|
|
||||||
STOP
|
|
||||||
exit 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#-----------------------------------------
|
|
||||||
sub _parseDSN {
|
|
||||||
my($dsn, $args) = @_;
|
|
||||||
my($var, $val, $hash);
|
|
||||||
$hash = {};
|
|
||||||
|
|
||||||
if (!defined($dsn)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$dsn =~ s/^dbi:(\w*?)(?:\((.*?)\))?://i
|
|
||||||
or '' =~ /()/; # ensure $1 etc are empty if match fails
|
|
||||||
$hash->{driver} = $1;
|
|
||||||
|
|
||||||
while (length($dsn)) {
|
|
||||||
if ($dsn =~ /([^:;]*)[:;](.*)/) {
|
|
||||||
$val = $1;
|
|
||||||
$dsn = $2;
|
|
||||||
} else {
|
|
||||||
$val = $dsn;
|
|
||||||
$dsn = '';
|
|
||||||
}
|
|
||||||
if ($val =~ /([^=]*)=(.*)/) {
|
|
||||||
$var = $1;
|
|
||||||
$val = $2;
|
|
||||||
if ($var eq 'hostname' || $var eq 'host') {
|
|
||||||
$hash->{'host'} = $val;
|
|
||||||
} elsif ($var eq 'db' || $var eq 'dbname') {
|
|
||||||
$hash->{'database'} = $val;
|
|
||||||
} else {
|
|
||||||
$hash->{$var} = $val;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
foreach $var (@$args) {
|
|
||||||
if (!defined($hash->{$var})) {
|
|
||||||
$hash->{$var} = $val;
|
|
||||||
last;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return $hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub readLines {
|
|
||||||
my $file = shift;
|
|
||||||
my @lines;
|
|
||||||
if (open(my $fh, '<', $file)) {
|
|
||||||
while (my $line = <$fh>) {
|
|
||||||
$line =~ s/#.*//;
|
|
||||||
$line =~ s/^\s+//;
|
|
||||||
$line =~ s/\s+$//;
|
|
||||||
next if !$line;
|
|
||||||
push @lines, $line;
|
|
||||||
}
|
|
||||||
close $fh;
|
|
||||||
}
|
|
||||||
return @lines;
|
|
||||||
}
|
|
||||||
|
|
||||||
__END__
|
__END__
|
||||||
|
|
||||||
|
|
@ -392,34 +119,33 @@ upgrade - Upgrade WebGUI database to the latest revision.
|
||||||
|
|
||||||
=head1 SYNOPSIS
|
=head1 SYNOPSIS
|
||||||
|
|
||||||
upgrade --doit
|
upgrade --doit
|
||||||
[--backupDir path]
|
[--backupDir path]
|
||||||
[--history]
|
[--mysql pathname]
|
||||||
[--mysql pathname]
|
[--mysqldump pathname]
|
||||||
[--mysqldump pathname]
|
[--override]
|
||||||
[--override]
|
[--skipBackup]
|
||||||
[--skipBackup]
|
[--skipDelete]
|
||||||
[--skipDelete]
|
[--skipMaintenance]
|
||||||
[--skipMaintenance]
|
[--quiet]
|
||||||
[--quiet]
|
upgrade --history
|
||||||
|
|
||||||
upgrade --help
|
upgrade --help
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
This WebGUI utility script is able to upgrade B<any> WebGUI database
|
This WebGUI utility script is able to upgrade B<any> WebGUI database
|
||||||
from 7.3.22 upward to the currently installed version. The WebGUI
|
to the currently installed version. The WebGUI software distribution
|
||||||
software distribution includes a set of upgrade scripts that
|
includes a set of upgrade scripts that perform the necessary database
|
||||||
perform the necessary database changes (schema and data) to bring
|
changes (schema and data) to bring the database up-to-date in order
|
||||||
the database up-to-date in order to match the currently installed
|
to match the currently installed WebGUI libraries and programs.
|
||||||
WebGUI libraries and programs.
|
|
||||||
|
|
||||||
This utility is designed to be run as a superuser on Linux systems,
|
This utility is designed to be run as a superuser on Linux systems,
|
||||||
since it needs to be able to access several system directories
|
since it needs to be able to access several system directories
|
||||||
and change ownership of files. If you want to run this utility without
|
and change ownership of files. If you want to run this utility without
|
||||||
superuser privileges, use the B<--override> option described below.
|
superuser privileges, use the C<--override> option described below.
|
||||||
|
|
||||||
=head1 WARNING
|
=head2 WARNING
|
||||||
|
|
||||||
There are B<NO> guarantees of any kind provided with this software.
|
There are B<NO> guarantees of any kind provided with this software.
|
||||||
This utility has been tested rigorously, and has performed without
|
This utility has been tested rigorously, and has performed without
|
||||||
|
|
@ -431,62 +157,64 @@ B<BEFORE YOU UPGRADE> you should definitely read docs/gotcha.txt to
|
||||||
find out what things you should know about that will affect your
|
find out what things you should know about that will affect your
|
||||||
upgrade.
|
upgrade.
|
||||||
|
|
||||||
=over
|
=head1 OPTIONS
|
||||||
|
|
||||||
=item B<--doit>
|
=over 4
|
||||||
|
|
||||||
|
=item C<--doit>
|
||||||
|
|
||||||
You B<MUST> include this flag in the command line or the script
|
You B<MUST> include this flag in the command line or the script
|
||||||
will refuse to run. This is to force you to read this documentation
|
will refuse to run. This is to force you to read this documentation
|
||||||
at least once and be sure that you B<REALLY> want to perform the
|
at least once and be sure that you B<REALLY> want to perform the
|
||||||
upgrade.
|
upgrade.
|
||||||
|
|
||||||
=item B<--backupDir path>
|
=item C<--backupDir path>
|
||||||
|
|
||||||
Specify a path where database backups should be created during the
|
Specify a path where database backups should be created during the
|
||||||
upgrade procedure. If left unspecified, it defaults to B</tmp/backups>.
|
upgrade procedure. If left unspecified, it defaults to C</tmp/backups>.
|
||||||
|
|
||||||
=item B<--history>
|
=item C<--history>
|
||||||
|
|
||||||
Displays the upgrade history for each of your sites. Running with this
|
Displays the upgrade history for each of your sites. Running with this
|
||||||
flag will B<NOT> perform the upgrade.
|
flag will B<NOT> perform the upgrade.
|
||||||
|
|
||||||
=item B<--mysql pathname>
|
=item C<--mysql pathname>
|
||||||
|
|
||||||
The full pathname to your mysql client executable. If left unspecified,
|
The full pathname to your mysql client executable. If left unspecified,
|
||||||
it defaults to B</usr/bin/mysql>.
|
it defaults to C</usr/bin/mysql>.
|
||||||
|
|
||||||
=item B<--mysqldump pathname>
|
=item C<--mysqldump pathname>
|
||||||
|
|
||||||
The full pathname to your mysqldump executable. If left unspecified,
|
The full pathname to your mysqldump executable. If left unspecified,
|
||||||
it defaults to B</usr/bin/mysqldump>.
|
it defaults to C</usr/bin/mysqldump>.
|
||||||
|
|
||||||
=item B<--override>
|
=item C<--override>
|
||||||
|
|
||||||
This flag will allow you to run this utility without being the super user,
|
This flag will allow you to run this utility without being the super user,
|
||||||
but note that it may not work as intended.
|
but note that it may not work as intended.
|
||||||
|
|
||||||
=item B<--skipBackup>
|
=item C<--skipBackup>
|
||||||
|
|
||||||
Use this if you B<DO NOT> want database backups to be performed
|
Use this if you B<DO NOT> want database backups to be performed
|
||||||
during the upgrade procedure.
|
during the upgrade procedure.
|
||||||
|
|
||||||
=item B<--skipDelete>
|
=item C<--skipDelete>
|
||||||
|
|
||||||
The upgrade procedure normally deletes WebGUI's cache and temporary files
|
The upgrade procedure normally deletes WebGUI's cache and temporary files
|
||||||
created as part of the upgrade. This cleanup is very important during
|
created as part of the upgrade. This cleanup is very important during
|
||||||
large upgrades, but can make the procedure quite slow. This option
|
large upgrades, but can make the procedure quite slow. This option
|
||||||
skips the deletion of these files.
|
skips the deletion of these files.
|
||||||
|
|
||||||
=item B<--skipMaintenance>
|
=item C<--skipMaintenance>
|
||||||
|
|
||||||
The upgrade procedure normally puts up a simple maintenance page on all
|
The upgrade procedure normally puts up a simple maintenance page on all
|
||||||
the sites while running, but this option will skip that step.
|
the sites while running, but this option will skip that step.
|
||||||
|
|
||||||
=item B<--quiet>
|
=item C<--quiet>
|
||||||
|
|
||||||
Disable all output unless there's an error.
|
Disable all output unless there's an error.
|
||||||
|
|
||||||
=item B<--help>
|
=item C<--help>
|
||||||
|
|
||||||
Shows this documentation, then exits.
|
Shows this documentation, then exits.
|
||||||
|
|
||||||
|
|
|
||||||
11
t/Upgrade.t
11
t/Upgrade.t
|
|
@ -30,7 +30,12 @@ our $configFile = WebGUI::Test->config->getFilename;
|
||||||
*WebGUI::Paths::siteConfigs = sub { $configFile };
|
*WebGUI::Paths::siteConfigs = sub { $configFile };
|
||||||
}
|
}
|
||||||
|
|
||||||
my $upgrade = Test::MockObject::Extends->new('WebGUI::Upgrade');
|
my $upgrade = Test::MockObject::Extends->new(
|
||||||
|
WebGUI::Upgrade->new(
|
||||||
|
createBackups => 0,
|
||||||
|
useMaintenanceMode => 0,
|
||||||
|
),
|
||||||
|
);
|
||||||
$upgrade->set_always('getCurrentVersion', '8.0.0');
|
$upgrade->set_always('getCurrentVersion', '8.0.0');
|
||||||
$upgrade->set_always('getCodeVersion', '8.4.3');
|
$upgrade->set_always('getCodeVersion', '8.4.3');
|
||||||
|
|
||||||
|
|
@ -90,7 +95,8 @@ $upgrade->mock(testUpgrade => sub {
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
my $stdout = capture { $upgrade->testUpgrade('output.pl', 1) };
|
$upgrade->quiet(1);
|
||||||
|
my $stdout = capture { $upgrade->testUpgrade('output.pl') };
|
||||||
ok $stdout !~ 'Simple Output', 'quiet flag silences report command';
|
ok $stdout !~ 'Simple Output', 'quiet flag silences report command';
|
||||||
ok $stdout !~ 'Done', 'quiet flag silences done command';
|
ok $stdout !~ 'Done', 'quiet flag silences done command';
|
||||||
}
|
}
|
||||||
|
|
@ -102,6 +108,7 @@ my $session = WebGUI::Test->session;
|
||||||
|
|
||||||
my $dbh = $upgrade->dbhForConfig(WebGUI::Test->config);
|
my $dbh = $upgrade->dbhForConfig(WebGUI::Test->config);
|
||||||
our $totalAssets = $dbh->selectrow_array('SELECT COUNT(*) FROM asset');
|
our $totalAssets = $dbh->selectrow_array('SELECT COUNT(*) FROM asset');
|
||||||
|
|
||||||
$upgrade->testUpgrade('dbh.pl');
|
$upgrade->testUpgrade('dbh.pl');
|
||||||
|
|
||||||
$upgrade->testUpgrade('config.pl');
|
$upgrade->testUpgrade('config.pl');
|
||||||
|
|
|
||||||
|
|
@ -29,8 +29,11 @@ builder {
|
||||||
|
|
||||||
enable '+WebGUI::Middleware::HTTPExceptions';
|
enable '+WebGUI::Middleware::HTTPExceptions';
|
||||||
|
|
||||||
|
enable 'ErrorDocument', 503 => $config->get('maintenancePage');
|
||||||
enable_if { ! $_[0]->{'webgui.debug'} } 'ErrorDocument', 500 => $config->get('maintenancePage');
|
enable_if { ! $_[0]->{'webgui.debug'} } 'ErrorDocument', 500 => $config->get('maintenancePage');
|
||||||
|
|
||||||
|
enable '+WebGUI::Middleware::Maintenance';
|
||||||
|
|
||||||
enable_if { $_[0]->{'webgui.debug'} } 'StackTrace';
|
enable_if { $_[0]->{'webgui.debug'} } 'StackTrace';
|
||||||
enable_if { $_[0]->{'webgui.debug'} } 'Debug', panels => [
|
enable_if { $_[0]->{'webgui.debug'} } 'Debug', panels => [
|
||||||
'Environment',
|
'Environment',
|
||||||
|
|
|
||||||
14
var/upgrades/7.9.8-8.0.0/addMaintenancePageToConfig.pl
Normal file
14
var/upgrades/7.9.8-8.0.0/addMaintenancePageToConfig.pl
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
use WebGUI::Upgrade::Script;
|
||||||
|
|
||||||
|
use File::Basename;
|
||||||
|
use Cwd qw(realpath);
|
||||||
|
use File::Spec::Functions;
|
||||||
|
use WebGUI::Paths;
|
||||||
|
|
||||||
|
report "\tMoving preload files ";
|
||||||
|
|
||||||
|
my $webgui_root = realpath( catdir( dirname( $INC{'WebGUI/Upgrade/Script.pm'} ), updir x 3 ) );
|
||||||
|
|
||||||
|
config->set('maintenancePage', catfile( $webgui_root, 'www', 'maintenance.html' );
|
||||||
|
|
||||||
|
done;
|
||||||
35
var/upgrades/7.9.8-8.0.0/migrateToNewCache.pl
Normal file
35
var/upgrades/7.9.8-8.0.0/migrateToNewCache.pl
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
use WebGUI::Upgrade::Script;
|
||||||
|
use Module::Find;
|
||||||
|
|
||||||
|
report "\tMigrating to new cache ";
|
||||||
|
|
||||||
|
rm_lib
|
||||||
|
findallmod('WebGUI::Cache'),
|
||||||
|
'WebGUI::Workflow::Activity::CleanDatabaseCache',
|
||||||
|
'WebGUI::Workflow::Activity::CleanFileCache',
|
||||||
|
;
|
||||||
|
|
||||||
|
config->set("cache", {
|
||||||
|
'driver' => 'FastMmap',
|
||||||
|
'expires_variance' => '0.10',
|
||||||
|
'root_dir' => '/tmp/WebGUICache',
|
||||||
|
});
|
||||||
|
|
||||||
|
config->set('hotSessionFlushToDb', 600);
|
||||||
|
config->delete('disableCache');
|
||||||
|
config->delete('cacheType');
|
||||||
|
config->delete('fileCacheRoot');
|
||||||
|
config->deleteFromArray('workflowActivities/None', 'WebGUI::Workflow::Activity::CleanDatabaseCache');
|
||||||
|
config->deleteFromArray('workflowActivities/None', 'WebGUI::Workflow::Activity::CleanFileCache');
|
||||||
|
|
||||||
|
sql 'DROP TABLE cache';
|
||||||
|
sql 'DELETE FROM WorkflowActivity WHERE className in (?,?)',
|
||||||
|
'WebGUI::Workflow::Activity::CleanDatabaseCache',
|
||||||
|
'WebGUI::Workflow::Activity::CleanFileCache',
|
||||||
|
;
|
||||||
|
sql 'DELETE FROM WorkflowActivityData WHERE activityId IN (?,?)',
|
||||||
|
'pbwfactivity0000000002',
|
||||||
|
'pbwfactivity0000000022',
|
||||||
|
;
|
||||||
|
|
||||||
|
done;
|
||||||
20
var/upgrades/7.9.8-8.0.0/moveFileLocations.pl
Normal file
20
var/upgrades/7.9.8-8.0.0/moveFileLocations.pl
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
use WebGUI::Upgrade::Script;
|
||||||
|
|
||||||
|
use File::Basename;
|
||||||
|
use Cwd qw(realpath);
|
||||||
|
use File::Spec::Functions;
|
||||||
|
use WebGUI::Paths;
|
||||||
|
|
||||||
|
report "\tMoving preload files ";
|
||||||
|
|
||||||
|
my $webgui_root = realpath( catdir( dirname( $INC{'WebGUI/Upgrade/Script.pm'} ), updir x 3 ) );
|
||||||
|
|
||||||
|
unlink catfile($webgui_root, 'lib', 'default.ttf');
|
||||||
|
|
||||||
|
unlink catfile($webgui_root, 'sbin', 'preload.custom.example');
|
||||||
|
unlink catfile($webgui_root, 'sbin', 'preload.exclude.example');
|
||||||
|
|
||||||
|
rename catfile($webgui_root, 'sbin', 'preload.custom'), WebGUI::Paths->preloadCustom;
|
||||||
|
rename catfile($webgui_root, 'sbin', 'preload.exclude'), WebGUI::Paths->preloadExclusions;
|
||||||
|
|
||||||
|
done;
|
||||||
12
var/upgrades/7.9.8-8.0.0/moveMaintenance.pl
Normal file
12
var/upgrades/7.9.8-8.0.0/moveMaintenance.pl
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
use WebGUI::Upgrade::Script;
|
||||||
|
|
||||||
|
use File::Spec::Functions;
|
||||||
|
use Cwd qw(realpath);
|
||||||
|
|
||||||
|
my $webgui_root = realpath( catdir( dirname( $INC{'WebGUI/Upgrade/Script.pm'} ), (updir) x 3 ) );
|
||||||
|
|
||||||
|
report "\tMoving maintenance file ";
|
||||||
|
|
||||||
|
unlink catfile($webgui_root, 'docs', 'maintenance.html');
|
||||||
|
|
||||||
|
done;
|
||||||
|
|
@ -1,117 +1,25 @@
|
||||||
#!/usr/bin/env perl
|
use WebGUI::Upgrade::Script;
|
||||||
|
|
||||||
#-------------------------------------------------------------------
|
report "\tRunning an upgrade step...";
|
||||||
# WebGUI is Copyright 2001-2009 Plain Black Corporation.
|
|
||||||
#-------------------------------------------------------------------
|
|
||||||
# Please read the legal notices (docs/legal.txt) and the license
|
|
||||||
# (docs/license.txt) that came with this distribution before using
|
|
||||||
# this software.
|
|
||||||
#-------------------------------------------------------------------
|
|
||||||
# http://www.plainblack.com info@plainblack.com
|
|
||||||
#-------------------------------------------------------------------
|
|
||||||
|
|
||||||
use strict;
|
# if (! quiet) { ... }
|
||||||
use Getopt::Long;
|
|
||||||
use WebGUI::Paths -inc;
|
|
||||||
use WebGUI::Session;
|
|
||||||
use WebGUI::Storage;
|
|
||||||
use WebGUI::Asset;
|
|
||||||
|
|
||||||
|
# clear_cache;
|
||||||
|
|
||||||
my $toVersion = "0.0.0"; # make this match what version you're going to
|
# my $session = session;
|
||||||
my $quiet; # this line required
|
# my $config = config;
|
||||||
|
# my $dbh = dbh;
|
||||||
|
# sql 'CREATE TABLE ...';
|
||||||
|
# version_tag "Doing asset work";
|
||||||
|
|
||||||
|
# rm_lib 'WebGUI::Old::Module';
|
||||||
|
|
||||||
my $session = start(); # this line required
|
# my $asset = asset('assetId');
|
||||||
|
# my $asset = asset('asset/url');
|
||||||
|
# my $asset = import_node->addChild( ... );
|
||||||
|
# my $assets = root_asset->getLineage( ... );
|
||||||
|
|
||||||
# upgrade functions go here
|
# my $file = collateral->file('filename');
|
||||||
|
# import_package 'some_files.wgpkg';
|
||||||
|
|
||||||
finish($session); # this line required
|
done;
|
||||||
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------------
|
|
||||||
# Describe what our function does
|
|
||||||
#sub exampleFunction {
|
|
||||||
# my $session = shift;
|
|
||||||
# print "\tWe're doing some stuff here that you should know about... " unless $quiet;
|
|
||||||
# # and here's our code
|
|
||||||
# print "DONE!\n" unless $quiet;
|
|
||||||
#}
|
|
||||||
|
|
||||||
|
|
||||||
# -------------- DO NOT EDIT BELOW THIS LINE --------------------------------
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------------
|
|
||||||
# Add a package to the import node
|
|
||||||
sub addPackage {
|
|
||||||
my $session = shift;
|
|
||||||
my $file = shift;
|
|
||||||
|
|
||||||
print "\tUpgrading package $file\n" unless $quiet;
|
|
||||||
# Make a storage location for the package
|
|
||||||
my $storage = WebGUI::Storage->createTemp( $session );
|
|
||||||
$storage->addFileFromFilesystem( $file );
|
|
||||||
|
|
||||||
# Import the package into the import node
|
|
||||||
my $package = eval {
|
|
||||||
my $node = WebGUI::Asset->getImportNode($session);
|
|
||||||
$node->importPackage( $storage, {
|
|
||||||
overwriteLatest => 1,
|
|
||||||
clearPackageFlag => 1,
|
|
||||||
setDefaultTemplate => 1,
|
|
||||||
} );
|
|
||||||
};
|
|
||||||
|
|
||||||
if ($package eq 'corrupt') {
|
|
||||||
die "Corrupt package found in $file. Stopping upgrade.\n";
|
|
||||||
}
|
|
||||||
if ($@ || !defined $package) {
|
|
||||||
die "Error during package import on $file: $@\nStopping upgrade\n.";
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#-------------------------------------------------
|
|
||||||
sub start {
|
|
||||||
my $configFile;
|
|
||||||
$|=1; #disable output buffering
|
|
||||||
GetOptions(
|
|
||||||
'configFile=s'=>\$configFile,
|
|
||||||
'quiet'=>\$quiet
|
|
||||||
);
|
|
||||||
my $session = WebGUI::Session->open($configFile);
|
|
||||||
$session->user({userId=>3});
|
|
||||||
my $versionTag = WebGUI::VersionTag->getWorking($session);
|
|
||||||
$versionTag->set({name=>"Upgrade to ".$toVersion});
|
|
||||||
return $session;
|
|
||||||
}
|
|
||||||
|
|
||||||
#-------------------------------------------------
|
|
||||||
sub finish {
|
|
||||||
my $session = shift;
|
|
||||||
updateTemplates($session);
|
|
||||||
my $versionTag = WebGUI::VersionTag->getWorking($session);
|
|
||||||
$versionTag->commit;
|
|
||||||
$session->db->write("insert into webguiVersion values (".$session->db->quote($toVersion).",'upgrade',".time().")");
|
|
||||||
$session->close();
|
|
||||||
}
|
|
||||||
|
|
||||||
#-------------------------------------------------
|
|
||||||
sub updateTemplates {
|
|
||||||
my $session = shift;
|
|
||||||
return undef unless (-d "packages-".$toVersion);
|
|
||||||
print "\tUpdating packages.\n" unless ($quiet);
|
|
||||||
opendir(DIR,"packages-".$toVersion);
|
|
||||||
my @files = readdir(DIR);
|
|
||||||
closedir(DIR);
|
|
||||||
my $newFolder = undef;
|
|
||||||
foreach my $file (@files) {
|
|
||||||
next unless ($file =~ /\.wgpkg$/);
|
|
||||||
# Fix the filename to include a path
|
|
||||||
$file = "packages-" . $toVersion . "/" . $file;
|
|
||||||
addPackage( $session, $file );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#vim:ft=perl
|
|
||||||
|
|
|
||||||
|
|
@ -1,172 +0,0 @@
|
||||||
#!/usr/bin/env perl
|
|
||||||
|
|
||||||
#-------------------------------------------------------------------
|
|
||||||
# WebGUI is Copyright 2001-2009 Plain Black Corporation.
|
|
||||||
#-------------------------------------------------------------------
|
|
||||||
# Please read the legal notices (docs/legal.txt) and the license
|
|
||||||
# (docs/license.txt) that came with this distribution before using
|
|
||||||
# this software.
|
|
||||||
#-------------------------------------------------------------------
|
|
||||||
# http://www.plainblack.com info@plainblack.com
|
|
||||||
#-------------------------------------------------------------------
|
|
||||||
|
|
||||||
use strict;
|
|
||||||
use File::Path qw/rmtree/;
|
|
||||||
use Getopt::Long;
|
|
||||||
use WebGUI::Paths -inc;
|
|
||||||
use WebGUI::Session;
|
|
||||||
use WebGUI::Storage;
|
|
||||||
use WebGUI::Asset;
|
|
||||||
|
|
||||||
|
|
||||||
my $toVersion = "8.0.0"; # make this match what version you're going to
|
|
||||||
my $quiet; # this line required
|
|
||||||
|
|
||||||
|
|
||||||
my $session = start(); # this line required
|
|
||||||
|
|
||||||
moveMaintenance($session);
|
|
||||||
migrateToNewCache($session);
|
|
||||||
moveFileLocations($session);
|
|
||||||
addMaintenancePageToConfig($session);
|
|
||||||
|
|
||||||
finish($session); # this line required
|
|
||||||
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------------
|
|
||||||
sub migrateToNewCache {
|
|
||||||
my $session = shift;
|
|
||||||
print "\tMigrating to new cache " unless $quiet;
|
|
||||||
rmtree "../../lib/WebGUI/Cache";
|
|
||||||
unlink "../../lib/WebGUI/Workflow/Activity/CleanDatabaseCache.pm";
|
|
||||||
unlink "../../lib/WebGUI/Workflow/Activity/CleanFileCache.pm";
|
|
||||||
my $config = $session->config;
|
|
||||||
$config->set("cache", {
|
|
||||||
"driver" => "FastMmap",
|
|
||||||
"expires_variance" => "0.10",
|
|
||||||
"root_dir" => "/tmp/WebGUICache",
|
|
||||||
});
|
|
||||||
$config->set("hotSessionFlushToDb", 600);
|
|
||||||
$config->delete("disableCache");
|
|
||||||
$config->delete("cacheType");
|
|
||||||
$config->delete("fileCacheRoot");
|
|
||||||
$config->deleteFromArray("workflowActivities/None", "WebGUI::Workflow::Activity::CleanDatabaseCache");
|
|
||||||
$config->deleteFromArray("workflowActivities/None", "WebGUI::Workflow::Activity::CleanFileCache");
|
|
||||||
my $db = $session->db;
|
|
||||||
$db->write("drop table cache");
|
|
||||||
$db->write("delete from WorkflowActivity where className in ('WebGUI::Workflow::Activity::CleanDatabaseCache','WebGUI::Workflow::Activity::CleanFileCache')");
|
|
||||||
$db->write("delete from WorkflowActivityData where activityId in ('pbwfactivity0000000002','pbwfactivity0000000022')");
|
|
||||||
print "DONE!\n" unless $quiet;
|
|
||||||
}
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------------
|
|
||||||
sub moveMaintenance {
|
|
||||||
my $session = shift;
|
|
||||||
print "\tMoving maintenance file " unless $quiet;
|
|
||||||
unlink '../../docs/maintenance.html';
|
|
||||||
print "DONE!\n" unless $quiet;
|
|
||||||
}
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------------
|
|
||||||
sub addMaintenancePageToConfig {
|
|
||||||
my $session = shift;
|
|
||||||
print "\tAdd maintenance page entry to the config file " unless $quiet;
|
|
||||||
$session->config->set('maintenancePage', '/data/WebGUI/www/maintenance.html');
|
|
||||||
print "DONE!\n" unless $quiet;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub moveFileLocations {
|
|
||||||
my $session = shift;
|
|
||||||
print "\tMoving preload files " unless $quiet;
|
|
||||||
unlink '../../sbin/preload.custom.example';
|
|
||||||
rename '../../sbin/preload.custom', File::Spec->catfile(WebGUI::Paths->configBase, 'preload.custom');
|
|
||||||
unlink '../../sbin/preload.exclude.example';
|
|
||||||
rename '../../sbin/preload.exclude', File::Spec->catfile(WebGUI::Paths->configBase, 'preload.exclude');
|
|
||||||
unlink '../../lib/default.ttf';
|
|
||||||
print "Done.\n" unless $quiet;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# -------------- DO NOT EDIT BELOW THIS LINE --------------------------------
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------------
|
|
||||||
# Add a package to the import node
|
|
||||||
sub addPackage {
|
|
||||||
my $session = shift;
|
|
||||||
my $file = shift;
|
|
||||||
|
|
||||||
# Make a storage location for the package
|
|
||||||
my $storage = WebGUI::Storage->createTemp( $session );
|
|
||||||
$storage->addFileFromFilesystem( $file );
|
|
||||||
|
|
||||||
# Import the package into the import node
|
|
||||||
my $package = eval { WebGUI::Asset->getImportNode($session)->importPackage( $storage ); };
|
|
||||||
|
|
||||||
if ($package eq 'corrupt') {
|
|
||||||
die "Corrupt package found in $file. Stopping upgrade.\n";
|
|
||||||
}
|
|
||||||
if ($@ || !defined $package) {
|
|
||||||
die "Error during package import on $file: $@\nStopping upgrade\n.";
|
|
||||||
}
|
|
||||||
|
|
||||||
# Turn off the package flag, and set the default flag for templates added
|
|
||||||
my $assetIds = $package->getLineage( ['self','descendants'] );
|
|
||||||
for my $assetId ( @{ $assetIds } ) {
|
|
||||||
my $asset = WebGUI::Asset->newByDynamicClass( $session, $assetId );
|
|
||||||
if ( !$asset ) {
|
|
||||||
print "Couldn't instantiate asset with ID '$assetId'. Please check package '$file' for corruption.\n";
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
my $properties = { isPackage => 0 };
|
|
||||||
if ($asset->isa('WebGUI::Asset::Template')) {
|
|
||||||
$properties->{isDefault} = 1;
|
|
||||||
}
|
|
||||||
$asset->update( $properties );
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#-------------------------------------------------
|
|
||||||
sub start {
|
|
||||||
my $configFile;
|
|
||||||
$|=1; #disable output buffering
|
|
||||||
GetOptions(
|
|
||||||
'configFile=s'=>\$configFile,
|
|
||||||
'quiet'=>\$quiet
|
|
||||||
);
|
|
||||||
my $session = WebGUI::Session->open($configFile);
|
|
||||||
$session->user({userId=>3});
|
|
||||||
my $versionTag = WebGUI::VersionTag->getWorking($session);
|
|
||||||
$versionTag->set({name=>"Upgrade to ".$toVersion});
|
|
||||||
return $session;
|
|
||||||
}
|
|
||||||
|
|
||||||
#-------------------------------------------------
|
|
||||||
sub finish {
|
|
||||||
my $session = shift;
|
|
||||||
updateTemplates($session);
|
|
||||||
my $versionTag = WebGUI::VersionTag->getWorking($session);
|
|
||||||
$versionTag->commit;
|
|
||||||
$session->db->write("insert into webguiVersion values (".$session->db->quote($toVersion).",'upgrade',".$session->datetime->time().")");
|
|
||||||
$session->close();
|
|
||||||
}
|
|
||||||
|
|
||||||
#-------------------------------------------------
|
|
||||||
sub updateTemplates {
|
|
||||||
my $session = shift;
|
|
||||||
return undef unless (-d "packages-".$toVersion);
|
|
||||||
print "\tUpdating packages.\n" unless ($quiet);
|
|
||||||
opendir(DIR,"packages-".$toVersion);
|
|
||||||
my @files = readdir(DIR);
|
|
||||||
closedir(DIR);
|
|
||||||
my $newFolder = undef;
|
|
||||||
foreach my $file (@files) {
|
|
||||||
next unless ($file =~ /\.wgpkg$/);
|
|
||||||
# Fix the filename to include a path
|
|
||||||
$file = "packages-" . $toVersion . "/" . $file;
|
|
||||||
addPackage( $session, $file );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#vim:ft=perl
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue