Netzpiraten - cat /dev/brain

05
Jun

Capistrano Multistage synchronisation

Für das Deployment des Radiant CMS verwende ich schon seit längerem Capistrano und bin auch sehr zufrieden damit. Nachdem nun auch schon einige Seiten damit produktiv sind, bin ich immer häufiger über die gleiche Aufgabe gestolpert wenn eine Weiterentwicklung anstand:

  1. Produktive Datenbank dumpen
  2. Dump und Assets auf die lokale Maschine kopieren
  3. Datenbankdump einlesen
  4. Entwickeln
  5. Lokale Datenbank dumpen
  6. Dump und Assets auf die Stagingumgebung kopieren
  7. Datenbank einlesen
  8. Kunden informieren
  9. Datenbankdump und Assets auf die Produktivumgebung kopieren
  10. Datenbankdump einlesen

Uff… jedes Mail ziemlich viel repetitive Arbeit. Da ich minimalistisch veranlagt bin, habe ich natürlich eine Lösung gesucht um mich wieder auf die wesentlichen Dinge konzentrieren zu können. Dabei rausgekommen ist mein…

Capistrano Sync Rezept

Installation

Für die Installation muss man das Rezept einfach nach lib/recipes in die Ruby on Rails Applikation kopieren und in das Capfile folgende Zeile einfügen:


Dir['lib/recipes/*.rb'].each { |receipe| load(receipe) }

Konfiguration

In der Deploykonfiguration config/deploy.rb können nun zwei Einstellungen vorgenommen werden:


set :sync_directories, %w(assets)
set :sync_backups, 3

Mit sync_directories werden die Verzeichnisse definiert, welche man zwischen den Umgebungen synchronisiert haben möchte - ‘assets’ ist dabei auch gleich die Defaulteinstellungund kann beliebig erweitern werden (z.B. mit ‘galleries’). sync_backups definiert die Anzahl der Backups welche auf dem System behalten werden, doch mehr dazu später.

Für den Zugriff auf die Datenbank liest das Rezept die lokale config/database.yml Datei, wesshalb dort dann auch die Zugriffsdaten der Datenbank aller Umgebungen eingetragen werden müssen. Dies ist ja kein Problem, da diese Datei sowieso schon im .gitignore eingetragen ist und nie eingecheckt wird, oder?

Für das Reibungslose deployment sollte man natürlich die Public-Key SSH Authentifizierung eingerichtet haben.

Sync!

Da in einer Multistageumgebung x Umgebungen vorhanden sein können, gibt es keine Kommandos für eine direkte Synchronisation zwischen den Umgebungen. Es muss immer via die lokale Entwicklungsumgebung synchronisiert werden.

Das zu Beginn beschriebene Synchronisationsszenario sieht nun mit dem Capistrano Rezept folgendermassen aus:

  1. cap production sync:down
  2. Entwickeln
  3. cap staging sync:up
  4. Kunden informieren
  5. cap production sync:up

Das ist also schon definitiv etwas schneller… Der Task sync:down ruft übrigens lediglich die beiden tasks sync:down:db und sync:down:fs auf. Es ist also mit diesen Tasks auch möglich, nur das Dateisystem oder die Datenbank zu synchronisieren, wie uns das Kommando ‘cap -T’ zeigt:


cap sync:down
cap sync:down:db
cap sync:down:fs
cap sync:setup
cap sync:up
cap sync:up:db
cap sync:up:fs

Abhängigkeiten

Das Rezept benötigt rsync für die Synchronisation der Dateien, damit nur immer die Differenz und nicht jedesmal alle Dateien synchronisiert werde. Auch wird der Datenbankdump mit mysqldump gemacht, wesshalb im Moment die Datenbanksynchronisation nur mit MySql läuft. Die Faulheit welche mit zum Schreiben des Rezeptes veranlasst hat, verhindert eben auch gleichzeitig die Entwicklung von Features welches ich selber im Moment nicht benötige ;-)

Backups

Da ich unter einer angeborenen Datenverlustsparanoia leide, musste natürlich auch ein Backupmechanismus her. Dazu wird das Verzeichnis ‘shared/sync‘ beim deploy:setup task automatisch angelegt. In diesem Verzeichnis werden nun die erzeugten Datenbankdumps abgelegt und beim Hochladen eines DB-Dumps wird vor dem Einlesen noch zusätzlich ein Dump auf der Umgebung erstellt bevor der hochgeladene Dump eingelesen wird.

Auch bei der Synchronisation von Verzeichnissen auf die Umgebung wird vorher ein Archiv erstellt und abgelegt - sicher ist sicher ;-)

Ein Task für ein Rollback existiert nicht - bei einem Fehler ist dann einfach Handarbeit angesagt.

Happy syncing!

11
Apr

Nicht alles wo Bio draufsteht ist gut…

…zum Beispiel die geplanten familienfreundlichen Biometrie-Pässe sind es sicher nicht. Auf Wikipedia kann man den wunderbaren Satz


