[Rt-commit] rt branch, 4.2/refactor-rt-server, created. rt-4.0.1-241-g25b8fea
Alex Vandiver
alexmv at bestpractical.com
Thu Jul 21 13:47:53 EDT 2011
The branch, 4.2/refactor-rt-server has been created
at 25b8fea1e3c0c1d8d6986e28f4896be6a4b0e5d4 (commit)
- Log -----------------------------------------------------------------
commit 533a3e327543254597ba0c61ad196063be98d524
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Mon Jun 20 21:58:30 2011 -0400
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.in b/sbin/rt-server.in
index bb4c664..1b0ae0b 100755
--- a/sbin/rt-server.in
+++ b/sbin/rt-server.in
@@ -92,7 +92,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.
@@ -134,127 +134,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';
+ return RT::PlackRunner->app;
}
-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;
-}
+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;
-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);
-}
-
-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;
- }
-}
-
-
-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__
commit 25b8fea1e3c0c1d8d6986e28f4896be6a4b0e5d4
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Thu Jul 21 13:12:56 2011 -0400
Catch and fix var/ when rt-server is incorrectly run as root
rt-server often gets incorrectly run as root for testing, leaving the
mason cache later un-writable by the real web user (when run as fastcgi,
for example). Attempt to correct for this by chown'ing the var path to
the web user and group if we were run as root.
diff --git a/sbin/rt-server.in b/sbin/rt-server.in
index 1b0ae0b..7ba983a 100755
--- a/sbin/rt-server.in
+++ b/sbin/rt-server.in
@@ -146,8 +146,15 @@ my $r = RT::PlackRunner->new( RT->InstallMode ? ( server => 'Standalone' ) :
$0 =~ /fcgi$/ ? ( server => 'FCGI', env => "deployment" )
: ( server => 'Starlet', env => "deployment" ) );
$r->parse_options(@ARGV);
-$r->run;
+# Try to clean up wrong-permissions var/
+$SIG{INT} = sub {
+ local $@;
+ system("chown", "-R", "@WEB_USER@:@WEB_GROUP@", "@RT_VAR_PATH_R@");
+ exit 0;
+} if $> == 0;
+
+$r->run;
__END__
-----------------------------------------------------------------------
More information about the Rt-commit
mailing list