<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Nap&#039;s mini world &#187; Développement</title>
	<atom:link href="http://www.gabes.fr/jean/tag/developpement/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.gabes.fr/jean</link>
	<description>Être admin, ça a parfois des airs de /dev/random...</description>
	<lastBuildDate>Mon, 12 Jul 2010 08:30:01 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" />
		<item>
		<title>Shinken : tagguez vos pollers</title>
		<link>http://www.gabes.fr/jean/2010/05/05/shinken-tagguez-vos-pollers/</link>
		<comments>http://www.gabes.fr/jean/2010/05/05/shinken-tagguez-vos-pollers/#comments</comments>
		<pubDate>Wed, 05 May 2010 08:10:20 +0000</pubDate>
		<dc:creator>Nap</dc:creator>
				<category><![CDATA[Shinken]]></category>
		<category><![CDATA[Développement]]></category>
		<category><![CDATA[Supervision]]></category>

		<guid isPermaLink="false">http://www.gabes.fr/jean/?p=551</guid>
		<description><![CDATA[Découpage organisationnel/technique
Dans l&#8217;Architecture de Shinken, un point important concerne les Realms (royaumes) qui servent à découper dans pans entiers d&#8217;infrastructure, comme un site distant par exemple, ou bien un client pour une entreprise qui propose une prestation de supervision.
Ce découpage est donc soit organisationnel, soit technique. Mais pour ce dernier, le choix du découpage se [...]]]></description>
			<content:encoded><![CDATA[<h2>Découpage organisationnel/technique</h2>
<p>Dans l&#8217;Architecture de Shinken, un point important concerne les Realms (royaumes) qui servent à découper dans pans entiers d&#8217;infrastructure, comme un site distant par exemple, ou bien un client pour une entreprise qui propose une prestation de supervision.</p>
<p>Ce découpage est donc soit organisationnel, soit technique. Mais pour ce dernier, le choix du découpage se fait sur des critères géographiques, en terme de réseau principalement (pour ne pas avoir de fréquentes communications inter-continents par exemple).</p>
<p>Shinken fonctionne sur Windows (avec des services et tout et tout), et il est donc tentant de placer un poller sur un tel OS afin de lancer directement ses checks depuis une machine (et un compte de domaine) qui a les droits sur les autres machines, pour faire du WMI par exemple.</p>
<p>Mais comment faire en sorte que les commandes pour Windows partent sur ces pollers &#8220;Windows&#8221; et pas les classiques pollers &#8220;Linux&#8221;? On peut se dire que l&#8217;on utilise les realms, mais ce n&#8217;est pas une bonne idée en fait. Les realms sont des cloisonnements, il n&#8217;y a pas d&#8217;échange entre les schedulers (même au sein d&#8217;un realm d&#8217;ailleurs). Donc si un administrateur défini un Realm Linux et un Realm Windows, il va pouvoir obtenir l&#8217;effet souhaité (des commandes qui vont sur les bons pollers), mais à un prix énorme : plus de liens (dépendances) entre les hôtes Linux et Windows&#8230;</p>
<h2>Cloisonnement technique</h2>
<p>C&#8217;est pour cela que dans un même realm, il doit être possible de cloisonner &#8220;techniquement&#8221; les commandes sur des pollers. Ce cloisonnement, qui va être optionnel bien sûr, se fera dans la configuration avec une nouvelle option : <strong>poller_tag</strong>. Comme son nom l&#8217;indique, un poller va avoir un ou plusieurs tags, et les checks vont pouvoir également être <em>taggués</em>.</p>
<p>Si le tag au niveau des pollers est simple, se pose la question du tag des commandes : à quel niveau doit-on tagguer? commands, services, hosts? Et pourquoi pas les 3 finalement? L&#8217;héritage serait host-&gt;service-&gt;commands.</p>
<p>Le tag des commands est simple : une commande définie comme un exe au sens windows (PE et non pas ELF) sera naturellement tagguée &#8220;windows-poller&#8221;. Les tags au niveau service/hosts seraient un peu comme un &#8220;mini-realm&#8221; : au lieu de définir un realm complet (avec un couple scheduler/poller) pour une DMZ par exemple, il peut être pratique de juste dédier un poller (ou deux) dans cet environnement, et de <em>tagguer </em>les hôtes/services.</p>
<h2>Un mini-realm?</h2>
<p>Ceci n&#8217;est pas complètement orthogonal aux realms je l&#8217;admets, mais c&#8217;est plus une réponse aux &#8220;proxy nrpe windows&#8221; qu&#8217;à un réel besoin organisationnel que proposent les Realms.</p>
<p>Au passage, cette implémentation va être un bon exemple de &#8220;Hack&#8221; possible de Shinken. Je vais essayer de noter/expliquer l&#8217;implémentation dans un document afin de montrer que développer pour Shinken n&#8217;est pas complexe, loin de là <img src='http://www.gabes.fr/jean/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.gabes.fr/jean/2010/05/05/shinken-tagguez-vos-pollers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Partie à trois : Python, __slots__ et metaclass</title>
		<link>http://www.gabes.fr/jean/2010/02/15/partie-a-trois-python-__slots__-et-metaclass/</link>
		<comments>http://www.gabes.fr/jean/2010/02/15/partie-a-trois-python-__slots__-et-metaclass/#comments</comments>
		<pubDate>Mon, 15 Feb 2010 13:08:33 +0000</pubDate>
		<dc:creator>Nap</dc:creator>
				<category><![CDATA[Programmation]]></category>
		<category><![CDATA[Développement]]></category>
		<category><![CDATA[metaclass]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[slots]]></category>
		<category><![CDATA[__slots__]]></category>

		<guid isPermaLink="false">http://www.gabes.fr/jean/?p=453</guid>
		<description><![CDATA[Les langages dynamiques sont pratiques pour se frotter facilement à de nouveaux paradigmes de programmations. Aucune technique n&#8217;étant parfaite, l&#8217;aspect dynamique se paye.
Le prix à payer pour les langages dynamiques
Bien souvent on pense au coût CPU pour ces langages, mais cette ressource n&#8217;est pas la seule à prendre cher. Là où un accès à une [...]]]></description>
			<content:encoded><![CDATA[<p>Les langages dynamiques sont pratiques pour se frotter facilement à de nouveaux paradigmes de programmations. Aucune technique n&#8217;étant parfaite, l&#8217;aspect dynamique se paye.</p>
<h2>Le prix à payer pour les langages dynamiques</h2>
<p>Bien souvent on pense au coût CPU pour ces langages, mais cette ressource n&#8217;est pas la seule à prendre cher. Là où un accès à une structure est en 0(1) en C ou C++, il peut être plus élevé dans des langages où les propriétés des objets ne sont pas identiques entre les instances. Il en est de même pour la RAM : les objets pouvant avoir de nouvelles propriétés à chaud, leur accès se fait en vérifiant le dictionnaire <em>__dict__</em> des objets. Le dictionnaire est fort simple:</p>
<p class="wp-caption" style="text-align: left;">class Test:<br />
&nbsp;&nbsp;&nbsp;def __init__(self, x, y):<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.x = x<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.y = y<br />
point = Test(1, 2)<br />
print &#8216;Initialement&#8217;, point.__dict__<br />
point.z = 3<br />
print &#8216;Apres&#8217;, point.__dict__</p>
<p style="text-align: left;">Donne :</p>
<p class="wp-caption" style="text-align: left;">Initialement {&#8217;y': 2, &#8216;x&#8217;: 1}<br />
Apres {&#8217;y': 2, &#8216;x&#8217;: 1, &#8216;z&#8217;: 3}</p>
<p style="text-align: left;">C&#8217;est sympa, c&#8217;est dynamique. Mais ceci a un coût en Mémoire : ici nous avons un seul objet, mais si nous avons 1000 points, chacun aura son propre __dict__ indépendant, et surtout les chaînes &#8216;x&#8217;, &#8216;y&#8217; et &#8216;z&#8217; seront dupliquées dans chaque instance. Imaginons que nous avons 1000000 de points à conserver, la consommation de RAM va être de 176mo sur notre exemple (Python 2.6.4). Si nous prenons des classes avec des noms de propriétés plus grandes que &#8216;x&#8217;, on peut atteindre des sommets en terme de consommation de RAM pour finalement pas grand chose.</p>
<p>Le module guppy (disponible sur pypi de mémoire) peut être très pratique pour observer qui consomme de la RAM dans notre application. Son utilisation est fort simple :</p>
<p class="wp-caption" style="text-align: left;">from guppy import hpy<br />
hp=hpy()<br />
print hp.heap()</p>
<p style="text-align: left;">Sa sortie est (relativement) éloquente :</p>
<p class="wp-caption" style="text-align: left;">Partition of a set of 2024657 objects. Total size = 173885852 bytes.<br />
Index  Count   %     Size   % Cumulative  % Kind (class / dict of class)<br />
0 999999  49 135999864  78 135999864  78 dict of __main__.Test<br />
1 999999  49 31999968  18 167999832  97 __main__.Test<br />
2    127   0  4073248   2 172073080  99 list<br />
3  10686   1   744928   0 172818008  99 str<br />
4   5540   0   203368   0 173021376 100 tuple<br />
5    347   0   115160   0 173136536 100 dict (no owner)<br />
6   1539   0   104652   0 173241188 100 types.CodeType<br />
7     64   0   100480   0 173341668 100 dict of module<br />
8    175   0    94840   0 173436508 100 dict of type<br />
9    194   0    86040   0 173522548 100 type</p>
<p style="text-align: left;">78% de la consommation mémoire est due aux<em> __dict__</em> de nos points, les valeurs de ces instances consommant quant à elles 18%.</p>
<h2>__slots__ : c&#8217;est les soldes pour Python</h2>
<p>Lorsque l&#8217;on sait à l&#8217;avance quelles vont être les possibilités des noms de propriétés de nos instances, il peut être pratique de recourir à l&#8217;utilisation des <em>__slots__</em>. C&#8217;est un tuple dans la classe où les noms des propriétés vont être mises en commun pour toutes les instances de la classe. Attention, son utilisation est fort simple, mais elle limite certaines possibilités de Python par la suite, comme certains problèmes avec tout ce qui touche la sérialisation d&#8217;objet par exemple.</p>
<p>Si vous souhaitez l&#8217;utiliser, c&#8217;est fort simple, il suffit de rajouter le tuple à la classe si elle hérite d&#8217;<em>object</em> :</p>
<p class="wp-caption" style="text-align: left;">class Test(object):<br />
&nbsp;&nbsp;&nbsp;__slots__ = (&#8217;x', &#8216;y&#8217;, &#8216;z&#8217;)<br />
&nbsp;&nbsp;&nbsp;def __init__(self, x, y):<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.x = x<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.y = y</p>
<p style="text-align: left;">Si simple? Non en fait. le <em>__slots__</em> va remplacer <em>__dict__</em> qui va tout simplement disparaitre! Notre code va lamentablement échouer avec:</p>
<p class="wp-caption" style="text-align: left;">Initialement<br />
Traceback (most recent call last):<br />
File &#8220;test_slot.py&#8221;, line 10, in &lt;module&gt;<br />
print &#8216;Initialement&#8217;, point.__dict__<br />
AttributeError: &#8216;Test&#8217; object has no attribute &#8216;__dict__&#8217;</p>
<p style="text-align: left;">Pour contourner cela, il suffit de rajouter __dict__ au slots:</p>
<p class="wp-caption" style="text-align: left;">class Test(object):<br />
&nbsp;&nbsp;&nbsp;__slots__ = (&#8217;__dict__&#8217;, &#8216;x&#8217;, &#8216;y&#8217;, &#8216;z&#8217;)<br />
&nbsp;&nbsp;&nbsp;def __init__(self, x, y):<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.x = x<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.y = y</p>
<p style="text-align: left;">On relance, la consommation passe à 47Mo. (Les gains sont encore plus importants avec des chaînes de plus d&#8217;un caractère <img src='http://www.gabes.fr/jean/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ). Pour Shinken par exemple, avec 100000 services, j&#8217;étais à plus de 2Go de RAM consommée, avec les slots, je suis tombé à moins 50Mo environs&#8230;</p>
<h2>Metaclass : une classe pour en modifier d&#8217;autres</h2>
<p>En Python, on a déjà vu que les classes sont des objets comme les autres. Qui dit objet dit instanciation. Lors de cette instanciation, il peut être pratique de changer des choses à la volée. C&#8217;est justement le rôle des <em>metaclass</em>. C&#8217;est une classe qui va contrôler la création d&#8217;une autre. Elles peuvent être utilisées pour par exemple tracer automatiquement tous les appels de méthode d&#8217;une classe. Pour un tel exemple, voir sur <a href="http://www.afpy.org/Members/kerflyn/metaclass">http://www.afpy.org/Members/kerflyn/metaclass</a> qui présente très bien cela.</p>
<h2>On mixe le tout</h2>
<p>Vous allez me dire: bon c&#8217;est bien les <em>metaclass</em>, mais c&#8217;est quoi le rapport avec les <em>__slots__</em>? Et bien c&#8217;est pratique lorsque l&#8217;on a beaucoup de propriétés dans une classe, comme par exemple Service ou Host de Shinken. Jusqu&#8217;à maintenant, lorsque je rajoutait une nouvelle propriété à ces classes, je rajoutais une ligne dans le tableau <em>properties</em> ou <em>running_properties</em>, mais je devais penser à rajouter ce même paramètre dans le tuple  <em>__slots__</em> de la classe. Autant dire qu&#8217;une fois sur deux, j&#8217;oubliais. De plus, ça fait un gros pâté en début de classe, et je n&#8217;aime pas ça.</p>
<p>Je suis tombé sur <a href="http://code.activestate.com/recipes/435880/">http://code.activestate.com/recipes/435880/</a> qui présente comment générer automatiquement le tuple <em>__slots__</em> pour ses classes en regardant tout simplement les variables fournies à <em>__init__</em> (il semble créer d&#8217;ailleurs une liste qui doit être changée en tuple par l&#8217;interpréteur). Bon pour les Host et Service, il n&#8217;y a qu&#8217;un seul paramètre, un tableau de construction. Mais ça m&#8217;a donné l&#8217;idée d&#8217;adapter ce code pour qu&#8217;il utilise les tableaux <em>properties </em>et <em>running_properties</em> de mes classes qui contiennent toutes les propriétés de mes objets.</p>
<p>Edit : Merci à Bertrand Mathieu pour la simplification du code par set.</p>
<p>Ceci donne au final la classe <em>AutoSlots</em> suivante :</p>
<p class="wp-caption" style="text-align: left;">class AutoSlots(type):<br />
&nbsp;&nbsp;&nbsp;def __new__(cls, name, bases, dct):<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;slots = dct.get(&#8217;__slots__&#8217;, set())<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#Now get properties from properties and running_properties<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if &#8216;properties&#8217; in dct:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;slots.update((p for p in dct['properties']))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if &#8216;running_properties&#8217; in dct:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lots.update((p for p in dct['running_properties']))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dct['__slots__'] = tuple(slots)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return type.__new__(cls, name, bases, dct)</p>
<p style="text-align: left;">Qui est appelée avec :</p>
<p class="wp-caption" style="text-align: left;">class Service(SchedulingItem):<br />
&nbsp;&nbsp;&nbsp;#AutoSlots create the __slots__ with properties and<br />
&nbsp;&nbsp;&nbsp;#running_properties names<br />
&nbsp;&nbsp;&nbsp;__metaclass__ = AutoSlots</p>
<p class="wp-caption" style="text-align: left;">[..]</p>
<p>Maintenant les <em>__slots__</em> sont construits à la volée, et il n&#8217;y a plus de risque d&#8217;oublier des paramètres et mes classes Host/Service se re-concentrent un peu sur ce qu&#8217;elles doivent faire, et non sur une astuce pour contourner une consommation excessive de RAM par Python.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gabes.fr/jean/2010/02/15/partie-a-trois-python-__slots__-et-metaclass/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Python et le Data-Driven programming</title>
		<link>http://www.gabes.fr/jean/2009/12/16/python-et-le-data-driven-programming/</link>
		<comments>http://www.gabes.fr/jean/2009/12/16/python-et-le-data-driven-programming/#comments</comments>
		<pubDate>Wed, 16 Dec 2009 09:22:34 +0000</pubDate>
		<dc:creator>Nap</dc:creator>
				<category><![CDATA[Shinken]]></category>
		<category><![CDATA[Développement]]></category>

		<guid isPermaLink="false">http://www.gabes.fr/jean/?p=407</guid>
		<description><![CDATA[Suite au post d&#8217;un journal sur linux-fr concernant Shinken et l&#8217;avenir de Nagios (http://linuxfr.org/~naparuba/29141.html) certains m&#8217;ont demandé pourquoi j&#8217;ai choisi le Python (www.python.org) pour Shinken. J&#8217;ai répondu que 80% du choix était dû à mon goût perso, 20% pour les qualités du langages sur la résolution du problème. Les 20% sont en fait le module [...]]]></description>
			<content:encoded><![CDATA[<p>Suite au post d&#8217;un journal sur linux-fr concernant Shinken et l&#8217;avenir de Nagios (<a href="http://linuxfr.org/~naparuba/29141.html">http://linuxfr.org/~naparuba/29141.html</a>) certains m&#8217;ont demandé pourquoi j&#8217;ai choisi le Python (<a href="http://www.python.org">www.python.org</a>) pour Shinken. J&#8217;ai répondu que 80% du choix était dû à mon goût perso, 20% pour les qualités du langages sur la résolution du problème. Les 20% sont en fait le module Pyro (<a href="http://pyro.sourceforge.net/">http://pyro.sourceforge.net/</a>)pour les objets distants (un peu comme Corba, mais autrement plus simple à utiliser et plus dynamique (pas de déclaration de squelette)).</p>
<h2>Et les 80% restant?</h2>
<p>On peu un peu se demander ce qu&#8217;il y a dans les 80% restant. Outre le fait que le langage ne pique pas les yeux (et évite les nœuds &#8230; au cerveau), et qu&#8217;il a d&#8217;intégré un module pour la gestion des pools de process (lancement des checks en parallèle),  il a de réelles qualités sur son dynamisme qui permettent d&#8217;utiliser une vaste panoplie de paradigme de programmation. Il ne les fait pas tous bien entendu (genre la programmation logique (et le prolog)), mais il permets déjà d&#8217;utiliser les principaux:</p>
<ul>
<li>programmation itérative et récursive</li>
<li>programmation orientée objet</li>
<li>programmation orientée aspect (<em>decorator</em>)</li>
</ul>
<p>Bon c&#8217;est bien, mais le rapport avec la choucroute il et où? Et bien suivant la situation, avec Python on peut choisir, c&#8217;est plutôt sympa. Lorsque vous gérez des graphes, le récursif s&#8217;impose de lui même (ou alors vous être vraiment tordu&#8230;), en règle général c&#8217;est de l&#8217;objet, et dans quelques cas particuliers l&#8217;aspect.</p>
<h2>Une matrice de création nommée ADN</h2>
<p>Concernant l&#8217;objet, la création des objets n&#8217;est pas classique pour la plupart des types dans Shinken. Nagios utilise des techniques d&#8217;héritages sur des objets (hosts/services) qui ont de multiples propriétés (et c&#8217;est rien de le dire). Alors m&#8217;amuser à faire des constructeurs de 5 lignes non extensibles facilement, non merci. Si c&#8217;est pour faire ça, autant rester à faire du C.</p>
<p>C&#8217;est là que vient le <em>data-driven</em> (enfin je crois que c&#8217;est comme ça que ca s&#8217;appelle) : vous décrivez votre objet dans un tableau quelconque, et au lieu de coder ce que vous devez faire pour chaque propriétés, vous faire une boucle sur votre tableau de description pour faire l&#8217;action, avec outre le nom de la propriété, les informations dans ce tableau sur quoi faire pour telle propriété. C&#8217;est tout (bah oui, c&#8217;est tout con, d&#8217;ailleurs je l&#8217;ai fait avant de savoir comment ça s&#8217;appelait&#8230;). L&#8217;intérêt? Aucun si vote objet a trois pauvres propriétés, mais énorme si elles commencent à devenir nombreuses (genre une bonne vingtaine).</p>
<p>Comme pour la plupart des techniques de programmations, l&#8217;intérêt est d&#8217;avoir une factorisation des informations. Ici vos propriétés (et les propriétés de ces propriétés&#8230;) sont définies dans un seul endroit. Si vous voulez changer, rajouter, supprimer quelque chose, pas besoin d&#8217;aller parcourir l&#8217;ensemble du code. Celui-ci ne connait pas ce que vous avez mis comme données dans vos tableaux. Il sait les traiter, mais ne connait pas à l&#8217;avance ce qu&#8217;il y a dedans. Le tableau est une sorte d&#8217;ADN de l&#8217;objet : c&#8217;est sa matrice de fabrication.</p>
<h2>Où qu&#8217;on le met cet ADN?</h2>
<p>Ce qui est embêtant est d&#8217;accéder à ce tableau lors de vos traitement. Bien sûr il y a la méthode consistant à le mettre en variable global, mais les variables globales c&#8217;est un peu comme le goto : le mal absolu. Mettre le tableau dans chaque objet? Bof, c&#8217;est crade, un objet n&#8217;a pas besoin d&#8217;avoir son ADN d&#8217;accroché pour vivre une fois crée (vous utilisez votre ADN vous? Non, vous utilisez les protéines qu&#8217;il a permis de fabriquer). Python nous aide ici. Si vous faite <em>objet.__class__</em> vous obtenez la classe de l&#8217;objet. Et oui, une classe est un objet. Et un objet en python peut se voir accrocher des propriétés&#8230; genre notre tableau.</p>
<p>Si on rajoute ceci à un héritage de nos objets à une classe &#8220;Item&#8221; qui va faire le travail de construction, on obtient une fabrique de n&#8217;importe quel objet le temps que l&#8217;on définisse son ADN dans la classe de l&#8217;objet. Pratique non? C&#8217;est diablement efficace pour factoriser le code à sa plus simple expression.</p>
<h2>Et au final on y gagne beaucoup?</h2>
<p>Vous voulez un exemple? Le code de Nagios pour juste la fabrication des objets avec les techniques d&#8217;héritages and co prends à lui seul plus de 11K lignes. Shinken dans son entier (architecture distribuée, configuration, envoi dans les bases de données, ordonnancement, etc) en prends un peu plus de 8K. <em>Owned</em> comme dirait l&#8217;autre.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gabes.fr/jean/2009/12/16/python-et-le-data-driven-programming/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Patch Nagios : SSL pour Ndo</title>
		<link>http://www.gabes.fr/jean/2009/10/16/patch-nagios-ssl-pour-ndo/</link>
		<comments>http://www.gabes.fr/jean/2009/10/16/patch-nagios-ssl-pour-ndo/#comments</comments>
		<pubDate>Fri, 16 Oct 2009 09:13:33 +0000</pubDate>
		<dc:creator>Nap</dc:creator>
				<category><![CDATA[Nagios]]></category>
		<category><![CDATA[Développement]]></category>

		<guid isPermaLink="false">http://www.gabes.fr/jean/?p=275</guid>
		<description><![CDATA[J&#8217;avais travaillé sur 3 patchs pour Nagios et je n&#8217;en ais évoqué ici que 2 pour la bonne raison que c&#8217;étaient les seuls à être intégrés. Et bien en fait c&#8217;est inexact : le troisième l&#8217;a été aussi  
Ce patch permet d&#8217;établir une connexion chiffrée entre le module ndomod et ndo2db. En effet, avant [...]]]></description>
			<content:encoded><![CDATA[<p>J&#8217;avais travaillé sur 3 patchs pour Nagios et je n&#8217;en ais évoqué ici que 2 pour la bonne raison que c&#8217;étaient les seuls à être intégrés. Et bien en fait c&#8217;est inexact : le troisième l&#8217;a été aussi <img src='http://www.gabes.fr/jean/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Ce patch permet d&#8217;établir une connexion chiffrée entre le module ndomod et ndo2db. En effet, avant tous les paquets étaient envoyés en clair sur le réseau. Ceci a beau être de la supervision, il y a tout de même le nom de toute nos machines, c&#8217;est assez embêtant. Avec le patch que j&#8217;ai proposé (commit sur <a href="http://nagios.git.sourceforge.net/git/gitweb.cgi?p=nagios/ndoutils;a=commitdiff;h=9d9dcccab9690c896a7f1c3d2015064430c5157a">http://nagios.git.sourceforge.net/git/gitweb.cgi?p=nagios/ndoutils;a=commitdiff;h=9d9dcccab9690c896a7f1c3d2015064430c5157a</a> par Hendrik Baecker) il y a une option de plus sur ndomod.cfg et ndo2db.cfg : use_ssl.</p>
<p>Par défaut elle est à 0 pour un soucis de compatibilité. Une fois passée à 1, la communication sur socket (uniquement celle en réseau, pas cette sur le socket unix) est chiffrée.</p>
<p>Je n&#8217;ai pas réinventé la roue, j&#8217;ai emprunté le code à NRPE tout simplement. Je l&#8217;ai juste un peu adapté et mis au bon endroit.</p>
<p>Et voila, je suis dans le fichier THANKS de ndoutils maintenant <img src='http://www.gabes.fr/jean/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.gabes.fr/jean/2009/10/16/patch-nagios-ssl-pour-ndo/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Shinken : 100K checks/5minutes</title>
		<link>http://www.gabes.fr/jean/2009/10/13/shinken-100k-checks5minutes/</link>
		<comments>http://www.gabes.fr/jean/2009/10/13/shinken-100k-checks5minutes/#comments</comments>
		<pubDate>Tue, 13 Oct 2009 13:05:53 +0000</pubDate>
		<dc:creator>Nap</dc:creator>
				<category><![CDATA[Nagios]]></category>
		<category><![CDATA[Développement]]></category>
		<category><![CDATA[Shinken]]></category>

		<guid isPermaLink="false">http://www.gabes.fr/jean/?p=268</guid>
		<description><![CDATA[Je viens de faire un test sur une &#8220;petite&#8221; machine : un Xeon 5140 (4coeurs, 3.1Ghz). J&#8217;ai réussi à dépasser la symbolique limite des 100000 (oui oui, 100K) checks en 5 minutes. J&#8217;ai un peu triché pour cela : j&#8217;ai exporté le broker et la base MySQL sur un autre serveur. J&#8217;arrive à un trafic [...]]]></description>
			<content:encoded><![CDATA[<p>Je viens de faire un test sur une &#8220;petite&#8221; machine : un Xeon 5140 (4coeurs, 3.1Ghz). J&#8217;ai réussi à dépasser la symbolique limite des 100000 (oui oui, 100K) checks en 5 minutes. J&#8217;ai un peu triché pour cela : j&#8217;ai exporté le broker et la base MySQL sur un autre serveur. J&#8217;arrive à un trafic à 50Ko/s entre le scheduler et le broker, ce qui est raisonnable vu le nombre de checks <img src='http://www.gabes.fr/jean/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Petite preuve avec un ninja situé sur la machine avec la base :</p>
<p><a href="http://www.gabes.fr/jean/wp-content/uploads/2009/10/100k.jpg"><img class="aligncenter size-full wp-image-269" title="100k" src="http://www.gabes.fr/jean/wp-content/uploads/2009/10/100k.jpg" alt="100k" width="580" height="389" /></a>Pour ceux qui sont curieux : oui, Ninja rame un peu avec autant de services à gérer, mais cela reste acceptable <img src='http://www.gabes.fr/jean/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Cette configuration sera de plus la plus répandue sur les gros environnements avec plusieurs schedulers. Pour rappel, sur cette même machine je plafonne à 10K checks avec un Nagios non tuné, 30K en le tunant un max.</p>
<p>Moi je ne dirais qu&#8217;une chose : merci Python, mettre en place un pool de process est d&#8217;une simplicité monstrueuse. Maintenant, reste à faire de même avec Nagios (et de convaincre ses auteurs&#8230;). Qui sait, la barre des 200K sera peu être atteinte un jour?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gabes.fr/jean/2009/10/13/shinken-100k-checks5minutes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Patch Nagios pour une gestion plus fine de la configuration</title>
		<link>http://www.gabes.fr/jean/2009/07/02/patch-nagios-pour-une-gestion-plus-fine-de-la-configuration/</link>
		<comments>http://www.gabes.fr/jean/2009/07/02/patch-nagios-pour-une-gestion-plus-fine-de-la-configuration/#comments</comments>
		<pubDate>Thu, 02 Jul 2009 11:39:21 +0000</pubDate>
		<dc:creator>Nap</dc:creator>
				<category><![CDATA[Nagios]]></category>
		<category><![CDATA[Développement]]></category>
		<category><![CDATA[Supervision]]></category>

		<guid isPermaLink="false">http://www.gabes.fr/jean/?p=187</guid>
		<description><![CDATA[Lorsque l&#8217;on étudie un peu la gestion de configuration de Nagios, on est impressionné  par la richesses des possibilité, que ce soit sur les macros, les services appliqués sur les groupes, les exeptions, etc. En fait, une seule fonctionalité manque lorsque l&#8217;on souhaite gérer finement et effiacement sa configuration : les exeptions sur les services [...]]]></description>
			<content:encoded><![CDATA[<p>Lorsque l&#8217;on étudie un peu la gestion de configuration de Nagios, on est impressionné  par la richesses des possibilité, que ce soit sur les macros, les services appliqués sur les groupes, les exeptions, etc. En fait, une seule fonctionalité manque lorsque l&#8217;on souhaite gérer finement et effiacement sa configuration : les exeptions sur les services appliqués sur des groupes de noeuds.</p>
<p>Un tel service appliqué sur un groupe prenait systématiquement le pas sur le même service appliqué sur un noeud. On était obligé de contourner le problème avec la mise en place de MACROS spécifiques et de modifier les commandes. Ce n&#8217;est désormais plus nécessaire avec la nouvelle version de Nagios. J&#8217;ai proposé dernièrement un patch qui a été appliqué dans la 3.1.2.</p>
<p>Cette modification permet à un service appliqué sur un noeud de prendre le pas sur le service appliqué d&#8217;un groupe. Cette possibilité permet de définir très simplement une execptions d&#8217;un service, sans avoir à sortir un noeud d&#8217;un groupe et dupliquer tous les autres services qui y étaient acrochés.</p>
<p>Par exemple, avec la défiition suivante :</p>
<p class="wp-caption" style="text-align: left;">define service{<br />
use     generic-service<br />
hostgroup_n<span class="wp-caption">ame       all-server<br />
service_description     service-test<br />
check_command   check_ping<br />
}</span></p>
<p class="wp-caption" style="text-align: left;"><span class="wp-caption">define service{<br />
use     generic-s</span>ervice<br />
host_name       srv-1<br />
service_description     service-test<br />
check_command   check_local_disk<br />
}</p>
<p style="text-align: left;">Et bien maintenant c&#8217;est la seconde définition qui va gagner, ce qui est tout de même bien pratique  <img src='http://www.gabes.fr/jean/wp-includes/images/smilies/icon_mrgreen.gif' alt=':mrgreen:' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.gabes.fr/jean/2009/07/02/patch-nagios-pour-une-gestion-plus-fine-de-la-configuration/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Shinken : quand un python rencontre Nagios</title>
		<link>http://www.gabes.fr/jean/2009/07/02/shinken-quand-un-python-rencontre-nagios/</link>
		<comments>http://www.gabes.fr/jean/2009/07/02/shinken-quand-un-python-rencontre-nagios/#comments</comments>
		<pubDate>Thu, 02 Jul 2009 11:31:08 +0000</pubDate>
		<dc:creator>Nap</dc:creator>
				<category><![CDATA[Nagios]]></category>
		<category><![CDATA[cluster]]></category>
		<category><![CDATA[Développement]]></category>
		<category><![CDATA[Shinken]]></category>
		<category><![CDATA[Supervision]]></category>

		<guid isPermaLink="false">http://www.gabes.fr/jean/?p=136</guid>
		<description><![CDATA[J&#8217;ai commencé voila quelques temps le projet Shinken. C&#8217;est une ré-implémentation de Nagios en Python qui va me permettre de maqueter certains principes pour Nagios avant de me les fader en C. C&#8217;est pour cela que j&#8217;ai choisi le langage Python qui est particulièrement élégant et jouissif. Si vous ne le connaissez pas, aller faire [...]]]></description>
			<content:encoded><![CDATA[<p>J&#8217;ai commencé voila quelques temps le projet <strong>Shinken</strong>. C&#8217;est une ré-implémentation de <a href="http://www.nagios.org">Nagios</a> en Python qui va me permettre de maqueter certains principes pour Nagios avant de me les fader en C. C&#8217;est pour cela que j&#8217;ai choisi le langage Python qui est particulièrement élégant et jouissif. Si vous ne le connaissez pas, aller faire un petit tour sur <a href="http://www.python.org/">http://www.python.org/</a> et laissez vous emporter par ce super langage.</p>
<p>Shinken est le résultat de mon étude de Nagios dont je parlerai un peu plus tard. Ce projet est déjà très efficace, mais j&#8217;étais persuadé que certains petits détails étaient encore améliorables. Par exemple, le lancement des sondes est ce qui coute le plus cher en terme de performance pour Nagios. Éviter de forker en ayant un pool de processus peut être bien plus intéressant. Ceci se code en quelques lignes de Python. De même, les aspects distribué de Nagios ne sont pas parfait. Les Nagios n&#8217;ont aucune connaissance des autres. Si avec des solutions comme Centreon il est facile de les gérer, certains problèmes persistent comme les notifications qui sont envoyées par chaque Nagios et ce séquentiellement.</p>
<p>L&#8217;intérêt de Shinken est de reprendre la configuration de Nagios ainsi que ses principes de supervision qui sont très pousés tout en proposant une novuelle architecture pour le programme à proprement parlé. Shinken est par exemple capable de couper automatiquement la configuration en partie totalement indépendantes qui vont pouvoir être, encore automatiquement, envoyées vers un scheduler qui va ordonnancer les vérifications et prendre les décisions en cas de problèmes.</p>
<p>Le nom du projet n&#8217;a pas été facile à trouver : je suis très long pour trouver des noms. Je peux dire merci à <a href="http://en.wikipedia.org/wiki/Shinken">Wikipedia </a>pour celui-là. je cherchai un nom de sabre japonais (j&#8217;aime bien la sonorité des noms japonais) et je suis tombé sur celui-là. Le sabre illustre la faculté de couper la charge automatiquement sur plusieurs machines. Et le Shinken est le sabre qui coupe le plus.</p>
<p>Le code est déjà bien avancé et est en licence AGPLv3.  Je reviendrai plus tard sur ce choix. Je suis en train de monter une première version sur <a href="https://sourceforge.net/projects/shinken/">sourceforge</a>. Et plus important encore, le logo est déjà prêt <img src='http://www.gabes.fr/jean/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><a href="http://www.gabes.fr/jean/wp-content/uploads/2009/06/shinken.png"><img class="alignnone size-medium wp-image-139" title="shinken" src="http://www.gabes.fr/jean/wp-content/uploads/2009/06/shinken-300x300.png" alt="shinken" width="300" height="300" /></a></p>
<p>Merci à l&#8217;auteur cisoun pour sa mascotte <a href="http://tux.crystalxp.net/en.id.2203-cisoun-ouaaargh.html">ouaaargh</a> qui a servi de base à ce logo <img src='http://www.gabes.fr/jean/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Pour ceux qui veulent voir un peu ce que cela donne, vous pouvez obtenir la dernière version du code avec git (paquet git-core sous debian):</p>
<pre class="wp-caption" style="text-align: left;"><code>git clone git://shinken.git.sourceforge.net/gitroot/shinken/shinken</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://www.gabes.fr/jean/2009/07/02/shinken-quand-un-python-rencontre-nagios/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Patch Nagios pour un démarrage (bien plus) rapide</title>
		<link>http://www.gabes.fr/jean/2009/07/02/patch-nagios-pour-un-demarrage-bien-plus-rapide/</link>
		<comments>http://www.gabes.fr/jean/2009/07/02/patch-nagios-pour-un-demarrage-bien-plus-rapide/#comments</comments>
		<pubDate>Thu, 02 Jul 2009 08:08:29 +0000</pubDate>
		<dc:creator>Nap</dc:creator>
				<category><![CDATA[Nagios]]></category>
		<category><![CDATA[Développement]]></category>
		<category><![CDATA[GNU/Linux]]></category>
		<category><![CDATA[Supervision]]></category>

		<guid isPermaLink="false">http://www.gabes.fr/jean/?p=149</guid>
		<description><![CDATA[Il y a de cela un an, j&#8217;ai pris au mot l&#8217;auteur de Nagios lorsqu&#8217;il écrit dans la documentation de Nagios concernant les vérifications effectuées au démarrage :
&#8220;That means all you CompSci graduate students who have been emailing me about doing your thesis on Nagios can contribute some code back.  &#8221;
Je ne sais pas [...]]]></description>
			<content:encoded><![CDATA[<p>Il y a de cela un an, j&#8217;ai pris au mot l&#8217;auteur de Nagios lorsqu&#8217;il écrit dans la documentation de Nagios concernant les vérifications effectuées au démarrage :<br />
<span class="wp-caption">&#8220;That means all you CompSci graduate students who have been emailing me about doing your thesis on Nagios can contribute some code back. <img src='http://www.gabes.fr/jean/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> &#8221;</span><br />
Je ne sais pas qui ils sont, mais j&#8217;ai essayé de résoudre le problème poser : la vérification des liens de parentés dans Nagios était horriblement longue. En fait, j&#8217;ai même réussi.</p>
<p>Pour rappel, Nagios permet de définir pour un host un ou plusieurs parents (en terme de réseau). De cette manière, si un switch tombe par exemple et que l&#8217;administrateur a bien configuré ses serveurs pour qu&#8217;ils soient des fils du switch en question, il ne va recevoir qu&#8217;une seule alerte, celle du switch, plutôt que N alertes des serveurs. C&#8217;est la dépendance réseau. Cette relation forme un arbre : Nagios remonte les branches pour trouver la cause du problème. La racine est le noeud Nagios lui même. Mais que se passe-t-il si on autorise les cycles dans la configuration? Nagios va tourner en rond lors de la recherche de l&#8217;erreur!  <img src='http://www.gabes.fr/jean/wp-includes/images/smilies/icon_evil.gif' alt=':evil:' class='wp-smiley' /> </p>
<p>Pour éviter cela, Nagios fait une vérification au démarrage afin de trouve les cycles dans cette configuration s&#8217;ils existent. Un premier algorithme naïf est en O(n²). Et bien dans Nagios arrivait à faire du O(n3)&#8230; Vous aller me dire que ce n&#8217;est pas si grave que ça. Et bien en fait si. Prenons une configuration &#8220;costaux&#8221; de 40000 hosts avec des relations de parentées. Et bien la vérification prends 70s sur un Core2 à 2.4Ghz. Ce n&#8217;est pas négligeable, car pendant ce temps, il n&#8217;y a pas de supervision&#8230;</p>
<p>J&#8217;ai donc décidé d&#8217;appliquer mes cours de théorie des graphes et de faire un simple <a href="http://en.wikipedia.org/wiki/Depth-first_search">parcours en profondeur</a>, aussi nommé Deep First Search (DFS). C&#8217;est donc un algorithme récursif, ce qui n&#8217;a rien d&#8217;étonnant dans le monde des graphs  <img src='http://www.gabes.fr/jean/wp-includes/images/smilies/icon_mrgreen.gif' alt=':mrgreen:' class='wp-smiley' /> </p>
<p>Son fonctionnement est légèrement différent du DFS standard, car le but n&#8217;était pas de savoir si une boucle existait, mais de trouver TOUS les noeuds étant dans une boucle, afin d&#8217;aider l&#8217;utilisateur à corriger les problèmes en un passage.De plus, il n&#8217;y a pas de noeud root sur cet arbre de relation. On peut potentiellement partir en plein milieu de l&#8217;arbre, ce qui ne facilite pas les choses.</p>
<p>Les noeuds peuvent avoir plusieurs attributs :</p>
<table style="width: 416px; height: 160px;" border="0">
<tbody>
<tr>
<td>DFS_UNCHECKED</td>
<td>0</td>
<td>valeur par défaut</td>
</tr>
<tr>
<td>DFS_TEMPORARY_CHECKED</td>
<td>1</td>
<td>a été parcouru une fois</td>
</tr>
<tr>
<td>DFS_OK</td>
<td>2</td>
<td>pas de problème</td>
</tr>
<tr>
<td>DFS_NEAR_LOOP</td>
<td>3</td>
<td>a des fils à problèmes</td>
</tr>
<tr>
<td>DFS_LOOP_INSIDE</td>
<td>4</td>
<td>fait parti d&#8217;une boucle</td>
</tr>
</tbody>
</table>
<p>Nouveau test avec ce parcours en profondeur au lieu de l&#8217;algorithme initial : 0.006864 sec  <img src='http://www.gabes.fr/jean/wp-includes/images/smilies/icon_biggrin.gif' alt=':-D' class='wp-smiley' /> </p>
<p>Après une longue période de non réponse de l&#8217;auteur de Nagios et le &#8220;coup de pied au cul&#8221; de Icinga avec leur tentative de Fork, de nouveaux développeurs ayant accès au CVS de Nagios ont été nommés. C&#8217;est ainsi que mon patch a été <a href="http://nagios.cvs.sourceforge.net/viewvc/nagios/nagios/base/config.c?r1=1.119&amp;r2=1.120" target="_blank">intégré</a> dans la version 3.1.2 de Nagios et que des milliers d&#8217;administrateurs vont voir leur Nagios démarrer bien plus rapidement.</p>
<p>Reste à appliquer ce principes aux autres relations de dépendances dans Nagios&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gabes.fr/jean/2009/07/02/patch-nagios-pour-un-demarrage-bien-plus-rapide/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FunkyPlayList : un script générateur de playlist</title>
		<link>http://www.gabes.fr/jean/2009/06/30/funkyplaylist-un-script-generateur-de-playlist/</link>
		<comments>http://www.gabes.fr/jean/2009/06/30/funkyplaylist-un-script-generateur-de-playlist/#comments</comments>
		<pubDate>Tue, 30 Jun 2009 06:24:15 +0000</pubDate>
		<dc:creator>Nap</dc:creator>
				<category><![CDATA[Divers]]></category>
		<category><![CDATA[Développement]]></category>

		<guid isPermaLink="false">http://www.gabes.fr/jean/?p=67</guid>
		<description><![CDATA[Ce script est parti d&#8217;un constat simple: j&#8217;avais besoin d&#8217;un programme qui me génère mes listes de lectures de mon répertoire de musique. La gestion de collection d&#8217;Amarok ne me convient pas vraiment : je ne fonctionne pas en fonction des artistes mais seulement en fonction des albums qui contiennent à chaque fois pleins d&#8217;artistes [...]]]></description>
			<content:encoded><![CDATA[<p>Ce script est parti d&#8217;un constat simple: j&#8217;avais besoin d&#8217;un programme qui me génère mes listes de lectures de mon répertoire de musique. La gestion de collection d&#8217;Amarok ne me convient pas vraiment : je ne fonctionne pas en fonction des artistes mais seulement en fonction des albums qui contiennent à chaque fois pleins d&#8217;artistes différents. a &#8220;collection&#8221; d&#8217;Amarok me donne vraiment un gros mix d&#8217;albums, chose dont je ne suis pas un grand fan.<br />
Donc j&#8217;ai fait un programme qui parcoure un répertoire, lorsqu&#8217;il trouve des musiques (mp3 ou ogg) il créé la liste de lecture avec comme nom le nom du répertoire tout simplement. C&#8217;est écrit en python, c&#8217;est simple (normal, c&#8217;est du Python&#8230;) et efficace. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.gabes.fr/jean/2009/06/30/funkyplaylist-un-script-generateur-de-playlist/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pyndsgest : gérer vos jeux NDS facilement</title>
		<link>http://www.gabes.fr/jean/2009/06/30/pyndsgest-gerer-vos-jeux-nds-facilement/</link>
		<comments>http://www.gabes.fr/jean/2009/06/30/pyndsgest-gerer-vos-jeux-nds-facilement/#comments</comments>
		<pubDate>Tue, 30 Jun 2009 06:21:10 +0000</pubDate>
		<dc:creator>Nap</dc:creator>
				<category><![CDATA[Divers]]></category>
		<category><![CDATA[Développement]]></category>

		<guid isPermaLink="false">http://www.gabes.fr/jean/?p=49</guid>
		<description><![CDATA[Pyndsgest est un modeste petit programme en Python/QT4 qui permet de gérer sa collection NDS. Il distribué est en licence GPLv2, donc vous pouvez faire ce que vous voulez avec le temps que cela reste libre  
Il permet de lister les sauvegardes de jeux que vous posséder. La liste utilisée est celle de  [...]]]></description>
			<content:encoded><![CDATA[<p>Pyndsgest est un modeste petit programme en Python/QT4 qui permet de gérer sa collection NDS. Il distribué est en licence GPLv2, donc vous pouvez faire ce que vous voulez avec le temps que cela reste libre <img src='http://www.gabes.fr/jean/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Il permet de lister les sauvegardes de jeux que vous posséder. La liste utilisée est celle de <a href="http://www.advanscene.com/"> advanscene</a> que je remercie chaleureusement. Ce programme permet aussi d&#8217;envoyer en un seul clic le jeu sur votre carte (DS-X ou M3 par exemple). Il permet au passage de gagner de l&#8217;espace car &#8220;trim&#8221; à la volée les données.</p>
<p>Les jeux peuvent être notées. De cette manière, n&#8217;apparaissent que ceux qui vous intéressent (qui veux d&#8217;un jeu en coréen? Non, vraiment <img src='http://www.gabes.fr/jean/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  ).<br />
Le programme utilise les librairies python <a href="http://linux.duke.edu/projects/urlgrabber/">URLGrabber</a> et <a href="http://www.joachim-bauch.de/projects/python/pylzma/">pylzma</a>. Elles ne sont pas obligatoires, mais conseillées. La première permet d&#8217;utiliser un proxy, la seconde de lire les archives 7z.</p>
<p>Pour finir, une petite capture du programme :</p>
<div id="attachment_50" class="wp-caption alignnone" style="width: 310px"><a href="http://www.gabes.fr/jean/wp-content/uploads/2009/06/PyNDSGestCapture1.png"><img class="size-medium wp-image-50" title="PyNDSGest 0.6" src="http://www.gabes.fr/jean/wp-content/uploads/2009/06/PyNDSGestCapture1-300x275.png" alt="PyNDSGest 0.6" width="300" height="275" /></a><p class="wp-caption-text">PyNDSGest 0.6</p></div>
]]></content:encoded>
			<wfw:commentRss>http://www.gabes.fr/jean/2009/06/30/pyndsgest-gerer-vos-jeux-nds-facilement/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

