So
Feb
01

2009

Benchmarking mit ab und autobench

autobench Diagramm

Vor kurzem habe ich ein wenig zum Thema Benchmarking geschrieben. Dieses Thema ist für viele Entwickler ein Buch mit sieben Siegeln. Deswegen hier ein paar erklärende Worte, wie man auf einfache Art und Weise eine aussagekräftige Messung inklusive vorzeigbarem Graphen für den eigenen Webserver generieren kann.

Das Problem

Niemand weiß so recht, wie schnell ein Webserver eigentlich ist und wie viele Anfragen er verarbeiten kann, bis er zusammenbricht. Abwarten, bis der GAU eintritt, ist die schlechteste Variante, dem Problem zu begegnen. Besser ist es, einen Benchmark durchzuführen, um die Skalierfähigkeit eines Servers einschätzen zu können. Antwortet des Server zu langsam auf Anfragen, bleiben eventuell Besucher fern und es wäre an der Zeit, über Lastverteilung oder einen dickeren Server nachzudenken.

Der einfachste Ansatz: ab

Jeder Apache-Webserver bringt von Hause aus ab mit. ab funktioniert denkbar einfach (Eingabe im Terminal/Kommandozeile/Shell):

ab -c 20 -n 100 http://127.0.0.1/

In diesem Fall werden 20 gleichzeitige Benutzer (concurrent requests) mit 100 Anfragen (number of requests) an den Webserver unter der Adresse 127.0.0.1 geschickt1. In diesem Fall wird die index.html meines lokalen Webservers ausgeliefert, was in der Regel schnell ablaufen dürfte. Die Ausgabe von ab bestätigt dies:


This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient)…..done

Server Software: Apache/2.2.9
Server Hostname: 127.0.0.1
Server Port: 80
Document Path: /
Document Length: 1456 bytes
Concurrency Level: 20
Time taken for tests: 0.081 seconds
Complete requests: 100
Failed requests: 0
Write errors: 0
Total transferred: 186000 bytes
HTML transferred: 145600 bytes
Requests per second: 1240.46 [#/sec] (mean)
Time per request: 16.123 [ms] (mean)
Time per request: 0.806 [ms] (mean, across all concurrent requests)
Transfer rate: 2253.19 [Kbytes/sec] received

Connection Times (ms)

min mean [+/-sd] median max
Connect: 0 0 0.3 0 1
Processing: 10 15 4.9 13 29
Waiting: 3 14 5.1 13 29
Total: 10 15 5.0 13 29

Percentage of the requests served within a certain time (ms)
50% 13
66% 14
75% 15
80% 19
90% 25
95% 27
98% 29
99% 29
100% 29 (longest request)

Diesen Test kann man nun mehrfach durchführen und den Wert für -c jeweils anpassen. Von -c 10 bis -c 150 oder noch weiter. Aus den erhaltenen Werten läßt sich nun ein Diagramm in Excel oder OOo.

Wenn es dem Apachen zu viele Anfragen werden, schaltet er einfach ab (Connection reset by peer):


Macintosh:~ stephan$ ab -c 150 -n 2000 http://127.0.0.1/
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient)
Completed 200 requests
Completed 400 requests
Completed 600 requests
Completed 800 requests
Completed 1000 requests
Completed 1200 requests
Completed 1400 requests
Completed 1600 requests
apr_socket_recv: Connection reset by peer (54)
Total of 1688 requests completed

Kurzer Exkurs in die Konfiguration des Apache

Warum wurde die Verbindung zurückgesetzt? Die Lösung findet sich (für den Apache 2.x unter Mac OS X 10.5.6) in der Datei /etc/apache2/extra/httpd-mpm.conf

<IfModule mpm_prefork_module>
  StartServers         1
  MinSpareServers      1
  MaxSpareServers     10
  MaxClients         150
  MaxRequestsPerChild  0
</IfModule>

Wenn der Wert für -c über dem Wert von MaxClients gesetzt wird, reagiert der Webserver per Definition nicht mehr auf diese Benutzer. Allerdings ist die Anzahl der Anfragen pro Client hier nicht begrenzt. Eine genaue Auseinandersetzung mit den Einstellungsmöglichkeiten und der Performanceoptimierung von Webservern ist jedoch nicht das Thema hier, sondern das Messen der Performance.

