Just because it's:

Archive for the ‘Longer articles’ Category

Von Liebesbriefen und Kopfgeldjägern

Sunday, August 10th, 2008

Viele von euch sind vermutlich wie ich auch bei Xing. Ich weiss nicht ob es nur mir so geht, aber sowohl die Kopfgeldjäger als auch die jung dynamisch sportlichen Startup Guys (ja, genau die mit dem unverwechselbaren Zahnpastalächeln) lieben mein Postfach. Beim lesen der Nachrichten stellt man schnell fest, dass fast alle Zuschriften einem ähnlichem Schema folgen. Wie nervig!

Ließt man sich die Zuschriften allerdings mit ein wenig bereitschaft zu humor und sarkasmus durch, entdeckt man unter Umständen doch die ein oder andere Passage, die einen zum schmunzeln bringen kann.

Deshalb hier ein paar Zitate aus freier Wildbahn, inklusive persönlicher Anmerkungen. Ich gehe davon aus, dass die Absender der Nachrichten, in diesem Fall gerne auf die korrekte Zitierung mit persönlicher Namensnennung verzichten. ;-)

Der Unkonventionelle

“Hi, wir kennen uns zwar noch nicht, aber ich schreibe Dich einfach mal proaktiv an, hoffe das ist okay.”

Ungefähr so beginnen auch 90% der E-Mails, die in meinem Spam Ordner liegen. Dabei sieht der junge Herr auf dem Foto garnicht aus wie ein nigereanischer Königssohn, Internet-Apotheker oder eines dieser heißen Luder, die mich regelmäßig auf einen völlig diskreten und selbstverständlich unverbindlichen Webcam Chat einladen. Also die Luder… nicht die Apotheker!

Nicht schlecht, wie er die Leute mich persönlich “proaktiv” und “einfach mal” so anschreibt. Diese persönliche Note wird nochmal durch eine Prise unkonventionalität betont, da er z.B. das Subjekt “ich” im dritten Nebensatz weglässt (um eine Doppelung mir dem Subjekt aus dem zweiten Nebensatz zu vermeiden) und direkt mit dem “Du” einsteigt. Im Internet darf man das ja.

Aber um die änfägliche Illusion des individuellen Anschreibens von einer auf ganze zwei Sekunden zu steigern, empfehle ich doch zumindest den Vornamen mit in die Anrede aufzunehmen. Sonst merkt doch jeder, dass das nur kopiert und eingefügt wurde. Der nächste hier hat das schon raus:

Der Anspruchsvolle

“Hallo Dennis,
ich habe mir erlaubt, Dich direkt anzuschreiben. Auch wenn wir uns nicht kennen.”

Geht doch! Aber trotzdem heftig, was die sich alle rausnehmen. Leute nicht kennen, aber dennoch einfach mal Kontakt knüpfen. Am Ende wohlmöglich auch noch Networking betreiben. Wo kämen wir denn da hin?

“Zur Erweiterung unseres Teams suchen wir deshalb dringend nach guten
Software-Entwicklern. Falls das etwas für Dich ist oder Du
irgendjemand kennst: Freunde, Bekannte, Studienfreunde, ehemalig
Kollegen, Freunde von Freunden, Verwandte und Nachbarn: über jeden
Tipp würde ich mich sehr freuen.”

Ob das was für mich wäre weiss ich nicht. Aber zumindest kenne ich die da oben alle! Mensch was für ein Glück, Sie suchen ja genau mich! Da sag nochmal jemand, man müsse konkrete Qualifikationen mitbringen. Blödsinn! Die richtigen Leute muss man kennen. Und ich kenne Sie alle!

Achja, einen Tip habe ich auch gleich noch: mit logischen Verknüpften Bedingungen immer vorsichtig umgehen. Ausserdem darf man auch nach elliptischen Sätzen normale Punkte setzen. ;-)

Die Interessierte

“[...] wir sind auf Ihr interessantes Profil in xing gestoßen und würden sehr gerne mit Ihnen in Kontakt treten.”

