3 SGN::Deploy::Apache - deploy the SGN site on an Apache web server
11 ServerName sgn.localhost.localdomain
20 use lib '/crypt/rob/cxgn/curr/sgn/lib';
21 use lib '/crypt/rob/cxgn/curr/ITAG/lib';
22 use lib '/crypt/rob/cxgn/curr/Phenome/lib';
23 use lib '/crypt/rob/cxgn/curr/tomato_genome/lib';
24 use lib '/crypt/rob/cxgn/curr/Cview/lib';
25 use lib '/crypt/rob/cxgn/curr/cxgn-corelibs/lib';
26 use local::lib '/crypt/rob/cpan-lib';
28 use SGN::Deploy::Apache SGN => (
32 SGN_CONFIG => '/etc/cxgn/SGN.conf',
44 package SGN
::Deploy
::Apache
;
52 use File
::Path qw
/ mkpath /;
56 =head2 import( $app_class, %options )
59 Usage : use SGN::Deploy::Apache MyApp => ( vhost => 1, type => 'mod_perl' );
60 Returns : nothing meaningful
62 hash-style list of arguments as:
64 vhost => boolean of whether this
65 configuration should be applied
66 to the current virtual host (if true),
67 or the root Apache server (if false),
69 type => one of the deployment types listed below
71 env => hashref of environment variables to set. This
72 must be used instead of Apache's SetEnv or
73 PerlSetEnv in order for environment variables to
74 be available early enough to be used during
75 Catalyst's setup phases.
77 Side Eff: loads the app, and configures the Apache environment to
80 Configures the currently running Apache mod_perl server
81 to run this application.
85 In an Apache configuration file:
94 #the name of the virtual host we are defining
95 ServerName myapp.example.com
99 use local::lib qw( /usr/local/MyApp/local-lib );
100 use lib qw( /usr/local/MyApp/lib );
103 MyApp->setup_apache( vhost => 1, type => 'fcgi' );
115 $class->configure_apache( $app, @_ );
118 my ( $class, $app ) = @_;
119 Class
::MOP
::load_class
( $app );
121 for (qw( path_to config )) {
122 $app->can($_) or confess
"$class requires $app to support the '$_' method";
127 sub configure_apache
{
128 my ( $class, $app, %args ) = @_;
129 $args{type
} ||= 'fcgi';
131 if( my $env = $args{env
} ) {
132 $class->setup_env( $env );
135 my $setup_method = "configure_apache_$args{type}";
136 unless( $class->can($setup_method) ) {
137 croak
"'$args{type}' Apache configuration type not supported by $class";
139 $class->$setup_method( $app, \
%args );
142 # set the environment variables given in the hashref
144 my ( $class, $env_to_add ) = @_;
146 while( my ($k,$v) = each %$env_to_add ) {
152 my ($class, $args) = @_;
153 exists $args->{vhost
}
155 "'vhost' argument is required for apache mod_perl configuration\n";
157 require Apache2
::ServerUtil
;
158 require Apache2
::ServerRec
;
160 # add some other configuration to the web server
161 my $server = Apache2
::ServerUtil
->server;
162 # vhost currently being configured should be first in apache's list
163 $server = $server->next if $args->{vhost
};
168 =head1 SUPPORTED CONFIGURATION TYPES
172 Run the application as an Apache mod_perl handler.
176 sub configure_apache_mod_perl
{
177 my ( $class, $app, $args ) = @_;
179 # force CGI.pm into non-mod-perl mode so that the Catalyst CGI
180 # wrapping will work.
181 # notice that we do this BEFORE loading the app
185 $class->_load_app( $app );
187 my $server = $class->apache_server( $args );
189 my $app_name = $app->config->{name
};
190 my $cfg = $app->config;
191 -d
$cfg->{home
} or confess
<<EOM;
192 FATAL: Could not figure out the home dir for $app_name, it
193 guessed '$cfg->{home}', but that directory does not exist. Aborting start.
196 my $error_email = $cfg->{feedback_email
} || $ENV{SERVER_ADMIN
};
197 $server->add_config( $_ ) for map [ split /\n/, $_ ],
199 'ServerSignature Off',
201 # email address for apache to include in really bad error messages
202 qq|ServerAdmin
$cfg->{email
}|,
204 #where to write error messages
205 "ErrorLog ".$class->check_logfile( $cfg->{error_log
} ),
206 "CustomLog ".$class->check_logfile( $cfg->{access_log
} ).' combined',
208 # needed for CGI.pm compat
209 'PerlOptions +GlobalRequest',
211 ( 'ErrorDocument 500 "Internal server error: The server encountered an internal error or misconfiguration and was unable to complete your request.'
212 .( $error_email ?
<<"" : '"' )
213 Additionally
, an error report could
not be automatically sent
, please help us by informing us of the error at
$error_email."
217 # set our application to handle most requests by default
220 PerlResponseHandler
$app
222 . $class->_apache_access_control_str( $cfg )
225 $class->_conf_serve_static( $app ),
226 $class->_conf_features( $app ),
232 # return configuration for serving static files with Apache
233 sub _conf_serve_static {
234 my ( $class, $app ) = @_;
236 my $cfg = $app->config;
238 # serve files directly from the static/ subdir of the site,
239 # following the symlinks therein
243 my $dir = $app->path_to( $cfg->{root}, $url );
246 ." SetHandler
default-handler
\n"
251 @{ $cfg->{static}->{dirs} }
253 '<Directory '.$app->path_to($cfg->{root}).qq|>\n|
254 ." Options
+Indexes
-ExecCGI
+FollowSymLinks
\n"
255 ." Order allow
,deny
\n"
264 # Run the application under Apache's mod_fcgid
268 # sub configure_apache_fcgi {
269 # confess 'Unimplemented';
273 # given the context obj, return list of apache conf strings for each
274 # of the activated features
276 my ($class,$app) = @_;
278 if( $app->can('enabled_features') ) {
279 for ( $app->enabled_features ) {
280 push @confs, $_->apache_conf if $_->can('apache_conf');
286 # no arguments looks at the values of $self->{production_server} and
287 # $hostconf{shared_devel_server} to generate an access control
289 sub _apache_access_control_str {
290 my ($class,$cfg) = @_;
292 if ( $cfg->{production_server} ) {
293 # for production servers, allow connections from everywhere
295 # below is the access profile for a production webserver. allow connections from anywhere.
299 } elsif ( $cfg->{shared_devel_server
} ) {
300 # for a shared development server, allow connections from just
301 # a few places, and require passwords
302 my $auth_user_file = "/etc/cxgn/htpasswd-sgn";
304 or die "shared_devel_server enabled, but no htpasswd file ($auth_user_file) found. aborting configuration generation.";
306 # below is the access profile for a shared development server, only allow connections from a list of trusted hosts
309 AuthName "Development site; contact $cfg->{email} to request access"
311 AuthUserFile $auth_user_file
315 Allow from 127.0.0.0/16
316 Allow from 132.236.157.64/26
317 Allow from 128.253.40.0/26
318 Allow from 132.236.81.0/24
319 Allow from 128.84.197.64/26
324 # below is the access profile for a personal development server: only allow connections from 127.0.*.*
327 Allow from 127.0.0.0/16
328 Allow from 192.168.0.0/16
329 Allow from 172.16.0.0/12
330 Allow from 10.0.0.0/8
335 # three different windows into apache internals:
336 sub _apache_debugging
{
339 # 1.) the Apache server status plugin
340 # add a server-status location where you can monitor your
341 # you must run 'sudo a2enmod status' for this to work
342 <Location /server-status>
343 SetHandler server-status
348 Allow from *.sgn.cornell.edu
351 # 2.) the mod_perl status plugin
352 # add a /perl-status page where you can see mod_perl-specific status
354 <Location /perl-status>
355 SetHandler perl-script
356 PerlHandler Apache2::Status
361 Allow from *.sgn.cornell.edu
363 PerlSetVar StatusOptionsAll On
365 # 3.) support for interactive debugging of the mod_perl process
366 # enable apachedb if being run in debug mode
367 # under Debian, use it by running:
368 # sudo APACHE_RUN_USER=www-data APACHE_RUN_GROUP=www-data /usr/sbin/apache2 -D PERLDB -X
376 PerlFixupHandler Apache::DB
385 my $file = File
::Spec
->catfile(@_);
387 return $file if -w
$file;
389 my $dir = dirname
($file);
391 return $file if -w
$dir;
394 or do { my $r = mkpath
($dir); chmod 0755, $dir}
395 or die "cannot open log file '$file', dir '$dir' does not exist and I could not create it";
398 or die "cannot open log file '$file', dir '$dir' is not writable";