Komfortables Benchmarking mit autobench

Auf dem Mac kann man autobench unter anderem mit den MacPorts installieren:

$ sudo port install autobench

Zur Erzeugung von Graphen ist außerdem das Programm gnuplot notwendig:

$ sudo port install gnuplot

Ich vermute, dass die Installation von gnuplot nicht ganz korrekt verläuft, da bench2graph (in einem späteren Arbeitsschritt) unter OS X nicht funktioniert.

Die Funktionsweise von autobench

autobench ist ein Perl-Skript, welches httperf mit ansteigender Anzahl an Abfragen startet und die wesentlichen Ergebnisse in einer Komma- (csv) oder Tabulator-separierten (tsv) Datei abspeichert. Diese Datei wiederum kann als Grundlage für Graphen genutzt werden.

Das Prinzip ist also ähnlich wie bei einer Testreihe mit ab. Allerdings sieht man bereits an der Konfiguration, dass httperf bzw. autobench dem Benutzer etwas mehr abverlangt.

Konfiguration von autobench

.autobench.conf im Heimverzeichnis des Anwenders beinhaltet die Standardkonfiguration von autobench. Auf den ersten Blick zeigt sich ein deutlicher Unterschied zur Arbeit mit ab: Es können zwei Server konfiguriert (host1 und host2). Da hier jedoch nur ein Server getestet werden soll, konfiguriere ich nur host1. Die wesentlichen und in unserem Beispiel relevanten Einstellungen sehen wie folgt aus:

host1 = localhost
uri1  = /
port1 = 80
low_rate  = 10
high_rate = 200
rate_step = 10
num_conn  = 5000
num_call  = 10
timeout   = 5
output_fmt = tsv

autobench schickt also Anfragen an den Server localhost (127.0.0.1) auf Port 80 an die dort hinterlegte Startseite (in diesem Fall index.html). Begonnen wird mit 10 gleichzeitigen Verbindungen (low_rate) und 10 Anfragen (num_call) bei insgesamt 5000 Verbindungen für den einzelnen Testlauf (num_con). Pro Testlauf wird nun die Anzahl gleichzeitiger Verbindungen um 10 (rate_step) erhöht, bis sie 200 (high_rate) erreicht. Wenn der Webserver nicht innerhalb von 5 Sekunden (timeout) antwortet, so wird dies von autobench als Fehler gewertet. Das Ergebnis wird im tsv-Format (output_fmt) ausgegeben.

Ein Testlauf mit autobench

Es gibt prinzipiell zwei Möglichkeiten, autobench aufzurufen. Einerseits so, dass die Ergebnisse dargestellt werden und andererseits so, dass die Ergebnisse in einer Datei protokolliert werden. Gibt man auf der Kommandozeile keine expliziten Parameter an, dann werden die Einstellungen der .autobench.conf genutzt.

$ autobench —single_host —file bench.tsv

Mit —single_host wird autobench angewiesen, nur die Einstellungen für host1 zu verwenden, der Parameter —file zeigt an, dass die Ergebisse in die Datei bench.tsv geschrieben werden sollen.

Je nach Konfiguration heißt es jetzt ein bißchen warten. Wer gerne sehen möchte, was passiert, kann entweder auf der Konsole zusehen oder eine zweite Shell öffnen und dem Logfile beim Wachsen zusehen:

$ tail -f bench.tsv

Graphen mit bench2graph

Im Normalfall ist der nächste Schritt nach dem eigentlichen Test die Aufbereitung der Ergebnisse. Unter Mac OS X ist es mir leider nicht gelungen, mit gnuplot und bench2graph die tsv-Datei zu verarbeiten. Es kam immer dieselbe Fehlermeldung:


$bench2graph bench2.tsv result.ps
-n Enter the title :
Der Titel meines Benchmarking Graphen

-n plot
^
“gnuplot.cmd”, line 8: invalid command

Da ich kein Experte für gnuplot bin, habe ich einen einfachen (Um-)Weg gewählt (unter Ubuntu funktionierte die Erstellung des Graphen einwandfrei).

1 Natürlich muss der Wert für -c immer kleiner als der von -n sein, sonst gäbe es Benutzer, die keine Anfragen stellen würden und der Befehl in sich wird sinnlos.