Psst, bitte nicht so laut! Sonst wird mein uninteressantes Zweitprofil noch eifersüchtig. Sie wissen doch wie das ist. Tun sie mir doch einen persönlichen gefallen und melden sie sich nochmal auf dem anderen. Sonst bekommt das irgendwann noch Depressionen oder sowas.

Der Glückliche

[...] zufällig bin ich gestern auf Ihr Xing-Profil gestoßen, das mir besonders hinsichtlich Ihrer ausgewiesenen Programmier-Kenntnisse (Ruby on Rails) positiv aufgefallen ist.

Sie und ich! Wir beide, sind einfach für einander bestimmt! Wenn das mal kein Zeichen war. Und das wo sie doch vermutlich gerade (natürlich total zufällig) einen Ruby on Rails Entwickler suchen. Aber da man sich ja nicht immer auf das Schicksal verlassen kann, empfehle ich das nächste mal dann doch lieber die Xing Profisuche. Da kann man sogar Profile nach Fähigkeiten und Standorten durchsuchen. Ganz ehrlich!

Der Neue

Unsere Wunschkonstellation wäre eine Festanstellung mit marktüblichen Gehältern und einer Unternehmensbeteiligung.

Subtext: “Eine Nachricht um ihn zu finden, gering zu bezahlen und beteiligt zu binden!” – So oder zumindest so ähnliche kann man es auch formulieren. Es handelt sich im übrigen um ein Startup Unternehmen (Surprise!), dass gerade mal 6 Monate existiert. Arbeite gut und arbeite hart! Denn je besser und härter du arbeitest, desto größer wird nämlich der Wert deiner Beteiligung. Wenn wir nach der ersten Finanzierungsrunde allerdings wie viele andere Startups drauf gehen sollten, hast du ja immernoch dein marktübliches Gehalt bekommen.

Der Konkrete

“Bitte senden Sie uns Ihre aussagekräftigen Bewerbungsunterlagen an x@y.z. Im darauf folgenden Gespräch würden wir Ihnen gerne Ihre Möglichkeiten und Entwicklungsperspektiven bei XYZ vorstellen.”

Tut mir sehr leid. Ich habe im Moment nurnoch die weniger aussagekräftigen Unterlagen auf Vorrat. Auch wenn ich mich damit wohl soeben als Bewerber für den Entwicklerjob disqualifiziert habe, könnten Sie mich mit den weniger aussagekräftigen Unterlagen doch bestimmt wo anders unterbringen Oder?

Wie wäre denn mit Sportlerkommentaren, im Marketing, oder sogar in der Politik? Das wäre Klasse!

Fazit

Im Grunde genommen bin ich echt froh, dass es sowas wie Xing gibt. Leider finden tatsächlich nur wenig wirklich interessante Angebote Ihren weg in mein Postfach. Meistens handelt es sich um Massenware von der Stange und dient eher dazu, die Karteikästen und Konten der Vermittlerunternehmen zu füllen. Nichts desto trotz, kann man beim durchforsten dieser Nachrichten seinen Spass haben. ;-)

AGI mit Python

Friday, July 6th, 2007

Das Asterisk Gateway Interface (kurz AGI) ist die Schnittstelle der Asterisk Software Telefonanlage. AGI bietet nahezu jeder Programmiersprache die Möglichkeit mit dem Telefon-Server zu interagieren. Das Prinzip ist in etwa mit dem des Namensvetter Common Gateway Interface (CGI) bei Webservern zu vergleichen. Ein Request auf ein bestimmtes Dokument bzw. Telefonnummer erreicht den Server. Dann wird ein externer Interpreter gestartet, der ein Programm ausführt und dem Server das Ergebnis des Programmlaufs mitteilt.

