On Fri, 2012-10-19 at 12:21 -0500, Alex Hanselka wrote: Upon strace-ing the file, it seems to have a lot of issues with "(No > such file or directory)" errors. I assume this is because it searches > for the files and the first places it tries are wrong?
Correct, those are expected as perl searches through @INC looking for library files. > I also see a bunch of "Inappropriate ioctl for device." I can provide > a pastebin of the strace if necessary. The ioctl error is somewhat more surprising. Seeing a pastebin of the strace might be useful. > As for my configure line, it was very simple: "./configure > --with-web-user=nginx --with-web-group=nginx --with-db-type=Pg"... Did I > miss something? Nope. I just wanted to see the user and group you'd passed to configure. Re-reading your original mail, I'd expect the spawn-fcgi incant to work, but the failure case of rt-server.fcgi not working with --port is a known bug, and one which is resolved in the 4.2/refactor-rt-server branch. I've included below a backport of the relevant commit; I'd be curious to hear if it solves your problem or gives a more coherent error message. - Alex ------------------------------------ 8< ------------------------------- >From 0745a7c578ffb50ff17124334934fefdb0c61a2d Mon Sep 17 00:00:00 2001 From: Alex Vandiver <[email protected]> Date: Mon, 20 Jun 2011 21:58:30 -0400 Subject: [PATCH] Refactor rt-server.in into RT::PlackRunner This properly detects --port, --listen, and --socket options, and falls back to $WebPort only when none are specified. It also provides better handling for fastcgi, detecting when STDIN is a socket, and bailing with a correct error message if it has no other options to listen on. diff --git a/lib/RT/PlackRunner.pm b/lib/RT/PlackRunner.pm new file mode 100644 index 0000000..8a7ea3d --- /dev/null +++ b/lib/RT/PlackRunner.pm @@ -0,0 +1,139 @@ +use warnings; +use strict; + +package RT::PlackRunner; + +use base 'Plack::Runner'; + +sub parse_options { + my $self = shift; + my @args = @_; + # handle "rt-server 8888" for back-compat, but complain about it + if (@args && $args[0] =~ m/^\d+$/) { + warn "Deprecated: please run $0 --port $ARGV[0] instead\n"; + unshift @args, '--port'; + } + + $self->SUPER::parse_options(@args); + + $self->{app} ||= $self->app; + $self->{server} ||= $self->loader->guess; + + my %args = @{$self->{options}}; + if ($self->{server} eq "FCGI") { + # We deal with the possible failure modes of this in ->run + } elsif ($args{port}) { + $self->{explicit_port} = 1; + my $old_app = $self->{app}; + $self->{app} = sub { + my $env = shift; + $env->{'rt.explicit_port'} = $args{port}; + $old_app->($env, @_); + }; + } else { + $self->set_options(port => (RT->Config->Get('WebPort') || '8080')); + } +} + +# Override to not default to port 5000 +sub mangle_host_port_socket { + my($self, $host, $port, $socket, @listen) = @_; + + for my $listen (reverse @listen) { + if ($listen =~ /:\d+$/) { + ($host, $port) = split /:/, $listen, 2; + $host = undef if $host eq ''; + } else { + $socket ||= $listen; + } + } + + unless (@listen) { + if ($socket) { + @listen = ($socket); + } elsif ($port) { + @listen = ($host ? "$host:$port" : ":$port"); + } + } + + return host => $host, port => $port, listen => \@listen, socket => $socket; +} + +sub prepare_devel { + my($self, $app) = @_; + # Don't install the Lint, StackTrace, and AccessLog middleware + + push @{$self->{options}}, server_ready => sub { + my($args) = @_; + my $name = $args->{server_software} || ref($args); + my $host = $args->{host} || RT->Config->Get('WebDomain'); + my $proto = $args->{proto} || 'http'; + print STDERR "$name: Accepting connections at $proto://$host:$args->{port}/\n"; + }; + + $app; +} + + +sub app { + require RT::Interface::Web::Handler; + my $app = RT::Interface::Web::Handler->PSGIApp; + + if ($ENV{RT_TESTING}) { + my $screen_logger = $RT::Logger->remove('screen'); + require Log::Dispatch::Perl; + $RT::Logger->add( + Log::Dispatch::Perl->new( + name => 'rttest', + min_level => $screen_logger->min_level, + action => { + error => 'warn', + critical => 'warn' + } + ) + ); + require Plack::Middleware::Test::StashWarnings; + $app = Plack::Middleware::Test::StashWarnings->wrap($app); + } + + return $app; +} + +sub run { + my $self = shift; + + my %args = @{$self->{options}}; + + # Plack::Handler::FCGI has its own catch for this, but doesn't + # notice that listen is an empty list, and we can also provide a + # better error message. + if ($self->{server} eq "FCGI" and not -S STDIN and not @{$args{listen}}) { + print STDERR "STDIN is not a socket, and no --listen, --socket, or --port provided\n"; + exit 1; + } + + eval { $self->SUPER::run(@_) }; + my $err = $@; + exit 0 unless $err; + + if ( $err =~ /listen/ ) { + print STDERR <<EOF; +WARNING: RT couldn't start up a web server on port $args{port}. +This is often the case if the port is already in use or you're running @{[$0]} +as someone other than your system's "root" user. You may also specify a +temporary port with: $0 --port <port> +EOF + + if ($self->{explicit_port}) { + print STDERR + "Please check your system configuration or choose another port\n\n"; + } + exit 1; + } else { + die + "Something went wrong while trying to run RT's standalone web server:\n\t" + . $err; + } +} + +1; diff --git a/sbin/rt-server b/sbin/rt-server index f84f6c1..fccd895 100755 --- a/sbin/rt-server +++ b/sbin/rt-server @@ -99,7 +99,7 @@ my ($integrity, $state, $msg) = RT::Handle->CheckIntegrity; unless ( $integrity ) { print STDERR <<EOF; - + RT couldn't connect to the database where tickets are stored. If this is a new installation of RT, you should visit the URL below to configure RT and initialize your database. @@ -141,127 +141,20 @@ if ($RT::Handle) { undef $RT::Handle; } -require RT::Interface::Web::Handler; -my $app = RT::Interface::Web::Handler->PSGIApp; - -if ($ENV{RT_TESTING}) { - my $screen_logger = $RT::Logger->remove('screen'); - require Log::Dispatch::Perl; - $RT::Logger->add( - Log::Dispatch::Perl->new( - name => 'rttest', - min_level => $screen_logger->min_level, - action => { - error => 'warn', - critical => 'warn' - } - ) - ); - require Plack::Middleware::Test::StashWarnings; - $app = Plack::Middleware::Test::StashWarnings->wrap($app); -} - +require RT::PlackRunner; # when used as a psgi file if (caller) { - return $app; -} - - -# load appropriate server - -require Plack::Runner; - -my $is_fastcgi = $0 =~ m/fcgi$/; -my $r = Plack::Runner->new( $0 =~ /standalone/ ? ( server => 'Standalone' ) : - $is_fastcgi ? ( server => 'FCGI' ) - : (), - env => 'deployment' ); - -# figure out the port -my $port; - -# handle "rt-server 8888" for back-compat, but complain about it -if ($ARGV[0] && $ARGV[0] =~ m/^\d+$/) { - warn "Deprecated: please run $0 --port $ARGV[0] instead\n"; - unshift @ARGV, '--port'; -} - -my @args = @ARGV; - -use List::MoreUtils 'last_index'; -my $last_index = last_index { $_ eq '--port' } @args; - -my $explicit_port; - -if ( $last_index != -1 && $args[$last_index+1] =~ /^\d+$/ ) { - $explicit_port = $args[$last_index+1]; - $port = $explicit_port; - - # inform the rest of the system what port we manually chose - my $old_app = $app; - $app = sub { - my $env = shift; - - $env->{'rt.explicit_port'} = $port; - - $old_app->($env, @_); - }; -} -else { - # default to the configured WebPort and inform Plack::Runner - $port = RT->Config->Get('WebPort') || '8080'; - push @args, '--port', $port; -} - -push @args, '--server', 'Standalone' if RT->InstallMode; -push @args, '--server', 'Starlet' unless $r->{server} || grep { m/--server/ } @args; - -$r->parse_options(@args); - -delete $r->{options} if $is_fastcgi; ### mangle_host_port_socket ruins everything - -unless ($r->{env} eq 'development') { - push @{$r->{options}}, server_ready => sub { - my($args) = @_; - my $name = $args->{server_software} || ref($args); # $args is $server - my $host = $args->{host} || 0; - my $proto = $args->{proto} || 'http'; - print STDERR "$name: Accepting connections at $proto://$host:$args->{port}/\n"; - }; -} -eval { $r->run($app) }; -if (my $err = $@) { - handle_startup_error($err); + return RT::PlackRunner->app; } -exit 0; - -sub handle_startup_error { - my $err = shift; - if ( $err =~ /listen/ ) { - handle_bind_error(); - } else { - die - "Something went wrong while trying to run RT's standalone web server:\n\t" - . $err; - } -} +my $r = RT::PlackRunner->new( RT->InstallMode ? ( server => 'Standalone' ) : + $0 =~ /standalone/ ? ( server => 'Standalone' ) : + $0 =~ /fcgi$/ ? ( server => 'FCGI', env => "deployment" ) + : ( server => 'Starlet', env => "deployment" ) ); +$r->parse_options(@ARGV); +$r->run; -sub handle_bind_error { - - print STDERR <<EOF; -WARNING: RT couldn't start up a web server on port @{[$port]}. -This is often the case if the port is already in use or you're running @{[$0]} -as someone other than your system's "root" user. You may also specify a -temporary port with: $0 --port <port> -EOF - - if ($explicit_port) { - print STDERR - "Please check your system configuration or choose another port\n\n"; - } -} __END__ -- 1.7.11.3 -------- Final RT training for 2012 in Atlanta, GA - October 23 & 24 http://bestpractical.com/training We're hiring! http://bestpractical.com/jobs