Sa
Jan
17

2009

Benchmarking und Load-Tests von Webservern

Loadtesting mit jMeter

Help! My boss wants me to load test our web app titelt die Dokumentation von jMeter, dem vermutlich bekanntlichtesten Werkzeug für die Analyse von Webserverleistung. Ein kurzer Blick offenbart recht schnell, dass man nicht mal eben so nebenbei einen Lasttest eines Webserver bzw. einer Webseite durchführen kann, und sofort aussagekräftige Werte hat.

Wichtigste Frage, bevor überhaupt ein Test stattfinden kann, ist, für wie viele Benutzer ein Server dimensioniert wurde und wie viele Benutzer durchschnittlich erwartet werden. Es gibt bei den Tests einen Unterschied zwischen Benchmarking und Lasttests. Bei einem Benchmark will man herausfinden, wie schnell ein Server antworten kann. Das kennt manch einer aus den Balkendiagrammen, die die Geschwindigkeit neuer Computer gegenüber denen aus dem Vorjahr darstellen. Lasttests hingegen werden häufig auch genutzt um herauszufinden, ab wann ein Server in die Knie geht, wo eine Leistungsgrenze ist. Ähnlich wie beim Sporttest beim Arzt, wenn man mit hochrotem Kopf auf dem Ergometer sitzt und gegenüber der Sprechstundenhilfe nicht zugeben will, dass man eigentlich schon seit 85 Watt Belastung außer Puste war, aber dennoch den Ehrgeiz hat, auch die 185 noch für fünf Minuten zu überstehen.

Die Interpretation der Ergebnisse ist mitunter etwas schwierig, muss man sich vor dem Test doch im Klaren sein, was man eigentlich messen möchte. Einerseits kann es also darum gehen, eine Aussage über die Leistungsfähigkeit eines Systems zu treffen. Das würde in etwa so klingen:

Im Schnitt kann der Server eine Million Anfragen am Tag abarbeiten, vorausgesetzt, dass sie sich exakt gleich über den Tag verteilen und auch keine komplexeren Anfragen, als jene aus dem Test darstellen.

Andererseits kann man aber auch einen Lasttest verwenden, um zu sehen, wo eventuell Fehler in der Programmierung einer Seite oder der Konfiguration von Serverkomponenten sind. Wo liegen die Schwachstellen eines Systems: in der Datenbank, der Anwendungslogik oder am Load-Balancer davor?

Es sollte jedem klar sein, dass ein Leistungstest nur dann sinnvoll ist, wenn ein Server nicht bereits produktiv eingesetzt wird. Führt man im Live-Betrieb einen Lasttest zum Beispiel gegen amazon.de durch, dann heißt das DOS und ist nicht legal (es sei denn natürlich, dass man der Eigentümer von amazon.de wäre, aber dann wäre es tatsächlich hirnverbrannt, seine eigene Seite vorsätzlich abzuschießen).
Ganz abgesehen davon sind die Testergebnisse auch überhaupt nicht aussagekräftig, da ja die anderen Anfragen nicht gesteuert werden und somit der Statistik entkommen.

Anleitungen für das Testen von Webseiten gibt es zuhauf im Internet. Load testing for webservers von Lukas Beeler sei hier stellvertretend genannt. Aber einen Test durchzuführen, ohne sich mit dem zu testenden System zumindest ansatzweise auszukennen, ist wenig zielführend.

Die verfügbaren Werkzeuge sind zahlreich. Neben apache benchmark und siege gibt es natürlich auch noch Programme, die komplexere Testszenarien unterstützen. Hierzu zählt beispielsweise Selenium.

Eine (etwas veraltete) Übersicht über Linux Test Tools bei SourceForge bildet generel einen ganz guten Einstieg ins Thema Testing unter Linux-Systemen.

Prinzipiell ist es mittlerweile nahezu ein Kinderspiel geworden, die verfügbaren Programme zum Test zu nutzen und ein paar Zahlen zu generieren. Allerdings ist die Interpretation der Ergebnisse nicht ganz leicht und abhängig von der Testkonstellation. Mit ein wenig Geduld und Spucke kann man sich aber sehr einfach in das Thema einarbeiten und dann auch aussagekräftige Analysen von Servern und Seiten durchführen.

