r/a=mkanat git-svn-id: svn://10.0.0.236/trunk@263006 18797224-902f-48f8-a5cc-f745e15eee43
382 lines
12 KiB
Perl
382 lines
12 KiB
Perl
# -*- Mode: perl; indent-tabs-mode: nil -*-
|
|
#
|
|
# The contents of this file are subject to the Mozilla Public
|
|
# License Version 1.1 (the "License"); you may not use this file
|
|
# except in compliance with the License. You may obtain a copy of
|
|
# the License at http://www.mozilla.org/MPL/
|
|
#
|
|
# Software distributed under the License is distributed on an "AS
|
|
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
# implied. See the License for the specific language governing
|
|
# rights and limitations under the License.
|
|
#
|
|
# The Initial Developer of the Original Code is Everything Solved.
|
|
# Portions created by Everything Solved are Copyright (C) 2006
|
|
# Everything Solved. All Rights Reserved.
|
|
#
|
|
# The Original Code is the Bugzilla Bug Tracking System.
|
|
#
|
|
# Contributor(s): Max Kanat-Alexander <mkanat@bugzilla.org>
|
|
|
|
package Bugzilla::Install::Localconfig;
|
|
|
|
# NOTE: This package may "use" any modules that it likes. However,
|
|
# all functions in this package should assume that:
|
|
#
|
|
# * The data/ directory does not exist.
|
|
# * Templates are not available.
|
|
# * Files do not have the correct permissions
|
|
# * The database is not up to date
|
|
|
|
use strict;
|
|
|
|
use Bugzilla::Constants;
|
|
use Bugzilla::Install::Util qw(bin_loc install_string);
|
|
use Bugzilla::Util qw(generate_random_password);
|
|
|
|
use Data::Dumper;
|
|
use File::Basename qw(dirname);
|
|
use Safe;
|
|
|
|
use base qw(Exporter);
|
|
|
|
our @EXPORT_OK = qw(
|
|
read_localconfig
|
|
update_localconfig
|
|
);
|
|
|
|
use constant LOCALCONFIG_VARS => (
|
|
{
|
|
name => 'create_htaccess',
|
|
default => 1,
|
|
},
|
|
{
|
|
name => 'webservergroup',
|
|
default => ON_WINDOWS ? '' : 'apache',
|
|
},
|
|
{
|
|
name => 'use_suexec',
|
|
default => 0,
|
|
},
|
|
{
|
|
name => 'db_driver',
|
|
default => 'mysql',
|
|
},
|
|
{
|
|
name => 'db_host',
|
|
default => 'localhost',
|
|
},
|
|
{
|
|
name => 'db_name',
|
|
default => 'bugs',
|
|
},
|
|
{
|
|
name => 'db_user',
|
|
default => 'bugs',
|
|
},
|
|
{
|
|
name => 'db_pass',
|
|
default => '',
|
|
},
|
|
{
|
|
name => 'db_port',
|
|
default => 0,
|
|
},
|
|
{
|
|
name => 'db_sock',
|
|
default => '',
|
|
},
|
|
{
|
|
name => 'db_check',
|
|
default => 1,
|
|
},
|
|
{
|
|
name => 'index_html',
|
|
default => 0,
|
|
},
|
|
{
|
|
name => 'cvsbin',
|
|
default => sub { bin_loc('cvs') },
|
|
},
|
|
{
|
|
name => 'interdiffbin',
|
|
default => sub { bin_loc('interdiff') },
|
|
},
|
|
{
|
|
name => 'diffpath',
|
|
default => sub { dirname(bin_loc('diff')) },
|
|
},
|
|
{
|
|
name => 'site_wide_secret',
|
|
# 64 characters is roughly the equivalent of a 384-bit key, which
|
|
# is larger than anybody would ever be able to brute-force.
|
|
default => sub { generate_random_password(64) },
|
|
},
|
|
);
|
|
|
|
sub read_localconfig {
|
|
my ($include_deprecated) = @_;
|
|
my $filename = bz_locations()->{'localconfig'};
|
|
|
|
my %localconfig;
|
|
if (-e $filename) {
|
|
my $s = new Safe;
|
|
# Some people like to store their database password in another file.
|
|
$s->permit('dofile');
|
|
|
|
$s->rdo($filename);
|
|
if ($@ || $!) {
|
|
my $err_msg = $@ ? $@ : $!;
|
|
die install_string('error_localconfig_read',
|
|
{ error => $err_msg, localconfig => $filename }), "\n";
|
|
}
|
|
|
|
my @read_symbols;
|
|
if ($include_deprecated) {
|
|
# First we have to get the whole symbol table
|
|
my $safe_root = $s->root;
|
|
my %safe_package;
|
|
{ no strict 'refs'; %safe_package = %{$safe_root . "::"}; }
|
|
# And now we read the contents of every var in the symbol table.
|
|
# However:
|
|
# * We only include symbols that start with an alphanumeric
|
|
# character. This excludes symbols like "_<./localconfig"
|
|
# that show up in some perls.
|
|
# * We ignore the INC symbol, which exists in every package.
|
|
# * Perl 5.10 imports a lot of random symbols that all
|
|
# contain "::", and we want to ignore those.
|
|
@read_symbols = grep { /^[A-Za-z0-1]/ and !/^INC$/ and !/::/ }
|
|
(keys %safe_package);
|
|
}
|
|
else {
|
|
@read_symbols = map($_->{name}, LOCALCONFIG_VARS);
|
|
}
|
|
foreach my $var (@read_symbols) {
|
|
my $glob = $s->varglob($var);
|
|
# We can't get the type of a variable out of a Safe automatically.
|
|
# We can only get the glob itself. So we figure out its type this
|
|
# way, by trying first a scalar, then an array, then a hash.
|
|
#
|
|
# The interesting thing is that this converts all deprecated
|
|
# array or hash vars into hashrefs or arrayrefs, but that's
|
|
# fine since as I write this all modern localconfig vars are
|
|
# actually scalars.
|
|
if (defined $$glob) {
|
|
$localconfig{$var} = $$glob;
|
|
}
|
|
elsif (@$glob) {
|
|
$localconfig{$var} = \@$glob;
|
|
}
|
|
elsif (%$glob) {
|
|
$localconfig{$var} = \%$glob;
|
|
}
|
|
}
|
|
}
|
|
|
|
return \%localconfig;
|
|
}
|
|
|
|
|
|
#
|
|
# This is quite tricky. But fun!
|
|
#
|
|
# First we read the file 'localconfig'. Then we check if the variables we
|
|
# need are defined. If not, we will append the new settings to
|
|
# localconfig, instruct the user to check them, and stop.
|
|
#
|
|
# Why do it this way?
|
|
#
|
|
# Assume we will enhance Bugzilla and eventually more local configuration
|
|
# stuff arises on the horizon.
|
|
#
|
|
# But the file 'localconfig' is not in the Bugzilla CVS or tarfile. You
|
|
# know, we never want to overwrite your own version of 'localconfig', so
|
|
# we can't put it into the CVS/tarfile, can we?
|
|
#
|
|
# Now, when we need a new variable, we simply add the necessary stuff to
|
|
# LOCALCONFIG_VARS. When the user gets the new version of Bugzilla from CVS and
|
|
# runs checksetup, it finds out "Oh, there is something new". Then it adds
|
|
# some default value to the user's local setup and informs the user to
|
|
# check that to see if it is what the user wants.
|
|
#
|
|
# Cute, ey?
|
|
#
|
|
sub update_localconfig {
|
|
my ($params) = @_;
|
|
|
|
my $output = $params->{output} || 0;
|
|
my $answer = Bugzilla->installation_answers;
|
|
my $localconfig = read_localconfig('include deprecated');
|
|
|
|
my @new_vars;
|
|
foreach my $var (LOCALCONFIG_VARS) {
|
|
my $name = $var->{name};
|
|
my $value = $localconfig->{$name};
|
|
# Regenerate site_wide_secret if it was made by our old, weak
|
|
# generate_random_password. Previously we used to generate
|
|
# a 256-character string for site_wide_secret.
|
|
$value = undef if ($name eq 'site_wide_secret' and defined $value
|
|
and length($value) == 256);
|
|
|
|
if (!defined $value) {
|
|
push(@new_vars, $name);
|
|
$var->{default} = &{$var->{default}} if ref($var->{default}) eq 'CODE';
|
|
if (exists $answer->{$name}) {
|
|
$localconfig->{$name} = $answer->{$name};
|
|
}
|
|
else {
|
|
$localconfig->{$name} = $var->{default};
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!$localconfig->{'interdiffbin'} && $output) {
|
|
print "\n", install_string('patchutils_missing'), "\n";
|
|
}
|
|
|
|
my @old_vars;
|
|
foreach my $var (keys %$localconfig) {
|
|
push(@old_vars, $var) if !grep($_->{name} eq $var, LOCALCONFIG_VARS);
|
|
}
|
|
|
|
my $filename = bz_locations->{'localconfig'};
|
|
|
|
# Move any custom or old variables into a separate file.
|
|
if (scalar @old_vars) {
|
|
my $filename_old = "$filename.old";
|
|
open(my $old_file, ">>:utf8", $filename_old)
|
|
or die "$filename_old: $!";
|
|
local $Data::Dumper::Purity = 1;
|
|
foreach my $var (@old_vars) {
|
|
print $old_file Data::Dumper->Dump([$localconfig->{$var}],
|
|
["*$var"]) . "\n\n";
|
|
}
|
|
close $old_file;
|
|
my $oldstuff = join(', ', @old_vars);
|
|
print install_string('lc_old_vars',
|
|
{ localconfig => $filename, old_file => $filename_old,
|
|
vars => $oldstuff }), "\n";
|
|
}
|
|
|
|
# Re-write localconfig
|
|
open(my $fh, ">:utf8", $filename) or die "$filename: $!";
|
|
foreach my $var (LOCALCONFIG_VARS) {
|
|
my $name = $var->{name};
|
|
my $desc = install_string("localconfig_$name", { root => ROOT_USER });
|
|
chomp($desc);
|
|
# Make the description into a comment.
|
|
$desc =~ s/^/# /mg;
|
|
print $fh $desc, "\n",
|
|
Data::Dumper->Dump([$localconfig->{$name}],
|
|
["*$name"]), "\n";
|
|
}
|
|
|
|
if (@new_vars) {
|
|
my $newstuff = join(', ', @new_vars);
|
|
print "\n", install_string('lc_new_vars',
|
|
{ localconfig => $filename, new_vars => $newstuff }), "\n";
|
|
exit;
|
|
}
|
|
|
|
# Reset the cache for Bugzilla->localconfig so that it will be re-read
|
|
delete Bugzilla->request_cache->{localconfig};
|
|
|
|
return { old_vars => \@old_vars, new_vars => \@new_vars };
|
|
}
|
|
|
|
1;
|
|
|
|
__END__
|
|
|
|
=head1 NAME
|
|
|
|
Bugzilla::Install::Localconfig - Functions and variables dealing
|
|
with the manipulation and creation of the F<localconfig> file.
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
use Bugzilla::Install::Requirements qw(update_localconfig);
|
|
update_localconfig({ output => 1 });
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
This module is used primarily by L<checksetup.pl> to create and
|
|
modify the localconfig file. Most scripts should use L<Bugzilla/localconfig>
|
|
to access localconfig variables.
|
|
|
|
=head1 CONSTANTS
|
|
|
|
=over
|
|
|
|
=item C<LOCALCONFIG_VARS>
|
|
|
|
An array of hashrefs. These hashrefs contain three keys:
|
|
|
|
name - The name of the variable.
|
|
default - The default value for the variable. Should always be
|
|
something that can fit in a scalar.
|
|
desc - Additional text to put in localconfig before the variable
|
|
definition. Must end in a newline. Each line should start
|
|
with "#" unless you have some REALLY good reason not
|
|
to do that.
|
|
|
|
=item C<OLD_LOCALCONFIG_VARS>
|
|
|
|
An array of names of variables. If C<update_localconfig> finds these
|
|
variables defined in localconfig, it will print out a warning.
|
|
|
|
=back
|
|
|
|
=head1 SUBROUTINES
|
|
|
|
=over
|
|
|
|
=item C<read_localconfig>
|
|
|
|
=over
|
|
|
|
=item B<Description>
|
|
|
|
Reads the localconfig file and returns all valid values in a hashref.
|
|
|
|
=item B<Params>
|
|
|
|
=over
|
|
|
|
=item C<$include_deprecated>
|
|
|
|
C<true> if you want the returned hashref to include *any* variable
|
|
currently defined in localconfig, even if it doesn't exist in
|
|
C<LOCALCONFIG_VARS>. Generally this is is only for use
|
|
by L</update_localconfig>.
|
|
|
|
=back
|
|
|
|
=item B<Returns>
|
|
|
|
A hashref of the localconfig variables. If an array is defined in
|
|
localconfig, it will be an arrayref in the returned hash. If a
|
|
hash is defined, it will be a hashref in the returned hash.
|
|
Only includes variables specified in C<LOCALCONFIG_VARS>, unless
|
|
C<$include_deprecated> is true.
|
|
|
|
=back
|
|
|
|
|
|
=item C<update_localconfig>
|
|
|
|
Description: Adds any new variables to localconfig that aren't
|
|
currently defined there. Also optionally prints out
|
|
a message about vars that *should* be there and aren't.
|
|
Exits the program if it adds any new vars.
|
|
|
|
Params: C<$output> - C<true> if the function should display informational
|
|
output and warnings. It will always display errors or
|
|
any message which would cause program execution to halt.
|
|
|
|
Returns: A hashref, with C<old_vals> being an array of names of variables
|
|
that were removed, and C<new_vals> being an array of names
|
|
of variables that were added to localconfig.
|
|
|
|
=back
|