#!/usr/bin/perl
#
# Script to generate all necessary configuration files on a MacOS X Server
#
# robert.frank@stud.unibas.ch
# http://www.informatik.unibas.ch/personen/frank_r.html
#
use strict;
########################
# File local names.
my $jkLoadModuleName = 'jk_module'; # The names of the module to load and add in apache.
my $jkAddModuleName = 'mod_jk'; # For apache 1.x
my $propertiesFile = 'build.properties';
########################
# File locations, could be read from some other file, i.e. build.properties,
# should be system dependent!
my $workersFile; # Set from httpd conf file if present.
my $httpdConfigFile = '/etc/httpd/httpd.conf';
my $generatedIncludes = 'conf';
# Let's go look at the build.properties file ...
open(P, $propertiesFile) || die "Could not open the build.properties file\n";
my @properties =
;
close(P);
my @instance = grep { chomp(); /^\s*instance\.id=/ } @properties;
my (undef, $instance) = split(/=/, $instance[0]);
my @baseDir = grep { chomp(); /^\s*base\.dir=/ } @properties;
my (undef, $baseDir) = split(/=/, $baseDir[0]);
my @userDataDir = grep { chomp(); /^\s*userdata\.dir=/ } @properties;
my (undef, $userDataDir) = split(/=/, $userDataDir[0]);
$userDataDir =~ s/\${?base\.dir}?/$baseDir/;
my @logDir = grep { chomp(); /^\s*log\.dir=/ } @properties;
my (undef, $logDir) = split(/=/, $logDir[0]);
$logDir =~ s/\${?base\.dir}?/$baseDir/;
$logDir =~ s/\${?userdata\.dir}?/$userDataDir/;
my @apacheHostPort = grep { chomp(); /^\s*apache\.host\.port=/ } @properties;
my (undef, $apacheHostPort) = split(/=/, $apacheHostPort[0]);
my @apacheHostName = grep { chomp(); /^\s*apache\.host\.name=/ } @properties;
my (undef, $apacheHostName) = split(/=/, $apacheHostName[0]);
# Which OS are we running on?
my $os = `uname -s`; chomp($os);
my $version = `uname -r`; chomp($version);
# Set the OS dependent paths. Note that the workers file will be extracted from the httpd.conf
# if it is found!
if ($os eq 'Darwin') {
$version =~ s/\..*//;
$workersFile = '/etc/httpd/workers.properties' if (-f '/etc/httpd/workers.properties');
$httpdConfigFile = '/etc/httpd/httpd.conf' if (-f '/etc/httpd/httpd.conf');
} elsif ($os eq 'Linux') {
$workersFile = '';
$httpdConfigFile = '/etc/httpd/conf/httpd.conf' if (-f '/etc/httpd/conf/httpd.conf');
}
# elseif ... other oses
print "Starting analysis with the following parameters:\n".
" Instance : $instance\n".
" Base Directory : $baseDir\n".
" User Data Directory : $userDataDir\n".
" Log Directory : $logDir\n".
" Apache Host Name : $apacheHostName\n".
" Apache Host Port : $apacheHostPort\n".
" Httpd Configuration File : $httpdConfigFile\n".
"\n";
print "Httpd configuration file [$httpdConfigFile]? ";
my $c = ; chomp($c);
$httpdConfigFile = $c if ($c ne '');
################################ subroutine readConfig ############################################
# Check a httpd configuration file. This subroutine will recursively go through all included files.
my $vhost = 'global'; # The current section for which we are storing information.
my $vhostCount = 1;
my $haveLoadModule = 0; # Flag to signal neccessary loading of the jk module.
my $haveAddModule = 0; # Flag to signal neccessary adding of the jk module for apache 1.x
my %configs; # The hash with the collected information.
sub readConfig($) {
my $confFile = shift; # The (possibly included) config file to read.
open(H, $confFile) || return "Could not open $httpdConfigFile\n";
my @httpConf = ;
close(H);
foreach (@httpConf) {
chomp(); # Get rid of line endings, they disturb.
if ($vhost eq 'global') {
$haveLoadModule|= /^\s*LoadModule\s*$jkLoadModuleName/;
$haveAddModule|= /^\s*AddModule\s*$jkAddModuleName/;
}
if (/^\s*((JK|Server)[^\s]+)\s+(.*)/i) { # Capture all options starting with Jk or Server.
$configs{$vhost}{lc($1)} = $3;
if ($3 =~ /$instance\s*$/) {
$configs{$vhost}{'haveInstance'} = $confFile;
}
} elsif (/^\s*]+)>/) {
$vhost = 'V'.$vhostCount++; # We are now in a virtual host definition.
$configs{$vhost}{'VirtualHost'} = $1;
$configs{$vhost}{'file'} = $confFile;
} elsif (/^\s*<\/VirtualHost\s*>/) { # Ended a virtual host definition.
$vhost = 'global';
} elsif (/^\s*Include\s+"?([^"]*)"?/) { # Need this for the editor: "
my $file = $1; # Something was included here, see what it is.
if ($file =~ /([^\*]*)(.*\*.*)/) { # Do we have a '*' in the name?
my $dir = $1; # Yes, get all matching files.
my $pat = $2;
if (opendir(D, $dir)) {
$pat =~ s/\./\\\./g;
$pat =~ s/\*/\.\*/;
foreach (grep { /$pat/ } readdir(D)) {
readConfig($dir.$_);
}
}
} else {
readConfig($file); # No, just read the file.
}
}
}
}
############################################# httpd configuration #############################
print "\nAnalysing $httpdConfigFile and included files ...";
readConfig($httpdConfigFile);
print " done\n";
if (!($haveLoadModule || $haveAddModule)) {
print "You must load and enable the jk module , then rerun this script before you can use Olat.\n";
exit(1);
}
############################################# workders file #############################
if (defined($configs{'global'}{'jkworkersfile'})) {
$workersFile = $configs{'global'}{'jkworkersfile'};
} else {
print "Use the workers file [$workersFile]? ";
my $w = ; chomp($w);
$workersFile = $w if ($w ne '');
}
print "Analysing $workersFile ...";
# Check the workers file for any earlier entry.
open(W, $workersFile) || die "Could not open $workersFile\n";
my @workers = ;
close(W);
if (! grep { /^\s*worker\.list=.*$instance.*/ } @workers) {
my $cnt = @workers;
for (my $i = 0; $i < $cnt; $i++) {
if ($workers[$i] =~ /^\s*worker\.list=.*$instance.*/) {
$workers[$i].= ", $instance";
}
}
# Add the worker to the end, this should be read from the output of the build!
push(@workers, "worker.$instance.type=ajp13\n");
push(@workers, "worker.$instance.host=localhost\n");
push(@workers, "worker.$instance.port=8009\n");
push(@workers, "#worker.$instance.lbfactor=3.5\n");
}
print " done\n";
############################################# generate workers file #############################
# Output the possibly updated workers file.
open(O, ">$generatedIncludes/workers.properties") || die "Could not open workers.properties.generated\n";
print O "@workers";
close(O);
############################################# generate includes #############################
foreach my $vhost (sort keys %configs) {
# foreach my $entry (sort keys %{$configs{$vhost}}) {
# print " $entry: ".$configs{$vhost}{$entry}."\n";
# }
my $vname = defined($configs{$vhost}{'servername'})?$configs{$vhost}{'servername'}:$vhost;
my $comment = ($vname eq 'global')?"(Not recommended) ":"";
print "\nAdd Olat to $vname? $comment (yes, no, ) [no] ";
my $a = ; chomp($a);
if ($a =~ /y(es)?/i) {
if (defined($configs{$vhost}{'haveInstance'})) {
my $notSame = ($configs{$vhost}{'file'} ne $configs{$vhost}{'haveInstance'})?("\n(defined in ".$configs{$vhost}{'file'}.
")\n"):"";
print "This virtual host ".$configs{$vhost}{'file'}.$notSame.
"already has a mount of this instance defined in the file\n".
$configs{$vhost}{'haveInstance'}.
"\nYou will have to remove this definition before including the one generated.\n";
}
open(I, ">$generatedIncludes/httpd.conf.$vhost") || die "Could not open httpd.conf.$vhost for writing\n";
# Generate an include file
if (!defined($configs{$vhost}{'jkworkersfile'}) && !defined($configs{'global'}{'jkworkersfile'})) {
print I " JkWorkersFile \"$baseDir/$generatedIncludes/$workersFile\"\n";
}
if (!defined($configs{$vhost}{'jklogfile'}) && !defined($configs{'global'}{'jklogfile'})) {
print I " JkLogFile \"$logDir/mod_jk.log.txt\"\n".
" JkRequestLogFormat \"%w %V %T %r\"\n".
" JkLogLevel info\n";
}
# This MUST be read from a file which generated the appropriate entries!!! Just read the generated file
# and then print instead of the following.
print I " JkOptions +ForwardURICompatUnparsed\n".
" JkMount /$instance/* $instance\n".
" JkMount /$instance $instance\n".
" \n".
" AllowOverride None\n".
" deny from all\n".
" \n".
"\n".
" AddType text/html .html .htm\n".
" AddType image/x-icon .ico\n".
"\n".
" ## OLAT monitoring alias\n".
" Alias /monitoring \"$userDataDir/monitoring\"\n".
" Alias /webalizer \"$userDataDir/webalizer\"\n".
"\n".
" ## Security settings\n".
" \n".
" Options Indexes IncludesNoExec FollowSymLinks\n".
" AllowOverride All\n".
" Order deny,allow\n".
" Allow from all\n".
" \n".
" \n".
" Options -Indexes IncludesNoExec FollowSymLinks\n".
" AllowOverride None\n".
" \n".
" \n".
" Options -Indexes IncludesNoExec FollowSymLinks\n".
" AllowOverride None\n".
" \n";
close(I);
print "\n--\nYou must include '$baseDir/$generatedIncludes/httpd.conf.$vhost'\nin the httpd configuration file\n".$configs{$vhost}{'file'}."'\n"
}
}
exit(0);