Im Gegensatz zu CGI ist AGI von Natur aus auf ein kontinuierliche Verbindung ausgelegt. Das bedeutet, dass wenn eine neue Telefonsitzung angenommen wird, stehtig Daten rein und raus gehen können ohne die Verbindung zwischenzeitlich zu unterbrechen. Wohingegen CGI für paketbasierte Kommunikation entworfen wurde, und normalerweise nur einmal zu Beginn der Anfrage, Daten über die Umgebungsvariablen übergeben bekommt.

Wie bereits erwähnt, kann man AGI mit nahezu jeder Sprache ansprechen. Warum ist das so? Ganz einfach: AGI kommuniziert über die drei heiligen Datenkanäle STDIN, STDOUT und STDERR und nutzt im “Protokoll” Plaintext Befehle. Da praktisch jede Programmiersprache im PC bereich zumindest zwei dieser Kanäle unterstützen sollte um irgendwie existenzberechtigt zu sein, ist man bei der Wahl der Sprache ziemlich frei.

In meinem Fall habe ich mich für Python entschieden. Es gibt eine Menge freier AGI Bibliotheken für Python. Leider mangelt es wie so häufig an der API Dokumentation und/oder guten Beispielen. Aufgrund der einfachen Umgangs mit AGI und wegen des gewissen Lerneffekts, ist es auch eigentlich kein Problem sich direkt selbst mit dem Server zu unterhalten. Mit wenigen Zeilen Code lässt sich ein funktionierendes AGI Template bauen. Auf das Listing verzichte ich an dieser Stelle aus technischen Gründen einfach mal weil das Vimcolor Plugin suckt viel besser zu kopieren ist, wenn man sich den Quelltext direkt runterladen kann.

Eingebunden wird das AGI Programm in der /etc/asterisk/extensions.conf unter einem gültigen Kontext mit dem Befehl “AGI(/path/to/script)“.

Was mir bei AGI allerdings negativ aufgefallen ist, ist die beschränkte Möglichkeit des debuggens. Zwar hat man in der Asterisk Konsole die Möglichkeit, mit dem Befehl “agi debug” in den Debug Modus zu wechseln, was einem aber in der Regel nicht sehr viel weiter hilft, wenn es hart auf hart kommt. Eines meiner Lieblingszenarien ist, wenn Asterisk nicht die nötigen Rechte zum öffnen des AGI hat. Dann bekommt man nämlich keine Fehlermeldung, sondern wird vom AGI Debugger darüber Informiert, dass das Script gestartet wurde und mit Return-Code 0 (d.h. alles in Ordnung) beendet wurde. Folgende Arbeitsweisen haben sich für mich als gutes Workaround für die AGI-Debug problematik herausgestellt:

  1. Teste/Validiere das Programm bevor du es von Asterisk ausführen lässt. In Vim für Python z.B. mit dem Befehl “! python %” oder für Ruby mit “! ruby -c %
  2. Nutze ein eigenes Logging. Output Debugging über Asterisk ist meiner Meinung nach zweckentfremdung, denn alles was man zu Asterisk schickt sollten Befehle sein. Außerdem ist es hässlich zu lesen. Stattdessen besser in ein externes Logfile schreiben und im terminal mit “tail -f $my_logfile” das Geschehen live mitverfolgen.

Anbei noch ein paar nützliche Links zum Thema:

Subversion Grundlagen: SVN Tools Cheat Sheet

Tuesday, April 3rd, 2007

Auch bei Subversion, ist es ganz zu Anfang immer etwas kompliziert sich diverse Befehle und konventionen zu merken. DEshalb habe ich an dieser Stelle einen kurzen Spickzettel häufig benötigter Befehle und URLs gelistest. Viel Erfolg!

Zugriffsmöglichkeiten

  • file:///path/to/repository : Zugriff auf lokales Repository.
  • svn://host/repository : Zugriff auf ein entferntes Repository.
  • svn+ssh://host//repository : Zugriff auf ein entferntes Repository durch einen SSH Tunnel.

