diff options
Diffstat (limited to 'rt/sbin')
-rw-r--r-- | rt/sbin/rt-setup-database | 707 | ||||
-rw-r--r-- | rt/sbin/rt-setup-database.in | 11 | ||||
-rw-r--r-- | rt/sbin/rt-test-dependencies | 481 |
3 files changed, 8 insertions, 1191 deletions
diff --git a/rt/sbin/rt-setup-database b/rt/sbin/rt-setup-database deleted file mode 100644 index 49af151e7..000000000 --- a/rt/sbin/rt-setup-database +++ /dev/null @@ -1,707 +0,0 @@ -#!/usr/bin/perl -w -# BEGIN BPS TAGGED BLOCK {{{ -# -# COPYRIGHT: -# -# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC -# <jesse@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 }}} -use strict; -use vars qw($PROMPT $VERSION $Handle $Nobody $SystemUser $item); -use vars - qw(@Groups @Users @ACL @Queues @ScripActions @ScripConditions @Templates @CustomFields @Scrips @Attributes); - -use lib "/opt/rt3/local/lib"; -use lib "/opt/rt3/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 -use RT; -use Carp; -use RT::User; -use RT::CurrentUser; -use RT::Template; -use RT::ScripAction; -use RT::ACE; -use RT::Group; -use RT::User; -use RT::Queue; -use RT::ScripCondition; -use RT::CustomField; -use RT::Scrip; - -RT::LoadConfig(); -use Term::ReadKey; -use Getopt::Long; - -my %args; - -GetOptions( - \%args, - 'prompt-for-dba-password', 'force', 'debug', - 'action=s', 'dba=s', 'dba-password=s', 'datafile=s', - 'datadir=s' -); - -unless ( $args{'action'} ) { - help(); - exit(-1); -} - -$| = 1; #unbuffer that output. - -require RT::Handle; -my $Handle = RT::Handle->new($RT::DatabaseType); -$Handle->BuildDSN; -my $dbh; - -if ( $args{'prompt-for-dba-password'} ) { - $args{'dba-password'} = get_dba_password(); - chomp( $args{'dba-password'} ); -} - -if ( $args{'action'} eq 'init' ) { - $dbh = DBI->connect( get_system_dsn(), $args{'dba'}, $args{'dba-password'} ) - || die "Failed to connect to " . get_system_dsn() . " as $args{'dba'}: $DBI::errstr"; - print "Now creating a database for RT.\n"; - if ( $RT::DatabaseType ne 'Oracle' || $args{'dba'} ne $RT::DatabaseUser ) { - create_db(); - } else { - print "...skipped as ".$args{'dba'} ." is not " . $RT::DatabaseUser . " or we're working with Oracle.\n"; - } - - if ( $RT::DatabaseType eq "mysql" ) { - # Check which version we're running - my ($version) = $dbh->selectrow_hashref("show variables like 'version'")->{Value} =~ /^(\d\.\d+)/; - print "*** Warning: RT is unsupported on MySQL versions before 4.0.x\n" if $version < 4; - - # MySQL must have InnoDB support - my $innodb = $dbh->selectrow_hashref("show variables like 'have_innodb'")->{Value}; - if ( $innodb eq "NO" ) { - die "RT requires that MySQL be compiled with InnoDB table support.\n". - "See http://dev.mysql.com/doc/mysql/en/InnoDB.html\n"; - } elsif ( $innodb eq "DISABLED" ) { - die "RT requires that MySQL InnoDB table support be enabled.\n". - ($version < 4 - ? "Add 'innodb_data_file_path=ibdata1:10M:autoextend' to the [mysqld] section of my.cnf\n" - : "Remove the 'skip-innodb' line from your my.cnf file, restart MySQL, and try again.\n"); - } - } - - # SQLite can't deal with the disconnect/reconnect - unless ( $RT::DatabaseType eq 'SQLite' ) { - - $dbh->disconnect; - - if ( $RT::DatabaseType eq "Oracle" ) { - $RT::DatabasePassword = $RT::DatabasePassword; #Warning avidance - $dbh = DBI->connect( $Handle->DSN, ${RT::DatabaseUser}, ${RT::DatabasePassword} ) || die $DBI::errstr; - } else { - $dbh = DBI->connect( $Handle->DSN, $args{'dba'}, $args{'dba-password'} ) || die $DBI::errstr; - } - } - print "Now populating database schema.\n"; - insert_schema(); - print "Now inserting database ACLs\n"; - insert_acl() unless $RT::DatabaseType eq 'Oracle'; - print "Now inserting RT core system objects\n"; - insert_initial_data(); - print "Now inserting RT data\n"; - insert_data( $RT::EtcPath . "/initialdata" ); -} -elsif ( $args{'action'} eq 'drop' ) { - unless ( $dbh = - DBI->connect( get_system_dsn(), $args{'dba'}, $args{'dba-password'} ) ) - { - warn $DBI::errstr; - warn "Database doesn't appear to exist. Aborting database drop."; - exit; - } - drop_db(); -} -elsif ( $args{'action'} eq 'insert' ) { - insert_data( $args{'datafile'} || ($args{'datadir'}."/content") ); -} -elsif ( $args{'action'} eq 'acl' ) { - $dbh = DBI->connect( $Handle->DSN, $args{'dba'}, $args{'dba-password'} ) - || die "Failed to connect to " . get_system_dsn() . " as $args{'dba'}: $DBI::errstr"; - insert_acl($args{'datadir'}); -} -elsif ( $args{'action'} eq 'schema' ) { - $dbh = DBI->connect( $Handle->DSN, $args{'dba'}, $args{'dba-password'} ) - || die "Failed to connect to " . get_system_dsn() . " as $args{'dba'}: $DBI::errstr"; - insert_schema($args{'datadir'}); -} -else { - print STDERR "$0 called with an invalid --action parameter\n"; - exit(-1); -} - -# {{{ sub insert_schema -sub insert_schema { - my $base_path = (shift || $RT::EtcPath); - my (@schema); - print "Creating database schema.\n"; - - my $schema_file = $base_path . "/schema." . $RT::DatabaseType; - if ( -f $schema_file ) { - open( SCHEMA, "<$schema_file" ) or die "Can't open $schema_file: $!"; - my @lines = <SCHEMA>; - - my $local_schema_file = $RT::LocalEtcPath . "/schema." . $RT::DatabaseType; - if (-f $local_schema_file) { - open( SCHEMA_LOCAL, "<$local_schema_file" ) - or die "Can't open $local_schema_file: $!"; - push @lines, ';;', <SCHEMA_LOCAL>; - } - - my $statement = ""; - foreach my $line (@lines) { - $line =~ s/\#.*//g; - $line =~ s/--.*//g; - $statement .= $line; - if ( $line =~ /;(\s*)$/ ) { - $statement =~ s/;(\s*)$//g; - push @schema, $statement; - $statement = ""; - } - } - - local $SIG{__WARN__} = sub {}; - my $is_local = 0; # local/etc/schema needs to be nonfatal. - $dbh->begin_work or die $dbh->errstr; - foreach my $statement (@schema) { - if ( $statement =~ /^\s*;$/ ) { $is_local = 1; next; } - - print STDERR "SQL: $statement\n" if defined $args{'debug'}; - my $sth = $dbh->prepare($statement) or die $dbh->errstr; - unless ( $sth->execute or $is_local ) { - die "Problem with statement:\n $statement\n" . $sth->errstr; - } - } - $dbh->commit or die $dbh->errstr; - } - else { - die "Couldn't find schema file for " . $RT::DatabaseType . "\n"; - } - print "Done setting up database schema.\n"; -} - -# }}} - -# {{{ sub drop_db -sub drop_db { - if ( $RT::DatabaseType eq 'Oracle' ) { - print <<END; - -To delete the tables and sequences of the RT Oracle database by running - \@etc/drop.Oracle -through SQLPlus. - -END - return; - } - unless ( $args{'force'} ) { - print <<END; - -About to drop $RT::DatabaseType database $RT::DatabaseName on $RT::DatabaseHost. -WARNING: This will erase all data in $RT::DatabaseName. - -END - exit unless _yesno(); - - } - - print "Dropping $RT::DatabaseType database $RT::DatabaseName.\n"; - - if ( $RT::DatabaseType eq 'SQLite' ) { - unlink $RT::DatabaseName or warn $!; - return; - } - $dbh->do("Drop DATABASE $RT::DatabaseName") or warn $DBI::errstr; -} - -# }}} - -# {{{ sub create_db -sub create_db { - print "Creating $RT::DatabaseType database $RT::DatabaseName.\n"; - if ( $RT::DatabaseType eq 'SQLite' ) { - return; - } - elsif ( $RT::DatabaseType eq 'Pg' ) { - $dbh->do("CREATE DATABASE $RT::DatabaseName WITH ENCODING='UNICODE'"); - if ( $DBI::errstr ) { - $dbh->do("CREATE DATABASE $RT::DatabaseName") || die $DBI::errstr; - } - } - elsif ( $RT::DatabaseType eq 'Oracle' ) { - insert_acl(); - } - elsif ( $RT::DatabaseType eq 'Informix' ) { - $ENV{DB_LOCALE} = 'en_us.utf8'; - $dbh->do("CREATE DATABASE $RT::DatabaseName WITH BUFFERED LOG"); - } - else { - $dbh->do("CREATE DATABASE $RT::DatabaseName") or die $DBI::errstr; - } -} - -# }}} - -sub get_dba_password { - print "In order to create or update your RT database,"; - print "this script needs to connect to your " - . $RT::DatabaseType - . " instance on " - . $RT::DatabaseHost . " as " - . $args{'dba'} . ".\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: "; - ReadMode('noecho'); - my $password = ReadLine(0); - ReadMode('normal'); - print "\n"; - return ($password); -} - -# {{{ sub _yesno -sub _yesno { - print "Proceed [y/N]:"; - my $x = scalar(<STDIN>); - $x =~ /^y/i; -} - -# }}} - -# {{{ insert_acls -sub insert_acl { - my $base_path = (shift || $RT::EtcPath); - - if ( $RT::DatabaseType =~ /^oracle$/i ) { - do $base_path . "/acl.Oracle" - || die "Couldn't find ACLS for Oracle\n" . $@; - } - elsif ( $RT::DatabaseType =~ /^pg$/i ) { - do $base_path . "/acl.Pg" || die "Couldn't find ACLS for Pg\n" . $@; - } - elsif ( $RT::DatabaseType =~ /^mysql$/i ) { - do $base_path . "/acl.mysql" - || die "Couldn't find ACLS for mysql in $base_path\n" . $@; - } - elsif ( $RT::DatabaseType =~ /^Sybase$/i ) { - do $base_path . "/acl.Sybase" - || die "Couldn't find ACLS for Sybase in $base_path\n" . $@; - } - elsif ( $RT::DatabaseType =~ /^informix$/i ) { - do $base_path . "/acl.Informix" - || die "Couldn't find ACLS for Informix in $base_path\n" . $@; - } - elsif ( $RT::DatabaseType =~ /^SQLite$/i ) { - return; - } - else { - die "Unknown RT database type"; - } - - my @acl = acl($dbh); - foreach my $statement (@acl) { - print STDERR $statement if $args{'debug'}; - my $sth = $dbh->prepare($statement) or die $dbh->errstr; - unless ( $sth->execute ) { - die "Problem with statement:\n $statement\n" . $sth->errstr; - } - } - print "Done setting up database ACLs.\n"; -} - -# }}} - -=head2 get_system_dsn - -Returns a dsn suitable for database creates and drops -and user creates and drops - -=cut - -sub get_system_dsn { - - my $dsn = $Handle->DSN; - - #with mysql, you want to connect sans database to funge things - if ( $RT::DatabaseType eq 'mysql' ) { - $dsn =~ s/dbname=$RT::DatabaseName//; - - # with postgres, you want to connect to database1 - } - elsif ( $RT::DatabaseType eq 'Pg' ) { - $dsn =~ s/dbname=$RT::DatabaseName/dbname=template1/; - } - elsif ( $RT::DatabaseType eq 'Informix' ) { - # with Informix, you want to connect sans database: - $dsn =~ s/Informix:$RT::DatabaseName/Informix:/; - } - return $dsn; -} - -sub insert_initial_data { - - RT::InitLogging(); - - #connect to the db, for actual RT work - require RT::Handle; - $RT::Handle = RT::Handle->new(); - $RT::Handle->Connect(); - - #Put together a current user object so we can create a User object - my $CurrentUser = new RT::CurrentUser(); - - print "Checking for existing system user..."; - my $test_user = RT::User->new($CurrentUser); - $test_user->Load('RT_System'); - if ( $test_user->id ) { - print "found!\n\nYou appear to have a functional RT database.\n" - . "Exiting, so as not to clobber your existing data.\n"; - exit(-1); - - } - else { - print "not found. This appears to be a new installation.\n"; - } - - print "Creating system user..."; - my $RT_System = new RT::User($CurrentUser); - - my ( $val, $msg ) = $RT_System->_BootstrapCreate( - Name => 'RT_System', - RealName => 'The RT System itself', - Comments => -'Do not delete or modify this user. It is integral to RT\'s internal database structures', - Creator => '1', - LastUpdatedBy => '1', - ); - - unless ( $val ) { - print "$msg\n"; - exit(-1); - } - print "done.\n"; - $RT::Handle->Disconnect() unless $RT::DatabaseType eq 'SQLite'; - -} - -# load some sort of data into the database - -sub insert_data { - my $datafile = shift; - - #Connect to the database and get RT::SystemUser and RT::Nobody loaded - RT::Init; - - my $CurrentUser = RT::CurrentUser->new(); - $CurrentUser->LoadByName('RT_System'); - - if ( $datafile eq $RT::EtcPath . "/initialdata" ) { - - print "Creating Superuser ACL..."; - - my $superuser_ace = RT::ACE->new($CurrentUser); - $superuser_ace->_BootstrapCreate( - PrincipalId => ACLEquivGroupId( $CurrentUser->Id ), - PrincipalType => 'Group', - RightName => 'SuperUser', - ObjectType => 'RT::System', - ObjectId => '1' ); - - print "done.\n"; - } - - # Slurp in stuff to insert from the datafile. Possible things to go in here:- - # @groups, @users, @acl, @queues, @ScripActions, @ScripConditions, @templates - - require $datafile - || die "Couldn't find initial data for import\n" . $@; - - if ( @Groups ) { - print "Creating groups..."; - foreach $item (@Groups) { - my $new_entry = RT::Group->new($CurrentUser); - my ( $return, $msg ) = $new_entry->_Create(%$item); - print "(Error: $msg)" unless $return; - print $return. "."; - } - print "done.\n"; - } - if ( @Users ) { - print "Creating users..."; - foreach $item (@Users) { - my $new_entry = new RT::User($CurrentUser); - my ( $return, $msg ) = $new_entry->Create(%$item); - print "(Error: $msg)" unless $return; - print $return. "."; - } - print "done.\n"; - } - if ( @Queues ) { - print "Creating queues..."; - for $item (@Queues) { - my $new_entry = new RT::Queue($CurrentUser); - my ( $return, $msg ) = $new_entry->Create(%$item); - print "(Error: $msg)" unless $return; - print $return. "."; - } - print "done.\n"; - } - if ( @ACL ) { - print "Creating ACL..."; - for my $item (@ACL) { - - my ($princ, $object); - - # Global rights or Queue rights? - if ( $item->{'Queue'} ) { - $object = RT::Queue->new($CurrentUser); - $object->Load( $item->{'Queue'} ); - } else { - $object = $RT::System; - } - - # Group rights or user rights? - if ( $item->{'GroupDomain'} ) { - $princ = RT::Group->new($CurrentUser); - if ( $item->{'GroupDomain'} eq 'UserDefined' ) { - $princ->LoadUserDefinedGroup( $item->{'GroupId'} ); - } elsif ( $item->{'GroupDomain'} eq 'SystemInternal' ) { - $princ->LoadSystemInternalGroup( $item->{'GroupType'} ); - } elsif ( $item->{'GroupDomain'} eq 'RT::System-Role' ) { - $princ->LoadSystemRoleGroup( $item->{'GroupType'} ); - } elsif ( $item->{'GroupDomain'} eq 'RT::Queue-Role' && - $item->{'Queue'} ) - { - $princ->LoadQueueRoleGroup( Type => $item->{'GroupType'}, - Queue => $object->id); - } else { - $princ->Load( $item->{'GroupId'} ); - } - } else { - $princ = RT::User->new($CurrentUser); - $princ->Load( $item->{'UserId'} ); - } - - # Grant it - my ( $return, $msg ) = $princ->PrincipalObj->GrantRight( - Right => $item->{'Right'}, - Object => $object ); - - if ( $return ) { - print $return. "."; - } - else { - print $msg . "."; - - } - - } - print "done.\n"; - } - if ( @CustomFields ) { - print "Creating custom fields..."; - for $item (@CustomFields) { - my $new_entry = new RT::CustomField($CurrentUser); - my $values = $item->{'Values'}; - delete $item->{'Values'}; - my ( $return, $msg ) = $new_entry->Create(%$item); - unless( $return ) { - print "(Error: $msg)\n"; - next; - } - - foreach my $value ( @{$values} ) { - my ( $eval, $emsg ) = $new_entry->AddValue(%$value); - print "(Error: $emsg)\n" unless $eval; - } - - if ( $item->{LookupType} && !exists $item->{'Queue'} ) { # enable by default - my $ocf = RT::ObjectCustomField->new($CurrentUser); - $ocf->Create( CustomField => $new_entry->Id ); - } - - print "(Error: $msg)\n" unless $return; - print $return. "."; - } - - print "done.\n"; - } - - if ( @ScripActions ) { - print "Creating ScripActions..."; - - for $item (@ScripActions) { - my $new_entry = RT::ScripAction->new($CurrentUser); - my ($return,$msg) = $new_entry->Create(%$item); - unless ($return) { - print "(Error: $msg)\n"; - next; - } - print $return. "."; - } - - print "done.\n"; - } - - if ( @ScripConditions ) { - print "Creating ScripConditions..."; - - for $item (@ScripConditions) { - my $new_entry = RT::ScripCondition->new($CurrentUser); - my ($return,$msg) = $new_entry->Create(%$item); - unless ($return) { - print "(Error: $msg)\n"; - next; - } - print $return. "."; - } - - print "done.\n"; - } - - if ( @Templates ) { - print "Creating templates..."; - - for $item (@Templates) { - my $new_entry = new RT::Template($CurrentUser); - my $return = $new_entry->Create(%$item); - print $return. "."; - } - print "done.\n"; - } - if ( @Scrips ) { - print "Creating scrips..."; - - for $item (@Scrips) { - my $new_entry = new RT::Scrip($CurrentUser); - my ( $return, $msg ) = $new_entry->Create(%$item); - if ( $return ) { - print $return. "."; - } - else { - print "(Error: $msg)\n"; - } - } - print "done.\n"; - } - if ( @Attributes ) { - print "Creating predefined searches..."; - my $sys = RT::System->new($CurrentUser); - - for $item (@Attributes) { - my $obj = delete $item->{Object}; # XXX: make this something loadable - $obj ||= $sys; - my ( $return, $msg ) = $obj->AddAttribute (%$item); - if ( $return ) { - print $return. "."; - } - else { - print "(Error: $msg)\n"; - } - } - print "done.\n"; - } - $RT::Handle->Disconnect() unless $RT::DatabaseType eq 'SQLite'; - print "Done setting up database content.\n"; -} - -=head2 ACLEquivGroupId - -Given a userid, return that user's acl equivalence group - -=cut - -sub ACLEquivGroupId { - my $username = shift; - my $user = RT::User->new($RT::SystemUser); - $user->Load($username); - my $equiv_group = RT::Group->new($RT::SystemUser); - $equiv_group->LoadACLEquivalenceGroup($user); - return ( $equiv_group->Id ); -} - -sub help { - - print <<EOF; - -$0: Set up RT's database - ---action init Initialize the database - drop Drop the database. - This will ERASE ALL YOUR DATA - 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. - - acl Initialize only the database ACLs - To use a local or supplementary datafile, specify it - using the '--datadir' option below. - - schema Initialize only the database schema - To use a local or supplementary datafile, specify it - using the '--datadir' option below. - ---datafile /path/to/datafile ---datadir /path/to/ Used to specify a path to find the local - database schema and acls to be installed. - - ---dba dba's username ---dba-password dba's password ---prompt-for-dba-password Ask for the database administrator's password interactively - - -EOF - -} - -1; diff --git a/rt/sbin/rt-setup-database.in b/rt/sbin/rt-setup-database.in index f134f5b84..cf607e286 100644 --- a/rt/sbin/rt-setup-database.in +++ b/rt/sbin/rt-setup-database.in @@ -3,7 +3,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC # <jesse@bestpractical.com> # # (Except where explicitly superseded by other copyright notices) @@ -25,7 +25,7 @@ # 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. +# http://www.gnu.org/copyleft/gpl.html. # # # CONTRIBUTION SUBMISSION POLICY: @@ -160,6 +160,9 @@ elsif ( $args{'action'} eq 'drop' ) { } drop_db(); } +elsif ( $args{'action'} eq 'insert_initial' ) { + insert_initial_data(); +} elsif ( $args{'action'} eq 'insert' ) { insert_data( $args{'datafile'} || ($args{'datadir'}."/content") ); } @@ -677,7 +680,9 @@ $0: Set up RT's database --action init Initialize the database drop Drop the database. This will ERASE ALL YOUR DATA - insert Insert data into RT's database. + insert_initial + Insert RT's core system objects + 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. diff --git a/rt/sbin/rt-test-dependencies b/rt/sbin/rt-test-dependencies deleted file mode 100644 index fb14f8459..000000000 --- a/rt/sbin/rt-test-dependencies +++ /dev/null @@ -1,481 +0,0 @@ -#!/usr/bin/perl -# BEGIN BPS TAGGED BLOCK {{{ -# -# COPYRIGHT: -# -# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC -# <jesse@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 }}} -# -# This is just a basic script that checks to make sure that all -# the modules needed by RT before you can install it. -# - -use strict; -no warnings qw(numeric redefine); -use Getopt::Long; -my %args; -my %deps; -GetOptions( - \%args, 'v|verbose', - 'install', 'with-MYSQL', - 'with-POSTGRESQL|with-pg|with-pgsql', 'with-SQLITE', - 'with-ORACLE', 'with-FASTCGI', - 'with-SPEEDYCGI', 'with-MODPERL1', - 'with-MODPERL2', 'with-DEV', - 'with-STANDALONE', - 'download=s', - 'repository=s' -); - -unless (keys %args) { - help(); - exit(0); -} -# Set up defaults -my %default = ( - 'with-MASON' => 1, - 'with-CORE' => 1, - 'with-CLI' => 1, - 'with-MAILGATE' => 1, - 'with-DEV' => 0, - 'with-STANDALONE' => 0, -); -$args{$_} = $default{$_} foreach grep !exists $args{$_}, keys %default; - - -{ - my $section; - my %always_show_sections = ( - perl => 1, - users => 1, - ); - - sub section { - my $s = shift; - $section = $s; - print "$s:\n"; - } - - my $any_missing = 0; - sub found { - my $msg = shift; - my $test = shift; - my $extra = shift; - - $any_missing = 1 unless $test; - if ($args{'v'} or not $test or $always_show_sections{$section}) { - print "\t$msg..."; - print $test ? "found" : "MISSING"; - print "\n"; - } - - print "\t\t$extra\n" if defined $extra; - } - - sub conclude { - if ($any_missing) { - print "\nSOMETHING WAS MISSING!\n"; - exit 1; - } else { - print "\nEverything was found.\n"; - } - } -} - -sub help { - - print <<'.'; - -By default, testdeps determine whether you have -installed all the perl modules RT needs to run. - - --install Install missing modules - -The following switches will tell the tool to check for specific dependencies - - --with-mysql Database interface for MySQL - --with-postgresql Database interface for PostgreSQL - --with-sqlite Database interface and driver for SQLite (unsupported) - --with-oracle Database interface for oracle (unsupported) - - --with-standalone Libraries needed to support the standalone simple pure perl server - --with-fastcgi Libraries needed to support the fastcgi handler - --with-speedycgi Libraries needed to support the speedycgi handler - --with-modperl1 Libraries needed to support the modperl 1 handler - --with-modperl2 Libraries needed to support the modperl 2 handler - - --with-dev Tools needed for RT development - -You can also specify -v or --verbose to list the status of all dependencies, -rather than just the missing ones. - -The "RT_FIX_DEPS_CMD" environment variable, if set, will be used -instead of the standard CPAN shell by --install to install any -required modules. It will be called with the module name, or, if -"RT_FIX_DEPS_CMD" contains a "%s", will replace the "%s" with the -module name before calling the program. -. -} - - -sub text_to_hash { - my %hash; - for my $line ( split /\n/, $_[0] ) { - my($key, $value) = $line =~ /(\S+)\s*(\S*)/; - $value ||= ''; - $hash{$key} = $value; - } - - return %hash; -} - -$deps{'CORE'} = [ text_to_hash( << '.') ]; -Digest::base -Digest::MD5 2.27 -DBI 1.37 -Class::ReturnValue 0.40 -Date::Format -DBIx::SearchBuilder 1.53 -Text::Template -File::Spec 0.8 -HTML::Entities -HTML::Scrubber 0.08 -Log::Dispatch 2.0 -Locale::Maketext 1.06 -Locale::Maketext::Lexicon 0.32 -Locale::Maketext::Fuzzy -MIME::Entity 5.108 -Mail::Mailer 1.57 -Net::SMTP -Text::Wrapper -Time::ParseDate -Time::HiRes -File::Temp -Text::Autoformat -Text::Quoted 2.02 -Tree::Simple 1.04 -Regexp::Common -Scalar::Util -Module::Versions::Report 1.03 -Cache::Simple::TimedExpiry -UNIVERSAL::require -Calendar::Simple -CSS::Squish 0.06 -Devel::StackTrace 1.19 -. - -$deps{'MASON'} = [ text_to_hash( << '.') ]; -HTML::Mason 1.23 -Errno -Digest::MD5 2.27 -CGI::Cookie 1.20 -Storable 2.08 -Apache::Session 1.53 -XML::RSS 1.05 -GD -GD::Graph -GD::Text -Text::WikiFormat 0.76 -CSS::Squish 0.06 -. - -$deps{'STANDALONE'} = [ text_to_hash( << '.') ]; -HTTP::Server::Simple 0.07 -HTTP::Server::Simple::Mason 0.09 -. - -$deps{'MAILGATE'} = [ text_to_hash( << '.') ]; -HTML::TreeBuilder -HTML::FormatText -Getopt::Long -LWP::UserAgent -Pod::Usage -. - -$deps{'CLI'} = [ text_to_hash( << '.') ]; -Getopt::Long 2.24 -LWP -HTTP::Request::Common -Text::ParseWords -Term::ReadLine -Term::ReadKey -. - -$deps{'DEV'} = [ text_to_hash( << '.') ]; -Test::Inline -Apache::Test -HTML::Form -HTML::TokeParser -WWW::Mechanize -Test::WWW::Mechanize 1.04 -Module::Refresh 0.03 -Test::Expect 0.30 -XML::Simple -File::Find -. - -$deps{'FASTCGI'} = [ text_to_hash( << '.') ]; -CGI 2.92 -FCGI -CGI::Fast -. - -$deps{'SPEEDYCGI'} = [ text_to_hash( << '.') ]; -CGI 2.92 -CGI::SpeedyCGI -. - - -$deps{'MODPERL1'} = [ text_to_hash( << '.') ]; -CGI 2.92 -Apache::Request -Apache::DBI 0.92 -. - -$deps{'MODPERL2'} = [ text_to_hash( << '.') ]; -CGI 3.10 -Apache::DBI -HTML::Mason 1.31 -. - -$deps{'MYSQL'} = [ text_to_hash( << '.') ]; -DBD::mysql 2.1018 -. -$deps{'ORACLE'} = [ text_to_hash( << '.') ]; -DBD::Oracle -. -$deps{'POSTGRESQL'} = [ text_to_hash( << '.') ]; -DBD::Pg 1.43 -. - -$deps{'SQLITE'} = [ text_to_hash( << '.') ]; -DBD::SQLite 1.00 -. - -if ($args{'download'}) { - - download_mods(); -} - - -check_perl_version(); - -check_users(); - - -foreach my $type (sort grep $args{$_}, keys %args) { - next unless ($type =~ /^with-(.*?)$/); - - $type = $1; - section("$type dependencies"); - - my @missing; - my @deps = @{ $deps{$type} }; - while (@deps) { - my $module = shift @deps; - my $version = shift @deps; - my $ret = test_dep($module, $version); - - push @missing, $module, $version unless $ret; - } - if ( $args{'install'} ) { - while( @missing ) { - resolve_dep(shift @missing, shift @missing); - } - } -} - -conclude(); - -sub test_dep { - my $module = shift; - my $version = shift; - - eval "use $module $version ()"; - if ($@) { - my $error = $@; - $error =~ s/\n(.*)$//s; - undef $error unless $error =~ /this is only/; - found("$module $version", 0, $error); - - return undef; - } else { - my $msg = "$module"; - $msg .= " >=$version" if $version; - found($msg, 1); - return 1; - } -} - -sub resolve_dep { - my $module = shift; - my $version = shift; - - print "\nInstall module $module\n"; - - my $ext = $ENV{'RT_FIX_DEPS_CMD'}; - unless( $ext ) { - my $configured = 1; - { - local @INC = @INC; - if ( $ENV{'HOME'} ) { - unshift @INC, "$ENV{'HOME'}/.cpan"; - } - $configured = eval { require CPAN::MyConfig } || eval { require CPAN::Config }; - } - unless ( $configured ) { - print <<END; -You didn't configure CPAN shell yet. -Please run `/usr/bin/perl -MCPAN -e shell` tool and configure it. -END - exit(1); - } - my $rv = eval { require CPAN; CPAN::Shell->install($module) }; - return $rv unless $@; - - print <<END; -Failed to load module CPAN. - --------- Error --------- -$@ ------------------------- - -When we tried to start installing RT's perl dependencies, -we were unable to load the CPAN client. This module is usually distributed -with Perl. This usually indicates that your vendor has shipped an unconfigured -or incorrectly configured CPAN client. -The error above may (or may not) give you a hint about what went wrong - -You have several choices about how to install dependencies in -this situatation: - -1) use a different tool to install dependencies by running setting the following - shell environment variable and rerunning this tool: - RT_FIX_DEPS_CMD='/usr/bin/perl -MCPAN -e"install %s"' -2) Attempt to configure CPAN by running: - `/usr/bin/perl -MCPAN -e shell` program from shell. - If this fails, you may have to manually upgrade CPAN (see below) -3) Try to update the CPAN client. Download it from: - http://search.cpan.org/dist/CPAN and try again -4) Install each dependency manually by downloading them one by one from - http://search.cpan.org - -END - exit(1); - } - - if( $ext =~ /\%s/) { - $ext =~ s/\%s/$module/g; # sprintf( $ext, $module ); - } else { - $ext .= " $module"; - } - print "\t\tcommand: '$ext'\n"; - return scalar `$ext 1>&2`; -} - -sub download_mods { - my %modules; - use CPAN; - - foreach my $key (keys %deps) { - my @deps = (@{$deps{$key}}); - while (@deps) { - my $mod = shift @deps; - my $ver = shift @deps; - next if ($mod =~ /^(DBD-|Apache-Request)/); - $modules{$mod} = $ver; - } - } - my @mods = keys %modules; - CPAN::get(); - my $moddir = $args{'download'}; - foreach my $mod (@mods) { - $CPAN::Config->{'build_dir'} = $moddir; - CPAN::get($mod); - } - - opendir(DIR, $moddir); - while ( my $dir = readdir(DIR)) { - print "Dir is $dir\n"; - next if ( $dir =~ /^\.\.?$/); - - # Skip things we've previously tagged - my $out = `svn ls $args{'repository'}/tags/$dir`; - next if ($out); - - if ($dir =~ /^(.*)-(.*?)$/) { - `svn_load_dirs -no_user_input -t tags/$dir -v $args{'repository'} dists/$1 $moddir/$dir`; - `rm -rf $moddir/$dir`; - - } - - } - closedir(DIR); - exit; -} - -sub check_perl_version { - section("perl"); - eval {require 5.008003}; - if ($@) { - found("5.8.3", 0,"RT is known to be non-functional on versions of perl older than 5.8.3. Please upgrade to 5.8.3 or newer."); - exit(1); - } else { - found( ">=5.8.3($])", 1); - } -} - -sub check_users { - section("users"); - found("rt group (www)", defined getgrnam("www")); - found("bin owner (root)", defined getpwnam("root")); - found("libs owner (root)", defined getpwnam("root")); - found("libs group (bin)", defined getgrnam("bin")); - found("web owner (www)", defined getpwnam("www")); - found("web group (www)", defined getgrnam("www")); -} - - - -1; |