[Rt-commit] rt branch, 4.2/refactor-rt-server, created. rt-4.1.8-263-g5dcb6a0

Alex Vandiver alexmv at bestpractical.com
Tue May 7 15:24:28 EDT 2013


The branch, 4.2/refactor-rt-server has been created
        at  5dcb6a09115a8dbbaada237e10786c3f1f229099 (commit)

- Log -----------------------------------------------------------------
commit bb7f75874c5136c4b73cee5fe4621872741d68bd
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..90fbad4
--- /dev/null
+++ b/lib/RT/PlackRunner.pm
@@ -0,0 +1,187 @@
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
+#                                          <sales at bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
+# This work is made available to you under the terms of Version 2 of
+# the GNU General Public License. A copy of that license should have
+# been provided with this software, but in any event can be snarfed
+# from www.gnu.org.
+#
+# This work is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+
+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 c0e39bc..86f692b 100644
--- a/sbin/rt-server.in
+++ b/sbin/rt-server.in
@@ -94,7 +94,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.
@@ -136,127 +136,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 5dcb6a09115a8dbbaada237e10786c3f1f229099
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 86f692b..769a1a5 100644
--- a/sbin/rt-server.in
+++ b/sbin/rt-server.in
@@ -148,8 +148,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