Softwareliste:

Weiterführende Links:

So
Mai
04

2008

Praktische Hashes of Arrays

Einer der recht häufig besuchten Artikel hier im Blog ist Hashes of Arrays oder Hashes of Hashes. Allem Anschein nach besteht noch immer großes Interesse an praktischen Beispielen für deren Anwendung in Perl. Dem soll nun Rechnung getragen werden.

Die Aufgabe:

Meine MP3- (und inzwischen AAC-)Sammlung ist mittlerweile recht groß. Leider sind auch die Lautstärkeschwankungen zwischen zwei Alben ziemlich ausgeprägt, so dass ich mittels aacgain eine Anpassung vornehmen möchte1.

Der Code:

Listing 1: aacgain.pl
#Code
0001#!/usr/bin/perl -w
0002# aacgain.pl benoetigt ein ausfuehrbares aacgain im pfad
0003# v1 - 02.05.2008 - initial release
0004print "### aacgain.pl ###\n";
0005use strict;
0006use DirHandle;
0007use Cwd;
0008use File::Find;
0009 
0010# Variablendeklaration
0011my ( %directories, @files, $current_directory, $options, $command );
0012 
0013&show_help
0014 if $ARGV[0] =~ /^(help|-h|h|--help|\?|-\?)/; # zeige Hilfetext wenn notwendig
0015 
0016@ARGV = qw(.)
0017 unless @ARGV; # suche im Startverzeichnis, wenn nichts anderes angegeben wurde
0018$options = '-a -k'; # Album-Modus, kein clipping, 89db (Standardeinstellung)
0019 
0020# Finde alle Songs im angegebenen Verzeichnis inkl. Unterverzeichnisse
0021find( \&find_songs, @ARGV );
0022 
0023&process_files;
0024 
0025sub find_songs {
0026 return
0027 unless /(\.m4a|\.mp3)/; # finde nur Dateien, mit entsprechender Endung
0028 $current_directory = cwd;
0029 push( @{ $directories{$current_directory} }, $_ );
0030}
0031 
0032sub process_files {
0033 foreach my $key ( keys %directories ) {
0034 @files = qw//;
0035 foreach ( @{ $directories{$key} } ) {
0036 push @files, $key . '/' . $_;
0037 }
0038 $command = 'aacgain ' . $options; # konstruiere den aacgain-Befehl
0039 foreach (@files) {
0040 $command .= ' ' . "\"$_\"";
0041 }
0042 print qx($command); # fuehre aacgain aus und zeige die Ausgabe
0043 }
0044}
0045 
0046sub show_help {
0047 print "aacgain.pl erlaubt die Mehrfachbearbeitung von MP3/AAC-Dateien.\n";
0048 print "Hierzu werden alle Unterverzeichnisse nach Dateien durchsucht.\n";
0049 print "Songs innerhalb eines Ordners werden als Album behandelt.\n";
0050 print "Syntax: perl aacgain.pl <Verzeichnisname>\n";
0051 exit;
0052}
0053 

Code herunterladen
[Downloads: 623]

Dies ist ein recht kurzes Beispiel, wie Hashes of Arrays genutzt werden können. Im Hash %directories werden die Verzeichnisse hinterlegt, in denen Songs (mit den Endungen mp3 oder m4a) gefunden wurden. Entscheidend ist Zeile 29, die Speicherung der Suchergebnisse:

Hier werden die gefundenen Songs in ein Array gepusht, welches innerhalb eines Hashes existiert. Der Key des Hashes ist der Speicherort der Musikdateien, Inhalt des Verzechnisses ist ein Array aus den gefundenen Dateinamen.

Die eigentliche Verarbeitung der Songs erfolgt in zwei foreach-Schleifen.

Für jedes Verzeichnis (=Element des Hashes) sollen die darin enthaltenen Dateien (=Elemente des Arrays) verarbeitet werden. Das Kommando hat folgende Syntax:

aacgain -a -k /path/to/song1 /path/to/song2

Um etwaige Leerzeichen im Pfad- oder Songnamen zu unterstützen werden die Dateinamen in Anführungszeichen gesetzt. Eine Rückmeldung von aacgain wird durch die qx in Verbindung mit print ermöglicht.

