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"
249 @{ $cfg->{static}->{dirs} }
251 '<Directory '.$app->path_to($cfg->{root}).qq|>\n|
252 ." Options
+Indexes
-ExecCGI
+FollowSymLinks
\n"
253 ." Order allow
,deny
\n"
262 # Run the application under Apache's mod_fcgid
266 # sub configure_apache_fcgi {
267 # confess 'Unimplemented';
271 # given the context obj, return list of apache conf strings for each
272 # of the activated features
274 my ($class,$app) = @_;
276 if( $app->can('enabled_features') ) {
277 for ( $app->enabled_features ) {
278 push @confs, $_->apache_conf if $_->can('apache_conf');
284 # no arguments looks at the values of $self->{production_server} and
285 # $hostconf{shared_devel_server} to generate an access control
287 sub _apache_access_control_str {
288 my ($class,$cfg) = @_;
290 if ( $cfg->{production_server} ) {
291 # for production servers, allow connections from everywhere
293 # below is the access profile for a production webserver. allow connections from anywhere.
297 } elsif ( $cfg->{shared_devel_server
} ) {
298 # for a shared development server, allow connections from just
299 # a few places, and require passwords
300 my $auth_user_file = "/etc/cxgn/htpasswd-sgn";
302 or die "shared_devel_server enabled, but no htpasswd file ($auth_user_file) found. aborting configuration generation.";
304 # below is the access profile for a shared development server, only allow connections from a list of trusted hosts
307 AuthName "Development site; contact $cfg->{email} to request access"
309 AuthUserFile $auth_user_file
313 Allow from 127.0.0.0/16
314 Allow from 132.236.157.64/26
315 Allow from 128.253.40.0/26
316 Allow from 132.236.81.0/24
317 Allow from 128.84.197.64/26
322 # below is the access profile for a personal development server: only allow connections from 127.0.*.*
325 Allow from 127.0.0.0/16
326 Allow from 192.168.0.0/16
327 Allow from 172.16.0.0/12
328 Allow from 10.0.0.0/8
333 # three different windows into apache internals:
334 sub _apache_debugging
{
337 # 1.) the Apache server status plugin
338 # add a server-status location where you can monitor your
339 # you must run 'sudo a2enmod status' for this to work
340 <Location /server-status>
341 SetHandler server-status
346 Allow from *.sgn.cornell.edu
349 # 2.) the mod_perl status plugin
350 # add a /perl-status page where you can see mod_perl-specific status
352 <Location /perl-status>
353 SetHandler perl-script
354 PerlHandler Apache2::Status
359 Allow from *.sgn.cornell.edu
361 PerlSetVar StatusOptionsAll On
363 # 3.) support for interactive debugging of the mod_perl process
364 # enable apachedb if being run in debug mode
365 # under Debian, use it by running:
366 # sudo APACHE_RUN_USER=www-data APACHE_RUN_GROUP=www-data /usr/sbin/apache2 -D PERLDB -X
374 PerlFixupHandler Apache::DB
383 my $file = File
::Spec
->catfile(@_);
385 return $file if -w
$file;
387 my $dir = dirname
($file);
389 return $file if -w
$dir;
392 or do { my $r = mkpath
($dir); chmod 0755, $dir}
393 or die "cannot open log file '$file', dir '$dir' does not exist and I could not create it";
396 or die "cannot open log file '$file', dir '$dir' is not writable";