my %attrs = (mysql_enable_utf8 => 1);
+ # MySQL SSL options
+ my ($ssl_ca_file, $ssl_ca_path, $ssl_cert, $ssl_key, $ssl_pubkey) =
+ @$params{qw(db_mysql_ssl_ca_file db_mysql_ssl_ca_path
+ db_mysql_ssl_client_cert db_mysql_ssl_client_key db_mysql_ssl_get_pubkey)};
+ if ($ssl_ca_file || $ssl_ca_path || $ssl_cert || $ssl_key || $ssl_pubkey) {
+ $attrs{'mysql_ssl'} = 1;
+ $attrs{'mysql_ssl_ca_file'} = $ssl_ca_file if $ssl_ca_file;
+ $attrs{'mysql_ssl_ca_path'} = $ssl_ca_path if $ssl_ca_path;
+ $attrs{'mysql_ssl_client_cert'} = $ssl_cert if $ssl_cert;
+ $attrs{'mysql_ssl_client_key'} = $ssl_key if $ssl_key;
+ $attrs{'mysql_get_server_pubkey'} = $ssl_pubkey if $ssl_pubkey;
+ }
+
return {dsn => $dsn, user => $user, pass => $pass, attrs => \%attrs};
}
use Cwd qw(realpath);
use English qw(-no_match_vars $PROGRAM_NAME);
use File::Spec::Functions qw(catfile catdir);
-use Future::Utils qw(repeat try_repeat);
+use Future::Utils qw(repeat try_repeat_until_success);
use Future;
use IO::Async::Loop;
use IO::Async::Process;
}
sub assert_database {
+ my $assert_dbierrstr = "";
my $loop = IO::Async::Loop->new;
my $lc = Bugzilla::Install::Localconfig::read_localconfig();
}
my $dsn = "dbi:mysql:database=$lc->{db_name};host=$lc->{db_host}";
- my $repeat = repeat {
+ my $repeat = try_repeat_until_success {
$loop->delay_future(after => 0.25)->then(sub {
- my $dbh
- = DBI->connect($dsn, $lc->{db_user}, $lc->{db_pass},
- {RaiseError => 0, PrintError => 0},
- );
+ my $attrs = {RaiseError => 1, PrintError => 1};
+ my ($ssl_ca_file, $ssl_ca_path, $ssl_cert, $ssl_key, $ssl_pubkey) =
+ @$lc{qw(db_mysql_ssl_ca_file db_mysql_ssl_ca_path
+ db_mysql_ssl_client_cert db_mysql_ssl_client_key db_mysql_ssl_get_pubkey)};
+ if ($ssl_ca_file || $ssl_ca_path || $ssl_cert || $ssl_key || $ssl_pubkey) {
+ $attrs->{'mysql_ssl'} = 1;
+ $attrs->{'mysql_ssl_ca_file'} = $ssl_ca_file if $ssl_ca_file;
+ $attrs->{'mysql_ssl_ca_path'} = $ssl_ca_path if $ssl_ca_path;
+ $attrs->{'mysql_ssl_client_cert'} = $ssl_cert if $ssl_cert;
+ $attrs->{'mysql_ssl_client_key'} = $ssl_key if $ssl_key;
+ $attrs->{'mysql_get_server_pubkey'} = $ssl_pubkey if $ssl_pubkey;
+ }
+ my $dbh;
+ eval {
+ $dbh
+ = DBI->connect($dsn, $lc->{db_user}, $lc->{db_pass}, $attrs);
+ };
+ if ($!) { $assert_dbierrstr = $@; die $@; }
+ $assert_dbierrstr = DBI->errstr() || '';
+ die "$assert_dbierrstr" if $assert_dbierrstr;
Future->wrap($dbh);
});
- }
- until => sub { defined shift->get };
+ };
my $timeout
= $loop->timeout_future(after => 20)->else_fail('assert_database timeout');
my $any_f = Future->wait_any($repeat, $timeout);
return $any_f->transform(
done => sub {return},
- fail => sub {"unable to connect to $dsn as $lc->{db_user}"},
+ fail => sub {"unable to connect to $dsn as $lc->{db_user}: $assert_dbierrstr"},
);
}
{name => 'db_port', default => 0,},
{name => 'db_sock', default => '',},
{name => 'db_check', default => 1,},
+ {name => 'db_mysql_ssl_ca_file', default => '',},
+ {name => 'db_mysql_ssl_ca_path', default => '',},
+ {name => 'db_mysql_ssl_client_cert', default => '',},
+ {name => 'db_mysql_ssl_client_key', default => '',},
+ {name => 'db_mysql_ssl_get_pubkey', default => 0,},
{name => 'index_html', default => 0,},
{name => 'cvsbin', default => sub { bin_loc('cvs') },},
{name => 'interdiffbin', default => sub { bin_loc('interdiff') },},
$answer{'defaultseverity'} = 'normal';
$answer{'skin'} = 'Mozilla';
$answer{'docs_urlbase'} = 'https://bmo.readthedocs.io/en/latest/';
+$answer{'db_mysql_ssl_get_pubkey'} = 1;
want that.
END
localconfig_db_user => "Who we connect to the database as.",
+ localconfig_db_mysql_ssl_ca_file => <<'END',
+Path to a PEM file with a list of trusted SSL CA certificates.
+The file must be readable by web server user.
+END
+ localconfig_db_mysql_ssl_ca_path => <<'END',
+Path to a directory containing trusted SSL CA certificates in PEM format.
+Directory and files inside must be readable by the web server user.
+END
+ localconfig_db_mysql_ssl_client_cert => <<'END',
+Full path to the client SSL certificate in PEM format we will present to the DB server.
+The file must be readable by web server user.
+END
+ localconfig_db_mysql_ssl_client_key => <<'END',
+Full path to the private key corresponding to the client SSL certificate.
+The file must not be password-protected and must be readable by web server user.
+END
+ localconfig_db_mysql_ssl_get_pubkey => <<'END',
+Whether to have Bugzilla automatically fetch the public key from the server at connection time.
+This is less secure than specifying the ca_file above.
+END
localconfig_diffpath => <<'END',
For the "Difference Between Two Patches" feature to work, we need to know
what directory the "diff" bin is in. (You only need to set this if you