Damit ich das Programm auch in der nächsten Woche noch verstehen kann, gibt es eine minimale Hilfefunktion und großzügige Kommentare im Quelltext.

1 Ja, mir ist bewusst, dass man dieses Problem auch mit MacMP3Gain lösen kann, aber mit Perl macht es mehr Spaß. aacgain kann man auf dem Mac übrigens mit MacPorts einfach und schnell selbst kompilieren.

Do
Jun
07

2007

Remotezugriff auf OpenWrt-Router (Updated)

Lange Zeit hatte ich einen Account bei dyndns. Dadurch konnte ich meinen Rechner zuhause trotz DSL aus dem Internet ansprechen. Die dynamisch vergebene IP-Adresse wurde automatisch durch eine Helferapplikation bei dyndns mit einem URL verbunden.

Inzwischen bin ich weg von dyndns, ich brauche es eigentlich auch gar nicht. Dank meines Asus-Routers mit OpenWrt kann ich zeitgesteuert meine IP-Adresse zuhause in eine Textdatei auf meinem gemieteten Webspace schreiben lassen. Dadurch kann ich von überall auf Router und meinen Rechner zuhause (sofern er eingeschaltet ist) zugreifen.

Ziel: Der Router soll periodisch seine IP-Adressen auslesen und in eine Textdatei auf einem FTP-Account schreiben.

Der erste Schritt, ist die Installation einiger Pakete auf dem Router, damit ein Upload möglich ist. Prinzipiell geht es auch via ftp, ich bevorzuge jedoch curl.

ipkg install curl

Als nächstes lege ich ein Skript an, welches für das Auslesen und Hochladen der IP-Infos zuständig ist: /mnt/usb/usr/bin/publish_ip.sh

#!/bin/sh
date > /tmp/ip
ifconfig vlan1 | grep -v inet6 | grep inet | cut -f2 -d: | awk '{print $1}' >> /tmp/ip
curl -T /tmp/ip -u username:password ftp://ftp.webspace.de/ip/inet_addr

Zeile 1 ist die Shebang, in Zeile 2 wird ein aktueller Zeitstempel in die Datei /tmp/ip geschrieben. Zeile 3 führt das Programm ifconfig aus und sucht dort nach der IP-Adresse, indem die Ausgabe von ifconfig via grep durchforstet, mittels cut zurechtgestutzt und anhand von awk ausgegeben wird. Das Ergebnis wird an die Datei /tmp/ip angehangen. In Zeile 4 sorgt curl dafür, dass die Textdatei via ftp auf den Webspace kopiert wird. Das geht natürlich auch mit ftp oder anderen ftp-fähigen Werkzeugen.

Nicht vergessen: Die Datei muss ausführbar sein:

chmod +x /mnt/usb/usr/bin/publish_ip.sh

Dann wird ein Cronjob eingerichtet. Wenn Cron bereits läuft, ist alles gut, alternativ muss es eingerichtet werden:

Eine Datei namens /etc/init.d/S61 muss mit dem folgenden Inhalt angelegt werden (dies sollte via Webinterface auch automatisch gehen):

#!/bin/sh
crond -c /etc/crontabs -b

Diese Datei muss ausführbar gemacht werden:

chmod +x /etc/init.d/S61crond

Dann folgt entweder ein Neustart oder der Aufruf des crond-Startskripts:

sh /etc/init.d/S61crond

Das Anlegen des Cronjobs kann unter anderem durch den Befehl “crontab -e” erfolgen. Folgende Zeile füge ich hinzu:

59 4 * * * /mnt/usb/usr/bin/publish_ip.sh

Somit wird jeden Morgen gegen 5 Uhr Uhr das Skript ausgeführt und die IP-Adresse auf den Webspace geladen. Das Ergebnis sieht in etwa so aus:

Sun Jun 10 04:59:01 CEST 2007
26.134.211.32

Die IP-Adresse des Routers im Internet am 10. Juni um 04:59 Uhr ist also 26.134.211.32.

Um den Komfort noch etwas zu erhöhen, könnte das kleine Skript publish_ip.sh ebensogut eine HTML-Seite generieren, die anhand eines Meta-Tags im Head der Seite eine automatische Weiterleitung vornimmt:

