Upgrading through RT4.1.1 fails with Couldn't load ACLs

I’m in the process of moving an elderly RT instance (4.0.24 on Ubuntu 10.04(!) using postgresql 8.4) to the latest stable release (RT4.4.1 on Debian Stretch using postgresql 9.6) and have hit a wall during the database upgrade process. The ‘make upgrade-database’ step fails while processing the 4.1.1 upgrade step with the message ‘ERROR: Couldn’t load ACLs’. To summarize the process so far… load the RT application on a new (clean) system, create a new Postgres instance called rt4 and load it from a file created by pg_dump on the existing production system.

Any advice on how to determine what’s the problem? Nothing is logged by postgres, nothing beyond a slightly reformat of the messages that appeared on the terminal get logged in /var/log/messages

The upgrade outputs the following to the terminal with my account detail redacted:
make upgrade-database
/usr/bin/perl -I/opt/rt4/local/lib -I/opt/rt4/lib sbin/rt-setup-database --action upgrade --prompt-for-dba-password
In order to create or update your RT database, this script needs to connect to your Pg instance on localhost (port ‘5432’) as postgres
Please specify that user’s database password below. If the user has no database
password, just press return.

Password:
Working with:
Type: Pg
Host: localhost
Port: 5432
Name: rt4
User: rt_user
DBA: postgres
Enter RT version you’re upgrading from: 4.0.24

Going to apply following upgrades:

  • 4.1.0
  • 4.1.1
  • 4.1.4
  • 4.1.5
  • 4.1.6
  • 4.1.7
  • 4.1.8
  • 4.1.9
  • 4.1.10
  • 4.1.11
  • 4.1.12
  • 4.1.13
  • 4.1.14
  • 4.1.15
  • 4.1.16
  • 4.1.17
  • 4.1.18
  • 4.1.19
  • 4.1.20
  • 4.1.21
  • 4.1.22
  • 4.1.23
  • 4.2.1
  • 4.2.2
  • 4.2.4
  • 4.2.6
  • 4.2.7
  • 4.2.8
  • 4.2.10
  • 4.2.11
  • 4.3.0
  • 4.3.1
  • 4.3.2
  • 4.3.3
  • 4.3.5
  • 4.3.6
  • 4.3.7
  • 4.3.8
  • 4.3.9
  • 4.3.10
  • 4.3.11
  • 4.3.12
  • 4.3.13
  • 4.4.1

Enter RT version if you want to stop upgrade at some point,
or leave it blank if you want apply above upgrades:

IT’S VERY IMPORTANT TO BACK UP BEFORE THIS STEP

Proceed [y/N]:y
Processing 4.1.0
[14729] [Thu Apr 20 13:21:22 2017] [warning]: RT::Authen::ExternalAuth has been cored since RT 4.4, please check the upgrade document for more details (/home/XXXX/Downloads/rt-4.4.1/sbin/…/lib/RT.pm:748)
[14729] [Thu Apr 20 13:21:22 2017] [warning]: RT::Authen::ExternalAuth has been cored since RT 4.4, please check the upgrade document for more details (/home/XXXX/Downloads/rt-4.4.1/sbin/…/lib/RT.pm:748)
[14729] [Thu Apr 20 13:21:23 2017] [info]: RT’s GnuPG libraries couldn’t successfully read your configured GnuPG home directory (/opt/rt4/var/data/gpg). GnuPG support has been disabled (/home/XXXX/Downloads/rt-4.4.1/sbin/…/lib/RT/Config.pm:790)
Now inserting data.
Processing 4.1.1
Now populating database schema.
Now inserting database ACLs.
Couldn’t finish ‘upgrade’ step.

ERROR: Couldn’t load ACLs:

Makefile:389: recipe for target ‘upgrade-database’ failed
make: *** [upgrade-database] Error 255

According to etc/upgrade/4.4.1/acl.Pg, it may fail because the DBA used has no right to do grants .

Any more informations in your RT or postgresql log files?

The content of this (nearly last, you have to run 4.4.1/content after) upgrade step is easy to read, you may try to run it manually using psql to check for problems here.

Thank you for that… there’s food for thought there… unfortunately I’ve had to spend the day dealing with other issues, the RT replacement is somewhat a background task.

I was expecting that the upgrades would use the ‘postgres’ account which should be postgresql superuser and should have right to do grants (checking, it does, which implies it’s not using postgres to do the upgrades even though the beginning of the run says that is what it will do).

Incidentally it appears the 4.1.1 upgrade script is not idempotent for us… so re-running means dropping and reloading the database.

It looks like it’s down to a difference in Perl behavior. In perl 5.24.1 the code that loads the ACL file (and I presume would load every subsequent ACL file and if I checked probably the schema files as well) ends in error always. In perl 5.22.1 it doesn’t.

A simplified analog of the setup demonstrates this…

file test.pl contains:
my $file = “test2.pl”;
print “about to do $file \n”;
do $file || return (0, “oops, fail”);
my $retval = do $file;
print “Returned value = $retval \n”;
my $retval2 = fred (“inputstring”);
print “Returned value from fred = $retval2 \n”;

file test2.pl contains:
sub fred {
my $inpval = shift;
print “in subroutine fred \n”;
print “input was $inpval \n”;
return (“fredded”);
}
print “hello world \n”;
1;

on Perl 5.22 running test1.pl produces:
about to do test2.pl
hello world
hello world
Returned value = 1
in subroutine fred
input was inputstring
Returned value from fred = fredded

On Perl 5.24
about to do test2.pl
Can’t return outside a subroutine at ./test.pl line 3

If I remove the ||… test and allow it to not report the failure instead I get:
about to do test2.pl
Returned value =
Undefined subroutine &main::fred called at ./test.pl line 6.

That’s either a defect in Perl 5.24.1 or an incompatibility between RT and Perl5.24.1… well, I was warned during the install that there were JSON::XS issues but this isn’t JSON::XS. Why 5.24.1? Well, there’s a strong preference here for Debian and Jessie runs an ‘Encode’ version that is too old… and it appears Stretch runs a Perl version that is slightly broken.

Newer perl versions don’t accept relative paths in certain contexts (like do), and the error handling for ACL only reports $@ and not $! (from do failure).

Facing the same issue on Debian9 during upgrade from RT 4.2.10 to 4.4.2 version.

Looks like the line
do $path || return (0, "Couldn't load ACLs: " . $@);
in lib/RT/Handle.pm is problematic.

How to workaround this issue?

Commenting out the line
#pop @INC if $INC[-1] eq '.' and !$ENV{PERL_USE_UNSAFE_INC};
in /etc/perl/sitecustomize.pl solved the issue.

Seems it needs to be patched as Perl since 5.26 version will not include ‘.’ in @INC by default.