Archiv für Januar 2010

Trac-Themes

Donnerstag, 28. Januar 2010

2 Jahre ist es jetzt in etwa her, dass ich einen Artikel über Eigene Templates in Trac geschrieben habe. Seitdem ist ein wenig passiert. Diesen Änderungen möchte ich hiermit Rechnung tragen. Ich habe das ganze Trac-Themes genannt, weil es weniger um Templating an sich gehen soll, sondern eher um eine Möglichkeit gemeinsame Styles festlegen zu können.

Leider ist es mit Trac immer noch nicht möglich unter einem Environment mehrere Projekte bzw. Repositories laufen zu lassen. Darum wird für jedes Projekt eine eigene Trac-Umgebung angelegt. Wichtig hierbei ist insbesondere für Firmen, dass alle Projekte zumindest in der Grundstruktur gleich aussehen und die Firmenfarben tragen.

“… was bisher geschah”

Wer zuerst probieren will, wie und was er alles anpassen kann, sollte sich das Verzeichnis templates unterhalb seiner Trac-Umgebung anschauen. Standardmäßig liegt dort die Datei site.html. Wenn man sie das erste Mal aufmacht, kommt sie sehr unscheinbar daher, denn wie man sieht, sieht man nichts. Nur einen html-Tag und ein paar unbekannt anmutende Python-Attribute.
Auf der Seite http://trac.edgewall.org/wiki/TracInterfaceCustomization ist glücklicherweise bereits ein Beispiel-Code für den Inhalt dieser Datei. Für jene, die gerne lieber mehrere Dateien nutzen wollen hier gleich die Anpassung mit Einbindung externer Dateien:

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:py="http://genshi.edgewall.org/"
      xmlns:xi="http://www.w3.org/2001/XInclude"
      py:strip="">

  <!--! Add site-specific style sheet -->
  <head py:match="head" py:attrs="select('@*')">
    ${select('*|comment()|text()')}
    <link rel="stylesheet" type="text/css"
          href="${href.chrome('common/style.css')}" />
  </head>

  <body py:match="body" py:attrs="select('@*')">
    <!--! Add site-specific header -->
    <div id="siteheader">
       <xi:include href="site_header.cs">
         <xi:fallback />
       </xi:include>
    </div>

    ${select('*|text()')}

    <!--! Add site-specific footer -->
    <div id="sitefooter">
      <xi:include href="site_footer.cs">
        <xi:fallback />
      </xi:include>
    </div>
  </body>
</html>

Interessanterweise funktioniert das einfache Anlegen einer site_header.cs und site_footer.cs nicht immer – bzw. bei mir hat das noch nie funktioniert -, wie es auf manchen Seiten beschrieben wird.
Mit diesem Grundgerüst ausgestattet lässt sich schon anfangen herumzuspielen. Für weiterführende Informationen zu Genshi und Clearsilver – den Engines im Hintergrund – sei auf folgende Seiten verwiesen:

Neue und alte Freunde

Ein altbekannter Helfer beim Erstellen von Templates ist auch in der Version 0.11.5 noch vorhanden. Der Konfigurationsparameter template_dir.

[inherit]
template_dir=

Mit diesem Parameter lässt sich das Verzeichnis für die Templates festlegen und wodurch verschiedene Seiten mit ein und demselben Template ausgestattet werden können.

Daneben ist ein neuer Freund dazugekommen der Parameter htdocs_location. Mit diesem Parameter werden alle internen URLs, die mit “common/” beginnen in die URL umgeschrieben, die als Wert angegeben wurde.

[trac]
htdocs_location=http://localhost/mytemplate

Führt, dazu, dass aus

<link rel="stylesheet" href="/trac/templating/chrome/common/css/trac.css" type="text/css" />

folgendes wird

<link rel="stylesheet" href="http://localhost/mytemplate/css/trac.css" type="text/css" />

Achtung! Leider hat die Sache einen Haken. Eigene Links aus der site.html werden nicht übersetzt. Der folgende Code

${href.chrome('common/style.css')}

wird nur in "/trac/templating/chrome/common/style.css" umgewandelt, aber nicht weiter.

Wichtig ist außerdem zu beachten, dass htdocs_location nur für statische Inhalte, wie Bilder, JavaScript- und CSS-Dateien gedacht ist. Templates werden nicht automatisch von dort erkannt. Diese müssen explizit über template_dir konfiguriert werden. Leider ist es hier nur möglich lokale Verzeichnisse zu setzen. Wer z.B. versucht eine Internetadresse anzugeben, bekommt zwar keine Fehlermeldung, wird aber mit einem Standard-Template “belohnt”.