<meta http-equiv="Refresh" content="5; url=127.0.0.1">

Update für Kamikaze: Um die aktuelle WAN-IP herauszufinden, lautet das Kommando

ifconfig eth0.1 | grep -v inet6 | grep inet | cut -f2 -d: | awk '{print $1}' >> /tmp/ip

Do
Mai
31

2007

OpenWRT auf Asus WL-500g Premium

Seit Anfang Mai habe ich einen WLAN-Router von Asus, den WL-500g Premium, natürlich mit einem freien Betriebssystem: OpenWRT. Der Router verfügt neben vier Netzwerkports, 32 MB RAM und einer schicken Antenne über zwei USB 2.0 Ports, an welche man einen Drucker oder USB-Speicher anschließen kann. Ich habe derzeit nur einen alten 512 MB USB-Stick angeschlossen, da der Drucker in einem anderen Zimmer steht.

Die Installation von OpenWRT 0.9, Codename White Russian war dank der guten Dokumentation vergleichsweise einfach, Image downloaden, flashen, warten, neustarten, fertig. Als nächstes dann die Konfiguration und erste Schritte, bis hin zur Einbindung des USB-Speichers.

Upgrade der Firmware

Die Erst-Installation des Images erfolgte via Windows XP (Asche auf mein Haupt) mit dem Firmware Restoration Tool von Asus. Die installierte Firmware ist openwrt-brcm-2.4-squashfs.trx.
Nach längerem Warten – lieber eine Minute zu lang als zu kurz – habe ich den Router neu gestartet.

Der erste Bootvorgang

Nach dem ersten Boot funktionierte bereits der Betrieb via Kabel einwandfrei. Dank DHCP hatte der Asus eine Verbindung zum Kabelmodem, welches seinerseits mit dem Internet verbunden war.
Zunächst ging es darum, den Administrationszugang abzusichern.

Administrationszugang via ssh

Via telnet auf den Router (192.168.1.1), dort via passwd das Passwort für den ssh-Zugang gesetzt, anschließend den Router neu gestartet mittels reboot.
Anmerkung: steht vor der Zeile stephan$, so ist der Befehl auf dem Rechner einzugeben, an dem der Benutzer gerade angemeldet ist, steht dort root@OpenWrt, so ist der Befehl auf dem Router einzugeben. Es wird davon ausgegangen, dass der Router unter der Adresse 192.168.1.1 zu erreichen ist.

stephan$ telnet 192.168.1.1
root@OpenWrt:~# passwd
Changing password for root
Enter the new password (minimum of 5, maximum of 8 characters)
Please use a combination of upper and lower case letters and numbers.
Enter new password:
Re-enter new password:
Password changed.
root@OpenWrt:~# reboot

Es kann ein klein wenig dauern, doch dann kann man via ssh auf den Router zugreifen, das Passwort ist das zuvor eingestellte:

stephan$ ssh root@192.168.1.1

Da ich von meinem Rechner aus gerne ohne Eingabe eines Passwortes auf den Router gelangen möchte, folgt die Konfiguration der Public Key Authentication. Falls noch kein dsa-Schlüsselpaar vorhanden ist, wird dieses mittels

stephan$ ssh-keygen -t dsa

erzeugt. Dann muss der Key auf den Router kopiert werden:

stephan$ scp ~/.ssh/id_dsa.pub root@192.168.1.1:/tmp

Der Schlüssel muss noch zu den Authorized Keys hinzugefügt werden:

root@OpenWrt:~# cd /etc/dropbear
root@OpenWrt:~# cat /tmp/id_*.pub >> authorized_keys
root@OpenWrt:~# chmod 0600 authorized_keys

Eventuell sollte man bei Problemen in der Datei ~/.ssh/known_hosts eine eventuell vorhandene Zeile, die mit 192.168.1.1 beginnt entfernen.

Aktualisierung des Images und Einrichtung WLAN

Die folgenden Befehle sind auf der Kommandozeile einzugeben. Hiermit wird die Paketverwaltung aktualisiert bzw. benötigte Pakete werden installiert. Die Meldung Successfully terminated ist eine Erfolgsmeldung.

