From 7ff0b7a72050104bba80a30c00c31c3f44fffa9e Mon Sep 17 00:00:00 2001 From: byron jones Date: Tue, 13 Mar 2018 04:01:31 +0800 Subject: Bug 1439993 - Remove COMPILE_DIR => setting from Bugzilla::Template --- Bugzilla/Template.pm | 4 +++- Bugzilla/Util.pm | 43 +++++++++++++++++++++++++++++++++++++------ 2 files changed, 40 insertions(+), 7 deletions(-) (limited to 'Bugzilla') diff --git a/Bugzilla/Template.pm b/Bugzilla/Template.pm index d27896532..3c2663e74 100644 --- a/Bugzilla/Template.pm +++ b/Bugzilla/Template.pm @@ -572,7 +572,9 @@ sub create { ABSOLUTE => 1, RELATIVE => $ENV{MOD_PERL} ? 0 : 1, - COMPILE_DIR => bz_locations()->{'template_cache'}, + # Only use an on-disk template cache if we're running as the web + # server. This ensures the permissions of the cache remain correct. + COMPILE_DIR => is_webserver_group() ? bz_locations()->{'template_cache'} : undef, # Don't check for a template update until 1 hour has passed since the # last check. diff --git a/Bugzilla/Util.pm b/Bugzilla/Util.pm index 7d85a4dfd..a1316c7ef 100644 --- a/Bugzilla/Util.pm +++ b/Bugzilla/Util.pm @@ -17,7 +17,8 @@ use base qw(Exporter); with_writable_database with_readonly_database html_quote url_quote xml_quote css_class_quote html_light_quote - i_am_cgi i_am_webservice correct_urlbase remote_ip + i_am_cgi i_am_webservice is_webserver_group + correct_urlbase remote_ip validate_ip do_ssl_redirect_if_required use_attachbase diff_arrays on_main_db css_url_rewrite trim wrap_hard wrap_comment find_wrap_point @@ -32,19 +33,20 @@ use base qw(Exporter); use Bugzilla::Constants; use Bugzilla::RNG qw(irand); -use Date::Parse; use Date::Format; -use DateTime; +use Date::Parse; use DateTime::TimeZone; +use DateTime; use Digest; use Email::Address; -use List::MoreUtils qw(none); -use Scalar::Util qw(tainted blessed); -use Text::Wrap; use Encode qw(encode decode resolve_alias); use Encode::Guess; +use English qw(-no_match_vars $EGID); +use List::MoreUtils qw(any none); use POSIX qw(floor ceil); +use Scalar::Util qw(tainted blessed); use Taint::Util qw(untaint); +use Text::Wrap; use Try::Tiny; sub with_writable_database(&) { @@ -280,6 +282,30 @@ sub i_am_webservice { || $usage_mode == USAGE_MODE_REST; } +sub is_webserver_group { + my @effective_gids = split(/ /, $EGID); + + state $web_server_gid; + if (!defined $web_server_gid) { + my $web_server_group = Bugzilla->localconfig->{webservergroup}; + + if ($web_server_group eq '' || ON_WINDOWS) { + $web_server_gid = $effective_gids[0]; + } + + elsif ($web_server_group =~ /^\d+$/) { + $web_server_gid = $web_server_group; + } + + else { + $web_server_gid = eval { getgrnam($web_server_group) }; + $web_server_gid //= 0; + } + } + + return any { $web_server_gid == $_ } @effective_gids; +} + # This exists as a separate function from Bugzilla::CGI::redirect_to_https # because we don't want to create a CGI object during XML-RPC calls # (doing so can mess up XML-RPC). @@ -1071,6 +1097,11 @@ in a command-line script. Tells you whether or not the current usage mode is WebServices related such as JSONRPC or XMLRPC. +=item C + +Tells you whether or not the current process's group matches that +configured as webservergroup. + =item C Returns the IP address of the remote client. If Bugzilla is behind -- cgit v1.2.3-24-g4f1b From 9a8e6dd21f64b0242939c2abf789e274995b4ded Mon Sep 17 00:00:00 2001 From: Dylan William Hardison Date: Mon, 12 Mar 2018 17:02:09 -0400 Subject: Bug 1437238 - Create override parameters for mailer configuration --- Bugzilla/BugMail.pm | 2 +- Bugzilla/Install/Localconfig.pm | 14 +++++++------- Bugzilla/Mailer.pm | 8 ++++---- Bugzilla/Send/Sendmail.pm | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) (limited to 'Bugzilla') diff --git a/Bugzilla/BugMail.pm b/Bugzilla/BugMail.pm index defe7c84f..915405a0e 100644 --- a/Bugzilla/BugMail.pm +++ b/Bugzilla/BugMail.pm @@ -421,7 +421,7 @@ sub sendMail { bugmailtype => $bugmailtype, }; - if (Bugzilla->params->{'use_mailer_queue'}) { + if (Bugzilla->get_param_with_override('use_mailer_queue')) { enqueue($vars); } else { MessageToMTA(_generate_bugmail($vars)); diff --git a/Bugzilla/Install/Localconfig.pm b/Bugzilla/Install/Localconfig.pm index ba8e8dc57..de2219f16 100644 --- a/Bugzilla/Install/Localconfig.pm +++ b/Bugzilla/Install/Localconfig.pm @@ -43,7 +43,7 @@ our @EXPORT_OK = qw( # might want to change this for upstream use constant ENV_PREFIX => 'BMO_'; -use constant PARAM_OVERRIDE => qw( shadowdb shadowdbhost shadowdbport shadowdbsock ); +use constant PARAM_OVERRIDE => qw( use_mailer_queue mail_delivery_method shadowdb shadowdbhost shadowdbport shadowdbsock ); sub _sensible_group { return '' if ON_WINDOWS; @@ -135,12 +135,12 @@ use constant LOCALCONFIG_VARS => ( { name => 'param_override', default => { - memcached_servers => undef, - memcached_namespace => undef, - shadowdb => undef, - shadowdbhost => undef, - shadowdbport => undef, - shadowdbsock => undef, + use_mailer_queue => undef, + mail_delivery_method => undef, + shadowdb => undef, + shadowdbhost => undef, + shadowdbport => undef, + shadowdbsock => undef, }, }, { diff --git a/Bugzilla/Mailer.pm b/Bugzilla/Mailer.pm index 6e46d1862..e245a05e0 100644 --- a/Bugzilla/Mailer.pm +++ b/Bugzilla/Mailer.pm @@ -37,10 +37,10 @@ use Bugzilla::Version qw(vers_cmp); sub MessageToMTA { my ($msg, $send_now) = (@_); - my $method = Bugzilla->params->{'mail_delivery_method'}; + my $method = Bugzilla->get_param_with_override('mail_delivery_method'); return if $method eq 'None'; - if (Bugzilla->params->{'use_mailer_queue'} and !$send_now) { + if (Bugzilla->get_param_with_override('use_mailer_queue') and !$send_now) { Bugzilla->job_queue->insert('send_mail', { msg => $msg }); return; } @@ -66,7 +66,7 @@ sub MessageToMTA { } # Ensure that we are not sending emails too quickly to recipients. - if (Bugzilla->params->{use_mailer_queue} + if (Bugzilla->get_param_with_override('use_mailer_queue') && (EMAIL_LIMIT_PER_MINUTE || EMAIL_LIMIT_PER_HOUR)) { $dbh->do( @@ -226,7 +226,7 @@ sub MessageToMTA { } # insert into email_rates - if (Bugzilla->params->{use_mailer_queue} + if (Bugzilla->get_param_with_override('use_mailer_queue') && (EMAIL_LIMIT_PER_MINUTE || EMAIL_LIMIT_PER_HOUR)) { $dbh->do( diff --git a/Bugzilla/Send/Sendmail.pm b/Bugzilla/Send/Sendmail.pm index 71c1f67ce..81c2190e5 100644 --- a/Bugzilla/Send/Sendmail.pm +++ b/Bugzilla/Send/Sendmail.pm @@ -37,7 +37,7 @@ sub send { unless (close $pipe) { return failure "error when closing pipe to $mailer: $!" if $!; my ($error_message, $is_transient) = _map_exitcode($? >> 8); - if (Bugzilla->params->{'use_mailer_queue'}) { + if (Bugzilla->get_param_with_override('use_mailer_queue')) { # Return success for errors which are fatal so Bugzilla knows to # remove them from the queue if ($is_transient) { -- cgit v1.2.3-24-g4f1b From 7430718ecad3f49801dfca1c9c93992435cfc732 Mon Sep 17 00:00:00 2001 From: Dylan William Hardison Date: Mon, 12 Mar 2018 17:07:04 -0400 Subject: no bug - make memcached optional --- Bugzilla/Memcached.pm | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Bugzilla') diff --git a/Bugzilla/Memcached.pm b/Bugzilla/Memcached.pm index 0ceed97c0..9868dfb42 100644 --- a/Bugzilla/Memcached.pm +++ b/Bugzilla/Memcached.pm @@ -206,6 +206,8 @@ sub should_rate_limit { my $prefix = RATE_LIMIT_PREFIX . $name . ':'; my $memcached = $self->{memcached}; + return 0 unless $memcached; + $tries //= 3; for (0 .. $tries) { -- cgit v1.2.3-24-g4f1b From 7cd5ab63ae59aae5c6d3c82ce4a7cbab9753efb3 Mon Sep 17 00:00:00 2001 From: Dylan William Hardison Date: Mon, 12 Mar 2018 17:24:42 -0400 Subject: fix typo in logging --- Bugzilla/DaemonControl.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Bugzilla') diff --git a/Bugzilla/DaemonControl.pm b/Bugzilla/DaemonControl.pm index b7f7bcbe9..510886dba 100644 --- a/Bugzilla/DaemonControl.pm +++ b/Bugzilla/DaemonControl.pm @@ -117,7 +117,7 @@ sub run_cereal_and_httpd { if ( ($lc->{inbound_proxies} // '') eq '*' && $lc->{urlbase} =~ /^https/) { push @httpd_args, '-DHTTPS'; } - elsif (not $lc->{urlbase} =~ /^https/) { + elsif ($lc->{urlbase} =~ /^https/) { WARN("HTTPS urlbase but inbound_proxies is not '*'"); } my $httpd_exit_f = run_httpd(@httpd_args); -- cgit v1.2.3-24-g4f1b From dd407867684c5bcf41e0a979959add088b6a6307 Mon Sep 17 00:00:00 2001 From: Dylan William Hardison Date: Mon, 12 Mar 2018 19:40:38 -0400 Subject: Bug 1443162 - attachment links should include urlbase --- Bugzilla/Template.pm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Bugzilla') diff --git a/Bugzilla/Template.pm b/Bugzilla/Template.pm index 3c2663e74..7a97f6da2 100644 --- a/Bugzilla/Template.pm +++ b/Bugzilla/Template.pm @@ -284,7 +284,8 @@ sub get_attachment_link { $link_text =~ s/ \[details\]$//; $link_text =~ s/ \[diff\]$//; - my $linkval = "attachment.cgi?id=$attachid"; + state $urlbase = Bugzilla->localconfig->{urlbase}; + my $linkval = "${urlbase}attachment.cgi?id=$attachid"; # If the attachment is a patch and patch_viewer feature is # enabled, add link to the diff. -- cgit v1.2.3-24-g4f1b From eb43100faf2350b815d3a1e840e7aa0285b9bd76 Mon Sep 17 00:00:00 2001 From: Dylan William Hardison Date: Mon, 12 Mar 2018 19:51:47 -0400 Subject: Bug 1445041 - if memcached server does not end with a port, append :11211 --- Bugzilla/Memcached.pm | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'Bugzilla') diff --git a/Bugzilla/Memcached.pm b/Bugzilla/Memcached.pm index 9868dfb42..388d8c5ed 100644 --- a/Bugzilla/Memcached.pm +++ b/Bugzilla/Memcached.pm @@ -16,7 +16,7 @@ use Log::Log4perl qw(:easy); use Bugzilla::Error; use Scalar::Util qw(blessed); use List::Util qw(sum); -use Bugzilla::Util qw(trick_taint); +use Bugzilla::Util qw(trick_taint trim); use URI::Escape; use Encode; use Sys::Syslog qw(:DEFAULT); @@ -37,7 +37,7 @@ sub _new { $self->{namespace} = Bugzilla->localconfig->{memcached_namespace}; TRACE("connecting servers: $servers, namespace: $self->{namespace}"); $self->{memcached} = Cache::Memcached::Fast->new({ - servers => [ split(/[, ]+/, $servers) ], + servers => [ _parse_memcached_server_list($servers) ], namespace => $self->{namespace}, max_size => 1024 * 1024 * 4, }); @@ -48,6 +48,13 @@ sub _new { return bless($self, $class); } +sub _parse_memcached_server_list { + my ($server_list) = @_; + my @servers = split(/[, ]+/, trim($server_list)); + + return map { /:[0-9]+$/s ? $_ : "$_:11211" } @servers; +} + sub enabled { return $_[0]->{memcached} ? 1 : 0; } -- cgit v1.2.3-24-g4f1b From 294b3090c1eac02ed1d561ddb797814bd3537bfb Mon Sep 17 00:00:00 2001 From: Dylan William Hardison Date: Mon, 12 Mar 2018 21:25:49 -0400 Subject: no bug - TRACE instead of INFO for clearing cache --- Bugzilla/Memcached.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Bugzilla') diff --git a/Bugzilla/Memcached.pm b/Bugzilla/Memcached.pm index 388d8c5ed..85e3505e1 100644 --- a/Bugzilla/Memcached.pm +++ b/Bugzilla/Memcached.pm @@ -281,7 +281,7 @@ sub _inc_prefix { delete Bugzilla->request_cache->{"memcached_prefix_$name"}; # BMO - log that we've wiped the cache - INFO("$name cache cleared"); + TRACE("$name cache cleared"); } sub _global_prefix { -- cgit v1.2.3-24-g4f1b From 6b8fa6c161e88a9054cdcef49aa76aa857ed9a72 Mon Sep 17 00:00:00 2001 From: Dylan William Hardison Date: Tue, 13 Mar 2018 10:37:03 -0400 Subject: Bug 1441181 - Step 4 - Re-implement subprocess code with IO::Async --- Bugzilla/Install/Filesystem.pm | 1 + Bugzilla/JobQueue.pm | 21 ++++++ Bugzilla/JobQueue/Runner.pm | 163 +++++++++++++++++++++++++---------------- Bugzilla/JobQueue/Worker.pm | 30 ++++++++ 4 files changed, 150 insertions(+), 65 deletions(-) create mode 100644 Bugzilla/JobQueue/Worker.pm (limited to 'Bugzilla') diff --git a/Bugzilla/Install/Filesystem.pm b/Bugzilla/Install/Filesystem.pm index 97ab69b9b..71169345b 100644 --- a/Bugzilla/Install/Filesystem.pm +++ b/Bugzilla/Install/Filesystem.pm @@ -225,6 +225,7 @@ sub FILESYSTEM { 'metrics.pl' => { perms => WS_EXECUTE }, 'Makefile.PL' => { perms => OWNER_EXECUTE }, 'gen-cpanfile.pl' => { perms => OWNER_EXECUTE }, + 'jobqueue-worker.pl' => { perms => OWNER_EXECUTE }, 'clean-bug-user-last-visit.pl' => { perms => WS_EXECUTE }, 'Bugzilla.pm' => { perms => CGI_READ }, diff --git a/Bugzilla/JobQueue.pm b/Bugzilla/JobQueue.pm index 55d40bfb8..e3cf9733f 100644 --- a/Bugzilla/JobQueue.pm +++ b/Bugzilla/JobQueue.pm @@ -14,6 +14,10 @@ use warnings; use Bugzilla::Constants; use Bugzilla::Error; use Bugzilla::Install::Util qw(install_string); +use Bugzilla::DaemonControl qw(catch_signal); +use IO::Async::Timer::Periodic; +use IO::Async::Loop; +use Future; use base qw(TheSchwartz); # This maps job names for Bugzilla::JobQueue to the appropriate modules. @@ -91,6 +95,23 @@ sub insert { return $retval; } +sub work { + my ($self, $delay) = @_; + $delay ||= 5; + my $loop = IO::Async::Loop->new; + my $timer = IO::Async::Timer::Periodic->new( + first_interval => 0, + interval => $delay, + reschedule => 'drift', + on_tick => sub { $self->work_once } + ); + $loop->add($timer); + $timer->start; + Future->wait_any(map { catch_signal($_) } qw( INT TERM HUP ))->get; + $timer->stop; + $loop->remove($timer); +} + # Clear the request cache at the start of each run. sub work_once { my $self = shift; diff --git a/Bugzilla/JobQueue/Runner.pm b/Bugzilla/JobQueue/Runner.pm index 5b3164ef9..d95f9c3c3 100644 --- a/Bugzilla/JobQueue/Runner.pm +++ b/Bugzilla/JobQueue/Runner.pm @@ -14,23 +14,32 @@ package Bugzilla::JobQueue::Runner; use 5.10.1; use strict; use warnings; +use autodie qw(open close unlink system); +use Bugzilla::Constants; +use Bugzilla::DaemonControl qw(:utils); +use Bugzilla::JobQueue::Worker; +use Bugzilla::JobQueue; +use Bugzilla::Util qw(get_text); use Cwd qw(abs_path); +use English qw(-no_match_vars $PROGRAM_NAME $EXECUTABLE_NAME); use File::Basename; use File::Copy; +use File::Spec::Functions qw(catfile); +use Future; +use IO::Async::Loop; +use IO::Async::Process; +use IO::Async::Signal; use Pod::Usage; -use Bugzilla::Constants; -use Bugzilla::JobQueue; -use Bugzilla::Util qw(get_text); -BEGIN { eval "use base qw(Daemon::Generic)"; } +use parent qw(Daemon::Generic); -our $VERSION = BUGZILLA_VERSION; +our $VERSION = 2; # Info we need to install/uninstall the daemon. -our $chkconfig = "/sbin/chkconfig"; -our $initd = "/etc/init.d"; -our $initscript = "bugzilla-queue"; +our $chkconfig = '/sbin/chkconfig'; +our $initd = '/etc/init.d'; +our $initscript = 'bugzilla-queue'; # The Daemon::Generic docs say that it uses all sorts of # things from gd_preconfig, but in fact it does not. The @@ -40,11 +49,10 @@ sub gd_preconfig { my $self = shift; my $pidfile = $self->{gd_args}{pidfile}; - if (!$pidfile) { - $pidfile = bz_locations()->{datadir} . '/' . $self->{gd_progname} - . ".pid"; + if ( !$pidfile ) { + $pidfile = bz_locations()->{datadir} . '/' . $self->{gd_progname} . '.pid'; } - return (pidfile => $pidfile); + return ( pidfile => $pidfile ); } # All config other than the pidfile has to be done in gd_getopt @@ -54,24 +62,30 @@ sub gd_getopt { $self->SUPER::gd_getopt(); - if ($self->{gd_args}{progname}) { + if ( $self->{gd_args}{progname} ) { $self->{gd_progname} = $self->{gd_args}{progname}; } else { - $self->{gd_progname} = basename($0); + $self->{gd_progname} = basename($PROGRAM_NAME); } - # There are places that Daemon Generic's new() uses $0 instead of + # There are places that Daemon Generic's new() uses $PROGRAM_NAME instead of # gd_progname, which it really shouldn't, but this hack fixes it. - $self->{_original_zero} = $0; - $0 = $self->{gd_progname}; + $self->{_original_program_name} = $PROGRAM_NAME; + + ## no critic (Variables::RequireLocalizedPunctuationVars) + $PROGRAM_NAME = $self->{gd_progname}; + ## use critic } sub gd_postconfig { my $self = shift; + # See the hack above in gd_getopt. This just reverses it # in case anything else needs the accurate $0. - $0 = delete $self->{_original_zero}; + ## no critic (Variables::RequireLocalizedPunctuationVars) + $PROGRAM_NAME = delete $self->{_original_program_name}; + ## use critic } sub gd_more_opt { @@ -83,8 +97,8 @@ sub gd_more_opt { } sub gd_usage { - pod2usage({ -verbose => 0, -exitval => 'NOEXIT' }); - return 0 + pod2usage( { -verbose => 0, -exitval => 'NOEXIT' } ); + return 0; } sub gd_can_install { @@ -95,66 +109,63 @@ sub gd_can_install { my $sysconfig = '/etc/sysconfig'; my $config_file = "$sysconfig/$initscript"; - if (!-x $chkconfig or !-d $initd) { + if ( !-x $chkconfig || !-d $initd ) { return $self->SUPER::gd_can_install(@_); } return sub { - if (!-w $initd) { + if ( !-w $initd ) { print "You must run the 'install' command as root.\n"; return; } - if (-e $dest_file) { + if ( -e $dest_file ) { print "$initscript already in $initd.\n"; } else { - copy($source_file, $dest_file) + copy( $source_file, $dest_file ) or die "Could not copy $source_file to $dest_file: $!"; - chmod(0755, $dest_file) + chmod 0755, $dest_file or die "Could not change permissions on $dest_file: $!"; } - system($chkconfig, '--add', $initscript); - print "$initscript installed.", - " To start the daemon, do \"$dest_file start\" as root.\n"; + system $chkconfig, '--add', $initscript; + print "$initscript installed.", " To start the daemon, do \"$dest_file start\" as root.\n"; - if (-d $sysconfig and -w $sysconfig) { - if (-e $config_file) { + if ( -d $sysconfig and -w $sysconfig ) { + if ( -e $config_file ) { print "$config_file already exists.\n"; return; } - open(my $config_fh, ">", $config_file) - or die "Could not write to $config_file: $!"; - my $directory = abs_path(dirname($self->{_original_zero})); - my $owner_id = (stat $self->{_original_zero})[4]; - my $owner = getpwuid($owner_id); - print $config_fh <', $config_file; + my $directory = abs_path( dirname( $self->{_original_program_name} ) ); + my $owner_id = ( stat $self->{_original_program_name} )[4]; + my $owner = getpwuid $owner_id; + print $config_fh <<"END"; #!/bin/sh BUGZILLA="$directory" USER=$owner END - close($config_fh); + close $config_fh; } else { print "Please edit $dest_file to configure the daemon.\n"; } - } + } } sub gd_can_uninstall { my $self = shift; - if (-x $chkconfig and -d $initd) { + if ( -x $chkconfig and -d $initd ) { return sub { - if (!-e "$initd/$initscript") { + if ( !-e "$initd/$initscript" ) { print "$initscript not installed.\n"; return; } - system($chkconfig, '--del', $initscript); - print "$initscript disabled.", - " To stop it, run: $initd/$initscript stop\n"; - } + system $chkconfig, '--del', $initscript; + print "$initscript disabled.", " To stop it, run: $initd/$initscript stop\n"; + } } return $self->SUPER::gd_can_install(@_); @@ -164,49 +175,71 @@ sub gd_check { my $self = shift; # Get a count of all the jobs currently in the queue. - my $jq = Bugzilla->job_queue(); - my @dbs = $jq->bz_databases(); + my $jq = Bugzilla->job_queue(); + my @dbs = $jq->bz_databases(); my $count = 0; foreach my $driver (@dbs) { - $count += $driver->select_one('SELECT COUNT(*) FROM ts_job', []); + $count += $driver->select_one( 'SELECT COUNT(*) FROM ts_job', [] ); } - print get_text('job_queue_depth', { count => $count }) . "\n"; + print get_text( 'job_queue_depth', { count => $count } ) . "\n"; } +# override this to use IO::Async. sub gd_setup_signals { - my $self = shift; - $self->SUPER::gd_setup_signals(); - $SIG{TERM} = sub { $self->gd_quit_event(); } + my $self = shift; + my @signals = qw( INT HUP TERM ); + $self->{_signal_future} = Future->wait_any( map { catch_signal( $_, $_ ) } @signals ); } sub gd_other_cmd { my ($self) = shift; - if ($ARGV[0] eq "once") { - $self->_do_work("work_once"); - - exit(0); + if ( $ARGV[0] eq 'once' ) { + Bugzilla::JobQueue::Worker->run('work_once'); + exit; } - + $self->SUPER::gd_other_cmd(); } +sub gd_quit_event { FATAL('gd_quit_event() should never be called') } +sub gd_reconfig_event { FATAL('gd_reconfig_event() should never be called') } + sub gd_run { my $self = shift; - $self->_do_work("work"); + # This is so the process shows up in (h)top in a useful way. + local $PROGRAM_NAME = "$self->{gd_progname} [supervisor]"; + my $code = $self->run_worker('work')->get; + unlink $self->{gd_pidfile}; + exit $code; } -sub _do_work { - my ($self, $fn) = @_; +# This executes the script "jobqueue-worker.pl" +# $EXECUTABLE_NAME is the name of the perl interpreter. +sub run_worker { + my ( $self, $fn ) = @_; - my $jq = Bugzilla->job_queue(); - $jq->set_verbose($self->{debug}); - foreach my $module (values %{ Bugzilla::JobQueue->job_map() }) { - eval "use $module"; - $jq->can_do($module); + my $script = catfile( bz_locations->{cgi_path}, 'jobqueue-worker.pl' ); + my @command = ( $EXECUTABLE_NAME, $script, '--function' => $fn ); + if ( $self->{gd_args}{progname} ) { + push @command, '--name' => "$self->{gd_args}{progname} [worker]"; } - $jq->$fn; + my $loop = IO::Async::Loop->new; + my $exit_f = $loop->new_future; + my $worker = IO::Async::Process->new( + command => \@command, + on_finish => on_finish($exit_f), + on_exception => on_exception( 'jobqueue worker', $exit_f ) + ); + $exit_f->on_cancel( + sub { + DEBUG('terminate worker'); + $worker->kill('TERM'); + } + ); + $loop->add($worker); + return $exit_f; } 1; diff --git a/Bugzilla/JobQueue/Worker.pm b/Bugzilla/JobQueue/Worker.pm new file mode 100644 index 000000000..db8ebe35e --- /dev/null +++ b/Bugzilla/JobQueue/Worker.pm @@ -0,0 +1,30 @@ +# 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. + +package Bugzilla::JobQueue::Worker; +use 5.10.1; +use strict; +use warnings; + +use Bugzilla::Logging; +use Module::Runtime qw(require_module); + +sub run { + my ( $class, $fn ) = @_; + DEBUG("Starting up for $fn"); + my $jq = Bugzilla->job_queue(); + + DEBUG('Loading jobqueue modules'); + foreach my $module ( values %{ Bugzilla::JobQueue->job_map() } ) { + DEBUG("JobQueue can do $module"); + require_module($module); + $jq->can_do($module); + } + $jq->$fn; +} + +1; -- cgit v1.2.3-24-g4f1b From 7b5a64793f8b4b8d464f5522975ef19a830b2c2e Mon Sep 17 00:00:00 2001 From: Dylan William Hardison Date: Tue, 13 Mar 2018 10:40:12 -0400 Subject: Bug 1441181 - Step 5 - Add logging to jobqueue --- Bugzilla/JobQueue.pm | 10 ++++++++++ Bugzilla/JobQueue/Runner.pm | 1 + 2 files changed, 11 insertions(+) (limited to 'Bugzilla') diff --git a/Bugzilla/JobQueue.pm b/Bugzilla/JobQueue.pm index e3cf9733f..8c8d73dcd 100644 --- a/Bugzilla/JobQueue.pm +++ b/Bugzilla/JobQueue.pm @@ -11,6 +11,7 @@ use 5.10.1; use strict; use warnings; +use Bugzilla::Logging; use Bugzilla::Constants; use Bugzilla::Error; use Bugzilla::Install::Util qw(install_string); @@ -95,6 +96,14 @@ sub insert { return $retval; } +sub debug { + my ($self, @args) = @_; + my $caller_pkg = caller; + local $Log::Log4perl::caller_depth = $Log::Log4perl::caller_depth + 1; + my $logger = Log::Log4perl->get_logger($caller_pkg); + $logger->debug(@args); +} + sub work { my ($self, $delay) = @_; $delay ||= 5; @@ -105,6 +114,7 @@ sub work { reschedule => 'drift', on_tick => sub { $self->work_once } ); + DEBUG("working every $delay seconds"); $loop->add($timer); $timer->start; Future->wait_any(map { catch_signal($_) } qw( INT TERM HUP ))->get; diff --git a/Bugzilla/JobQueue/Runner.pm b/Bugzilla/JobQueue/Runner.pm index d95f9c3c3..a3cf3ff55 100644 --- a/Bugzilla/JobQueue/Runner.pm +++ b/Bugzilla/JobQueue/Runner.pm @@ -16,6 +16,7 @@ use strict; use warnings; use autodie qw(open close unlink system); +use Bugzilla::Logging; use Bugzilla::Constants; use Bugzilla::DaemonControl qw(:utils); use Bugzilla::JobQueue::Worker; -- cgit v1.2.3-24-g4f1b From 3698ab542ac64fc52a59d1f9e5855893cae87184 Mon Sep 17 00:00:00 2001 From: Dylan William Hardison Date: Tue, 13 Mar 2018 10:45:01 -0400 Subject: Bug 1441181 - Step 6 - Add concurrency --- Bugzilla/JobQueue/Runner.pm | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'Bugzilla') diff --git a/Bugzilla/JobQueue/Runner.pm b/Bugzilla/JobQueue/Runner.pm index a3cf3ff55..1c74bc28f 100644 --- a/Bugzilla/JobQueue/Runner.pm +++ b/Bugzilla/JobQueue/Runner.pm @@ -28,6 +28,7 @@ use File::Basename; use File::Copy; use File::Spec::Functions qw(catfile); use Future; +use Future::Utils qw(fmap_void); use IO::Async::Loop; use IO::Async::Process; use IO::Async::Signal; @@ -94,6 +95,7 @@ sub gd_more_opt { return ( 'pidfile=s' => \$self->{gd_args}{pidfile}, 'n=s' => \$self->{gd_args}{progname}, + 'jobs|j=i' => \$self->{gd_args}{jobs}, ); } @@ -206,13 +208,18 @@ sub gd_quit_event { FATAL('gd_quit_event() should never be called') } sub gd_reconfig_event { FATAL('gd_reconfig_event() should never be called') } sub gd_run { - my $self = shift; + my $self = shift; + my $jobs = $self->{gd_args}{jobs} // 1; + my $signal_f = $self->{_signal_future}; + my $workers_f = fmap_void { $self->run_worker("work") } + concurrent => $jobs, + generate => sub { !$signal_f->is_ready }; # This is so the process shows up in (h)top in a useful way. local $PROGRAM_NAME = "$self->{gd_progname} [supervisor]"; - my $code = $self->run_worker('work')->get; + Future->wait_any($signal_f, $workers_f)->get; unlink $self->{gd_pidfile}; - exit $code; + exit 0; } # This executes the script "jobqueue-worker.pl" -- cgit v1.2.3-24-g4f1b From 1f043d69e2b017150bf49d80f01ce20143890344 Mon Sep 17 00:00:00 2001 From: Dylan William Hardison Date: Tue, 13 Mar 2018 16:40:59 -0400 Subject: Bug 1441181 - Step 8 - Add jobqueue command to entrypoint --- Bugzilla/DaemonControl.pm | 68 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 52 insertions(+), 16 deletions(-) (limited to 'Bugzilla') diff --git a/Bugzilla/DaemonControl.pm b/Bugzilla/DaemonControl.pm index 510886dba..6586cc01b 100644 --- a/Bugzilla/DaemonControl.pm +++ b/Bugzilla/DaemonControl.pm @@ -28,7 +28,8 @@ use POSIX qw(setsid WEXITSTATUS); use base qw(Exporter); our @EXPORT_OK = qw( - run_httpd run_cereal run_cereal_and_httpd + run_httpd run_cereal run_jobqueue + run_cereal_and_httpd run_cereal_and_jobqueue catch_signal on_finish on_exception assert_httpd assert_database assert_selenium ); @@ -39,10 +40,12 @@ our %EXPORT_TAGS = ( utils => [qw(catch_signal on_exception on_finish)], ); -use constant CEREAL_BIN => realpath(catfile( bz_locations->{cgi_path}, 'scripts', 'cereal.pl')); - -use constant HTTPD_BIN => '/usr/sbin/httpd'; -use constant HTTPD_CONFIG => realpath(catfile( bz_locations->{confdir}, 'httpd.conf' )); +use constant { + JOBQUEUE_BIN => realpath( catfile( bz_locations->{cgi_path}, 'jobqueue.pl' ) ), + CEREAL_BIN => realpath( catfile( bz_locations->{cgi_path}, 'scripts', 'cereal.pl' ) ), + HTTPD_BIN => '/usr/sbin/httpd', + HTTPD_CONFIG => realpath( catfile( bz_locations->{confdir}, 'httpd.conf' ) ), +}; sub catch_signal { my ($name, @done) = @_; @@ -75,7 +78,7 @@ sub run_cereal { my $cereal = IO::Async::Process->new( command => [CEREAL_BIN], on_finish => on_finish($exit_f), - on_exception => on_exception( "cereal", $exit_f ), + on_exception => on_exception( 'cereal', $exit_f ), ); $exit_f->on_cancel( sub { $cereal->kill('TERM') } ); $loop->add($cereal); @@ -85,15 +88,18 @@ sub run_cereal { sub run_httpd { my (@args) = @_; - my $loop = IO::Async::Loop->new; + my $loop = IO::Async::Loop->new; my $exit_f = $loop->new_future; my $httpd = IO::Async::Process->new( code => sub { + # we have to setsid() to make a new process group # or else apache will kill its parent. setsid(); - exec HTTPD_BIN, '-DFOREGROUND', '-f' => HTTPD_CONFIG, @args; + my @command = ( HTTPD_BIN, '-DFOREGROUND', '-f' => HTTPD_CONFIG, @args ); + exec @command + or die "failed to exec $command[0] $!"; }, on_finish => on_finish($exit_f), on_exception => on_exception( 'httpd', $exit_f ), @@ -104,21 +110,52 @@ sub run_httpd { return $exit_f; } +sub run_jobqueue { + my (@args) = @_; + + my $loop = IO::Async::Loop->new; + my $exit_f = $loop->new_future; + my $jobqueue = IO::Async::Process->new( + command => [ JOBQUEUE_BIN, 'start', '-f', '-d', @args ], + on_finish => on_finish($exit_f), + on_exception => on_exception( 'httpd', $exit_f ), + ); + $exit_f->on_cancel( sub { $jobqueue->kill('TERM') } ); + $loop->add($jobqueue); + + return $exit_f; +} + +sub run_cereal_and_jobqueue { + my (@jobqueue_args) = @_; + + my $signal_f = catch_signal('TERM', 0); + my $cereal_exit_f = run_cereal(); + + return assert_cereal()->then( + sub { + my $jobqueue_exit_f = run_jobqueue(@jobqueue_args); + return Future->wait_any($cereal_exit_f, $jobqueue_exit_f, $signal_f); + } + ); +} + sub run_cereal_and_httpd { my @httpd_args = @_; - push @httpd_args, '-DNETCAT_LOGS'; - my $signal_f = catch_signal("TERM", 0); + my $signal_f = catch_signal('TERM', 0); my $cereal_exit_f = run_cereal(); return assert_cereal()->then( sub { + push @httpd_args, '-DNETCAT_LOGS'; + my $lc = Bugzilla::Install::Localconfig::read_localconfig(); if ( ($lc->{inbound_proxies} // '') eq '*' && $lc->{urlbase} =~ /^https/) { push @httpd_args, '-DHTTPS'; } elsif ($lc->{urlbase} =~ /^https/) { - WARN("HTTPS urlbase but inbound_proxies is not '*'"); + WARN('HTTPS urlbase but inbound_proxies is not "*"'); } my $httpd_exit_f = run_httpd(@httpd_args); @@ -140,24 +177,23 @@ sub assert_httpd { my $f = shift; ( $f->get =~ /^httpd OK/ ); }; - my $timeout = $loop->timeout_future(after => 20)->else_fail("assert_httpd timeout"); + my $timeout = $loop->timeout_future(after => 20)->else_fail('assert_httpd timeout'); return Future->wait_any($repeat, $timeout); } - sub assert_selenium { my ($host, $port) = @_; $host //= 'localhost'; $port //= 4444; - return assert_connect($host, $port, "assert_selenium"); + return assert_connect($host, $port, 'assert_selenium'); } sub assert_cereal { return assert_connect( 'localhost', $ENV{LOGGING_PORT} // 5880, - "assert_cereal" + 'assert_cereal' ); } @@ -199,7 +235,7 @@ sub assert_database { ); } until => sub { defined shift->get }; - my $timeout = $loop->timeout_future( after => 20 )->else_fail("assert_database timeout"); + 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 }, -- cgit v1.2.3-24-g4f1b From 973b61c083c83927b552c8985c1d8febe6847f72 Mon Sep 17 00:00:00 2001 From: Dylan William Hardison Date: Thu, 15 Mar 2018 17:44:47 -0400 Subject: Bug 1443058 - Backport 1087400 to bmo - CGI 4.05 throws tons of "CGI::param called in list context" warnings --- Bugzilla/CGI.pm | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'Bugzilla') diff --git a/Bugzilla/CGI.pm b/Bugzilla/CGI.pm index 3737b97e2..cd947841e 100644 --- a/Bugzilla/CGI.pm +++ b/Bugzilla/CGI.pm @@ -11,6 +11,7 @@ use 5.10.1; use strict; use warnings; +use Bugzilla::Logging; use CGI; use base qw(CGI); @@ -597,6 +598,19 @@ sub header { sub param { my $self = shift; + # We don't let CGI.pm warn about list context, but we do it ourselves. + local $CGI::LIST_CONTEXT_WARN = 0; + state $has_warned = {}; + + ## no critic (Freenode::Wantarray) + if ( wantarray && @_ ) { + my ( $package, $filename, $line ) = caller; + if ( $package ne 'CGI' && ! $has_warned->{"$filename:$line"}++) { + WARN("Bugzilla::CGI::param called in list context from $package $filename:$line"); + } + } + ## use critic + # When we are just requesting the value of a parameter... if (scalar(@_) == 1) { my @result = $self->SUPER::param(@_); -- cgit v1.2.3-24-g4f1b From 6353a89495e1a6e68bc9e09a771bb879531f510f Mon Sep 17 00:00:00 2001 From: Dylan William Hardison Date: Fri, 16 Mar 2018 12:53:01 -0400 Subject: Bug 1446156 - mkdir template_cache: Permission denied --- Bugzilla/Template.pm | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Bugzilla') diff --git a/Bugzilla/Template.pm b/Bugzilla/Template.pm index 7a97f6da2..ae4f9bbad 100644 --- a/Bugzilla/Template.pm +++ b/Bugzilla/Template.pm @@ -1074,6 +1074,8 @@ our %_templates_to_precompile; sub precompile_templates { my ($output) = @_; + return unless is_webserver_group(); + # Remove the compiled templates. my $cache_dir = bz_locations()->{'template_cache'}; my $datadir = bz_locations()->{'datadir'}; -- cgit v1.2.3-24-g4f1b From 1121193471e2f6f6b7d4e5c27a465f476f7f100f Mon Sep 17 00:00:00 2001 From: byron jones Date: Tue, 20 Mar 2018 21:14:11 +0800 Subject: Bug 1447221 - memcache no longer returning results due to mismatched key handling in get vs. set --- Bugzilla/Memcached.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Bugzilla') diff --git a/Bugzilla/Memcached.pm b/Bugzilla/Memcached.pm index 85e3505e1..136f43c61 100644 --- a/Bugzilla/Memcached.pm +++ b/Bugzilla/Memcached.pm @@ -324,7 +324,7 @@ sub _get { my $enc_key = $self->_encode_key($key) or return; - my $val = $self->{memcached}->get($key); + my $val = $self->{memcached}->get($enc_key); TRACE("get $enc_key: " . (defined $val ? "HIT" : "MISS")); return $val; } -- cgit v1.2.3-24-g4f1b From 7431f5772abfc859f830ad9f075dfe7b210e4a31 Mon Sep 17 00:00:00 2001 From: Dylan William Hardison Date: Tue, 20 Mar 2018 17:36:36 -0400 Subject: no bug - remove debugging for now --- Bugzilla/CGI.pm | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'Bugzilla') diff --git a/Bugzilla/CGI.pm b/Bugzilla/CGI.pm index cd947841e..b0bc15e78 100644 --- a/Bugzilla/CGI.pm +++ b/Bugzilla/CGI.pm @@ -600,16 +600,18 @@ sub param { # We don't let CGI.pm warn about list context, but we do it ourselves. local $CGI::LIST_CONTEXT_WARN = 0; - state $has_warned = {}; - - ## no critic (Freenode::Wantarray) - if ( wantarray && @_ ) { - my ( $package, $filename, $line ) = caller; - if ( $package ne 'CGI' && ! $has_warned->{"$filename:$line"}++) { - WARN("Bugzilla::CGI::param called in list context from $package $filename:$line"); + if (0) { + state $has_warned = {}; + + ## no critic (Freenode::Wantarray) + if ( wantarray && @_ ) { + my ( $package, $filename, $line ) = caller; + if ( $package ne 'CGI' && ! $has_warned->{"$filename:$line"}++) { + WARN("Bugzilla::CGI::param called in list context from $package $filename:$line"); + } } + ## use critic } - ## use critic # When we are just requesting the value of a parameter... if (scalar(@_) == 1) { -- cgit v1.2.3-24-g4f1b From 9356ed8882760e0b724db963a0dff8f8d1943450 Mon Sep 17 00:00:00 2001 From: Israel Madueme Date: Wed, 21 Mar 2018 17:00:33 -0400 Subject: Bug 1447669 - Add localconfig parameter for changing shadowdb user and pass --- Bugzilla/DB.pm | 9 +++++++-- Bugzilla/Install/Localconfig.pm | 8 ++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) (limited to 'Bugzilla') diff --git a/Bugzilla/DB.pm b/Bugzilla/DB.pm index ff75aa2cf..0dfa47c23 100644 --- a/Bugzilla/DB.pm +++ b/Bugzilla/DB.pm @@ -111,8 +111,13 @@ sub connect_shadow { my $connect_params = dclone(Bugzilla->localconfig); $connect_params->{db_host} = Bugzilla->get_param_with_override('shadowdbhost'); $connect_params->{db_name} = Bugzilla->get_param_with_override('shadowdb'); - $connect_params->{db_port} = Bugzilla->get_param_with_override('shadowport'); - $connect_params->{db_sock} = Bugzilla->get_param_with_override('shadowsock'); + $connect_params->{db_port} = Bugzilla->get_param_with_override('shadowdbport'); + $connect_params->{db_sock} = Bugzilla->get_param_with_override('shadowdbsock'); + + if ( Bugzilla->localconfig->{'shadowdb_user'} && Bugzilla->localconfig->{'shadowdb_pass'} ) { + $connect_params->{db_user} = Bugzilla->localconfig->{'shadowdb_user'}; + $connect_params->{db_pass} = Bugzilla->localconfig->{'shadowdb_pass'}; + } return _connect($connect_params); } diff --git a/Bugzilla/Install/Localconfig.pm b/Bugzilla/Install/Localconfig.pm index de2219f16..7a913358c 100644 --- a/Bugzilla/Install/Localconfig.pm +++ b/Bugzilla/Install/Localconfig.pm @@ -175,6 +175,14 @@ use constant LOCALCONFIG_VARS => ( name => 'inbound_proxies', default => _migrate_param( 'inbound_proxies', '' ), }, + { + name => 'shadowdb_user', + default => '', + }, + { + name => 'shadowdb_pass', + default => '', + } ); -- cgit v1.2.3-24-g4f1b From 9441c91d97a02034b2f2cfa9b19e3a555dbee317 Mon Sep 17 00:00:00 2001 From: Dylan William Hardison Date: Wed, 21 Mar 2018 23:17:12 -0400 Subject: Bug 1399713 - ensure existing production redirects work in a cloud hosted environment --- Bugzilla/ModPerl.pm | 8 +++++ Bugzilla/ModPerl/Hostage.pm | 71 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 Bugzilla/ModPerl/Hostage.pm (limited to 'Bugzilla') diff --git a/Bugzilla/ModPerl.pm b/Bugzilla/ModPerl.pm index a5c840897..120dd8210 100644 --- a/Bugzilla/ModPerl.pm +++ b/Bugzilla/ModPerl.pm @@ -20,6 +20,7 @@ use Carp (); use Template (); use Bugzilla::ModPerl::BlockIP; +use Bugzilla::ModPerl::Hostage; sub apache_config { my ($class, $cgi_path) = @_; @@ -74,6 +75,7 @@ __DATA__ # the built-in rand(), even though we never use it in Bugzilla itself, # so we need to srand() both of them.) PerlChildInitHandler "sub { Bugzilla::RNG::srand(); srand(); }" +PerlInitHandler Bugzilla::ModPerl::Hostage PerlAccessHandler Bugzilla::ModPerl::BlockIP # It is important to specify ErrorDocuments outside of all directories. @@ -84,6 +86,12 @@ ErrorDocument 403 /errors/403.html ErrorDocument 404 /errors/404.html ErrorDocument 500 /errors/500.html + + SetHandler perl-script + PerlResponseHandler Plack::Handler::Apache2 + PerlSetVar psgi_app [% cgi_path %]/helper.psgi + + AddHandler perl-script .cgi # No need to PerlModule these because they're already defined in mod_perl.pl diff --git a/Bugzilla/ModPerl/Hostage.pm b/Bugzilla/ModPerl/Hostage.pm new file mode 100644 index 000000000..a3bdfac58 --- /dev/null +++ b/Bugzilla/ModPerl/Hostage.pm @@ -0,0 +1,71 @@ +package Bugzilla::ModPerl::Hostage; +use 5.10.1; +use strict; +use warnings; + +use Apache2::Const qw(:common); ## no critic (Freenode::ModPerl) + +sub _attachment_root { + my ($base) = @_; + return undef unless $base; + return $base =~ m{^https?://(?:bug)?\%bugid\%\.([a-zA-Z\.-]+)} + ? $1 + : undef; +} + +sub _attachment_host_regex { + my ($base) = @_; + return undef unless $base; + my $val = $base; + $val =~ s{^https?://}{}s; + $val =~ s{/$}{}s; + my $regex = quotemeta $val; + $regex =~ s/\\\%bugid\\\%/\\d+/g; + return qr/^$regex$/s; +} + +sub handler { + my $r = shift; + state $urlbase = Bugzilla->localconfig->{urlbase}; + state $urlbase_uri = URI->new($urlbase); + state $urlbase_host = $urlbase_uri->host; + state $urlbase_host_regex = qr/^bug(\d+)\.\Q$urlbase_host\E$/; + state $attachment_base = Bugzilla->localconfig->{attachment_base}; + state $attachment_root = _attachment_root($attachment_base); + state $attachment_host_regex = _attachment_host_regex($attachment_base); + + my $hostname = $r->hostname; + return OK if $hostname eq $urlbase_host; + + my $path = $r->uri; + return OK if $path eq '/__lbheartbeat__'; + + if ($attachment_base && $hostname eq $attachment_root) { + $r->headers_out->set(Location => $urlbase); + return REDIRECT; + } + elsif ($attachment_base && $hostname =~ $attachment_host_regex) { + if ($path =~ m{^/attachment\.cgi}s) { + return OK; + } else { + my $new_uri = URI->new($r->unparsed_uri); + $new_uri->scheme($urlbase_uri->scheme); + $new_uri->host($urlbase_host); + $r->headers_out->set(Location => $new_uri); + return REDIRECT; + } + } + elsif (my ($id) = $hostname =~ $urlbase_host_regex) { + my $new_uri = $urlbase_uri->clone; + $new_uri->path('/show_bug.cgi'); + $new_uri->query_form(id => $id); + $r->headers_out->set(Location => $new_uri); + return REDIRECT; + } + else { + $r->headers_out->set(Location => $urlbase); + return REDIRECT; + } +} + +1; \ No newline at end of file -- cgit v1.2.3-24-g4f1b From f76a9d7c96dbed50ee1fb9da56bcff818ea2eb5b Mon Sep 17 00:00:00 2001 From: Dylan William Hardison Date: Sun, 25 Mar 2018 23:54:18 -0400 Subject: no bug - TheSchwartz debug log is really more like info level in how we have used it --- Bugzilla/JobQueue.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Bugzilla') diff --git a/Bugzilla/JobQueue.pm b/Bugzilla/JobQueue.pm index 8c8d73dcd..c10e859e2 100644 --- a/Bugzilla/JobQueue.pm +++ b/Bugzilla/JobQueue.pm @@ -101,7 +101,7 @@ sub debug { my $caller_pkg = caller; local $Log::Log4perl::caller_depth = $Log::Log4perl::caller_depth + 1; my $logger = Log::Log4perl->get_logger($caller_pkg); - $logger->debug(@args); + $logger->info(@args); } sub work { -- cgit v1.2.3-24-g4f1b From 104d8795b882ee413d1cbe882f1fed0da925814d Mon Sep 17 00:00:00 2001 From: Dylan William Hardison Date: Mon, 26 Mar 2018 00:04:19 -0400 Subject: no bug - run jobqueue faster --- Bugzilla/JobQueue.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Bugzilla') diff --git a/Bugzilla/JobQueue.pm b/Bugzilla/JobQueue.pm index c10e859e2..53b088c6e 100644 --- a/Bugzilla/JobQueue.pm +++ b/Bugzilla/JobQueue.pm @@ -106,7 +106,7 @@ sub debug { sub work { my ($self, $delay) = @_; - $delay ||= 5; + $delay ||= 1; my $loop = IO::Async::Loop->new; my $timer = IO::Async::Timer::Periodic->new( first_interval => 0, -- cgit v1.2.3-24-g4f1b From f6a6e63306e63825013f9a58b7527f2653420976 Mon Sep 17 00:00:00 2001 From: byron jones Date: Tue, 27 Mar 2018 05:01:46 +0800 Subject: Bug 1448681 - Bugmail Message-ID header format changed without changing In-Reply-To/References, breaking threading --- Bugzilla/Mailer.pm | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'Bugzilla') diff --git a/Bugzilla/Mailer.pm b/Bugzilla/Mailer.pm index e245a05e0..1dec3d4ff 100644 --- a/Bugzilla/Mailer.pm +++ b/Bugzilla/Mailer.pm @@ -252,15 +252,14 @@ sub build_thread_marker { $sitespec = "-$2$sitespec"; # Put the port number back in, before the '@' } - my $threadingmarker; + my $threadingmarker = "References: "; if ($is_new) { - $threadingmarker = "Message-ID: "; + $threadingmarker .= "\nMessage-ID: "; } else { my $rand_bits = generate_random_password(10); - $threadingmarker = "Message-ID: " . - "\nIn-Reply-To: " . - "\nReferences: "; + $threadingmarker .= "\nMessage-ID: " . + "\nIn-Reply-To: "; } return $threadingmarker; -- cgit v1.2.3-24-g4f1b From 575261c6d9e432ea181beedfc8086c24cc17ccc6 Mon Sep 17 00:00:00 2001 From: Dylan William Hardison Date: Wed, 28 Mar 2018 10:14:17 -0400 Subject: Bug 1449156 - Bugzilla::Memcached should use smaller timeouts and ping servers at instantiation time --- Bugzilla/Memcached.pm | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'Bugzilla') diff --git a/Bugzilla/Memcached.pm b/Bugzilla/Memcached.pm index 136f43c61..d34aaa595 100644 --- a/Bugzilla/Memcached.pm +++ b/Bugzilla/Memcached.pm @@ -36,11 +36,25 @@ sub _new { if (Bugzilla->feature('memcached') && $servers) { $self->{namespace} = Bugzilla->localconfig->{memcached_namespace}; TRACE("connecting servers: $servers, namespace: $self->{namespace}"); - $self->{memcached} = Cache::Memcached::Fast->new({ - servers => [ _parse_memcached_server_list($servers) ], - namespace => $self->{namespace}, - max_size => 1024 * 1024 * 4, - }); + $self->{memcached} = Cache::Memcached::Fast->new( + { + servers => [ _parse_memcached_server_list($servers) ], + namespace => $self->{namespace}, + max_size => 1024 * 1024 * 4, + max_failures => 1, + failure_timeout => 60, + io_timeout => 0.2, + connect_timeout => 0.2, + } + ); + my $versions = $self->{memcached}->server_versions; + if (keys %$versions) { + # this is needed to ensure forked processes don't start out with a connected memcached socket. + $self->{memcached}->disconnect_all; + } + else { + WARN("No memcached servers"); + } } else { TRACE("memcached feature is not enabled"); -- cgit v1.2.3-24-g4f1b From 7d1b15c95e1341fb308223576e15dc4777544ccb Mon Sep 17 00:00:00 2001 From: Dylan William Hardison Date: Wed, 28 Mar 2018 10:14:40 -0400 Subject: Bug 1449168 - Remove warning --function from jobqueue worker --- Bugzilla/JobQueue/Runner.pm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Bugzilla') diff --git a/Bugzilla/JobQueue/Runner.pm b/Bugzilla/JobQueue/Runner.pm index 1c74bc28f..5cf7d82eb 100644 --- a/Bugzilla/JobQueue/Runner.pm +++ b/Bugzilla/JobQueue/Runner.pm @@ -211,7 +211,7 @@ sub gd_run { my $self = shift; my $jobs = $self->{gd_args}{jobs} // 1; my $signal_f = $self->{_signal_future}; - my $workers_f = fmap_void { $self->run_worker("work") } + my $workers_f = fmap_void { $self->run_worker() } concurrent => $jobs, generate => sub { !$signal_f->is_ready }; @@ -225,10 +225,10 @@ sub gd_run { # This executes the script "jobqueue-worker.pl" # $EXECUTABLE_NAME is the name of the perl interpreter. sub run_worker { - my ( $self, $fn ) = @_; + my ( $self ) = @_; my $script = catfile( bz_locations->{cgi_path}, 'jobqueue-worker.pl' ); - my @command = ( $EXECUTABLE_NAME, $script, '--function' => $fn ); + my @command = ( $EXECUTABLE_NAME, $script); if ( $self->{gd_args}{progname} ) { push @command, '--name' => "$self->{gd_args}{progname} [worker]"; } -- cgit v1.2.3-24-g4f1b From 0225ce6e5b34ce3fc3e874efc3c0f249a5b4a1c2 Mon Sep 17 00:00:00 2001 From: Dylan William Hardison Date: Thu, 29 Mar 2018 15:13:33 -0400 Subject: Bug 1450008 - documentation link in API errors is wrong --- Bugzilla/Constants.pm | 5 ----- Bugzilla/WebService/Server/REST.pm | 3 ++- 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'Bugzilla') diff --git a/Bugzilla/Constants.pm b/Bugzilla/Constants.pm index 00f0f8104..6e3a12736 100644 --- a/Bugzilla/Constants.pm +++ b/Bugzilla/Constants.pm @@ -19,7 +19,6 @@ use Memoize; @Bugzilla::Constants::EXPORT = qw( BUGZILLA_VERSION - REST_DOC REMOTE_FILE LOCAL_FILE @@ -209,10 +208,6 @@ sub BUGZILLA_VERSION { eval { Bugzilla->VERSION } || $bugzilla_version; } -# A base link to the current REST Documentation. We place it here -# as it will need to be updated to whatever the current release is. -use constant REST_DOC => "https://bugzilla.readthedocs.io/en/latest/api/"; - # Location of the remote and local XML files to track new releases. use constant REMOTE_FILE => 'http://updates.bugzilla.org/bugzilla-update.xml'; use constant LOCAL_FILE => 'bugzilla-update.xml'; # Relative to datadir. diff --git a/Bugzilla/WebService/Server/REST.pm b/Bugzilla/WebService/Server/REST.pm index 6fb86fdd4..b8884b753 100644 --- a/Bugzilla/WebService/Server/REST.pm +++ b/Bugzilla/WebService/Server/REST.pm @@ -132,7 +132,8 @@ sub response { if (exists $json_data->{error}) { $result = $json_data->{error}; $result->{error} = $self->type('boolean', 1); - $result->{documentation} = REST_DOC; + + $result->{documentation} = Bugzilla->params->{docs_urlbase} . "api/"; delete $result->{'name'}; # Remove JSONRPCError } elsif (exists $json_data->{result}) { -- cgit v1.2.3-24-g4f1b From f58deda411a1f9c260b293ecd58e37843c2debca Mon Sep 17 00:00:00 2001 From: Dylan William Hardison Date: Thu, 29 Mar 2018 15:54:54 -0400 Subject: Bug 1450010 - The jobqueue supervisor's pidfile should not be stored in the data directory --- Bugzilla/JobQueue/Runner.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Bugzilla') diff --git a/Bugzilla/JobQueue/Runner.pm b/Bugzilla/JobQueue/Runner.pm index 5cf7d82eb..0177de40a 100644 --- a/Bugzilla/JobQueue/Runner.pm +++ b/Bugzilla/JobQueue/Runner.pm @@ -26,7 +26,7 @@ use Cwd qw(abs_path); use English qw(-no_match_vars $PROGRAM_NAME $EXECUTABLE_NAME); use File::Basename; use File::Copy; -use File::Spec::Functions qw(catfile); +use File::Spec::Functions qw(catfile tmpdir); use Future; use Future::Utils qw(fmap_void); use IO::Async::Loop; @@ -52,7 +52,7 @@ sub gd_preconfig { my $pidfile = $self->{gd_args}{pidfile}; if ( !$pidfile ) { - $pidfile = bz_locations()->{datadir} . '/' . $self->{gd_progname} . '.pid'; + $pidfile = catfile(tmpdir(), $self->{gd_progname} . '.pid'); } return ( pidfile => $pidfile ); } -- cgit v1.2.3-24-g4f1b From 427de4c955b23390972d6981db22e07c4c3b2ddf Mon Sep 17 00:00:00 2001 From: Dylan William Hardison Date: Thu, 29 Mar 2018 17:56:46 -0400 Subject: Bug 1441244 - prevent compounding error messages in tests --- Bugzilla/Error.pm | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'Bugzilla') diff --git a/Bugzilla/Error.pm b/Bugzilla/Error.pm index e7a99dba0..d67571848 100644 --- a/Bugzilla/Error.pm +++ b/Bugzilla/Error.pm @@ -38,15 +38,14 @@ sub _in_eval { sub _throw_error { my ($name, $error, $vars) = @_; - my $dbh = Bugzilla->dbh; $vars ||= {}; - $vars->{error} = $error; # Make sure any transaction is rolled back (if supported). # If we are within an eval(), do not roll back transactions as we are # eval'uating some test on purpose. - $dbh->bz_rollback_transaction() if ($dbh->bz_in_transaction() && !_in_eval()); + my $dbh = eval { Bugzilla->dbh }; + $dbh->bz_rollback_transaction() if ($dbh && $dbh->bz_in_transaction() && !_in_eval()); my $datadir = bz_locations()->{'datadir'}; # If a writable $datadir/errorlog exists, log error details there. @@ -191,10 +190,9 @@ sub ThrowCodeError { sub ThrowTemplateError { my ($template_err) = @_; - my $dbh = Bugzilla->dbh; - + my $dbh = eval { Bugzilla->dbh }; # Make sure the transaction is rolled back (if supported). - $dbh->bz_rollback_transaction() if $dbh->bz_in_transaction(); + $dbh->bz_rollback_transaction() if $dbh && $dbh->bz_in_transaction(); if (blessed($template_err) && $template_err->isa('Template::Exception')) { my $type = $template_err->type; -- cgit v1.2.3-24-g4f1b From 6fb33c210e6917f32056dcffd00e55d0d97302bc Mon Sep 17 00:00:00 2001 From: Dylan William Hardison Date: Fri, 30 Mar 2018 16:20:49 -0400 Subject: Bug 1450343 - Make the SES handler use Bugzilla::Logging and log more details --- Bugzilla/ModPerl/BasicAuth.pm | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'Bugzilla') diff --git a/Bugzilla/ModPerl/BasicAuth.pm b/Bugzilla/ModPerl/BasicAuth.pm index e93680e9d..7248a19f3 100644 --- a/Bugzilla/ModPerl/BasicAuth.pm +++ b/Bugzilla/ModPerl/BasicAuth.pm @@ -25,18 +25,22 @@ use warnings; # AUTH_VAR_NAME and AUTH_VAR_PASS are the names of variables defined in # `localconfig` which hold the authentication credentials. -use Apache2::Const -compile => qw(OK HTTP_UNAUTHORIZED); +use Apache2::Const -compile => qw(OK HTTP_UNAUTHORIZED); ## no critic (Freenode::ModPerl) +use Bugzilla::Logging; use Bugzilla (); sub handler { my $r = shift; my ($status, $password) = $r->get_basic_auth_pw; - return $status if $status != Apache2::Const::OK; + if ($status != Apache2::Const::OK) { + WARN("Got non-OK status: $status when trying to get password"); + return $status + } my $auth_var_name = $ENV{AUTH_VAR_NAME}; my $auth_var_pass = $ENV{AUTH_VAR_PASS}; unless ($auth_var_name && $auth_var_pass) { - warn "AUTH_VAR_NAME and AUTH_VAR_PASS environmental vars not set\n"; + ERROR('AUTH_VAR_NAME and AUTH_VAR_PASS environmental vars not set'); $r->note_basic_auth_failure; return Apache2::Const::HTTP_UNAUTHORIZED; } @@ -44,13 +48,14 @@ sub handler { my $auth_user = Bugzilla->localconfig->{$auth_var_name}; my $auth_pass = Bugzilla->localconfig->{$auth_var_pass}; unless ($auth_user && $auth_pass) { - warn "$auth_var_name and $auth_var_pass not configured\n"; + ERROR("$auth_var_name and $auth_var_pass not configured"); $r->note_basic_auth_failure; return Apache2::Const::HTTP_UNAUTHORIZED; } unless ($r->user eq $auth_user && $password eq $auth_pass) { $r->note_basic_auth_failure; + WARN('username and password do not match'); return Apache2::Const::HTTP_UNAUTHORIZED; } -- cgit v1.2.3-24-g4f1b