[Rt-commit] rt branch, 4.2/migrator-additions, created. rt-4.2.13-61-gfe3f274

Shawn Moore shawn at bestpractical.com
Thu Sep 22 17:46:56 EDT 2016


The branch, 4.2/migrator-additions has been created
        at  fe3f274ad079f2f6b0079ce13c8134884fc64285 (commit)

- Log -----------------------------------------------------------------
commit bedb3f91ecebdb913e531b5a323e4e09ff016563
Author: Shawn M Moore <shawn at bestpractical.com>
Date:   Thu Sep 22 21:41:14 2016 +0000

    Add a --limit-queues option to rt-serializer

diff --git a/lib/RT/Migrate/Serializer.pm b/lib/RT/Migrate/Serializer.pm
index f938bc1..cb067ae 100644
--- a/lib/RT/Migrate/Serializer.pm
+++ b/lib/RT/Migrate/Serializer.pm
@@ -58,6 +58,7 @@ sub cmp_version($$) { RT::Handle::cmp_version($_[0],$_[1]) };
 use RT::Migrate::Incremental;
 use RT::Migrate::Serializer::IncrementalRecord;
 use RT::Migrate::Serializer::IncrementalRecords;
+use List::MoreUtils 'none';
 
 sub Init {
     my $self = shift;
@@ -88,6 +89,7 @@ sub Init {
                   FollowScrips
                   FollowTickets
                   FollowACL
+                  Queues
                   Clone
                   Incremental
               /;
@@ -293,7 +295,14 @@ sub PushBasics {
         $self->PushCollections(qw(Topics Classes));
     }
 
-    $self->PushCollections(qw(Queues));
+    if ($self->{Queues}) {
+        my $queues = RT::Queues->new(RT->SystemUser);
+        $queues->Limit(FIELD => 'id', OPERATOR => 'IN', VALUE => $self->{Queues});
+        $self->PushObj($queues);
+    }
+    else {
+        $self->PushCollections(qw(Queues));
+    }
 }
 
 sub InitStream {
@@ -400,7 +409,13 @@ sub Observe {
     my $from = $args{from};
     if ($obj->isa("RT::Ticket")) {
         return 0 if $obj->Status eq "deleted" and not $self->{FollowDeleted};
+        my $queue = $obj->Queue;
+        return 0 if $self->{Queues} && none { $queue == $_ } @{ $self->{Queues} };
         return $self->{FollowTickets};
+    } elsif ($obj->isa("RT::Queue")) {
+        my $id = $obj->Id;
+        return 0 if $self->{Queues} && none { $id == $_ } @{ $self->{Queues} };
+        return 1;
     } elsif ($obj->isa("RT::ACE")) {
         return $self->{FollowACL};
     } elsif ($obj->isa("RT::Scrip") or $obj->isa("RT::Template") or $obj->isa("RT::ObjectScrip")) {
diff --git a/sbin/rt-serializer.in b/sbin/rt-serializer.in
index c008e78..8efe67f 100644
--- a/sbin/rt-serializer.in
+++ b/sbin/rt-serializer.in
@@ -104,6 +104,7 @@ GetOptions(
     "scrips!",
     "tickets!",
     "acls!",
+    "limit-queues=s@",
 
     "clone",
     "incremental",
@@ -127,12 +128,30 @@ $args{FollowScrips}  = $OPT{scrips}   if defined $OPT{scrips};
 $args{FollowTickets} = $OPT{tickets}  if defined $OPT{tickets};
 $args{FollowACL}     = $OPT{acls}     if defined $OPT{acls};
 
+$args{HyperlinkUnmigrated} = $OPT{'hyperlink-unmigrated'} if defined $OPT{'hyperlink-unmigrated'};
+
 $args{Clone}         = $OPT{clone}       if $OPT{clone};
 $args{Incremental}   = $OPT{incremental} if $OPT{incremental};
 
 $args{GC}   = defined $OPT{gc}   ? $OPT{gc}   : 5000;
 $args{Page} = defined $OPT{page} ? $OPT{page} : 100;
 
+if ($OPT{'limit-queues'}) {
+    my @queue_ids;
+
+    for my $name (split ',', join ',', @{ $OPT{'limit-queues'} }) {
+        $name =~ s/^\s+//; $name =~ s/\s+$//;
+        my $queue = RT::Queue->new(RT->SystemUser);
+        $queue->Load($name);
+        if (!$queue->Id) {
+            die "Unable to load queue '$name'";
+        }
+        push @queue_ids, $queue->Id;
+    }
+
+    $args{Queues} = \@queue_ids;
+}
+
 if (($OPT{clone} or $OPT{incremental})
         and grep { /^(users|groups|deleted|scrips|tickets|acls)$/ } keys %OPT) {
     die "You cannot specify object types when cloning.\n\nPlease see $0 --help.\n";
@@ -321,6 +340,11 @@ serialized.
 
 Skip serialization of all ticket data.
 
+=item B<--limit-queues>
+
+Takes a list of queue IDs or names separated by commas. When provided, only
+that set of queues (and the tickets in them) will be serialized.
+
 =item B<--clone>
 
 Serializes your entire database, creating a clone.  This option should

commit 1a78d32b9d5ef5ae86d63c70800c6a6afd0b91be
Author: Shawn M Moore <shawn at bestpractical.com>
Date:   Thu Sep 22 21:41:19 2016 +0000

    Clean up transactions and records for semi-migrated Links
    
    When serializing only a subset of records out of an RT instance,
    special consideration is needed for any RT::Link record relating
    some record in the serialized subset with some record not in the
    serialized subset. This commit drops such RT::Link records, and the
    related AddLink- and DeleteLink-type RT::Transaction records replace the
    missing link with a "(not migrated)" note.
    
    To inspect whether both sides of a link will be serialized, each record
    class's Serialize method needs a way to query the RT::Migrate::Serializer
    object orchestrating the serialization.
    
    To enable an RT::Link record opting out of being serialized,
    returning an empty hash from the Serialize method is now treated as a
    special case to skip that record.

diff --git a/lib/RT/Link.pm b/lib/RT/Link.pm
index 0dadc3b..b7e12ce 100644
--- a/lib/RT/Link.pm
+++ b/lib/RT/Link.pm
@@ -558,6 +558,23 @@ sub Serialize {
 
     delete $store{LocalBase}   if $store{Base};
     delete $store{LocalTarget} if $store{Target};
+
+    for my $dir (qw/Base Target/) {
+        my $uri = $self->${\($dir.'URI')};
+        my $object = $self->${\($dir.'Obj')};
+
+        if ($uri->IsLocal) {
+            if ($args{serializer}->Observe(object => $object)) {
+                # no action needed; the object is being migrated
+            }
+            else {
+                # object is not being migrated and hyperlinks not desired,
+                # so drop this RT::Link altogether
+                return;
+            }
+        }
+    }
+
     return %store;
 }
 
diff --git a/lib/RT/Migrate/Serializer.pm b/lib/RT/Migrate/Serializer.pm
index cb067ae..b722f8c 100644
--- a/lib/RT/Migrate/Serializer.pm
+++ b/lib/RT/Migrate/Serializer.pm
@@ -488,10 +488,13 @@ sub Visit {
             \%data,
         );
     } else {
+        my %serialized = $obj->Serialize(serializer => $self);
+        return unless %serialized;
+
         @store = (
             ref($obj),
             $obj->UID,
-            { $obj->Serialize },
+            \%serialized,
         );
     }
 
diff --git a/lib/RT/Transaction.pm b/lib/RT/Transaction.pm
index 15d62b2..d5dbc3f 100644
--- a/lib/RT/Transaction.pm
+++ b/lib/RT/Transaction.pm
@@ -2098,13 +2098,27 @@ sub Serialize {
         if ($store{OldValue}) {
             my $base = RT::URI->new( $self->CurrentUser );
             $base->FromURI( $store{OldValue} );
-            $store{OldValue} = \($base->Object->UID) if $base->Resolver and $base->Object;
+            if ($base->Resolver && (my $object = $base->Object)) {
+                if ($args{serializer}->Observe(object => $object)) {
+                    $store{OldValue} = \($object->UID);
+                }
+                else {
+                    $store{OldValue} = "(not migrated)";
+                }
+            }
         }
     } elsif ($type eq "AddLink") {
         if ($store{NewValue}) {
             my $base = RT::URI->new( $self->CurrentUser );
             $base->FromURI( $store{NewValue} );
-            $store{NewValue} = \($base->Object->UID) if $base->Resolver and $base->Object;
+            if ($base->Resolver && (my $object = $base->Object)) {
+                if ($args{serializer}->Observe(object => $object)) {
+                    $store{NewValue} = \($object->UID);
+                }
+                else {
+                    $store{NewValue} = "(not migrated)";
+                }
+            }
         }
     } elsif ($type eq "Set" and $store{Field} eq "Queue") {
         for my $field (qw/OldValue NewValue/) {

commit 43623ed76eb227f84a6febaf2418f0ad947b7419
Author: Shawn M Moore <shawn at bestpractical.com>
Date:   Thu Sep 22 21:41:21 2016 +0000

    Add a --hyperlink-unmigrated option to rt-serializer
    
    When serializing only a subset of records out of an RT instance, special
    consideration is needed for any RT::Link record relating some record in
    the serialized subset with some record not in the serialized subset. By
    default, such RT::Link records are dropped.
    
    With this commit, such RT::Link records will become hyperlinks instead,
    and the AddLink- and DeleteLink-type RT::Transaction records will use
    the hyperlink instead of the unmigrated local record.

diff --git a/lib/RT/Link.pm b/lib/RT/Link.pm
index b7e12ce..afbad99 100644
--- a/lib/RT/Link.pm
+++ b/lib/RT/Link.pm
@@ -567,6 +567,10 @@ sub Serialize {
             if ($args{serializer}->Observe(object => $object)) {
                 # no action needed; the object is being migrated
             }
+            elsif ($args{serializer}{HyperlinkUnmigrated}) {
+                # object is not being migrated; hyperlinkify
+                $store{$dir} = $uri->AsHREF;
+            }
             else {
                 # object is not being migrated and hyperlinks not desired,
                 # so drop this RT::Link altogether
diff --git a/lib/RT/Migrate/Serializer.pm b/lib/RT/Migrate/Serializer.pm
index b722f8c..5970a9a 100644
--- a/lib/RT/Migrate/Serializer.pm
+++ b/lib/RT/Migrate/Serializer.pm
@@ -90,6 +90,7 @@ sub Init {
                   FollowTickets
                   FollowACL
                   Queues
+                  HyperlinkUnmigrated
                   Clone
                   Incremental
               /;
diff --git a/lib/RT/Transaction.pm b/lib/RT/Transaction.pm
index d5dbc3f..8b7e9cb 100644
--- a/lib/RT/Transaction.pm
+++ b/lib/RT/Transaction.pm
@@ -2102,6 +2102,9 @@ sub Serialize {
                 if ($args{serializer}->Observe(object => $object)) {
                     $store{OldValue} = \($object->UID);
                 }
+                elsif ($args{serializer}{HyperlinkUnmigrated}) {
+                    $store{OldValue} = $base->AsHREF;
+                }
                 else {
                     $store{OldValue} = "(not migrated)";
                 }
@@ -2115,6 +2118,9 @@ sub Serialize {
                 if ($args{serializer}->Observe(object => $object)) {
                     $store{NewValue} = \($object->UID);
                 }
+                elsif ($args{serializer}{HyperlinkUnmigrated}) {
+                    $store{NewValue} = $base->AsHREF;
+                }
                 else {
                     $store{NewValue} = "(not migrated)";
                 }
diff --git a/sbin/rt-serializer.in b/sbin/rt-serializer.in
index 8efe67f..accaea0 100644
--- a/sbin/rt-serializer.in
+++ b/sbin/rt-serializer.in
@@ -105,6 +105,7 @@ GetOptions(
     "tickets!",
     "acls!",
     "limit-queues=s@",
+    "hyperlink-unmigrated!",
 
     "clone",
     "incremental",
@@ -345,6 +346,14 @@ Skip serialization of all ticket data.
 Takes a list of queue IDs or names separated by commas. When provided, only
 that set of queues (and the tickets in them) will be serialized.
 
+=item B<--hyperlink-unmigrated>
+
+Replace links to local records which are not being migrated with hyperlinks.
+The hyperlinks will use the serializing RT's configured URL.
+
+Without this option, such links are instead dropped, and transactions which
+had updated such links will be replaced with an explanatory message.
+
 =item B<--clone>
 
 Serializes your entire database, creating a clone.  This option should

commit 95584b6cdb810a5b6def537c1f63ec5b5192d960
Author: Shawn M Moore <shawn at bestpractical.com>
Date:   Thu Sep 22 21:41:24 2016 +0000

    Add a --limit-cfs option to rt-serializer

diff --git a/lib/RT/Migrate/Serializer.pm b/lib/RT/Migrate/Serializer.pm
index 5970a9a..bced7bc 100644
--- a/lib/RT/Migrate/Serializer.pm
+++ b/lib/RT/Migrate/Serializer.pm
@@ -90,6 +90,7 @@ sub Init {
                   FollowTickets
                   FollowACL
                   Queues
+                  CustomFields
                   HyperlinkUnmigrated
                   Clone
                   Incremental
@@ -254,6 +255,11 @@ sub PushBasics {
         OPERATOR => 'IN',
         VALUE => [ qw/RT::User RT::Group RT::Queue/ ],
     );
+
+    if ($self->{CustomFields}) {
+        $cfs->Limit(FIELD => 'id', OPERATOR => 'IN', VALUE => $self->{CustomFields});
+    }
+
     $self->PushObj( $cfs );
 
     # Global attributes
@@ -417,6 +423,18 @@ sub Observe {
         my $id = $obj->Id;
         return 0 if $self->{Queues} && none { $id == $_ } @{ $self->{Queues} };
         return 1;
+    } elsif ($obj->isa("RT::CustomField")) {
+        my $id = $obj->Id;
+        return 0 if $self->{CustomFields} && none { $id == $_ } @{ $self->{CustomFields} };
+        return 1;
+    } elsif ($obj->isa("RT::ObjectCustomFieldValue")) {
+        my $id = $obj->CustomField;
+        return 0 if $self->{CustomFields} && none { $id == $_ } @{ $self->{CustomFields} };
+        return 1;
+    } elsif ($obj->isa("RT::ObjectCustomField")) {
+        my $id = $obj->CustomField;
+        return 0 if $self->{CustomFields} && none { $id == $_ } @{ $self->{CustomFields} };
+        return 1;
     } elsif ($obj->isa("RT::ACE")) {
         return $self->{FollowACL};
     } elsif ($obj->isa("RT::Scrip") or $obj->isa("RT::Template") or $obj->isa("RT::ObjectScrip")) {
diff --git a/sbin/rt-serializer.in b/sbin/rt-serializer.in
index accaea0..2a9de13 100644
--- a/sbin/rt-serializer.in
+++ b/sbin/rt-serializer.in
@@ -105,6 +105,7 @@ GetOptions(
     "tickets!",
     "acls!",
     "limit-queues=s@",
+    "limit-cfs=s@",
     "hyperlink-unmigrated!",
 
     "clone",
@@ -153,6 +154,29 @@ if ($OPT{'limit-queues'}) {
     $args{Queues} = \@queue_ids;
 }
 
+if ($OPT{'limit-cfs'}) {
+    my @cf_ids;
+
+    for my $name (split ',', join ',', @{ $OPT{'limit-cfs'} }) {
+        $name =~ s/^\s+//; $name =~ s/\s+$//;
+
+        # numeric means id
+        if ($name =~ /^\d+$/) {
+            push @cf_ids, $name;
+        }
+        else {
+            my $cfs = RT::CustomFields->new(RT->SystemUser);
+            $cfs->Limit(FIELD => 'Name', VALUE => $name);
+            if (!$cfs->Count) {
+                die "Unable to load any custom field named '$name'";
+            }
+            push @cf_ids, map { $_->Id } @{ $cfs->ItemsArrayRef };
+        }
+    }
+
+    $args{CustomFields} = \@cf_ids;
+}
+
 if (($OPT{clone} or $OPT{incremental})
         and grep { /^(users|groups|deleted|scrips|tickets|acls)$/ } keys %OPT) {
     die "You cannot specify object types when cloning.\n\nPlease see $0 --help.\n";
@@ -346,6 +370,11 @@ Skip serialization of all ticket data.
 Takes a list of queue IDs or names separated by commas. When provided, only
 that set of queues (and the tickets in them) will be serialized.
 
+=item B<--limit-cfs>
+
+Takes a list of custom field IDs or names separated by commas. When provided,
+only that set of custom fields will be serialized.
+
 =item B<--hyperlink-unmigrated>
 
 Replace links to local records which are not being migrated with hyperlinks.

commit fe3f274ad079f2f6b0079ce13c8134884fc64285
Author: Shawn M Moore <shawn at bestpractical.com>
Date:   Thu Sep 22 21:45:28 2016 +0000

    Fix queue change transactions to mention unmigrated queues by name

diff --git a/lib/RT/Transaction.pm b/lib/RT/Transaction.pm
index 8b7e9cb..c8efcc3 100644
--- a/lib/RT/Transaction.pm
+++ b/lib/RT/Transaction.pm
@@ -2130,7 +2130,13 @@ sub Serialize {
         for my $field (qw/OldValue NewValue/) {
             my $queue = RT::Queue->new( RT->SystemUser );
             $queue->Load( $store{$field} );
-            $store{$field} = \($queue->UID);
+            if ($args{serializer}->Observe(object => $queue)) {
+                $store{$field} = \($queue->UID);
+            }
+            else {
+                $store{$field} = "$RT::Organization: " . $queue->Name . " (not migrated)";
+
+            }
         }
     } elsif ($type =~ /^(Add|Open|Resolve)Reminder$/) {
         my $ticket = RT::Ticket->new( RT->SystemUser );

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


More information about the rt-commit mailing list