[Rt-commit] rt branch, 4.2/fixup-version-history, created. rt-4.1.23-208-g1081f65

Alex Vandiver alexmv at bestpractical.com
Thu Sep 5 15:05:21 EDT 2013


The branch, 4.2/fixup-version-history has been created
        at  1081f65d6a30a17ea64b0ce6a2993ca8bd443707 (commit)

- Log -----------------------------------------------------------------
commit 6fe393c732e6c1fe2042f5d4f00345fd8ce21b2b
Author: Jim Brandt <jbrandt at bestpractical.com>
Date:   Fri Jul 5 10:58:45 2013 -0400

    Hide upgrade history from global attributes on config page
    
    Skipped the entry in code since applying a Limit removed the
    upgrade history when calling the attribute methods in the
    Upgrade history section later on the page.

diff --git a/share/html/Admin/Tools/Configuration.html b/share/html/Admin/Tools/Configuration.html
index 71d1702..0802938 100644
--- a/share/html/Admin/Tools/Configuration.html
+++ b/share/html/Admin/Tools/Configuration.html
@@ -216,6 +216,7 @@ for my $type (qw/Tickets Queues Transactions Groups PrivilegedUsers Unprivileged
 % my $attrs = $RT::System->Attributes;
 % my $index_size = 0;
 % while ( my $attr = $attrs->Next ) {
+% next if $attr->Name eq 'UpgradeHistory';
 <tr class="<% $index_size%2 ? 'oddline' : 'evenline'%>">
 % if ($attr->Name eq 'UserLogo') {
 %   my $content = $attr->Content;

commit 489efc26e418513d0011901d577b71d73093612f
Author: Jim Brandt <jbrandt at bestpractical.com>
Date:   Fri Aug 9 09:29:03 2013 -0400

    Add ids to recorded upgrade entries to track success/failure
    
    Installations and upgrades can run into issues that cause the
    upgrade scripts to die. Add ids to track this history and aid
    in future troubleshooting.
    
    full_id: An id for multi-step upgrades from 'make upgrade-database'
    The full_id tags each individual upgrade step as part of the larger
    upgrade to unambiguously show that individual upgrades were run as
    part of a full upgrade.
    
    individual_id: An id to bookend the start and end of an upgrade
    step and identify if a step failed to complete.
    
    Adds Data::GUID as a guid generator.

diff --git a/sbin/rt-setup-database.in b/sbin/rt-setup-database.in
index 8ae023e..38540f8 100644
--- a/sbin/rt-setup-database.in
+++ b/sbin/rt-setup-database.in
@@ -70,6 +70,7 @@ BEGIN { # BEGIN RT CMD BOILERPLATE
 
 use Term::ReadKey;
 use Getopt::Long;
+use Data::GUID;
 
 $| = 1; # unbuffer all output.
 
@@ -193,6 +194,7 @@ print "Working with:\n"
 
 my $package = $args{'package'} || 'RT';
 my $ext_version = $args{'ext-version'};
+my $full_id = Data::GUID->new->as_string;
 
 foreach my $action ( @actions ) {
     no strict 'refs';
@@ -285,6 +287,7 @@ sub action_insert {
     $file = $RT::EtcPath . "/initialdata" if $init && !$file;
     $file ||= $args{'datadir'}."/content";
 
+    my $individual_id = Data::GUID->new->as_string();
     my @ret;
 
     my $upgrade = sub { @ret = $RT::Handle->InsertData( $file, $root_password ) };
@@ -319,7 +322,10 @@ sub action_insert {
         action   => 'insert',
         filename => Cwd::abs_path($file),
         content  => $content,
-        stage    => 'after',);
+        stage    => 'after',
+        type     => 'process initialdata',
+        full_id => $full_id,
+        individual_id => $individual_id );
 
     $upgrade_data{'ext_version'} = $ext_version if $ext_version;
 
@@ -422,12 +428,16 @@ sub action_upgrade {
         from      => $upgrading_from,
         to        => $upgrading_to,
         versions  => [@versions],
+        full_id => $full_id,
+        individual_id => $full_id
     });
 
     my $previous = $upgrading_from;
     my ( $ret, $msg );
     foreach my $n ( 0..$#versions ) {
         my $v = $versions[$n];
+        my $individual_id = Data::GUID->new->as_string();
+
         my @back = grep {-e $_} map {"$base_dir/$versions[$_]/backcompat"} $n+1..$#versions;
         print "Processing $v\n";
 
@@ -437,6 +447,8 @@ sub action_upgrade {
             stage  => 'before',
             from   => $previous,
             to     => $v,
+            full_id => $full_id,
+            individual_id => $individual_id,
         });
 
         my %tmp = (%args, datadir => "$base_dir/$v", datafile => undef, backcompat => \@back);
@@ -469,6 +481,8 @@ sub action_upgrade {
             stage  => 'after',
             from   => $previous,
             to     => $v,
+            full_id => $full_id,
+            individual_id => $individual_id,
         });
 
         $previous = $v;
@@ -481,6 +495,8 @@ sub action_upgrade {
         from      => $upgrading_from,
         to        => $upgrading_to,
         versions  => [@versions],
+        full_id => $full_id,
+        individual_id => $full_id,
     });
 
     return 1;
diff --git a/sbin/rt-test-dependencies.in b/sbin/rt-test-dependencies.in
index 15e4e86..0b90187 100644
--- a/sbin/rt-test-dependencies.in
+++ b/sbin/rt-test-dependencies.in
@@ -182,6 +182,7 @@ CGI::PSGI 0.12
 Class::Accessor 0.34
 Crypt::Eksblowfish
 CSS::Squish 0.06
+Data::GUID
 Date::Extract 0.02
 Date::Manip
 DateTime 0.44

commit 75dee836c015bbde0bebda7cf9aa8f5310600a27
Author: Jim Brandt <jbrandt at bestpractical.com>
Date:   Fri Aug 9 10:03:59 2013 -0400

    Add before entry to insert actions
    
    Add a before to the upgrade history to track progress on
    possible failures and match the other before/after upgrade
    history pairs. Capture the return code in the after entry.

diff --git a/sbin/rt-setup-database.in b/sbin/rt-setup-database.in
index 38540f8..c3ec380 100644
--- a/sbin/rt-setup-database.in
+++ b/sbin/rt-setup-database.in
@@ -288,6 +288,19 @@ sub action_insert {
     $file ||= $args{'datadir'}."/content";
 
     my $individual_id = Data::GUID->new->as_string();
+
+    my %upgrade_data = (
+        action   => 'insert',
+        filename => Cwd::abs_path($file),
+        stage    => 'before',
+        type     => 'process initialdata',
+        full_id => $full_id,
+        individual_id => $individual_id );
+
+    $upgrade_data{'ext_version'} = $ext_version if $ext_version;
+
+    RT->System->AddUpgradeHistory($package => \%upgrade_data);
+
     my @ret;
 
     my $upgrade = sub { @ret = $RT::Handle->InsertData( $file, $root_password ) };
@@ -318,12 +331,13 @@ sub action_insert {
 
     RT->ConnectToDatabase();
 
-    my %upgrade_data = (
+    %upgrade_data = (
         action   => 'insert',
         filename => Cwd::abs_path($file),
         content  => $content,
         stage    => 'after',
         type     => 'process initialdata',
+        return_value => join (', ', @ret),
         full_id => $full_id,
         individual_id => $individual_id );
 

commit 6debb4960b605adc2ebc5fcd1e0231dee1fd2d01
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Thu Sep 5 00:43:13 2013 -0400

    Transform flat start/end events into an upgrade hierarchy

diff --git a/lib/RT/System.pm b/lib/RT/System.pm
index 59b4bbc..73466cb 100644
--- a/lib/RT/System.pm
+++ b/lib/RT/System.pm
@@ -260,6 +260,55 @@ sub UpgradeHistory {
     return $upgrade_history;
 }
 
+sub ParsedUpgradeHistory {
+    my $self = shift;
+    my $package = shift;
+
+    my $version_status = "Current version: ";
+    if ( $package eq 'RT' ){
+        $version_status .= $RT::VERSION;
+    } elsif ( grep {/$package/} @{RT->Config->Get('Plugins')} ) {
+        no strict 'refs';
+        $version_status .= ${ $package . '::VERSION' };
+    } else {
+        $version_status = "Not currently loaded";
+    }
+
+    my %ids;
+    my @lines;
+
+    my @events = $self->UpgradeHistory( $package );
+    for my $event (@events) {
+        if ($event->{stage} eq 'before') {
+            if ($ids{$event->{full_id}}) {
+                my $kids = $ids{$event->{full_id}}{sub_events} ||= [];
+                # Stitch non-"upgrade"s beneath the previous "upgrade"
+                if ( @{$kids} and $event->{action} ne 'upgrade' and $kids->[-1]{action} eq 'upgrade') {
+                    push @{ $kids->[-1]{sub_events} }, $event;
+                } else {
+                    push @{ $kids }, $event;
+                }
+            } else {
+                push @lines, $event;
+            }
+            $ids{$event->{individual_id}} = $event;
+        } elsif ($event->{stage} eq 'after') {
+            if ($ids{$event->{individual_id}}) {
+                my $end = $event;
+                $event = $ids{$event->{individual_id}};
+                $event->{end} = $end->{timestamp};
+
+                $event->{return_value} = [ split ', ', $end->{return_value}, 2 ]
+                    if $end->{return_value};
+                $event->{content} ||= $end->{content};
+            }
+        }
+    }
+
+    return ($version_status, @lines);
+}
+
+
 RT::Base->_ImportOverlays();
 
 1;

commit c382f7a5a84aac9d1976d60bb5ab208fca455676
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Thu Sep 5 00:47:07 2013 -0400

    Store the actual return value data structure, to allow for reconstruction

diff --git a/lib/RT/System.pm b/lib/RT/System.pm
index 73466cb..34f6835 100644
--- a/lib/RT/System.pm
+++ b/lib/RT/System.pm
@@ -298,8 +298,9 @@ sub ParsedUpgradeHistory {
                 $event = $ids{$event->{individual_id}};
                 $event->{end} = $end->{timestamp};
 
-                $event->{return_value} = [ split ', ', $end->{return_value}, 2 ]
-                    if $end->{return_value};
+                $end->{return_value} = [ split ', ', $end->{return_value}, 2 ]
+                    if $end->{return_value} and not ref $end->{return_value};
+                $event->{return_value} = $end->{return_value};
                 $event->{content} ||= $end->{content};
             }
         }
diff --git a/sbin/rt-setup-database.in b/sbin/rt-setup-database.in
index c3ec380..e31b7a8 100644
--- a/sbin/rt-setup-database.in
+++ b/sbin/rt-setup-database.in
@@ -337,7 +337,7 @@ sub action_insert {
         content  => $content,
         stage    => 'after',
         type     => 'process initialdata',
-        return_value => join (', ', @ret),
+        return_value => [ @ret ],
         full_id => $full_id,
         individual_id => $individual_id );
 

commit 75b7bdbe4c015a305577a6f72f11e0415f4cca9c
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Thu Sep 5 00:48:07 2013 -0400

    Make the "after" stage merely metadata; ther is no need to repeat the data

diff --git a/sbin/rt-setup-database.in b/sbin/rt-setup-database.in
index e31b7a8..7452c54 100644
--- a/sbin/rt-setup-database.in
+++ b/sbin/rt-setup-database.in
@@ -288,17 +288,18 @@ sub action_insert {
     $file ||= $args{'datadir'}."/content";
 
     my $individual_id = Data::GUID->new->as_string();
-
     my %upgrade_data = (
         action   => 'insert',
         filename => Cwd::abs_path($file),
         stage    => 'before',
-        type     => 'process initialdata',
-        full_id => $full_id,
-        individual_id => $individual_id );
-
+        full_id  => $full_id,
+        individual_id => $individual_id
+    );
     $upgrade_data{'ext_version'} = $ext_version if $ext_version;
 
+    open my $handle, '<', $file or warn "Unable to open $file: $!";
+    $upgrade_data{content} = do {local $/; <$handle>} if $handle;
+
     RT->System->AddUpgradeHistory($package => \%upgrade_data);
 
     my @ret;
@@ -318,30 +319,16 @@ sub action_insert {
 
     $upgrade->();
 
-    my $content;
-    open my $handle, '<', $file or warn "Unable to open $file: $!";
-    if ($handle) {
-        local $/; # slurp
-        $content = <$handle>;
-    }
-
     # XXX Reconnecting to insert the history entry
     # until we can sort out removing
     # the disconnect at the end of InsertData.
-
     RT->ConnectToDatabase();
 
     %upgrade_data = (
-        action   => 'insert',
-        filename => Cwd::abs_path($file),
-        content  => $content,
-        stage    => 'after',
-        type     => 'process initialdata',
-        return_value => [ @ret ],
-        full_id => $full_id,
-        individual_id => $individual_id );
-
-    $upgrade_data{'ext_version'} = $ext_version if $ext_version;
+        stage         => 'after',
+        individual_id => $individual_id,
+        return_value  => [ @ret ],
+    );
 
     RT->System->AddUpgradeHistory($package => \%upgrade_data);
 
@@ -490,12 +477,7 @@ sub action_upgrade {
         RT->ConnectToDatabase();
 
         RT->System->AddUpgradeHistory($package => {
-            action => 'upgrade',
-            type   => 'individual upgrade',
-            stage  => 'after',
-            from   => $previous,
-            to     => $v,
-            full_id => $full_id,
+            stage         => 'after',
             individual_id => $individual_id,
         });
 
@@ -503,13 +485,7 @@ sub action_upgrade {
     }
 
     RT->System->AddUpgradeHistory($package => {
-        type      => 'full upgrade',
-        action    => 'upgrade',
-        stage     => 'after',
-        from      => $upgrading_from,
-        to        => $upgrading_to,
-        versions  => [@versions],
-        full_id => $full_id,
+        stage         => 'after',
         individual_id => $full_id,
     });
 

commit 786b1f6b9546b84d57f41d17f908968d135a00c2
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Thu Sep 5 00:48:52 2013 -0400

    Store schema and acl events as well

diff --git a/sbin/rt-setup-database.in b/sbin/rt-setup-database.in
index 7452c54..0e23477 100644
--- a/sbin/rt-setup-database.in
+++ b/sbin/rt-setup-database.in
@@ -238,8 +238,28 @@ sub action_schema {
     my ($status, $msg) = RT::Handle->CheckCompatibility( $dbh, 'schema' );
     return ($status, $msg) unless $status;
 
+    my $individual_id = Data::GUID->new->as_string();
+    my %upgrade_data = (
+        action   => 'schema',
+        filename => Cwd::abs_path($args{'datafile'} || $args{'datadir'} || ''),
+        stage    => 'before',
+        full_id  => $full_id,
+        individual_id => $individual_id,
+    );
+    $upgrade_data{'ext_version'} = $ext_version if $ext_version;
+    RT->System->AddUpgradeHistory($package => \%upgrade_data) unless $init;
+
     print "Now populating database schema.\n";
-    return RT::Handle->InsertSchema( $dbh, $args{'datafile'} || $args{'datadir'} );
+    my @ret = RT::Handle->InsertSchema( $dbh, $args{'datafile'} || $args{'datadir'} );
+
+    %upgrade_data = (
+        stage         => 'after',
+        individual_id => $individual_id,
+        return_value  => [ @ret ],
+    );
+    RT->System->AddUpgradeHistory($package => \%upgrade_data) unless $init;
+
+    return @ret;
 }
 
 sub action_acl {
@@ -248,19 +268,63 @@ sub action_acl {
     my ($status, $msg) = RT::Handle->CheckCompatibility( $dbh, 'acl' );
     return ($status, $msg) unless $status;
 
+    my $individual_id = Data::GUID->new->as_string();
+    my %upgrade_data = (
+        action   => 'acl',
+        filename => Cwd::abs_path($args{'datafile'} || $args{'datadir'} || ''),
+        stage    => 'before',
+        full_id  => $full_id,
+        individual_id => $individual_id,
+    );
+    $upgrade_data{'ext_version'} = $ext_version if $ext_version;
+    RT->System->AddUpgradeHistory($package => \%upgrade_data) unless $init;
+
     print "Now inserting database ACLs.\n";
-    return RT::Handle->InsertACL( $dbh, $args{'datafile'} || $args{'datadir'} );
+    my @ret = RT::Handle->InsertACL( $dbh, $args{'datafile'} || $args{'datadir'} );
+
+    %upgrade_data = (
+        stage         => 'after',
+        individual_id => $individual_id,
+        return_value  => [ @ret ],
+    );
+    RT->System->AddUpgradeHistory($package => \%upgrade_data) unless $init;
+
+    return @ret;
 }
 
 sub action_indexes {
     my %args = @_;
+    RT->ConnectToDatabase;
+    my $individual_id = Data::GUID->new->as_string();
+    my %upgrade_data = (
+        action   => 'indexes',
+        filename => Cwd::abs_path($args{'datafile'} || $args{'datadir'} || ''),
+        stage    => 'before',
+        full_id  => $full_id,
+        individual_id => $individual_id,
+    );
+    $upgrade_data{'ext_version'} = $ext_version if $ext_version;
+    RT->System->AddUpgradeHistory($package => \%upgrade_data);
+
     my $dbh = get_admin_dbh();
     $RT::Handle = RT::Handle->new;
     $RT::Handle->dbh( $dbh );
     RT::InitLogging();
 
     print "Now inserting database indexes.\n";
-    return RT::Handle->InsertIndexes( $dbh, $args{'datafile'} || $args{'datadir'} );
+    my @ret = RT::Handle->InsertIndexes( $dbh, $args{'datafile'} || $args{'datadir'} );
+
+    $RT::Handle = RT::Handle->new;
+    $RT::Handle->dbh( undef );
+    RT->ConnectToDatabase;
+    %upgrade_data = (
+        stage         => 'after',
+        individual_id => $individual_id,
+        return_value  => [ @ret ],
+    );
+    RT->System->AddUpgradeHistory($package => \%upgrade_data);
+
+    return @ret;
 }
 
 sub action_coredata {

commit f67b9d0e890c985219b407921910af926ae6111b
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Thu Sep 5 00:50:47 2013 -0400

    Recursively walk through the parsed history to display it

diff --git a/share/html/Admin/Elements/UpgradeHistory b/share/html/Admin/Elements/UpgradeHistory
new file mode 100644
index 0000000..4e96a6d
--- /dev/null
+++ b/share/html/Admin/Elements/UpgradeHistory
@@ -0,0 +1,71 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+% for my $package (@packages) {
+%   my ($version_status, @lines) = RT->System->ParsedUpgradeHistory($package);
+<h4><% $package %> (<% $version_status %>)</h4>
+<table border="0" cellspacing="0" cellpadding="5" width="100%" class="collection upgrade-history">
+<thead>
+<tr class="collection-as-table">
+<th class="collection-as-table"> </th>
+<th class="collection-as-table"><&|/l&>Action</&></th>
+<th class="collection-as-table"><&|/l&>Date</&></th>
+<th class="collection-as-table"><&|/l&>Elapsed</&></th>
+<th class="collection-as-table"><&|/l, $package &>[_1] Version</&></th>
+</tr></thead>
+
+% my $i = 0;
+% for my $upgrade (@lines) {
+<& UpgradeHistoryRow, i => \$i, row => $upgrade &>
+% }
+</table>
+% }
+
+<%init>
+my $upgrade_history = RT->System->UpgradeHistory;
+my @packages = ('RT', sort grep { $_ ne 'RT' } keys %$upgrade_history);
+</%init>
diff --git a/share/html/Admin/Elements/UpgradeHistoryRow b/share/html/Admin/Elements/UpgradeHistoryRow
new file mode 100644
index 0000000..b9f579a
--- /dev/null
+++ b/share/html/Admin/Elements/UpgradeHistoryRow
@@ -0,0 +1,95 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<tr class="<% join ' ', map {CSSClass($_)} @classes %>">
+    <td class="upgrade-history-parent" id="parent-upgrade-history-<% $row->{individual_id} %>">
+% if ($top) {
+    <span class="widget"><a href="#" onclick="toggle_upgrade_history(this, '.upgrade-history-' + <% $row->{full_id} | n,j %>); return false";"></a></span>
+% }
+    </td>
+    <td class="collection-as-table" style="padding-left: <% $indent * 3%>em">
+%       if ($row->{'action'} eq 'upgrade') { # type is more specific for upgrades
+<&|/l, $row->{'from'}, $row->{'to'} &>Upgrade from [_1] to [_2]</&>
+%       } elsif ( $row->{'action'} eq 'insert' ) {
+<&|/l, $row->{filename} &>Insert from [_1]</&>
+%       } elsif ( $row->{'action'} eq 'schema' ) {
+<&|/l, $row->{filename} &>Schema updates from [_1]</&>
+%       } elsif ( $row->{'action'} eq 'acl' ) {
+<&|/l, $row->{filename} &>ACL updates from [_1]</&>
+%       } elsif ( $row->{'action'} eq 'indexes' ) {
+<&|/l, $row->{filename} &>Index updates from [_1]</&>
+%       } else {
+<% ucfirst($row->{action}) %>
+%       }
+    </td>
+    <td class="collection-as-table"><% $timestamp->AsString %></td>
+    <td class="collection-as-table"><% $duration %></td>
+    <td class="collection-as-table"><% $row->{ext_version} || $row->{rt_version} %></td>
+</tr>
+% for (@{$kids || []}) {
+<& UpgradeHistoryRow, row => $_, indent => $indent+1, i => $i &>
+% }
+<%args>
+$indent => 0
+$i
+$row
+</%args>
+<%init>
+my $complete = $row->{return_value} ? $row->{return_value}[0] : $row->{end};
+my $kids     = $row->{sub_events};
+my $top      = $row->{full_id} eq $row->{individual_id};
+
+my @classes;
+push @classes, $complete ? 'complete' : 'incomplete';
+push @classes, $$i++ % 2 ? 'oddline' : 'evenline';
+push @classes, 'upgrade-history-'.$row->{full_id} unless $top;
+
+my $timestamp = RT::Date->new($session{CurrentUser});
+$timestamp->Set(Value => $row->{timestamp});
+
+my $duration = $row->{end} ? $timestamp->DurationAsString($row->{end} - $row->{timestamp}) : '';
+</%init>
diff --git a/share/html/Admin/Tools/Configuration.html b/share/html/Admin/Tools/Configuration.html
index 0802938..a4ba3e8 100644
--- a/share/html/Admin/Tools/Configuration.html
+++ b/share/html/Admin/Tools/Configuration.html
@@ -268,49 +268,7 @@ if ($item =~ /^\s*(.*?)\s*v(\S+);/) {
 </&>
 
 <&|/Widgets/TitleBox, title => loc("RT upgrade history")&>
-
-% my $upgrade_history = RT->System->UpgradeHistory;
-% my @packages = ('RT', sort grep { $_ ne 'RT' } keys %$upgrade_history);
-% for my $package (@packages) {
-<h4><% $package %></h4>
-<table border="0" cellspacing="0" cellpadding="5" width="100%" class="collection">
-<tr class="collection-as-table">
-<th class="collection-as-table"><&|/l&>Action</&></th>
-<th class="collection-as-table"><&|/l&>Using RT Version</&></th>
-<th class="collection-as-table"><&|/l&>Time</&></th>
-<th class="collection-as-table"><&|/l&>Extra</&></th>
-
-<%perl>
-    my $i = 0;
-    for my $upgrade (@{ $upgrade_history->{$package} }) {
-        # only list completed upgrades
-        next unless $upgrade->{stage} eq 'after';
-</%perl>
-<tr class="<% $i++ %2 ? 'oddline' : 'evenline'%>">
-    <td class="collection-as-table">
-% if ($upgrade->{action} eq 'upgrade') { # type is more specific for upgrades
-    <% $upgrade->{type} %>
-% } else {
-    <% $upgrade->{action} %>
-% }
-    </td>
-    <td class="collection-as-table">
-        <% $upgrade->{rt_version} %>
-    </td>
-    <td class="collection-as-table">
-%          my $timestamp = RT::Date->new($session{CurrentUser});
-%          $timestamp->Set(Value => $upgrade->{timestamp});
-           <% $timestamp->AsString %>
-    </td>
-    <td class="collection-as-table">
-% if ($upgrade->{action} eq 'upgrade') {
-    <&|/l, $upgrade->{from}, $upgrade->{to} &>from [_1] to [_2]</&>
-% }
-    </td>
-</tr>
-% }
-</table>
-% }
+<& /Admin/Elements/UpgradeHistory &>
 </&>
 
 <&|/Widgets/TitleBox, title => loc("Perl configuration") &>
diff --git a/share/static/css/base/admin.css b/share/static/css/base/admin.css
index 46cc05f..95c5878 100644
--- a/share/static/css/base/admin.css
+++ b/share/static/css/base/admin.css
@@ -61,3 +61,24 @@ textarea[name="SMIMECertificate"] {
     width: 50em;
     height: 25em;
 }
+
+table.upgrade-history .incomplete {
+    font-weight: bold;
+    color: #900;
+}
+
+table.upgrade-history .upgrade-history-parent .widget a {
+  display: block;
+  margin: 0;
+  width: 20px;
+
+  background: url(../../../static/images/css/rollup-arrow.gif) no-repeat;
+  background-position: center 0;
+
+  padding: 7px 0 0 0;
+  overflow: hidden;
+}
+
+table.upgrade-history .upgrade-history-parent .widget a.rolled-up {
+    background-image: url(../../../static/images/css/rolldown-arrow.gif);
+}
diff --git a/share/static/js/util.js b/share/static/js/util.js
index 50df9f9..5a34647 100644
--- a/share/static/js/util.js
+++ b/share/static/js/util.js
@@ -30,6 +30,11 @@ function switchVisibility(id1, id2) {
     return false;
 }
 
+function toggle_upgrade_history(widget, selector) {
+    jQuery(selector).toggle();
+    jQuery(widget).toggleClass("rolled-up");
+}
+
 /* Classes */
 function jQueryWrap( id ) {
     return typeof id == 'object' ? jQuery(id) : jQuery('#'+id);

commit ff4eb2ee7eaffc81ebef07dd82c593e6eeb26a38
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Thu Sep 5 00:51:18 2013 -0400

    Reconstruct hierarchy on pre-GUID history records

diff --git a/lib/RT/System.pm b/lib/RT/System.pm
index 34f6835..3a02037 100644
--- a/lib/RT/System.pm
+++ b/lib/RT/System.pm
@@ -78,6 +78,7 @@ with "RT::Record::Role::Roles",
 
 use RT::ACL;
 use RT::ACE;
+use Data::GUID;
 
 __PACKAGE__->AddRight( Admin   => SuperUser           => 'Do anything and everything'); # loc_pair
 __PACKAGE__->AddRight( Staff   => ShowUserHistory     => 'Show history of public user properties'); # loc_pair
@@ -279,7 +280,17 @@ sub ParsedUpgradeHistory {
 
     my @events = $self->UpgradeHistory( $package );
     for my $event (@events) {
-        if ($event->{stage} eq 'before') {
+        if ($event->{stage} eq 'before' or (($event->{action}||'') eq 'insert' and not $event->{full_id})) {
+            if (not $event->{full_id}) {
+                # For upgrade done in the 4.1 series without GUIDs
+                if (($event->{type}||'') eq 'full upgrade') {
+                    $event->{full_id} = $event->{individual_id} = Data::GUID->new->as_string;
+                } else {
+                    $event->{individual_id} = Data::GUID->new->as_string;
+                    $event->{full_id} = (@lines ? $lines[-1]{full_id} : Data::GUID->new->as_string);
+                }
+                $event->{return_value} = [1] if $event->{stage} eq 'after';
+            }
             if ($ids{$event->{full_id}}) {
                 my $kids = $ids{$event->{full_id}}{sub_events} ||= [];
                 # Stitch non-"upgrade"s beneath the previous "upgrade"
@@ -293,7 +304,14 @@ sub ParsedUpgradeHistory {
             }
             $ids{$event->{individual_id}} = $event;
         } elsif ($event->{stage} eq 'after') {
-            if ($ids{$event->{individual_id}}) {
+            if (not $event->{individual_id}) {
+                if (($event->{type}||'') eq 'full upgrade') {
+                    $lines[-1]{end} = $event->{timestamp} if @lines;
+                } elsif (($event->{type}||'') eq 'individual upgrade') {
+                    $lines[-1]{sub_events}[-1]{end} = $event->{timestamp}
+                        if @lines and @{ $lines[-1]{sub_events} };
+                }
+            } elsif ($ids{$event->{individual_id}}) {
                 my $end = $event;
                 $event = $ids{$event->{individual_id}};
                 $event->{end} = $end->{timestamp};

commit 1081f65d6a30a17ea64b0ce6a2993ca8bd443707
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Thu Sep 5 14:38:20 2013 -0400

    Ensure that the Attributes table is big enough to contain the upgrades
    
    Prior to RT 4.0.6, the Content column of the Attributes table was only
    capable of holding 64k, being a BLOB or TEXT column (which it was
    depends on if it is prior to 3.7.87).  If there are a large number of
    upgrades which run prior to the 4.0.6 upgrade step which fixes this, the
    base64'd data may overflow, and truncate the upgrade history.
    
    Ensure that the first command run in the upgrade process is the relevant
    ALTER TABLE to increase the size of the Content column.  This is only
    relevant on mysql (see e249f67), and only if the initial version of the
    upgrade is prior to 4.0.6.  If rt-setup-database is run more than once,
    the ALTER will be idempotent.

diff --git a/sbin/rt-setup-database.in b/sbin/rt-setup-database.in
index 0e23477..d913e16 100644
--- a/sbin/rt-setup-database.in
+++ b/sbin/rt-setup-database.in
@@ -497,6 +497,21 @@ sub action_upgrade {
         individual_id => $full_id
     });
 
+    # Ensure that the Attributes column is big enough to hold the
+    # upgrade steps we're going to add; this step exists in 4.0.6 for
+    # mysql, but that may be too late.  Run it as soon as possible.
+    if (RT->Config->Get('DatabaseType') eq 'mysql'
+            and RT::Handle::cmp_version( $upgrading_from, '4.0.6') < 0) {
+        my $dbh = get_admin_dbh();
+        # Before the binary switch in 3.7.87, we want to alter text ->
+        # longtext, not blob -> longblob
+        if (RT::Handle::cmp_version( $upgrading_from, '3.7.87') < 0) {
+            $dbh->do("ALTER TABLE Attributes MODIFY Content LONGTEXT")
+        } else {
+            $dbh->do("ALTER TABLE Attributes MODIFY Content LONGBLOB")
+        }
+    }
+
     my $previous = $upgrading_from;
     my ( $ret, $msg );
     foreach my $n ( 0..$#versions ) {

-----------------------------------------------------------------------


More information about the Rt-commit mailing list