#!@PERL@
# BEGIN BPS TAGGED BLOCK {{{
-#
+#
# COPYRIGHT:
-#
-# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
-# <jesse@bestpractical.com>
-#
+#
+# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# <sales@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
# 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 }}}
use strict;
use warnings;
+use 5.010;
use vars qw($Nobody $SystemUser $item);
# fix lib paths, some may be relative
-BEGIN {
+BEGIN { # BEGIN RT CMD BOILERPLATE
require File::Spec;
+ require Cwd;
my @libs = ("@RT_LIB_PATH@", "@LOCAL_LIB_PATH@");
my $bin_path;
for my $lib (@libs) {
unless ( File::Spec->file_name_is_absolute($lib) ) {
- unless ($bin_path) {
- if ( File::Spec->file_name_is_absolute(__FILE__) ) {
- $bin_path = ( File::Spec->splitpath(__FILE__) )[1];
- }
- else {
- require FindBin;
- no warnings "once";
- $bin_path = $FindBin::Bin;
- }
- }
+ $bin_path ||= ( File::Spec->splitpath(Cwd::abs_path(__FILE__)) )[1];
$lib = File::Spec->catfile( $bin_path, File::Spec->updir, $lib );
}
unshift @INC, $lib;
}
-#This drags in RT's config.pm
-# We do it in a begin block because RT::Handle needs to know the type to do its
-# inheritance
-BEGIN {
- use RT;
- RT::LoadConfig();
- RT::InitClasses();
-}
-
use Term::ReadKey;
use Getopt::Long;
+use Data::GUID;
$| = 1; # unbuffer all output.
-my %args;
+my %args = (
+ package => 'RT',
+);
GetOptions(
\%args,
'action=s',
'force', 'debug',
- 'dba=s', 'dba-password=s', 'prompt-for-dba-password',
- 'datafile=s', 'datadir=s'
+ 'dba=s', 'dba-password=s', 'prompt-for-dba-password', 'package=s',
+ 'datafile=s', 'datadir=s', 'skip-create', 'root-password-file=s',
+ 'package=s', 'ext-version=s',
+ 'upgrade-from=s', 'upgrade-to=s',
+ 'help|h',
);
-unless ( $args{'action'} ) {
- help();
- exit(-1);
+no warnings 'once';
+if ( $args{help} || ! $args{'action'} ) {
+ require Pod::Usage;
+ Pod::Usage::pod2usage({ verbose => 2 });
+ exit;
+}
+
+require RT;
+RT->LoadConfig();
+RT->InitClasses();
+
+# Force warnings to be output to STDERR if we're not already logging
+# them at a higher level
+RT->Config->Set( LogToSTDERR => 'warning')
+ unless ( RT->Config->Get( 'LogToSTDERR' )
+ && RT->Config->Get( 'LogToSTDERR' ) =~ /^(debug|info|notice)$/ );
+RT::InitLogging();
+
+# get customized root password
+my $root_password;
+if ( $args{'root-password-file'} ) {
+ open( my $fh, '<', $args{'root-password-file'} )
+ or die "Couldn't open 'args{'root-password-file'}' for reading: $!";
+ $root_password = <$fh>;
+ chomp $root_password;
+ my $min_length = RT->Config->Get('MinimumPasswordLength');
+ if ($min_length) {
+ die
+"password needs to be at least $min_length long, please check file '$args{'root-password-file'}'"
+ if length $root_password < $min_length;
+ }
+ close $fh;
}
+
# check and setup @actions
my @actions = grep $_, split /,/, $args{'action'};
if ( @actions > 1 && $args{'datafile'} ) {
exit(-1);
}
foreach ( @actions ) {
- unless ( /^(?:init|create|drop|schema|acl|coredata|insert|upgrade)$/ ) {
+ unless ( /^(?:init|create|drop|schema|acl|indexes|coredata|insert|upgrade)$/ ) {
print STDERR "$0 called with an invalid --action parameter.\n";
exit(-1);
}
# convert init to multiple actions
my $init = 0;
if ( $actions[0] eq 'init' ) {
- @actions = qw(create schema acl coredata insert);
+ if ($args{'skip-create'}) {
+ @actions = qw(schema coredata insert);
+ } else {
+ @actions = qw(create schema acl coredata insert);
+ }
$init = 1;
}
my $db_type = RT->Config->Get('DatabaseType') || '';
my $db_host = RT->Config->Get('DatabaseHost') || '';
+my $db_port = RT->Config->Get('DatabasePort') || '';
my $db_name = RT->Config->Get('DatabaseName') || '';
my $db_user = RT->Config->Get('DatabaseUser') || '';
my $db_pass = RT->Config->Get('DatabasePassword') || '';
? $args{'dba-password'}
: $ENV{'RT_DBA_PASSWORD'};
-if ( !$args{force} && ( !defined $dba_pass || $args{'prompt-for-dba-password'} ) ) {
- $dba_pass = get_dba_password();
- chomp $dba_pass if defined($dba_pass);
+if ($args{'skip-create'}) {
+ $dba_user = $db_user;
+ $dba_pass = $db_pass;
+} else {
+ if ( !$args{force} && ( !defined $dba_pass || $args{'prompt-for-dba-password'} ) ) {
+ $dba_pass = get_dba_password();
+ chomp $dba_pass if defined($dba_pass);
+ }
}
+my $version_word_regex = join '|', RT::Handle->version_words;
+my $version_dir = qr/^\d+\.\d+\.\d+(?:$version_word_regex)?\d*$/;
+
print "Working with:\n"
- ."Type:\t$db_type\nHost:\t$db_host\nName:\t$db_name\n"
- ."User:\t$db_user\nDBA:\t$dba_user\n";
+ ."Type:\t$db_type\nHost:\t$db_host\nPort:\t$db_port\nName:\t$db_name\n"
+ ."User:\t$db_user\nDBA:\t$dba_user" . ($args{'skip-create'} ? ' (No DBA)' : '') . "\n";
+
+my $package = $args{'package'} || 'RT';
+my $ext_version = $args{'ext-version'};
+my $full_id = Data::GUID->new->as_string;
+
+my $log_actions = 0;
+if ($args{'package'} ne 'RT') {
+ RT->ConnectToDatabase();
+ RT->InitSystemObjects();
+ $log_actions = 1;
+}
foreach my $action ( @actions ) {
no strict 'refs';
my ($status, $msg) = *{ 'action_'. $action }{'CODE'}->( %args );
error($action, $msg) unless $status;
- print $msg ."\n" if $msg;
+ print $msg .".\n" if $msg;
print "Done.\n";
}
sub action_create {
my %args = @_;
my $dbh = get_system_dbh();
- my ($status, $msg) = RT::Handle->CheckCompatibility( $dbh, 'pre' );
+ my ($status, $msg) = RT::Handle->CheckCompatibility( $dbh, 'create' );
return ($status, $msg) unless $status;
print "Now creating a $db_type database $db_name for RT.\n";
unless ( $args{'force'} ) {
print <<END;
-About to drop $db_type database $db_name on $db_host.
+About to drop $db_type database $db_name on $db_host (port '$db_port').
WARNING: This will erase all data in $db_name.
END
sub action_schema {
my %args = @_;
my $dbh = get_admin_dbh();
- my ($status, $msg) = RT::Handle->CheckCompatibility( $dbh, 'pre' );
+ 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) if $log_actions;
+
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) if $log_actions;
+
+ return @ret;
}
sub action_acl {
my %args = @_;
my $dbh = get_admin_dbh();
- my ($status, $msg) = RT::Handle->CheckCompatibility( $dbh, 'pre' );
+ my ($status, $msg) = RT::Handle->CheckCompatibility( $dbh, 'acl' );
return ($status, $msg) unless $status;
- print "Now inserting database ACLs\n";
- return RT::Handle->InsertACL( $dbh, $args{'datafile'} || $args{'datadir'} );
+ 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) if $log_actions;
+
+ print "Now inserting database ACLs.\n";
+ 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) if $log_actions;
+
+ 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) if $log_actions;
+
+ my $dbh = get_admin_dbh();
+ $RT::Handle = RT::Handle->new;
+ $RT::Handle->dbh( $dbh );
+ RT::InitLogging();
+
+ print "Now inserting database indexes.\n";
+ 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) if $log_actions;
+
+ return @ret;
}
sub action_coredata {
my %args = @_;
- $RT::Handle = new RT::Handle;
+ $RT::Handle = RT::Handle->new;
$RT::Handle->dbh( undef );
RT::ConnectToDatabase();
- RT::InitLogging();
- my ($status, $msg) = RT::Handle->CheckCompatibility( $RT::Handle->dbh, 'pre' );
+ my ($status, $msg) = RT::Handle->CheckCompatibility( $RT::Handle->dbh, 'coredata' );
return ($status, $msg) unless $status;
- print "Now inserting RT core system objects\n";
+ print "Now inserting RT core system objects.\n";
return $RT::Handle->InsertInitialData;
}
sub action_insert {
+ state $RAN_INIT;
my %args = @_;
- $RT::Handle = new RT::Handle;
- RT::Init();
- my ($status, $msg) = RT::Handle->CheckCompatibility( $RT::Handle->dbh, 'pre' );
+ unless ($RAN_INIT) {
+ $RT::Handle = RT::Handle->new;
+ RT::Init();
+ $RAN_INIT++;
+ }
+ $log_actions = 1;
+
+ my ($status, $msg) = RT::Handle->CheckCompatibility( $RT::Handle->dbh, 'insert' );
return ($status, $msg) unless $status;
- print "Now inserting data\n";
+ print "Now inserting data.\n";
my $file = $args{'datafile'};
$file = $RT::EtcPath . "/initialdata" if $init && !$file;
$file ||= $args{'datadir'}."/content";
- return $RT::Handle->InsertData( $file );
+
+ my $individual_id = Data::GUID->new->as_string();
+ my %upgrade_data = (
+ action => 'insert',
+ filename => Cwd::abs_path($file),
+ stage => 'before',
+ 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;
+
+ my $upgrade = sub { @ret = $RT::Handle->InsertData( $file, $root_password ) };
+
+ for my $file (@{$args{backcompat} || []}) {
+ my $lines = do {local $/; local @ARGV = ($file); <>};
+ my $sub = eval "sub {\n# line 1 $file\n$lines\n}";
+ unless ($sub) {
+ warn "Failed to load backcompat $file: $@";
+ next;
+ }
+ my $current = $upgrade;
+ $upgrade = sub { $sub->($current) };
+ }
+
+ $upgrade->();
+
+ # XXX Reconnecting to insert the history entry
+ # until we can sort out removing
+ # the disconnect at the end of InsertData.
+ RT->ConnectToDatabase();
+
+ %upgrade_data = (
+ stage => 'after',
+ individual_id => $individual_id,
+ return_value => [ @ret ],
+ );
+
+ RT->System->AddUpgradeHistory($package => \%upgrade_data);
+
+ my $db_type = RT->Config->Get('DatabaseType');
+ $RT::Handle->Disconnect() unless $db_type eq 'SQLite';
+
+ return @ret;
}
sub action_upgrade {
if ( defined $upgrading_from ) {
print "Doesn't match #.#.#: ";
} else {
- print "Enter RT version you're upgrading from: ";
+ print "Enter $args{package} version you're upgrading from: ";
}
- $upgrading_from = scalar <STDIN>;
+ $upgrading_from = $args{'upgrade-from'} || scalar <STDIN>;
chomp $upgrading_from;
$upgrading_from =~ s/\s+//g;
- } while $upgrading_from !~ /^\d+\.\d+\.\d+$/;
+ } while $upgrading_from !~ /$version_dir/;
my $upgrading_to = $RT::VERSION;
return (0, "The current version $upgrading_to is lower than $upgrading_from")
return (1, "The version $upgrading_to you're upgrading to is up to date")
if RT::Handle::cmp_version( $upgrading_from, $upgrading_to ) == 0;
- my @versions = get_versions_from_to($base_dir, $upgrading_from, $upgrading_to);
-
- return (1, "No DB changes between $upgrading_from and $upgrading_to")
+ my @versions = get_versions_from_to($base_dir, $upgrading_from, undef);
+ return (1, "No DB changes since $upgrading_from")
unless @versions;
+ if (RT::Handle::cmp_version($versions[-1], $upgrading_to) > 0) {
+ print "\n***** There are upgrades for $versions[-1], which is later than $upgrading_to,\n";
+ print "***** which you are nominally upgrading to. Upgrading to $versions[-1] instead.\n";
+ $upgrading_to = $versions[-1];
+ }
+
print "\nGoing to apply following upgrades:\n";
print map "* $_\n", @versions;
if ( defined $custom_upgrading_to ) {
print "Doesn't match #.#.#: ";
} else {
- print "\nEnter RT version if you want to stop upgrade at some point,\n";
+ print "\nEnter $args{package} version if you want to stop upgrade at some point,\n";
print " or leave it blank if you want apply above upgrades: ";
}
- $custom_upgrading_to = scalar <STDIN>;
+ $custom_upgrading_to = $args{'upgrade-to'} || scalar <STDIN>;
chomp $custom_upgrading_to;
$custom_upgrading_to =~ s/\s+//g;
last unless $custom_upgrading_to;
- } while $custom_upgrading_to !~ /^\d+\.\d+\.\d+$/;
+ } while $custom_upgrading_to !~ /$version_dir/;
if ( $custom_upgrading_to ) {
return (
}
}
- print "\nIT'S VERY IMPORTANT TO BACK UP BEFORE THIS STEP\n\n";
- _yesno() or exit(-2) unless $args{'force'};
+ unless ( $args{'force'} ) {
+ print "\nIT'S VERY IMPORTANT TO BACK UP BEFORE THIS STEP\n\n";
+ _yesno() or exit(-2);
+ }
+
+ RT->ConnectToDatabase();
+ RT->InitSystemObjects();
+ $log_actions = 1;
+
+ RT->System->AddUpgradeHistory($package => {
+ type => 'full upgrade',
+ action => 'upgrade',
+ stage => 'before',
+ from => $upgrading_from,
+ to => $upgrading_to,
+ versions => [@versions],
+ full_id => $full_id,
+ 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 ) {
+ my $v = $versions[$n];
+ my $individual_id = Data::GUID->new->as_string();
- foreach my $v ( @versions ) {
+ my @back = grep {-e $_} map {"$base_dir/$versions[$_]/backcompat"} $n+1..$#versions;
print "Processing $v\n";
- my %tmp = (%args, datadir => "$base_dir/$v", datafile => undef);
+
+ RT->System->AddUpgradeHistory($package => {
+ action => 'upgrade',
+ type => 'individual 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);
+
if ( -e "$base_dir/$v/schema.$db_type" ) {
- action_schema( %tmp );
+ ( $ret, $msg ) = action_schema( %tmp );
+ return ( $ret, $msg ) unless $ret;
}
if ( -e "$base_dir/$v/acl.$db_type" ) {
- action_acl( %tmp );
+ ( $ret, $msg ) = action_acl( %tmp );
+ return ( $ret, $msg ) unless $ret;
+ }
+ if ( -e "$base_dir/$v/indexes" ) {
+ ( $ret, $msg ) = action_indexes( %tmp );
+ return ( $ret, $msg ) unless $ret;
}
if ( -e "$base_dir/$v/content" ) {
- action_insert( %tmp );
+ ( $ret, $msg ) = action_insert( %tmp );
+ return ( $ret, $msg ) unless $ret;
}
+
+ # XXX: Another connect since the insert called
+ # previous to this step will disconnect.
+
+ RT->ConnectToDatabase();
+
+ RT->System->AddUpgradeHistory($package => {
+ stage => 'after',
+ individual_id => $individual_id,
+ });
+
+ $previous = $v;
}
+
+ RT->System->AddUpgradeHistory($package => {
+ stage => 'after',
+ individual_id => $full_id,
+ });
+
return 1;
}
sub get_versions_from_to {
my ($base_dir, $from, $to) = @_;
- opendir my $dh, $base_dir or die "couldn't open dir: $!";
- my @versions = grep -d "$base_dir/$_" && /\d+\.\d+\.\d+/, readdir $dh;
+ opendir( my $dh, $base_dir ) or die "couldn't open dir: $!";
+ my @versions = grep -d "$base_dir/$_" && /$version_dir/, readdir $dh;
closedir $dh;
+ die "\nERROR: No upgrade data found in '$base_dir'! Perhaps you specified the wrong --datadir?\n"
+ unless @versions;
+
return
- grep RT::Handle::cmp_version($_, $to) <= 0,
+ grep defined $to ? RT::Handle::cmp_version($_, $to) <= 0 : 1,
grep RT::Handle::cmp_version($_, $from) > 0,
sort RT::Handle::cmp_version @versions;
}
sub get_dba_password {
print "In order to create or update your RT database,"
. " this script needs to connect to your "
- . " $db_type instance on $db_host as $dba_user\n";
+ . " $db_type instance on $db_host (port '$db_port') as $dba_user\n";
print "Please specify that user's database password below. If the user has no database\n";
print "password, just press return.\n\n";
print "Password: ";
return ($password);
}
-=head2 get_system_dbh
+# get_system_dbh
+# Returns L<DBI> database handle connected to B<system> with DBA credentials.
+# See also L<RT::Handle/SystemDSN>.
-Returns L<DBI> database handle connected to B<system> with DBA credentials.
-
-See also L<RT::Handle/SystemDSN>.
-
-=cut
sub get_system_dbh {
return _get_dbh( RT::Handle->SystemDSN, $dba_user, $dba_pass );
return _get_dbh( RT::Handle->DSN, $dba_user, $dba_pass );
}
-=head2 get_rt_dbh [USER, PASSWORD]
-
-Returns L<DBI> database handle connected to RT database,
-you may specify credentials(USER and PASSWORD) to connect
-with. By default connects with credentials from RT config.
+# get_rt_dbh [USER, PASSWORD]
-=cut
+# Returns L<DBI> database handle connected to RT database,
+# you may specify credentials(USER and PASSWORD) to connect
+# with. By default connects with credentials from RT config.
sub get_rt_dbh {
return _get_dbh( RT::Handle->DSN, $db_user, $db_pass );
$x =~ /^y/i;
}
-sub help {
+1;
- print <<EOF;
+__END__
-$0: Set up RT's database
+=head1 NAME
---action init Initialize the database. This is combination of
- multiple actions listed below. Create DB, schema,
- setup acl, insert core data and initial data.
+rt-setup-database - Set up RT's database
- upgrade Apply all needed schema/acl/content updates (will ask
- for version to upgrade from)
+=head1 SYNOPSIS
- create Create the database.
+ rt-setup-database --action ...
- drop Drop the database.
- This will ERASE ALL YOUR DATA
+=head1 OPTIONS
- schema Initialize only the database schema
- To use a local or supplementary datafile, specify it
- using the '--datadir' option below.
+=over
- acl Initialize only the database ACLs
- To use a local or supplementary datafile, specify it
- using the '--datadir' option below.
+=item action
- coredata Insert data into RT's database. This data is required
- for normal functioning of any RT instance.
+Several actions can be combined using comma separated list.
- insert Insert data into RT's database.
- By default, will use RT's installation data.
- To use a local or supplementary datafile, specify it
- using the '--datafile' option below.
+=over
-Several actions can be combined using comma separated list.
+=item init
---datafile /path/to/datafile
---datadir /path/to/ Used to specify a path to find the local
- database schema and acls to be installed.
+Initialize the database. This is combination of multiple actions listed below.
+Create DB, schema, setup acl, insert core data and initial data.
+=item upgrade
---dba dba's username
---dba-password dba's password
---prompt-for-dba-password Ask for the database administrator's password interactively
+Apply all needed schema/acl/content updates (will ask for version to upgrade
+from)
+=item create
-EOF
+Create the database.
-}
+=item drop
-1;
+Drop the database. This will B<ERASE ALL YOUR DATA>.
+
+=item schema
+
+Initialize only the database schema
+
+To use a local or supplementary datafile, specify it using the '--datadir'
+option below.
+
+=item acl
+
+Initialize only the database ACLs
+
+To use a local or supplementary datafile, specify it using the '--datadir'
+option below.
+
+=item coredata
+
+Insert data into RT's database. This data is required for normal functioning of
+any RT instance.
+
+=item insert
+
+Insert data into RT's database. By default, will use RT's installation data.
+To use a local or supplementary datafile, specify it using the '--datafile'
+option below.
+
+=back
+
+=item datafile
+
+file path of the data you want to action on
+
+e.g. C<--datafile /path/to/datafile>
+
+=item datadir
+
+Used to specify a path to find the local database schema and acls to be
+installed.
+
+e.g. C<--datadir /path/to/>
+
+=item dba
+
+dba's username
+
+=item dba-password
+
+dba's password
+
+=item prompt-for-dba-password
+
+Ask for the database administrator's password interactively
+
+=item skip-create
+
+for 'init': skip creating the database and the user account, so we don't need
+administrator privileges
+
+=item root-password-file
+
+for 'init' and 'insert': rather than using the default administrative password
+for RT's "root" user, use the password in this file.
+
+=item package
+
+the name of the entity performing a create or upgrade. Used for logging changes
+in the DB. Defaults to RT, otherwise it should be the fully qualified package name
+of the extension or plugin making changes to the DB.
+
+=item ext-version
+
+current version of extension making a change. Not needed for RT since RT has a
+more elaborate system to track upgrades across multiple versions.
+
+=item upgrade-from
+
+for 'upgrade': specifies the version to upgrade from, and do not prompt
+for it if it appears to be a valid version.
+
+=item upgrade-to
+
+for 'upgrade': specifies the version to upgrade to, and do not prompt
+for it if it appears to be a valid version.
+
+=back
+
+=cut