SVN Client

  • svn import [Quell-Pfad] [Ziel-URL] : Importiert eine lokale Datei oder ein Verzeichnis in das Repository.
  • svn mkdir [Verzeichnis-URL] : Erstellt ein neues Verzeichni, bestimmt durch die absolute Verzeichnis-URL.
  • svn list file [Verzeichnis-URL] : Listet alle Inhalte des bestimmten Verzeichnisses.
  • svn checkout [Repository-URL] [lokales Ziel] : Zieht eine Arbeitskopie des aktuellen Repositories.
  • svn commit [lokale Datei] : Führt dem Repository geänderte Arbeitskopien zur Versionierung zu.
  • svn update [lokales Verzeichnis] : Führt eine aktualisierung der Arbeiteskopie aus. Ist kein Pfad angegeben, wird versucht das aktuelle Verzeichnis zu aktualisieren.

SVN Admin

  • svnadmin create [Repository Name] : ein neues Repository erzeugen.
  • svnadmin hotcopy : Erstellt eine Kopie des Repositories wärend des Betriebs.
  • svnadmin recover [Archiv Pfad] : Startet eine Routine zur Rettung der internen Datenbank.

SVN Serve Parameter

  • –daemon : Startet den SVN Server als Daemon. Der Prozess wird direkt in den Hintergrund verschoben.
  • –listen-host [Hostname] : Bestimmt expliziet den Host/Ip auf dem der SVN Server lauschen soll.
  • –listen-port [Portname] : Bestimmt den Port auf dem der SVN Server lauschen soll.
  • –root [Verzeichnis Pfad] : Schränk die Dateisystem Umgebung des SVN Servers ein. Ansonsten kann auf jedes Repository des Systems zugegriffen werden.
  • –foreground : Diese Option verhindert, dass der SVN Server im Daemon Modus in den Hintergrund verschoben wird.

Subversion Grundlagen: Repositories aufsetzen

Tuesday, April 3rd, 2007

Die Installation

Dank des Advance Packaging Tool gestaltet sich die Installation der Subversion (kurz SVN) Basis-Software selbst, erfrischend einfach und unkompliziert. Die Verwendung des Befehls apt-get setzt selbstverständlich Root-Rechte voraus.

sudo apt-get install subversion

Das Paket “subversion” enthält diverse Tools und selbstverständlich die SVN Library. Auf Grundlage dieses einen Pakets wurden im Prinzip alle nötigen Programme installiert, die gebraucht werden, um ein lokales Repository in Betrieb nehmen und pflegen zu können.

Das lokale Repository

Im Gegensatz zu anderen Programmen zur Versionsverwaltung, zum Beispiel Perforce, bietet Subversion die Möglichkeit lokale Repositories anzulegen. Diese Variante ist insbesondere dann nützlich, wenn es sich nicht um ein Projekt mit einem verteiltem Benutzerstamm handelt. Ein lokales Repository ist zum Beispiel ideal dazu geeignet, sich bei eigenen kleinen Projekten das ständige Rücksichern verschiedener Zwischenstände zu ersparen. Nie wieder Tarball Chaos! Nie wieder Hände über den Kopf zusammen schlagen, weil man das Backup vergessen hat! Wie praktisch! Selbstverständlich ist auch hierbei immer noch ein gewisses Maß an Selbstdisziplin vorausgesetzt, wenn es um das Hinzufügen der gemachten Änderungen geht.

Doch bevor man sich mir dererlei Problemen befasst, muss natürlich ersteinmal ein funktionierendes Repository angelegt werden. Die SVN eigenen Tools werden alle grundsätzlich in der Konsole ausgeführt. Es gibt mittlerweile eine Vielzahl grafischer Frontends für SVN, auf die ich allerdings an anderer Stelle noch zu sprechen komme.

Ein lokales Subversion Repository anzulegen ist nahezu ein Kinderspiel. Wenn das neue Repository Beispielsweise “BillingApp” heißen soll, legt man es mit folgender Kommandozeilen Eingabe an:

svnadmin create BillingApp