root@OpenWrt:~# ipkg update
root@OpenWrt:~# ipkg install ntpclient
root@OpenWrt:~# ipkg install nas
root@OpenWrt:~# nvram set wl0_akm=psk psk2
root@OpenWrt:~# nvram set wl0_crypto=aes+tkip
root@OpenWrt:~# nvram set wl0_wpa_psk =MeinePassphraseFürDasWLAN
root@OpenWrt:~# nvram commit

X-Wrt

X-Wrt als Alternative zum bestehenden Webinterface bietet sich an, es reicht aus, auf der Webseite des Projekts die Adresse des Router einzugeben, das Update läuft automagisch.

USB-Unterstützung

Die fragmentarische Kurzfassung:

root@OpenWrt:~# ipkg install kmod-usb2
root@OpenWrt:~# ipkg install kmod-usb-storage
root@OpenWrt:~# ipkg install kmod-ext2
root@OpenWrt:~# ipkg install fdisk
root@OpenWrt:~# ipkg install e2fsprogs
root@OpenWrt:~# ipkg install swap-utils

Durch den Aufruf von dmesg lässt sich erkennen, welche Bezeichnung der USB-Stick hat, in meinem Fall /dev/scsi/host0/bus0/target0/lun0

root@OpenWrt:~# fdisk /dev/scsi/host0/bus0/target0/lun0/part1

Mittels fdisk lege ich eine Partition an, die später unter /mnt/usb/ eingehangen werden soll.

root@OpenWrt:~# echo ‘/dev/scsi/host0/bus0/target0/lun0/part1 /mnt/usb ext2 defaults 0 0’ > /etc/fstab

Links

Do
Apr
19

2007

Subversion unter Mac OS X benutzen

In diesem Tutorial geht es darum, wie man mittels MacPorts (ehemals darwinports) und Mac OS X 10.4.3 einen Subversion-Server einrichtet, der prinzipiell via Internet von jedem Rechner zugänglich ist, aber nur von bestimmten Nutzern tatsächlich benutzt werden kann. Benötigt werden

  • ein Computer mit Mac OS X (10.4.3 kam bei diesem Tutorial zum Einsatz)
  • ein Internetzugang
  • Grundlagenkenntnisse in Terminal.app
  • sowie in der Versionsverwaltung

Benötigte Software installieren

darwinports

darwinports ermöglichen die Installation von Softwarepaketen mitsamt ihren Abhängigkeiten. Subversion benötigt nebenbei noch einen Webserver (Apache 2) mit dem mod_dav_svn Modul. Damit die Installation einfacher und bequemer verläuft, kommt das Portsystem zum Einsatz.
Auf der Webseite der darwinports (darwinports.opendarwin.org) befindet sich eine recht gute Erklärung, wie die Paketverwaltung zu installieren ist.

Subversion und der Apache

Sobald die darwinports-Infrastruktur steht, kann Subversion installiert werden. Hierzu werden Administratorrechte benötigt. Der Befehl lautet:

sudo port install subversion +mod_dav_svn

Für die nächsten Minuten gibt es nichts zu tun als abzuwarten. Wenn die Installation erfolgreich war, zeigt sich in etwa folgendes Bild:

Meldungen im Terminal nach erfolgreicher Installation

Repository anlegen

Zur Arbeit mit Subversion wird ein Repository benötigt. Dieses kann prinzipiell an jeder beliebigen Stelle angelegt werden, da in diesem Beispiel das Repository nur über den Webserver angesprochen werden soll, erzeugen wir es an einem eher unauffälligen Ort: /usr/local/repos. Zuerst muss das Verzeichnis repos mit einem einzigen Befehl angelegt werden:

sudo mkdir /usr/local/repos

Das Repository wird anhand des Programms svnadmin erzeugt:

sudo svnadmin create /usr/local/repos

Jetzt fehlen nur noch Daten im Repository. Ich lege einen Ordner auf dem Desktop an, der importiert werden soll:

Ordnerstruktur Import

Zuerst wird der zu importierende Ordner angegeben, dann die Adresse des Repositorys. Jeder Commit bekommt eine Notiz, in diesem Fall lautet sie: “Eins”:

sudo svn import /Users/stephan/Desktop/stephan/ file:///usr/local/repos -m "Eins"