Die Biometrie (auch Biometrik, gr. Bio = Leben und Metron = Maß) beschäftigt sich mit Messungen an Lebewesen und den dazu erforderlichen Mess- und Auswerteverfahren.




nachlesen. Genau - wir sollen vermessen und dann schön bequem ausgewertet werden.

Und was jetzt? Keine Ahnung was die damit wollen? Also dann solltest du unbedingt gleich einmal den Artikel “Biometrische Volkszählung für afrikanische Pinguine” lesen (einfach afrikanischen Pinguin durch Schweizer ersetzten)!

Für die Lesemuffel unter euch, hier ein paar der Leckerbissen (auch wieder afrikanischen Pinguin durch Schweizer  und Biologen durch Staatsschützer ersetzten):


“Das bedeutet, dass wir die Pinguine draußen in der Wildnis beobachten können, in Echtzeit und mit ziemlicher Genauigkeit”



“…soll verlässliche Daten über die Bestände und die sozialen Verhaltensweisen der afrikanischen Pinguine liefern…”



“Wir glauben, dass diese neue Technik es Biologen erlauben wird, viele Vertreter verschiedener Arten kostengünstig, schnell und automatisch zu identifizieren und über längere Zeit zu beobachten”



Also von mir gibts ein fettes Nein am 17. Mai!

03
Mrz

Ruby on Rails Entwickler gesucht

Wir suchen einen erfahrenen und motivierten Softwareentwickler mit hervorrangenden Programmierkenntnissen und viel Kreativität als Verstärkung für unser Entwicklungsteam. Du liebst die Kunstfertigkeit der Programmierung und hast den Ergeiz verständlichen Code zu schreiben und diesen optimalerweise durch stetige, testgetriebene Refaktorisierung zu pflegen.

Als Senior bist du auch für den Design von Datenbanken zuständig und hast fundierte Kenntnisse in SQL sowohl auch der objektorientierter Analyse und Design unter Anwendung von Entwurfsmustern. Die bist von agilen Methodiken begeistert und arbeitest gerne im Team und verbesserst konstant die Abläufe und Qualität der Arbeiten und hilfts deinen Kollegen bei der Paarprogrammierung oder durch einen Code Review.

Du solltest sehr gute Kenntnisse im Design von besonders benutzerfreundlichen Webseiten haben, welche mit Prototype, Scritaculous und JQuery zum Leben erweckt werden. Du legst Wert auf eine saubere Trennung von XHTML, CSS und JavaScript und beherrscht diese Techniken anstandslos. Falls notwendig werden Unklarheiten in der Bedienung in einen Usability-Test geklärt.

Du arbeitest selbstständig im gesamten Prozess mit: Von der Beratung über den Design bis hin zur Entwicklung und Wartung der Systeme. Die bist kommunikativ und hilfst bei der Leitung der Projekte mit und kannst auch Pflichtenhefte und Kostenschätzungen erstellen.

Wir verwenden hauptsächlich Ruby on Rails/Radiant und Flex um hochdynamische Webapplikationen zu entwickeln, verwalten unseren Code mit Git und nutzen Apache/Passenger auf Linux Servern in der Produktion, auf welche wir mit Capistrano deployen.

Du solltest dich aber nicht scheuen auch einmal bei der Wartung von älteren Systemen in Java oder PHP Hand anzulegen, oder aber auch neues wie Erlang oder Objective C ausprobieren zu wollen. Kenntnisse von Java sind von Vorteil, da auch Ruby und Flex von der Java Plattform (JRuby) und Tools wie Ant profitieren können.

Obwohl unsere Applikationen professionell von einem externen Partner betrieben werden, solltest du dich gut mit der Administration diverser Linux Servern auskennen (Ubuntu/SuSE/RedHat/Debian) um die Umgebungen der diversen Test- und Produktivservern für unsere Projekte zu planen und verwalten.

Wir sind von den Vorteilen von Open Source überzeugt und stellen unsere eigenen Codes der Allgemeinheit zu Verfügung und helfen auch bei anderen Projekten aktiv mit.

Einige Jahre Erfahrung in der Entwicklung webbasierter Anwendungen sind ideal und du solltes über eine fundierte Ausbilung (ETH/Uni/FH) oder genügend praktischer Erfahrung in der Softwareentwicklung verfügen.

Wir sind ein kleines Team welches gerade im Umbruch ist. Weg von den grossen e-Commerce Systemen mit JEE zu eher kleinen, ausgetüftelten und  hoch-dynamischen Webseiten. Du hast die aussergewöhnliche Gelegenheit mit deinem Wissen den Weg in die Zukunft mitzugestalten.

Falls du dich angesprochen fühlst, schreib mir doch eine Email an michael.kessler@screenconcept.ch oder ruf mich unter 041 748 44 58 an, damit wir uns kennenlernen können. Und ja, wir arbeiten bereits an unserer eigenen Webseite, die aktuelle ist schrecklich ;-)

27
Jan