Der Befehl svnadmin bietet eine ganze Reihe weiterer Möglichkeiten zur Verwaltung eines Repositories, die als entsprechender Parameter mitgegeben werden. Viel wichiger allerdings ist der svn Befehl selbst. Sämtliche inhaltliche Änderungen in einem Repository, werden mit dem Konsolenkürzel svn und einem entsprechenden Befehlsparameter durchgeführt. Einige weitere wichtige SVN Befehlsparameter die man beim einrichten eines Repositories gebrauchen kann sind:

  • svn import [Lokaler-Pfad] [Ziel-URL] — Importiert eine lokale Datei oder ein Verzeichnis in das Repository.
  • svn mkdir [Ziel-URI] — Erstellt ein neues Verzeichni, bestimmt durch die absolute Verzeichnis-URL.
  • svn list file [Ziel-URI] — Listet alle Inhalte des bestimmten Verzeichnisses.
  • svn move [URI1] [URI2] — Verschieben oder umbenennen von Dateien in Arbeitskopie und Repository.
  • svn delete [URI] — Löscht Dateien und Verzeichnisse aus dem Repository.

Der aufmerksame Leser wird festgestellt haben, dass in der Befehlsyntax zumeist die rede von einer URI ist. Das liegt daran, dass die Inhalte eines Repositorys in einer Art virtuellem Dateisystem gehalten werden. Der tatsächliche Inhalt des Beispielordners “BillingApp” sieht wie folgt aus:

drwxr-xr-x  2 dennis dennis  80 2007-03-07 15:42 conf
drwxr-xr-x  2 dennis dennis  48 2007-03-07 15:42 dav
drwxr-sr-x  2 dennis dennis 472 2007-03-07 15:42 db
-r--r--r--  1 dennis dennis   2 2007-03-07 15:42 format
drwxr-xr-x  2 dennis dennis 232 2007-03-07 15:42 hooks
drwxr-xr-x  2 dennis dennis 104 2007-03-07 15:42 locks
-rw-r--r--  1 dennis dennis 379 2007-03-07 15:42 README.txt

Auf genauen Zwecke der einzelnen Dateien und Verzeichnisse gehe ich an dieser Stelle nicht ein. Vorerst reicht es zu wissen, dass es sich hierbei um Dateien handelt, die Subversion benötigt, um die Resourcen verwalten und versionieren zu können.

Um auf die Inhalte des Repositorys Zugriff nehmen zu können, übergibt man dem Befehl svn also URIs, anstelle des tatsächlichen Dateisystempfades. Subversion wandelt die URI dann intern entsprechend sich um. Importiert man Beispielsweise ein lokales Projekt in ein lokales Subversion Repository, so lautet der Befehl

