January 7th, 2010
I found out today that tomcat virtual hosts are pretty lame. I thought that these all java based tomcat`s fancy plugins are much more powerful than old, simpleapache httpd. Well they aren`t. I wasn`t able to configure massive virtual hosting for servlets. I wanted to run diffrent web application based on domain name that comes in URL. For example myapp1.example.com would run application myapp1, myapp2.example.com would run myapp2, etc. And there could be hundreds of them so I didn`t want to add hundreds of entries in server.xml config file. I`m a lazy person
In order to configure virtual hosting based on above assumptions I used apache http server as a proxy to tomcat.
First you need to add wildcard records to your domain (example.com) so that records of all its subdomains can be resolved to IP address of your server. Following record should be added to your bind server zone config:
* IN A 1.2.3.4
where 1.2.3.4 is IP address of your server.
Next you need to configure httpd server. Please make sure that you have ajp proxy module installed on your server, as connections to tomcat are based on AJP protocol. On CentOS/RHEL 5 this module is included in standard httpd package (see /etc/httpd/conf.d/proxy_ajp.conf).
Now you need to create configuration for your virual hosts. I created a new file /etc/httpd/conf.d/tomcat-vhosting.conf:
UseCanonicalName Off
RewriteEngine On
# vhost map using perl script
RewriteMap vhost prg:/usr/local/bin/apache-getvhost.pl
# do no rewrite restricted names
RewriteCond %{SERVER_NAME} !^docs\.
RewriteCond %{SERVER_NAME} !^examples\.
RewriteCond %{SERVER_NAME} !^host-manager\.
RewriteCond %{SERVER_NAME} !^ROOT\.
# rewrite it
RewriteRule ^/(.*)$ ajp://localhost:8009/${vhost:%{SERVER_NAME}}/$1 [P]
Quite simple and cool, isn`t it?
I`m sure that you probably expected VirtualHost directives, but all you need is a powerfull rewriting feature of apache. This configuration allows to access myapp application located in tomcat`s webapps directory via http://myapp.example.com.
I used custom rewrite map which is a simple perl script. All it does is extract subdomain from server name based on URL.
Put the following in /usr/local/bin/apache-getvhost.pl
#!/usr/bin/perl
$| = 1;
while (<STDIN>) {
if (/(.*?)\.example\.com/) {
print $1."\n";
} else {
print $_."\n";
}
}
and make it executable
chmod +x /usr/local/bin/apache-getvhost.pl
Now all you need to do is provide some applications to tomcat.
Tags: apache, howto, tomcat
Posted in apache, howto, linux | No Comments »
December 22nd, 2009
This is my first post in english. I am sorry if there are some mistakes – it is not my native language
Recently I had to rename volume group in one of my virtual machines. It is based on CentOS (both dom0 and domU) and it was paravirtualized. I couldn`t do it on running system because root partition was on logical volume. I had to boot the machine in rescue mode. I had no idea how to boot from CD/DVD iso image – AFAIK it is impossible on pv guests. I had to boot vm directly from kernel and initrd used in installation (both are xen aware). So I copied them to /tmp/xen from /images/xen/ on CD/DVD installation disc.
Then I had to comment out the following line from vm`s config file to bypass pygrub bootloader:
#bootloader = "/usr/bin/pygrub"
Now I needed to tell my vm to use kernel and initrd I had previously copied so I added the following lines:
kernel = "/tmp/xen/vmlinuz"
ramdisk = "/tmp/xen/initrd.img"
extra = "rescue method=http://192.168.0.2/install/centos/"
The last line passes extra arguments to kernel. There is a rescue keyword and a method which tells anaconda installer to get install files from my http server.
After that I was able to boot vm in rescue and rename my LVM virtual group.
Tags: linux, lvm, xen
Posted in linux, virtualization | No Comments »
November 23rd, 2009
Bardzo intensywnie wykorzystuję wirtualizację jaką oferuje CentOS, czyli opensource`ową wersję Xena. W połączeniu z LVM można bardzo efektywnie zarządzać maszynami m.in. poprzez snapshoty. Dodatkowo zastosowanie LVM jako backendu storage`owego owocuje wysoką wydajnością.
Xen posiada również możliwość migracji maszyn. Funkcja ta znana jako live migration jest odpowiednikiem vmotion dla produktów VMware. Można ją wykorzystać jedynie w przypadku, gdy wszystkie serwery dom0 mają dostęp do współdzielonego storage`u. Najłatwiej jest wykorzystać zasób NFS podmontowany na wszystkich serwerach, a maszyny wirtualne instalować na plikach (obrazy dysków) tam umieszczonych. Oczywiście tracimy na wydajności, a poza tym NFS nie wydaje się dobrym pomysłem dla większych instalacji.
I tu z pomocą przychodzi klastrowa odmiana LVM (CLVM). W RHEL/CentOS demon zarządzający klastrową częścią LVM (clvmd) komunikuje się z menadżerem klastra RHCS (Red Hat Cluster Suite). Mi osobiście to niezbyt pasuje. Nie tylko chyba ja uważam, że twór RHCS nie jest jeszcze stabilny ani też łatwy w konfiguracji i zarządzaniu/utrzymaniu. Ale to już chyba temat na odrębny wpis. Ku czemu innemu zmierzam. Mianowicie bardzo zainteresował mnie ten wpis. Okazuje się, że jest możliwe zmuszenie CLVM do działania bez skonfigurowanego RHCS! Należy zamiast tego użyć openais, który i tak wchodzi w skład RHCS. Jako odrębna część jest jednak o wiele przyjemniejsza w zarządzaniu i konfiguracji. Zachęcony wspomnianym wpisem przystąpiłem do pracy. Udało mi się przerobić paczkę lvm2-cluster, tak aby linkowała się z openais. Wpis ten byłby chyba pierwszym howto w sieci opisującym ten proces dla systemów RHEL/CentOS. Niestety w trakcie działania pojawiają się wycieki w pamięci w demonie aisexec. Przy każdorazowym wysłaniu wiadomości do aisexec przez demon clvmd ten pierwszy rezerwuje około 6MB pamięci i nie zwalnia jej poprawnie. Kilkunastogodzinne próby nie przyniosły rozwiązania. Wielka szkoda. Byłaby to świetna wiadomość i dalsze pole do eksperymentowania. Liczę, że uda mi się jeszcze powrócić do tematu, a o rezultatach postaram się niezwłocznie poinformować.
Tags: centos, clvm, linux, lvm, xen
Posted in linux, virtualization | No Comments »
October 6th, 2009
Zdarzyło mi się niedawno dołączyć dodatkowy dysk do działającego już systemu celem utworzenia redundancji na wszystkich partycjach (lub też na wolumenach LVM). Wszystko to działo się na Ubuntu 8.04 LTS, a więc prawie na debianie
Całość procesu jest dość prosta i opisywana już w wielu artykułach w sieci ( m.in. tutaj ). Wszędzie niemalże wspomina się o ustawianiu typu partycji na fd, czyli Linux raid autodetect. Nazwa sugeruje, że ma to coś wspólnego z autowykrywaniem raidu. Otóż okazuje się, że miało w przeszłości. Parametry konfiguracyjny CONFIG_MD_AUTODETECT zniknął już jakiś czas temu z kernela i tym samym zniknęła też autodetekcja. Opisuje to ten artykuł. Jest tam geneza usunięcia autodetekcji i rozwiązanie problemu bootowania z raidu 1. Wiąże się to z odpowiednio wygenerowanym plikiem initramfs. Ja się złapałem na tym, że system nie wstawał poprawnie, gdyż liczyłem że odpowiednio poustawiane typy partycji zrobią swoje i podczas startu wszystkie macierze samoczynnie wystartują. Krótka analiza struktury initramfs i kilka minut na googlach przyniosły rozwiązanie. Musiałem powiadomić mdadm o istnieniu macierzy, a zatem po ich utworzeniu wywołać polecenie
mdadm --examine --scan >> /etc/mdadm.conf
Następnie należy wygenerować plik initramfs uwzględniający te zmiany – załączy on ten plik do swojego drzewa i podczas startu odpowiednio wywołany mdadm z poziomu initramfs wystartuje podane tam macierze.
W Ubuntu generujemy nowy initramfs dla obecnego kernela poleceniem
update-initramfs -u
Teraz już możemy cieszyć się mirrorowaną partycją /boot.
Tags: softraid
Posted in linux | No Comments »
August 21st, 2009
Potrzebowałem na szybko statystyk wydruków. Do tego skonstruowałem taki oto twór:
perl -ne 'print "$1 $2\n" if /(\d+\/[a-zA-z]+\/20\d{2}).*for job (\d+)\./' /var/log/cups/error_log|sort |uniq | awk '{print "insert into printouts values(\""$1"\","$2");"}'| sqlite3 printouts.db
Ten z pozoru niezgrabny jednolinijkowiec parsuje plik logów cupsa wyciągając z niego numer zadania i datę, a następnie wkłada to do prostej bazy sqlite`a.
Dzięki temu mogłem szybko wydobyć ilość wydruków na dzień. Przy niewielkiej modyfikacji można dołączyć inne pola i już grupować sobie w sqlu co tylko dusza zapragnie. Nie jest to może wyszukany przypadek – raczej ciekawostka. To samo można uzyskać również za pomocą uniq -c, ale perspektywy tego rozwiązania są o wiele większe.
Na koniec tylko polecenie tworzące trywialną strukturę bazy printouts.db:
sqlite3 printouts.db 'create table printouts(date text,job int)'
Tags: logs, oneliners
Posted in linux | No Comments »
August 12th, 2009
Na co dzień pracuję z aplikacją, która wyrzuca bardzo dużo “śmieci” do logów. Tym samym zapycha ona error log, który z nazwy powinien zawierać błędy, a nie informacje o niezainicjalizowanej zmiennej X. Postanowiłem ukrócić ten proceder i filtrować wychodzące z procesów apache`a komunikaty.
Wykorzystałem do tego perla, gdyż dość sprawnie radzi on sobie z obróbką tekstu i wyrażeniami regularnymi. Poniżej zawartość skryptu apache-logfilter.pl
#!/usr/bin/perl -w
use strict;
$|=1; # use unbuffered output
my $logfile;
# check if logfile was passed as 1st argument
if ($ARGV[0]) {
$logfile=$ARGV[0];
}
# assign /dev/null as logfile unless it is already defined
$logfile="/dev/null" unless ($logfile);
# set umask
umask 0022;
my $loghandler=open(LOGFILE,'>>',$logfile);
# autoflush file handler
select((select(LOGFILE), $| = 1)[0]);
# inifinite loop over input from STDIN
while (<STDIN>) {
# omit unwanted lines matching the following patterns
next if (/^Use of uninitialized value/);
next if (/^"my" variable/);
next if (/^Subroutine \w+ redefined/);
next if (/^Variable ".*?" will not stay shared/);
next if (/^Odd number of elements in hash/);
next if (/^Argument ".*?" isn't numeric/);
next if (/^Useless use of .*? in void context/);
next if (/^substr outside of string at/);
next if (/^Unquoted string ".*?" may clash/);
next if (/^Scalar value @.*? better written as/);
next if (/^Parentheses missing around/);
# print to our logfile
print LOGFILE "$_";
}
Posiadając już taki skrypt należy przekazać w konfiguracji apache`a jego wywołanie. Odbywa się to za pomocą pipe`a przez który przekazywane są komunikaty do skrypty. W tym przypadku jako parametr podana jest ścieżka do właściwego pliku logu, do którego dopisywane są wiadomości (nie należy zapomnieć o właściwiej konfiguracji logrotate!).
Przykładowa część konfiguracji:
ErrorLog "|/usr/local/bin/apache-logfilter.pl /var/log/apache/error_log"
Ciekawą rzeczą jaką napotkałem tutaj był problem buforowanego wyjścia. Otóż do logu nie docierały żadne nowe wiadomości. Wielokrotnie sprawdzałem poprawność skryptu i za każdym razem działał on poprawnie zapuszczony z palca. Po krótkich poszukiwaniach znalazłem zmienną $|, której to niezerowe ustawienie powinno mój problem rozwiązać. A jednak nie rozwiązało. Dopiero wymuszenie tego na uchwycie otwartego pliku dało pożądane rezultaty. Odpowiada za to następujące wywołanie:
select((select(LOGFILE), $| = 1)[0]);
Teraz wszystko śmiga jak należy – czytelność logów zwiększyła się znacząco, a ich rozmiar zmniejszył się kilkukrotnie.
Tags: apache, logs, perl
Posted in apache, linux | No Comments »
August 4th, 2009
Obecnie nie potrafię sobie wyobrazić porządnego debugowania/troubleshootingu bez strace`a. Dzięki niemu jestem w stanie śledzić wywołania systemowe i wychwytywać wszelkie błędy w oprogramowaniu w sytuacjach gdy logi już nie wystarczają. Dodatkowo zawsze jest to ciekawie obejrzeć działanie “od kuchni”.
Jak używać strace`a? Najłatwiej poprzedzić wywołanie programu poleceniem strace. Częściej jednak będziemy chcieli sprawdzić co robi dany proces uruchomiony już w tle. Wówczas należy wywołać:
strace -p PID_PROCESU
Jeśli program tworzy forki to również warto dodać parametr -f śledzący jego procesy potomne.
Tags: debug, linux
Posted in linux | No Comments »
July 29th, 2009
Kilka miesięcy temu narodził się w mej głowie pomysł utworzenia własnego bloga. Długo szukałem odpowiedniej domeny – niestety obecnie większość ciekawych nazw jest już powykupywana przez firmy liczące na zyski z odsprzedaży. Na szczęście tld eu pozostaje jeszcze niewyczerpaną studnią nazw, z której to wydobyłem właśnie slashroot.eu.
Blog ten będzie swoistego rodzaju notatnikiem, gdzie będę umieszczać ciekawe rozwiązania wymyślone lub też podpatrzone, wiążące się tematycznie z systemami operacyjnymi, sieciami, ciekawymi konfiguracjami, nieudokumentowanymi “ficzerami”, oraz wszystkim tym co będę uważał za istotne i czym chciałbym się podzielić z całą społecznością. Mam nadzieję, że będzie to pewnego rodzaju odwzajemniona przysługa jaką oddam za setki stron obecnych w internecie, z których to czerpałem i czerpię do tej pory wiedzę.
Jednocześnie postaram nie rozpisywać się za dużo na tematy osobiste i prywatne, gdyż nie leży to w mojej naturze. Dołożę natomiast wszelkich starań, aby strona ta zawierała ciekawą (chociażby dla googlujących) treść i aby jej aktualizacja odbywała się w miarę regularnie.
Tags: personal
Posted in personal | 1 Comment »