Berechtigungen für ein zentrales Git Repository

Mein erstes Git Repository auf dem Server war schnell erstellt:


sudo mkidr -p /var/git/netzpiraten.git
cd /var/git/netzpiraten.git
git init --bare --shared=group

… und schon konnte ich loslegen …


git clone ssh://www.netzpiraten.ch/var/git/netzpiraten.git
cd netzpiraten
touch test
git add test
git commit -a -m "Adding first file"
git push origin master

… und hatte wirklich nie irgend welche Probleme mit dem zentralen Repository auf dem Server.

Ein paar Monate später wurden auch in der Firma alle Subversion Repositories auf Git umgestellt und das lief auch ein Weilchen ohne Probleme, bis eines Tages folgende Fehlermeldung aufgetreten ist:


Counting objects: 31, done.
Compressing objects: 100% (20/20), done.
Writing objects: 100% (22/22), 239.64 KiB, done.
Total 22 (delta 7), reused 0 (delta 0)
error: unable to write sha1 filename ./objects/1c/1d505f3a585b9e7d298eb9477ab07c5ea79aea: Permission denied

fatal: failed to write object
error: unpack failed: unpacker exited with error code
To ssh://git.screenconcept.ch/var/git/repository.git
 ! [remote rejected] master -> master (n/a (unpacker error))

Also nichts wie auf den Server um das Repository etwas genauer zu inspizieren.

Zum Glück konnte der Fehler schnell gefunden werden: Ich hatte vergessen auf den Git Repositories das Setgid Flag zu setzten, womit neue Dateien nicht der Git Gruppe gehörten sondern der Hauptgruppe des Benutzers. Klar das eine anderer Benutzer diese nun nicht einfach so überschreiben kann.

Also schnell den Missstand korrigieren:


sudo chown -R :git /var/git
sudo find /var/git -type d | xargs chmod ug+rwx,g+s

… und jetzt kann wieder gemeinsam gearbeitet werden.


Man merke sich also folgendes für das Erstellen eines zentralen Git Repository:

  • Git Repository Verzeichnis erstellen
  • Das Verzeichnis der Gruppe ‘git’ zuweisen
  • Auf dem Verzeichnis das Setgid Flag setzten
  • Git Repository initialisieren

oder anders formuliert


sudo mkdir /var/git/repository.git
sudo chown :git /var/git/repository.git
sudo chmod ug+rwx,g+s /var/git/repository.git
sudo git init --bare /var/git/repository.git

… und nicht vergessen, Git macht am meisten Spass, wenn man auf GitHub teilt.

13
Jan

AJAX Formular mit Anker in der URL versenden

Ein normales HTML Formular kann mit Prototype JS sehr einfach mittels AJAX versendet werden. Dazu wird ganz einfach ein normales Formular erstellt:


<form id="myform" method="post" action="/controller">
   <input type="text" name="firstname" />
   <input type="text" name="lastname" />
   ...
   <input type="button" onclick="sendForm();" value="Versenden"/>
</form>

Nun kann mit relativ wenig Code das Formular versendet werden:


function sendForm() {
   $('myform').request({
      onSuccess: function(transport) {
         ...
      },
      onFailure: function(transport) {
         ...
      }
 });
}

Genau das wollte ich heute mit einem Formular in Radiant CMS machen, welcher ein Mail mit der Mailer-Erweiterung versendet. Damit das ganze noch etwas eleganter daherkommt, wird das Formular in einem Fenster mit Prototype Window dargestellt. Das funktioniert auch wunderbar, doch der obligate Test mit dem verstaubten Internet Explorer war leider einmal mehr nicht erfolgreich. Der Explorer konnte das Fomular nicht fehlerfrei versenden.

Nach einer Analyse der HTTP Anfragen kam zu Tage, dass durch die Darstellung des Formulares in einer Dialogbox (dessen Inhalt selber wiederum mit AJAX geladen wird), die URL zum Mailer-Kontroller einen HTML Anker enthielt:


/pages/25/mailer#mail

Irgendwie kommt der IE mit einem Anker in der Zielurl ganz und gar nicht klar. Nach ein wenig herumexperimentieren blieb mir nichts anderes übrig, als die URL selber aus dem Formular zu holen, den Anker daraus zu entfernen und erst dann das Formular zu versenden:


var url = $('myform').action;
var anchor = url.indexOf('#');
if (anchor != -1) {
   url = url.substring(0, anchor);
}
new Ajax.Request(url , {
   method: 'post',
   parameters: Form.serialize('myform'),
   onSuccess: function(transport) {
      ...
   },
   onFailure: function(transport) {
      ...
   }
});

Wieder einmal mehr wird durch den Explorer ein Stück eleganter Code zu einem komischen Rumgebastel. Internet Explorer - ohne dich würde die Webentwicklung wirklich Spass machen!





Juli 2009
M D M D F S S
« Jun    
 12345
6789101112
13141516171819
20212223242526
2728293031  

Werbung


Buttonitis