svn import /home/dennis/projekt_verzeichnis/* file:///home/dennis/BillingApp

Die Angabe von URIs ist die einzige Möglichkeit, an die zu verwaltenen Dateien zu gelangen. Denn alle verwalteten Dateien liegen in einer Art virtuellem Dateisystem (bzw. einer Datenbank). Für den Befehl svn sind die Inhalte der Verzeichnisse /home/dennis/BillingApp und file:///home/dennis/BillingApp also von Grund auf verschieden. Bei dem ersten Pfad sieht svn die “System-Dateien” (conf/, dav/, db/ usw.), die man auch mit den Befehlen dir oder ls sehen würde. Beim zweiten Pfad (der File-URI) bekommt svn Einsicht/Zugriff auf alle “versionierten Dateien”, quasi die konkreten Quelltexte, Dokumente etc. mit denen eigentlich gearbeitet werden soll. Beide Zugriffsmethoden (echter Dateipfad und File-URI) haben absolut von einander abgegrenzte Umgebungen. Die Inhalte dieser Umgebungen werden niemals vermischt.

Zum anderen ist es Subversion auf diese Art möglich, die selben Befehle für lokale und entfernte Repositories nutzen zu können. Worauf man lediglich achten muss, ist dass man das Format der URI einhält. Der gleiche Aufruf für den Import in ein entferntes Repository könnte dann zum Beispiel so aussehen:

svn import /home/dennis/projekt_verzeichnis/* svn://myhost.com/BillingApp

Bei einem URI mit dem Schema “svn” weiss Subversion, dass es sich um ein entferntes Repository handelt und reagiert entsprechend um die Dateien zu übertragen. An dieser Stelle beginnt die Thematik der entfernten Repositories.

Das entfernte Repository

Jedes entfernte Repository setzt auf einem lokalen Repository auf. Es wird lediglich ein Dienst gestartet/installiert der dafür sorgt, dass man auch von außerhalb zugreifen kann. Hier gibt es nun diverse Möglichkeiten. In diesem Text beschäfftigen wir uns mit dem Subversion eigenen Daemon svnserve.

Svnserve ist in der Regel von Haus aus in der Subversion Grundausstattung enthalten. Das Programm bietet verschiedene Möglichkeiten, einen eigenen Repository Server in Betrieb zu nehmen:

  1. Als in inetd eingebundener Dienst.
  2. Als eigenenständiger Daemon Prozess.
  3. Über einen SSH/RSH Tunnel.

Wir beschäfftigen uns der Einfacheit halber mit der zweiten Variante, dem Betrieb als Daemon. Um einen einfachen svnserve Daemon zu starten, muss man in der Shell den Befehl svnserve –daemon ausgeführt werden. Damit wird ein neuer Prozess gestartet, der auf dem TCP Port 3690 wartet. Der Prozess wird in der Regel direkt in den Hintergrund geschoben. Soll dieses Verhalten vermieden werden kann der Parameter –foreground beigefügt werden. Außerdem empfehlen sich beim Betriebs von svnserve folgende Parameter anzugeben:

  • –root arg: Legt das Verzeichnis fest, in dem alle Repositories dieses Daemons liegen sollen. Wir diese Option nicht gesetzt, kann per Default mit abosluten Pfadangaben, jedes Repository des Systems genutzt werden.
  • –listen-host [arg] : Konfiguriert die Netzwerkadresse/Hostnamen auf dem der Subversion Server auf eingehende Verbindungen warten soll.
  • –listen-port [arg] : Konfiguriert den Port auf dem der Subversion Server auf eingehende Verbindungen warten soll.
  • –threads : Sollte abzusehen sein, dass der der Subversion Server einem starken Workload ausgesetzt sein wird, bietet es sich an dem Prozess über Threads anstelle von Forks laufen zu lassen.

Wenn das eigene Repository also in dem Pfad /var/svn/repositories liegt, bietet sich es also an, den Server wie folgt zu starten:

svnserve –daemon –root /var/svn/repositories

Hierbei ist natürlich wie immer darauf zu achten, dass das Verzeichnis /var/svn/repositories entsprechende Berechtigungen besitzt, damit der svnserve Prozess darauf zugreifen kann. Außerdem empfiehlt es sich in viele Fällen, den Zugriff auf das Repository zu beschränken. Dazu bringt Subversion zum Beispiel einen einfachen authentifizierungs Mechanismus mit. Jedes Repository-Verzeichnis enthält die Datei svnserve.conf im Unterverzeichnis conf/. Die accountbasierte Grundkonfiguration im Handumdrehen eingerichtet. Die Datei svnserve.conf benötigt im Grunde genommen nur folgende drei Zeilen:

[general]
realm = My First Repository
password-db = passwd

In diesem Beispiel wird eine Kennwortdatei “passwd” benutzt die ebenfalls in conf/ liegen muss.

[users]
jack = black

Zusätzlich hat man die Möglichkeit, über den Parameter anon-access und auth-access die Berechtigung für anonyme und authorisierte Zugriffe auf das Repository zu bestimmen.

Ist das Remote Repository so weit nun aufgesetzt, kann von jedem Rechner im Netz mit dem Commandline Tool svn auf das Repository zugegriffen werden. Genauere Informationen zu Subversion kann man wie immer den Manpages und Beispielkonfigurationen entlocken.