#!/usr/bin/perl # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # # This Source Code Form is "Incompatible With Secondary Licenses", as # defined by the Mozilla Public License, v. 2.0. # This file has detailed POD docs, do "perldoc checksetup.pl" to see them. ###################################################################### # Initialization ###################################################################### use 5.10.1; use strict; use warnings; use File::Basename; use File::Spec; BEGIN { require lib; my $dir = File::Spec->rel2abs(dirname(__FILE__)); lib->import($dir, File::Spec->catdir($dir, "lib"), File::Spec->catdir($dir, qw(local lib perl5))); chdir($dir); } use Getopt::Long qw(:config bundling); use Pod::Usage; # Bug 1270550 - Tie::Hash::NamedCapture must be loaded before Safe. use Tie::Hash::NamedCapture; use Safe; use English qw(-no_match_vars $EUID $EGID); use Bugzilla::Constants; use Bugzilla::Install::Requirements; use Bugzilla::Install::Util qw(install_string get_version_and_os init_console success); ###################################################################### # Live Code ###################################################################### # Do not run checksetup.pl from the web browser. Bugzilla::Install::Util::no_checksetup_from_cgi() if $ENV{'SERVER_SOFTWARE'}; # When we're running at the command line, we need to pick the right # language before ever displaying any string. init_console(); my %switch; GetOptions(\%switch, 'help|h|?', 'no-templates|t', 'verbose|v|no-silent', 'cpanm:s', 'check-modules', 'make-admin=s', 'reset-password=s', 'version|V', 'default-localconfig', 'no-database', 'no-permissions|p'); # Print the help message if that switch was selected. pod2usage({-verbose => 1, -exitval => 1}) if $switch{'help'}; # Read in the "answers" file if it exists, for running in # non-interactive mode. my $answers_file = $ARGV[0]; my $silent = $answers_file && !$switch{'verbose'}; print(install_string('header', get_version_and_os()) . "\n") unless $silent; exit 0 if $switch{'version'}; if (defined $switch{cpanm}) { my $default = 'all notest -oracle -mysql -pg -mod_perl -old_charts -new_charts -graphical_reports -detect_charset'; my @features = split(/\s+/, $switch{cpanm} || $default); my @cpanm_args = ('-l', 'local', '--installdeps'); while (my $feature = shift @features) { if ($feature eq 'all') { push @cpanm_args, '--with-all-features'; } elsif ($feature eq 'default') { unshift @features, split(/\s+/, $default); } elsif ($feature eq 'notest' || $feature eq 'skip-satisfied' || $feature eq 'quiet') { push @cpanm_args, "--$feature"; } elsif ($feature =~ /^-(.+)$/) { push @cpanm_args, "--without-feature=$1"; } else { push @cpanm_args, "--with-feature=$feature"; } } print "cpanm @cpanm_args \".\"\n" if !$silent; my $rv = system('cpanm', @cpanm_args, '.'); exit 1 if $rv != 0; } $ENV{PERL_MM_USE_DEFAULT} = 1; $ENV{BZ_SILENT_MAKEFILE} = 1; system($^X, "Makefile.PL"); if (! -f "MYMETA.json") { die "Makefile.PL failed to generate a MYMETA.json file.", "Try upgrading ExtUtils::MakeMaker"; } require Bugzilla::CPAN; my $meta = Bugzilla::CPAN->cpan_meta; if (keys %{$meta->{optional_features}} < 1) { die "Your version of ExtUtils::MakeMaker is too old or broken\n"; } my $requirements = check_cpan_requirements($meta, [@INC], !$silent); exit 1 unless $requirements->{ok}; check_all_cpan_features($meta, [@INC], !$silent); exit 0 if $switch{'check-modules'}; ########################################################################### # Load Bugzilla Modules ########################################################################### # It's never safe to "use" a Bugzilla module in checksetup. If a module # prerequisite is missing, and you "use" a module that requires it, # then instead of our nice normal checksetup message, the user would # get a cryptic perl error about the missing module. require Bugzilla; require Bugzilla::User; require Bugzilla::Util; import Bugzilla::Util qw(get_text); require Bugzilla::Config; import Bugzilla::Config qw(:admin); require Bugzilla::Install::Localconfig; import Bugzilla::Install::Localconfig qw(update_localconfig); require Bugzilla::Install::Filesystem; import Bugzilla::Install::Filesystem qw(update_filesystem create_htaccess fix_all_file_permissions); require Bugzilla::Install::DB; require Bugzilla::DB; require Bugzilla::Template; require Bugzilla::Field; require Bugzilla::Install; Bugzilla->installation_mode(INSTALLATION_MODE_NON_INTERACTIVE) if $answers_file; Bugzilla->installation_answers($answers_file); ########################################################################### # Check and update --LOCAL-- configuration ########################################################################### unless ($ENV{LOCALCONFIG_ENV}) { print "Reading " . bz_locations()->{'localconfig'} . "...\n" unless $silent; update_localconfig({ output => !$silent, use_defaults => $switch{'default-localconfig'} }); } my $lc_hash = Bugzilla->localconfig; if ( $EUID == 0 && $lc_hash->{webservergroup} && !ON_WINDOWS ) { # So checksetup was run as root, and we have a webserver group set. # Let's assume the user wants us to make files that are writable # by the webserver group. $EGID = getgrnam $lc_hash->{webservergroup}; ## no critic (Variables::RequireLocalizedPunctuationVars) umask 002 or die "failed to set umask 002: $!"; } unless ($switch{'no-database'}) { die "urlbase is not set\n" unless $lc_hash->{urlbase}; die "urlbase must end with slash\n" unless $lc_hash->{urlbase} =~ m{/$}ms; if ($lc_hash->{attachment_base}) { die "attachment_base must end with slash\n" unless $lc_hash->{attachment_base} =~ m{/$}ms; } } ########################################################################### # Check --DATABASE-- setup ########################################################################### # At this point, localconfig is defined and is readable. So we know # everything we need to create the DB. We have to create it early, # because some data required to populate data/params.json is stored in the DB. unless ($switch{'no-database'}) { Bugzilla::DB::bz_check_requirements(!$silent); Bugzilla::DB::bz_create_database() if $lc_hash->{'db_check'}; # now get a handle to the database: my $dbh = Bugzilla->dbh; # Clear all keys from Memcached to ensure we see the correct schema. Bugzilla->memcached->clear_all(); # Create the tables, and do any database-specific schema changes. $dbh->bz_setup_database(); # Populate the tables that hold the values for the