Abschließend möchte ich sagen, dass – gefühlt – wesentlich mehr über die trac.ini konfigurierbar ist, als es noch vor 2 Jahren der Fall war. Das macht definitiv Lust auf mehr, aber dennoch bleibt das ein oder andere noch zu tun.

Recipe: Apache 2 mit Tomcat 6 auf Ubuntu 9.10 für “Gourmets”

Samstag, 23. Januar 2010

Das folgende Thema wurde schon an diversen Stellen mehr oder minder explizit beschrieben. Allerdings noch nicht aus meiner Sicht.

Was mir bei den meisten Howtos aufgefallen ist, dass sie schlechte Wartbarkeit hervorrufen und/oder irgendwas vergessen. Darum jetzt mein Versuch die Konfigurationsdateien der Welt unlesbar zu machen.

Die “Speisekarte” oder “Was will ich eigentlich”?

Tja. Für den einen oder anderen gezielten Sucher ist das schon klar, aber nochmal kurz für jene, die nur zufällig hier sind. Ich möchte in meiner URL nicht mehr http://localhost:8080 eingeben müssen um auf meinen Tomcat zu gelangen, sondern nur noch sowas wie http://tomcat.localhost. Ich hätte jetzt auch sagen können http://localhost, aber das wäre gelogen.

Installation der einzelnen Komponenten

Für die Installation nehme man eine Maus, Synaptic Paketverwaltung und zwei aussagekräftige Suchbegriffe wie tomcat6 und apache2. Für die Verknüpfung der beiden ist dann noch das Paket libapache2-mod-jk notwendig. Man würze das ganze mit einer Prise “Anwenden” und violá Apache 2 und Tomcat 6 sind installiert. Auf zu Schritt 2: die Dateien.

Die Dateien

Nichts läuft ohne eine anständige Konfiguration. Zur Vorbereitung lege man sich im Editor seiner Wahl folgende Dateien zurecht. Am besten mit sudo öffnen um darauf auch Schreibrechte zu haben.

  • /etc/apache2/sites-available/default
  • /etc/apache2/sites-available/mod_jk_vhosts
  • /etc/apache2/mods-available/jk.conf
  • /etc/apache2/workers.properties
  • /etc/tomcat6/server.xml
  • /etc/hosts

Die Dateien mod_jk_vhosts, jk.conf und workers.properties existieren höchstwahrscheinlich noch nicht. Darum diese bitte selbst anlegen.

Soweit diese “Vorspeise” abgeschlossen ist, wollen wir uns dem “Hauptgang” widmen: der Konfiguration

Die Konfiguration

Für die Konfiguration gehe ich jede der oben genannten Dateien einzeln durch und stelle eine mögliche Konfiguration vor. Diese Konfigurationen sind nur auf das notwendigste beschränkt. Falls weitere Optionen oder Alternativen notwendig sind, verweise ich gerne auf die entsprechenden Fachseiten.

mod_jk_vhost

Beginnen möchte ich mit der mod_jk_vhosts, da diese am umfangreichsten ist. Ich präsentiere … den Inhalt:

