#!/usr/bin/perl # # # lib: Sys::Hostname, Getopt::Long, Fcntl::, POSIX:: # use strict; use Sys::Hostname; use Getopt::Long; use Fcntl; use POSIX qw(tmpnam); my %DEFAULT = ( 'search' => 'lj', 'ns1' => '10.2.0.1', ); my %MACHINE = ( "stan" => { 'ipco' => '10.0.0.3', 'do_web' => 1, 'web_slave' => 1, 'paid_web_slave' => 1, }, "kyle" => { 'ipco' => '10.0.0.4', 'do_web' => 1, 'web_slave' => 1, 'web_master' => 1, }, "wendy" => { 'ipco' => '10.0.0.5', 'do_web' => 1, 'web_slave' => 1, }, "bebe" => { 'ipco' => '10.0.0.6', 'do_web' => 1, 'web_slave' => 1, }, "terrance" => { 'ipco' => '10.0.0.7', 'do_web' => 1, 'web_slave' => 1, }, "phillip" => { 'ipco' => '10.0.0.8', 'do_web' => 1, 'web_slave' => 1, 'paid_web_slave' => 1, }, "ike" => { 'ipco' => '10.0.0.11', 'do_web' => 1, 'web_slave' => 1, }, "pip" => { 'ipco' => '10.0.0.12', 'do_web' => 1, 'web_slave' => 1, }, "kenny" => { 'ipco' => '10.0.0.1', 'db_slave' => 1, }, "cartman" => { 'ipco' => '10.0.0.2', 'db_master' => 1, }, "mackey" => { 'ipco' => '10.0.0.9', 'db_slave' => 1, }, "hat" => { 'ipco' => '10.0.0.10', 'db_slave' => 1, }, "marklar" => { 'ip' => '216.231.32.128', 'ipco' => '10.0.0.15', 'db_slave' => 1, }, ); my $machine = hostname(); unless ($machine =~ /^lj-(\w+)(\.livejournal\.com)?$/) { die "Weird hostname.\n"; } $machine = $1; my $DRY = 0; my $HELP = 0; exit 1 unless GetOptions( 'dryrun|n' => \$DRY, 'help' => \$HELP, ); if ($HELP || ! defined $MACHINE{$machine}) { die("Usage: machine_config.pl [opts]\n\nWhere opts can be:\n". "--dryrun -n Don't change any config files; just show changes.\n". "--help -h This message.\n"); } my $host = { %DEFAULT }; $host->{'name'} = $machine; foreach (keys %{$MACHINE{$machine}}) { $host->{$_} = $MACHINE{$machine}->{$_}; } print "Host information: ($host->{'name'})\n"; foreach (sort keys %{$host}) { printf " %10s : %s\n", $_, $host->{$_}; } setup_resolve_conf($host); setup_hosts($host); setup_httpd($host) if ($host->{'do_web'}); ##################### sub write_file { my $file = shift; my $new = shift; my $old; open (IN, $file); while () { $old .= $_; } close IN; if ($new ne $old) { if ($DRY) { my $tmp = tmpnam(); die "temp file exists!\n" if (-e $tmp); print "$file needs updating!\n"; open (OUT, ">$tmp"); print OUT $new; close OUT; print `diff -u $file $tmp`; unlink $tmp; } else { print "Updating: $file\n"; open (OUT, ">$file"); print OUT $new; close OUT; } } } sub setup_resolve_conf { my $host = shift; my $file = "/etc/resolv.conf"; my $new; if (exists($host->{'search'})) { $new .= "search\t$host->{'search'}\n"; } foreach my $ns (qw(ns1)) { next unless ($host->{$ns}); $new .= "nameserver\t$host->{$ns}\n"; } write_file($file, $new); } # NOTE: this used to do a lot more, before we had DNS running # internally. sub setup_hosts { my $host = shift; my $file = "/etc/hosts"; my $new; $new .= "127.0.0.1\tlocalhost\n"; write_file($file, $new); } sub setup_httpd { my $host = shift; my $file = "/usr/local/apache/conf/httpd.conf"; my $new; $new .= <<"END_CONF"; ServerType standalone ServerRoot "/usr/local/apache" PidFile /usr/local/apache/logs/httpd.pid ScoreBoardFile /usr/local/apache/logs/httpd.scoreboard Timeout 30 ## keep-alive KeepAlive Off MaxKeepAliveRequests 200 KeepAliveTimeout 50 MinSpareServers 15 MaxSpareServers 40 StartServers 170 MaxClients 255 MaxRequestsPerChild 0 # Dynamic Shared Object (DSO) Support # Note: The order is which modules are loaded is important. Don't change # the order below without expert advice. LoadModule vhost_alias_module libexec/mod_vhost_alias.so LoadModule env_module libexec/mod_env.so LoadModule config_log_module libexec/mod_log_config.so #LoadModule mime_magic_module libexec/mod_mime_magic.so LoadModule mime_module libexec/mod_mime.so #LoadModule negotiation_module libexec/mod_negotiation.so LoadModule status_module libexec/mod_status.so LoadModule info_module libexec/mod_info.so LoadModule includes_module libexec/mod_include.so LoadModule autoindex_module libexec/mod_autoindex.so LoadModule dir_module libexec/mod_dir.so LoadModule cgi_module libexec/mod_cgi.so #LoadModule asis_module libexec/mod_asis.so #LoadModule imap_module libexec/mod_imap.so LoadModule action_module libexec/mod_actions.so #LoadModule speling_module libexec/mod_speling.so #LoadModule userdir_module libexec/mod_userdir.so LoadModule alias_module libexec/mod_alias.so LoadModule rewrite_module libexec/mod_rewrite.so LoadModule access_module libexec/mod_access.so LoadModule auth_module libexec/mod_auth.so #LoadModule anon_auth_module libexec/mod_auth_anon.so #LoadModule dbm_auth_module libexec/mod_auth_dbm.so #LoadModule digest_module libexec/mod_digest.so #LoadModule proxy_module libexec/libproxy.so #LoadModule cern_meta_module libexec/mod_cern_meta.so LoadModule expires_module libexec/mod_expires.so #LoadModule headers_module libexec/mod_headers.so LoadModule usertrack_module libexec/mod_usertrack.so LoadModule unique_id_module libexec/mod_unique_id.so LoadModule setenvif_module libexec/mod_setenvif.so LoadModule fastcgi_module libexec/mod_fastcgi.so #LoadModule php4_module libexec/libphp4.so # Reconstruction of the complete module list from all available modules # (static and shared ones) to achieve correct module execution order. # [WHENEVER YOU CHANGE THE LOADMODULE SECTION ABOVE UPDATE THIS, TOO] ClearModuleList AddModule mod_vhost_alias.c AddModule mod_env.c AddModule mod_log_config.c #AddModule mod_mime_magic.c AddModule mod_mime.c #AddModule mod_negotiation.c AddModule mod_status.c AddModule mod_info.c AddModule mod_include.c AddModule mod_autoindex.c AddModule mod_dir.c AddModule mod_cgi.c #AddModule mod_asis.c #AddModule mod_imap.c AddModule mod_actions.c #AddModule mod_speling.c #AddModule mod_userdir.c AddModule mod_alias.c AddModule mod_rewrite.c AddModule mod_access.c AddModule mod_auth.c #AddModule mod_auth_anon.c #AddModule mod_auth_dbm.c #AddModule mod_digest.c #AddModule mod_proxy.c #AddModule mod_cern_meta.c AddModule mod_expires.c #AddModule mod_headers.c AddModule mod_usertrack.c AddModule mod_unique_id.c AddModule mod_so.c AddModule mod_setenvif.c AddModule mod_fastcgi.c #AddModule mod_php4.c ExtendedStatus On Port 80 END_CONF if ($host->{'ip'} && ! $host->{'web_slave'}) { $new .= "Listen $host->{'ip'}:80\n"; } $new .= <<"END_CONF"; Listen $host->{'ipco'}:80 User lj Group lj ServerAdmin webmaster\@livejournal.com ServerName lj-$host->{'name'}.livejournal.com DocumentRoot "/usr/local/apache/htdocs" SetHandler server-status Order deny,allow Deny from all Allow from 10.0 66.31.142.7 DirectoryIndex index.html index.bml Options Indexes FollowSymLinks ExecCGI #for speed, instead of "All" AllowOverride None Order allow,deny Allow from all SendBufferSize 131072 ####################################### END_CONF if ($host->{'ip'} && ! $host->{'web_slave'}) { $new .= "NameVirtualHost $host->{'ip'}:80\n"; } $new .= <<"END_CONF"; NameVirtualHost $host->{'ipco'}:80 FastCgiSuexec Off FastCgiConfig -maxClassProcesses 10 -startDelay 1 -idle-timeout 20 END_CONF if ($host->{'web_master'}) { $new .= <<"END_CONF"; # site's down message. Listen 10.0.0.4:81 NameVirtualHost 10.0.0.4:81 SetEnv LJHOME /home/lj FastCgiServer /home/lj/sites/sitedown/index.cgi -processes 1 ServerName livejournal.com ServerAlias *.livejournal.com DocumentRoot /home/lj/sites/sitedown/ DirectoryIndex index.cgi ErrorDocument 404 /index.cgi SetHandler fastcgi-script ### mrtg.livejournal.com Listen 10.0.0.4:88 NameVirtualHost 10.0.0.4:88 SetEnv LJHOME /home/lj ServerName mrtg.livejournal.com ServerAlias mrtg.livejournal.com ServerAdmin webmaster\@livejournal.com DocumentRoot /home/lj/sites/mrtg/ DirectoryIndex index.cgi AddHandler cgi-script .cgi Options -Indexes +ExecCGI # Putting netsaint's aliases here for now. Alias /netsaint/ /usr/local/netsaint/share/ ScriptAlias /cgi-bin/netsaint/ /usr/local/netsaint/sbin/ ErrorLog /dev/null TransferLog /dev/null END_CONF } $new .= " {'ip'} && $host->{'web_master'}) { $new .= " $host->{'ip'}:80"; } $new .= " $host->{'ipco'}:80>\n"; $new .=" SetEnv LJHOME /home/lj\n"; { my %fcgi = ('/home/lj/htdocs/users' => 10, '/home/lj/cgi-bin/log.cgi' => 4, '/home/lj/cgi-bin/404notfound.cgi' => 1, '/home/lj/htdocs/customview.cgi' => 4, '/home/lj/cgi-bin/bmlp.pl' => 7, '/home/lj/cgi-bin/sbmlp.pl' => 3, '/home/lj/htdocs/userpic' => 1); if ($host->{'name'} eq "kenny") { $fcgi{'/home/lj/htdocs/users'} = 5; $fcgi{'/home/lj/htdocs/customview.cgi'} = 2; $fcgi{'/home/lj/cgi-bin/bmlp.pl'} = 4; $fcgi{'/home/lj/cgi-bin/sbmlp.pl'} = 2; $fcgi{'/home/lj/cgi-bin/log.cgi'} = 2; } foreach my $app (sort keys %fcgi) { $new .= " FastCgiServer $app -processes $fcgi{$app} -initial-env LJHOME=/home/lj\n"; } } ########## rewrite stuff. no interpolation. $new .= <<'END_CONF'; RewriteEngine on RewriteLog /home/lj/logs/rewrite.log RewriteLogLevel 0 RewriteCond %{HTTP_HOST} ^(www\.)?livejournal\.com$ [NC] RewriteRule ^/~([a-z0-9_]+)(/?.*)$ /users/$1$2 [L,PT,NS] RewriteCond %{REQUEST_URI} !\.bml RewriteRule ^/community/([a-z0-9_]+)(/?.*)$ /users/$1$2 [L,PT,NS] RewriteCond %{HTTP_HOST} ^([a-z0-9_\-]+)\.livejournal\.com$ [NC] RewriteCond %1 !^www$ [NC] RewriteRule ^(.+) %{HTTP_HOST}$1 [C] RewriteRule ^([a-z0-9_\-]+)\.livejournal\.com(.+) /users/$1$2 [L,PT,NS] RewriteCond %{HTTP_HOST} ^(www\.)?livejournal\.com$ [NC] RewriteRule ^/confirm/([a-z0-9]+\.[a-z0-9]+) http://www.livejournal.com/register.bml?$1 [L,R] # if they send any Host header with letters (an IP address or blank # is okay) then it has to be www.livejournal.com or livejournal.com # (optional port, too) RewriteCond %{HTTP_HOST} [a-z] [NC] RewriteCond %{HTTP_HOST} !^(www\.)?livejournal\.com(:[0-9]+)?$ [NC] RewriteRule . . [F] END_CONF $new .= <<"END_CONF"; AddType text/rdf rdf AddType text/plain TCL AddType application/x-httpd-cgi CGI Options +ExecCGI ServerName lj-$host->{'name'}.livejournal.com ServerAlias livejournal.com *.livejournal.com ServerAdmin webmaster\@livejournal.com DocumentRoot /home/lj/htdocs/ ScriptAlias /cgi-bin/ /home/lj/cgi-bin/ ErrorDocument 403 /403.html END_CONF if ($host->{'paid_web_slave'}) { $new .= " ErrorDocument 500 /500-paid.html\n"; } else { $new .= " ErrorDocument 500 /500.html\n"; } $new .= <<"END_CONF"; ErrorDocument 404 /cgi-bin/404notfound.cgi # RedirectMatch 301 ^/users/?\$ http://www.livejournal.com/directory.bml AddType text/bml BML Action text/bml /cgi-bin/bmlp.pl AddType text/sbml SBML Action text/sbml /cgi-bin/sbmlp.pl DirectoryIndex index.html index.bml SetEnvIf Request_URI "^/img/" no-log SetEnvIf Request_URI "^/userpic/" no-log SetEnvIf Request_URI "^/status" no-log LogFormat "%h %l %u %t \\"%r\\" %s %b \\"%{Referer}i\\" \\"%{User-Agent}i\\" \\"%{Host}i\\"" ljlog ErrorLog "|/usr/local/apache/bin/rotatelogs /home/lj/logs/error-$host->{'name'} 3600" CustomLog "|/usr/local/apache/bin/rotatelogs /home/lj/logs/access-$host->{'name'} 3600" ljlog env=!no-log SetHandler fastcgi-script SetHandler fastcgi-script SetHandler fastcgi-script ErrorDocument 500 /500-log.html SetHandler fastcgi-script SetHandler fastcgi-script SetHandler fastcgi-script SetHandler fastcgi-script AllowOverride None Options None ExpiresActive on ExpiresByType image/gif "access plus 1 month" ExpiresByType image/jpeg "access plus 1 month" Deny from all Deny from all AuthUserFile /home/lj/pass-gen.txt AuthName "Brad only area" AuthType Basic require user bradfitz Options +Indexes Options -ExecCGI # backup image server (load balancer will prefer thttpd/tux/etc first) Listen $host->{'ipco'}:8081 NameVirtualHost $host->{'ipco'}:8081 {'ipco'}:8081> ServerName img.livejournal.com DocumentRoot /home/lj/htdocs/img DirectoryIndex index.html Options -ExecCGI # AccessFileName: The name of the file to look for in each directory # for access control information. # AccessFileName .htaccess Order allow,deny Deny from all Order allow,deny Deny from all Order allow,deny Deny from all UseCanonicalName Off TypesConfig /usr/local/apache/conf/mime.types ## MIME DefaultType text/plain MIMEMagicFile /usr/local/apache/conf/magic HostnameLookups Off ErrorLog "|/usr/local/apache/bin/rotatelogs /usr/local/apache/logs/error_log 86400" LogLevel error CustomLog /dev/null common ServerSignature On Alias /icons/ "/usr/local/apache/icons/" Options Indexes AllowOverride None Order allow,deny Allow from all # # FancyIndexing is whether you want fancy directory indexing or standard # IndexOptions FancyIndexing SuppressDescription SuppressColumnSorting FoldersFirst NameWidth=* # # AddIcon* directives tell the server which icon to show for different # files or filename extensions. These are only displayed for # FancyIndexed directories. # AddIconByEncoding (CMP,/icons/compressed.gif) x-compress x-gzip AddIconByType (TXT,/icons/text.gif) text/* AddIconByType (IMG,/icons/image2.gif) image/* AddIconByType (SND,/icons/sound2.gif) audio/* AddIconByType (VID,/icons/movie.gif) video/* AddIcon /icons/rpm.gif .rpm AddIcon /icons/debian.gif .deb AddIcon /icons/binary.gif .bin .exe AddIcon /icons/binhex.gif .hqx AddIcon /icons/tar.gif .tar AddIcon /icons/world2.gif .wrl .wrl.gz .vrml .vrm .iv AddIcon /icons/compressed.gif .Z .z .tgz .gz .zip AddIcon /icons/a.gif .ps .ai .eps AddIcon /icons/layout.gif .html .shtml .htm .pdf AddIcon /icons/text.gif .txt AddIcon /icons/c.gif .c AddIcon /icons/p.gif .pl .py AddIcon /icons/f.gif .for AddIcon /icons/dvi.gif .dvi AddIcon /icons/uuencoded.gif .uu AddIcon /icons/script.gif .conf .sh .shar .csh .ksh .tcl AddIcon /icons/tex.gif .tex AddIcon /icons/bomb.gif core AddIcon /icons/back.gif .. AddIcon /icons/hand.right.gif README AddIcon /icons/folder.gif ^^DIRECTORY^^ AddIcon /icons/blank.gif ^^BLANKICON^^ # # DefaultIcon is which icon to show for files which do not have an icon # explicitly set. # DefaultIcon /icons/unknown.gif ReadmeName README HeaderName HEADER IndexIgnore .??* *~ *# HEADER* RCS CVS *,v *,t AddEncoding x-compress Z AddEncoding x-gzip gz tgz AddType application/x-httpd-php .php AddType application/x-httpd-php-source .phps AddType application/x-tar .tgz BrowserMatch "Mozilla/2" nokeepalive BrowserMatch "MSIE 4\.0b2;" nokeepalive downgrade-1.0 force-response-1.0 BrowserMatch "RealPlayer 4\.0" force-response-1.0 BrowserMatch "Java/1\.0" force-response-1.0 BrowserMatch "JDK/1\.0" force-response-1.0 END_CONF write_file($file, $new); }