Da niemand außer dem Webserver (also dem User namens www) Zugriff auf das Repository haben muss, weisen wir die Rechte entsprechend zu:

sudo chown -R www /usr/local/repos/

Apache 2 konfigurieren

Die Konfiguration des Webservers ist zwar etwas umständlicher als die bisherigen Schritte, aber auch nicht weiter kompliziert. Eine Textdatei muss editiert und eine Passwortdatei angelegt werden.
Zunächst wird die Datei httpd.conf angelegt und im Editor geöffnet:

cd /opt/local/apache2/conf
sudo cp httpd.conf.sample httpd.conf
sudo vi httpd.conf

Anstelle des Editors vi kann auch jeder andere Texteditor (Textmate, Textwrangler, Smultron, jEdit) benutzt werden.

Zuerst ändern wir den Port, auf dem der Apache auf Anfragen wartet. Der voreingestellte Port 80 wird vom in Mac OS X enthaltenen Webserver bereits benutzt, also lassen wir Apache 2 auf dem alternativen Webserverport 8080 laufen. Die Zeile

Listen 80

muss geändert werden in:

Listen 8080

Desweiteren muss nach der Zeile

LoadModule dav_module modules/mod_dav.so

folgende Zeile hinzugefügt werden:

LoadModule dav_svn_module modules/mod_dav_svn.so

Am Ende der Datei müssen die Einstellungen für den Zugriff des Webservers auf das Subversion Repository hinzugefügt werden. In diesem Beispiel soll das Repository unter der Adresse http://127.0.0.1:8080/svn erreichbar sein, hierzu dient die Location-Anweisung:

<Location /svn>
DAV svn
SVNPath /usr/local/repos
AuthType Basic
AuthName "Stephans Subversion"
AuthUserFile /etc/svn-auth-file
Require valid-user
</Location>

Der Titel des Repositorys lautet “Stephans Subversion”. Zugriff erhalten nur User, deren Login und Passwort in der Datei /etc/svn-auth-file gespeichert sind.

Passwortschutz für Repository einrichten

Wir wollen das Repository für zwei User zugänglich machen. Diese heissen stephan und fred. Um den ersten User anzulegen, benötigen wir htpasswd mit den Optionen c und m:

sudo htpasswd -cm /etc/svn-auth-file stephan

Nun muss das entsprechende Passwort zweimal eingeben werden.
Für jeden weiteren Benutzer lautet der Befehl:

sudo htpasswd -m /etc/svn-auth-file fred

Die Option -c zur Erzeugung einer neuen Datei ist überflüssig, sobald /etc/svn-auth-file existiert. Um die bestehende Datei also nicht zu überschreiben, muss sie bei allen weiteren Usern weggelassen werden.

Apache 2 starten

Es gibt zwei Möglichkeiten, den Apache 2 Webserver zu starten: manuell oder bei jedem Systemstart. Manuell lässt er sich starten durch

sudo /opt/local/apache2/bin/apachectl start

Die zweite Möglichkeit bedarf derzeit (darwinports < 1.2) noch etwas Handarbeit.
Das Verzeichnis /opt/local/etc/StartupItems/apache2 muss in das Verzeichnis /Library/StartupItems kopiert werden. Dann muss in der Datei /etc/hostconfig angegeben werden, dass apache2 beim Systemstart gestartet wird. Dies geschieht anhand der Zeile:

APACHE2=-YES-

Beim nächsten Neustart wird Mac OS X eine Meldung bezüglich fehlerhafter Sicherheitseinstellungen ausgeben, diese lassen sich auf Knopfdruck korrigieren. Daraufhin folgt ein weiterer Neustart und schon ist das System betriebsbereit.

Arbeiten mit Subversion

Jetzt ist das Repository einsatzbereit. Mittels der Kommandozeile im Terminal lassen sich jetzt Dateien ein- und auschecken. Etwas komfortabler geht die Versionsverwaltung mit einem Werkzeug wie svnX. Da svnX nicht von einer darwinports-Installation ausgeht, muss noch der Pfad zum ausführbaren Programm svn in den Einstellungen angepasst werden:

/opt/local/bin

Quellen

Version Control with Subversion
Subversion lokal unter Mac OS X