ServerName localhost
# NameVirtualHost *:80
<VirtualHost *:80>
	ServerName 127.0.0.2
	ServerAlias tomcat.localhost
	ServerAlias www.tomcat.localhost
	ServerAdmin webmaster@tomcat.localhost
	#Take note of the jsp content directory placement
	DocumentRoot /var/lib/tomcat6/webapps/
	<Directory "/var/lib/tomcat6/webapps/">
		Options Indexes FollowSymLinks +Includes
		AllowOverride All
		# DirectoryIndex index.jsp
	</Directory>
	#Mount the folders with jsp pages
	JkMount /* worker1
</VirtualHost>

<VirtualHost *:80>
	ServerName 127.0.0.3
	ServerAlias apache.localhost
	ServerAlias www.apache.localhost
	ServerAdmin webmaster@apache.localhost

	DocumentRoot /var/www
	<Directory />
		Options FollowSymLinks
		AllowOverride None
	</Directory>
	<Directory /var/www/>
		Options Indexes FollowSymLinks MultiViews
		AllowOverride None
		Order allow,deny
		allow from all
	</Directory>

	ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
	<Directory "/usr/lib/cgi-bin">
		AllowOverride None
		Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
		Order allow,deny
		Allow from all
	</Directory>

	ErrorLog /var/log/apache2/error.log

	# Possible values include: debug, info, notice, warn, error, crit,
	# alert, emerg.
	LogLevel warn

	CustomLog /var/log/apache2/access.log combined

    Alias /doc/ "/usr/share/doc/"
    <Directory "/usr/share/doc/">
	Options Indexes MultiViews FollowSymLinks
	AllowOverride None
	Order deny,allow
	Deny from all
	Allow from 127.0.0.0/255.0.0.0 ::1/128
    </Directory>
</VirtualHost>

Diese Datei wird anstelle der /etc/apache2/sites-available/default zukünftig für die Konfiguration des Apaches verwendet. Darum enthält sie auch große Teile der Original-Datei. Wenn der Inhalt der default-Datei anders aussieht, einfach den unteren Teil der mod_jk_vhosts-Datei mit dem Inhalt der default-Konfiguration abgleichen.

Zur Aktivierung der alternativen Konfiguration in der Konsole folgende Zeile ausführen:

sudo a2ensite mod_jk_vhosts

jk.conf

Die zweite Datei der ich mich widmen will, ist die jk.conf. Wie bereits erwähnt: sollte diese Datei noch nicht existieren, einfach unter dem oben genannten Pfad mit folgendem Inhalt speichern.

JkWorkersFile /etc/apache2/workers.properties
JkLogFile /var/log/apache2/mod_jk.log
JkLogLevel info

Die Konfiguration ist sehr minimalistisch. Mehr wird auch erstmal nicht benötigt. Es wird nur die Stelle für die Konfigurationsdatei angegeben, die Apache braucht um mit dem Tomcat zu sprechen und die Logging-Konfiguration, für den Fall, dass etwas schief läuft.
Damit diese Konfiguration auch berücksichtigt wird muss sie mit

sudo ln -s /etc/apache2/mods-available/jk.conf /etc/apache2/mods-enabled/

verlinkt werden.

workers.properties

Die workers.properties kann man als das Herzstück der Konfiguration bezeichnen, da sie die eigentliche Kommunikation zwischen Apache und Tomcat ermöglicht.

workers.tomcat_home=/usr/share/tomcat6
workers.java_home=/usr/lib/jvm/java-6-sun
ps=/
worker.list=worker1
worker.worker1.port=8009
worker.worker1.host=localhost
worker.worker1.type=ajp13
worker.worker1.lbfactor=1

Der Kürze halber will ich an dieser Stelle nicht die einzelnen Parameter erklären, sondern nur auf die offizielle Dokumentation verweisen.

server.xml

Als dritte Datei kommen wir zur /etc/tomcat6/server.xml. Diese enthält die allgemeine Server-Konfiguration für den integrierten Tomcat von Ubuntu. An dieser Datei müssen zwei Änderungen durchgeführt werden:

  1. Aktivierung von Port 8009 und
  2. Server-Aliase für unseren VirtualHost setzen.

Für 1. einfach nach port="8009" suchen und die Zeile auskommentieren, sodass es in etwa so aussieht

...
<!-- Define an AJP 1.3 Connector on port 8009 -->
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
...

Die Server-Aliase werden im Abschnitt Host eingetragen.

...
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">
  ...
  <Alias>www.tomcat.localhost</Alias>
  <Alias>tomcat.localhost</Alias>
  <Alias>127.0.0.2</Alias>
  <Alias>tomcat.localhost</Alias>
</Host>
...

/etc/hosts

Als letzten Schritt soll auch Ubuntu erfahren zu welchem Servernamen welche IP gehört. Darum in die /etc/hosts folgende Zeilen hinzufügen:

127.0.0.2 tomcat.localhost www.tomcat.localhost
127.0.0.3 apache.localhost www.apache.localhost

Das “Dessert”

Auf das Dessert freut man sich ja eigentlich am meisten. So auch hier. Nachdem alles konfiguriert wurde, einfach den Tomcat und den Apache neustarten:

sudo /etc/init.d/tomcat6 restart
sudo /etc/init.d/apache2 restart

Violá, wir sind finis … zumindest was meinen Versuchsaufbau angeht. Falls noch alles läuft, habe ich was falsch gemacht. Im Ernst: Falls Kommentare sind, weil etwas nicht funktioniert bitte ich um User-generierten Content ;)