5
Nov/09
0

rush, un peu plus d’OOP dans les scripts

Problématique

Le lancement de l’application se fait par une tâche Rake, comme décrit précédemment dans le premier article concernant les builds.

task :start => :build do ...

La tâche de lancement est dépendante d’un build complet.

Cependant, on ne prend pas en compte l’environnement, et différents processus doivent être lancés avant de démarrer l’application. Il s’agit d’une dépendance sur des processus externes, et cela est généralement réalisé par des appels système.

Rush

Cependant, les commandes à créer sont un peu complexes et lourdes à maintenir. Pour cela, nous utiliserons donc une application Ruby qui s’inscrit dans la direction des shell basés sur de la programmation objet, comme le powershell de Microsoft.

Bienvenue à Rush. Rush a été créé pour les tâches d’administration liées au projet Heroku comme expliqué dans un article de l’auteur.

Vous pouvez également consulter une présentation de rush, qui expliquera bien mieux que moi les intérêts d’une telle technologie.

On l’installe comme tout autre gem :

gem install rush

A noter que je suis passé à gemcutter pour la gestion des modules (nouveau site officiel de gestion des gems).

ATTENTION ! Rake n’est pas vraiment compatible avec les systèmes de shell (et ceci m’a coûté beauuucoup de temps). En effet Rake redéfini les entrées et sorties standard, ce qui fait qu’il n’est plus possible de lire sur l’entrée standard, et donc qu’il est impossible de rediriger des commandes par pipe. C’est pourquoi les commandes shell seront écrites dans un fichier séparé.

Si vous insistez, vous vous retrouverez avec cette erreur peu compréhensible :

rake aborted!
Broken pipe

Start

On peut étendre la tâche de démarrage pour ajouter une dépendance à l’environnement :

task :start => [ :build, 'init:env' ] do 
end

et créer une tâche dans l’espace init :

require 'rush'
 
namespace 'init' do
  desc "Init servers"
  task :env do
    app = Rush[ROOT]
    app["*.dump"].each{ |f| f.destroy }
    app["*.swp"].each{ |f| f.destroy }
    system "#{ROOT}/process.sh"
  end
end

Ici, on efface des fichiers temporaires à chaque nouveau démarrage en utilisant la syntaxe rush (ROOT est une constante qui représente le chemin racine du projet).

Un point important, comme indiqué précédemment, c’est que la gestion des processus est délélguée à un fichier externe, et lancée dans un shell externe par la commande ruby directement. Ceci car rake et la gem session ne sont pas compatibles.

En tout cas, il n’est pas possible de démarrer une session bash dans une tâche rake, l’inverse étant sûrement possible.

Gestion des processus

La tâche d’initialisation a pour but de vérifier que les processus serveurs sont lancés, et si non de les lancer. Les serveurs sont actuellement Nginx et CouchDB.

On peut écrire le code ainsi (dans process.sh) :

#!/usr/bin/ruby -rubygems
 
require "rush"
 
if Rush::box.processes.filter(:cmdline => /nginx/).empty?
  puts "Starting nginx"
  Rush.box.bash "nginx", :user => "root"
end
 
if Rush::box.processes.filter(:cmdline => /couchdb/).empty?
  puts "Starting couchdb"
  Rush.box.bash "couchdb -b", :user => "root"
end

Et les processus ne seront démarrés que s’ils n’existent pas.

La commande indiquée dans le site est la suivante :

if Rush::box.processes.filter(:cmdline => /nginx/).alive?

Malheureusement, cela ne fonctionne pas du fait que les processus sont lancés en tant que root, et je n’ai pas trouvé comment contourner ce problème.

Filed under: Rake, build
Comments (0) Trackbacks (0)

No comments yet.

Leave a comment

No trackbacks yet.