Shinken : tagguez vos pollers

Posted in Shinken by Nap on May 5, 2010

Découpage organisationnel/technique

Dans l’Architecture de Shinken, un point important concerne les Realms (royaumes) qui servent à découper dans pans entiers d’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 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).

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.

Mais comment faire en sorte que les commandes pour Windows partent sur ces pollers “Windows” et pas les classiques pollers “Linux”? On peut se dire que l’on utilise les realms, mais ce n’est pas une bonne idée en fait. Les realms sont des cloisonnements, il n’y a pas d’échange entre les schedulers (même au sein d’un realm d’ailleurs). Donc si un administrateur défini un Realm Linux et un Realm Windows, il va pouvoir obtenir l’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…

Cloisonnement technique

C’est pour cela que dans un même realm, il doit être possible de cloisonner “techniquement” les commandes sur des pollers. Ce cloisonnement, qui va être optionnel bien sûr, se fera dans la configuration avec une nouvelle option : poller_tag. Comme son nom l’indique, un poller va avoir un ou plusieurs tags, et les checks vont pouvoir également être taggués.

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’héritage serait host->service->commands.

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 “windows-poller”. Les tags au niveau service/hosts seraient un peu comme un “mini-realm” : 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 tagguer les hôtes/services.

Un mini-realm?

Ceci n’est pas complètement orthogonal aux realms je l’admets, mais c’est plus une réponse aux “proxy nrpe windows” qu’à un réel besoin organisationnel que proposent les Realms.

Au passage, cette implémentation va être un bon exemple de “Hack” possible de Shinken. Je vais essayer de noter/expliquer l’implémentation dans un document afin de montrer que développer pour Shinken n’est pas complexe, loin de là :)

Partie à trois : Python, __slots__ et metaclass

Posted in Programmation by Nap on February 15, 2010 3 Comments

Les langages dynamiques sont pratiques pour se frotter facilement à de nouveaux paradigmes de programmations. Aucune technique n’étant parfaite, l’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’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 __dict__ des objets. Le dictionnaire est fort simple:

class Test:
   def __init__(self, x, y):
      self.x = x
      self.y = y
point = Test(1, 2)
print ‘Initialement’, point.__dict__
point.z = 3
print ‘Apres’, point.__dict__

Donne :

Initialement {’y': 2, ‘x’: 1}
Apres {’y': 2, ‘x’: 1, ‘z’: 3}

C’est sympa, c’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 ‘x’, ‘y’ et ‘z’ 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 ‘x’, on peut atteindre des sommets en terme de consommation de RAM pour finalement pas grand chose.

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 :

from guppy import hpy
hp=hpy()
print hp.heap()

Sa sortie est (relativement) éloquente :

Partition of a set of 2024657 objects. Total size = 173885852 bytes.
Index  Count   %     Size   % Cumulative  % Kind (class / dict of class)
0 999999  49 135999864  78 135999864  78 dict of __main__.Test
1 999999  49 31999968  18 167999832  97 __main__.Test
2    127   0  4073248   2 172073080  99 list
3  10686   1   744928   0 172818008  99 str
4   5540   0   203368   0 173021376 100 tuple
5    347   0   115160   0 173136536 100 dict (no owner)
6   1539   0   104652   0 173241188 100 types.CodeType
7     64   0   100480   0 173341668 100 dict of module
8    175   0    94840   0 173436508 100 dict of type
9    194   0    86040   0 173522548 100 type

78% de la consommation mémoire est due aux __dict__ de nos points, les valeurs de ces instances consommant quant à elles 18%.

__slots__ : c’est les soldes pour Python

Lorsque l’on sait à l’avance quelles vont être les possibilités des noms de propriétés de nos instances, il peut être pratique de recourir à l’utilisation des __slots__. C’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’objet par exemple.

Si vous souhaitez l’utiliser, c’est fort simple, il suffit de rajouter le tuple à la classe si elle hérite d’object :

class Test(object):
   __slots__ = (’x', ‘y’, ‘z’)
   def __init__(self, x, y):
      self.x = x
      self.y = y

Si simple? Non en fait. le __slots__ va remplacer __dict__ qui va tout simplement disparaitre! Notre code va lamentablement échouer avec:

Initialement
Traceback (most recent call last):
File “test_slot.py”, line 10, in <module>
print ‘Initialement’, point.__dict__
AttributeError: ‘Test’ object has no attribute ‘__dict__’

Pour contourner cela, il suffit de rajouter __dict__ au slots:

class Test(object):
   __slots__ = (’__dict__’, ‘x’, ‘y’, ‘z’)
   def __init__(self, x, y):
      self.x = x
      self.y = y

On relance, la consommation passe à 47Mo. (Les gains sont encore plus importants avec des chaînes de plus d’un caractère :) ). Pour Shinken par exemple, avec 100000 services, j’étais à plus de 2Go de RAM consommée, avec les slots, je suis tombé à moins 50Mo environs…

Metaclass : une classe pour en modifier d’autres

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’est justement le rôle des metaclass. C’est une classe qui va contrôler la création d’une autre. Elles peuvent être utilisées pour par exemple tracer automatiquement tous les appels de méthode d’une classe. Pour un tel exemple, voir sur http://www.afpy.org/Members/kerflyn/metaclass qui présente très bien cela.

On mixe le tout

Vous allez me dire: bon c’est bien les metaclass, mais c’est quoi le rapport avec les __slots__? Et bien c’est pratique lorsque l’on a beaucoup de propriétés dans une classe, comme par exemple Service ou Host de Shinken. Jusqu’à maintenant, lorsque je rajoutait une nouvelle propriété à ces classes, je rajoutais une ligne dans le tableau properties ou running_properties, mais je devais penser à rajouter ce même paramètre dans le tuple  __slots__ de la classe. Autant dire qu’une fois sur deux, j’oubliais. De plus, ça fait un gros pâté en début de classe, et je n’aime pas ça.

Je suis tombé sur http://code.activestate.com/recipes/435880/ qui présente comment générer automatiquement le tuple __slots__ pour ses classes en regardant tout simplement les variables fournies à __init__ (il semble créer d’ailleurs une liste qui doit être changée en tuple par l’interpréteur). Bon pour les Host et Service, il n’y a qu’un seul paramètre, un tableau de construction. Mais ça m’a donné l’idée d’adapter ce code pour qu’il utilise les tableaux properties et running_properties de mes classes qui contiennent toutes les propriétés de mes objets.

Edit : Merci à Bertrand Mathieu pour la simplification du code par set.

Ceci donne au final la classe AutoSlots suivante :

class AutoSlots(type):
   def __new__(cls, name, bases, dct):
      slots = dct.get(’__slots__’, set())
      #Now get properties from properties and running_properties
      if ‘properties’ in dct:
         slots.update((p for p in dct['properties']))
      if ‘running_properties’ in dct:
         lots.update((p for p in dct['running_properties']))
      dct['__slots__'] = tuple(slots)
      return type.__new__(cls, name, bases, dct)

Qui est appelée avec :

class Service(SchedulingItem):
   #AutoSlots create the __slots__ with properties and
   #running_properties names
   __metaclass__ = AutoSlots

[..]

Maintenant les __slots__ sont construits à la volée, et il n’y a plus de risque d’oublier des paramètres et mes classes Host/Service se re-concentrent un peu sur ce qu’elles doivent faire, et non sur une astuce pour contourner une consommation excessive de RAM par Python.

Python et le Data-Driven programming

Posted in Shinken by Nap on December 16, 2009 4 Comments

Suite au post d’un journal sur linux-fr concernant Shinken et l’avenir de Nagios (http://linuxfr.org/~naparuba/29141.html) certains m’ont demandé pourquoi j’ai choisi le Python (www.python.org) pour Shinken. J’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 (http://pyro.sourceforge.net/)pour les objets distants (un peu comme Corba, mais autrement plus simple à utiliser et plus dynamique (pas de déclaration de squelette)).

Et les 80% restant?

On peu un peu se demander ce qu’il y a dans les 80% restant. Outre le fait que le langage ne pique pas les yeux (et évite les nœuds … au cerveau), et qu’il a d’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’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’utiliser les principaux:

  • programmation itérative et récursive
  • programmation orientée objet
  • programmation orientée aspect (decorator)

Bon c’est bien, mais le rapport avec la choucroute il et où? Et bien suivant la situation, avec Python on peut choisir, c’est plutôt sympa. Lorsque vous gérez des graphes, le récursif s’impose de lui même (ou alors vous être vraiment tordu…), en règle général c’est de l’objet, et dans quelques cas particuliers l’aspect.

Une matrice de création nommée ADN

Concernant l’objet, la création des objets n’est pas classique pour la plupart des types dans Shinken. Nagios utilise des techniques d’héritages sur des objets (hosts/services) qui ont de multiples propriétés (et c’est rien de le dire). Alors m’amuser à faire des constructeurs de 5 lignes non extensibles facilement, non merci. Si c’est pour faire ça, autant rester à faire du C.

C’est là que vient le data-driven (enfin je crois que c’est comme ça que ca s’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’action, avec outre le nom de la propriété, les informations dans ce tableau sur quoi faire pour telle propriété. C’est tout (bah oui, c’est tout con, d’ailleurs je l’ai fait avant de savoir comment ça s’appelait…). L’intérêt? Aucun si vote objet a trois pauvres propriétés, mais énorme si elles commencent à devenir nombreuses (genre une bonne vingtaine).

Comme pour la plupart des techniques de programmations, l’intérêt est d’avoir une factorisation des informations. Ici vos propriétés (et les propriétés de ces propriétés…) sont définies dans un seul endroit. Si vous voulez changer, rajouter, supprimer quelque chose, pas besoin d’aller parcourir l’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’avance ce qu’il y a dedans. Le tableau est une sorte d’ADN de l’objet : c’est sa matrice de fabrication.

Où qu’on le met cet ADN?

Ce qui est embêtant est d’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’est un peu comme le goto : le mal absolu. Mettre le tableau dans chaque objet? Bof, c’est crade, un objet n’a pas besoin d’avoir son ADN d’accroché pour vivre une fois crée (vous utilisez votre ADN vous? Non, vous utilisez les protéines qu’il a permis de fabriquer). Python nous aide ici. Si vous faite objet.__class__ vous obtenez la classe de l’objet. Et oui, une classe est un objet. Et un objet en python peut se voir accrocher des propriétés… genre notre tableau.

Si on rajoute ceci à un héritage de nos objets à une classe “Item” qui va faire le travail de construction, on obtient une fabrique de n’importe quel objet le temps que l’on définisse son ADN dans la classe de l’objet. Pratique non? C’est diablement efficace pour factoriser le code à sa plus simple expression.

Et au final on y gagne beaucoup?

Vous voulez un exemple? Le code de Nagios pour juste la fabrication des objets avec les techniques d’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. Owned comme dirait l’autre.

Patch Nagios : SSL pour Ndo

Posted in Nagios by Nap on October 16, 2009 2 Comments

J’avais travaillé sur 3 patchs pour Nagios et je n’en ais évoqué ici que 2 pour la bonne raison que c’étaient les seuls à être intégrés. Et bien en fait c’est inexact : le troisième l’a été aussi :)

Ce patch permet d’é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’est assez embêtant. Avec le patch que j’ai proposé (commit sur http://nagios.git.sourceforge.net/git/gitweb.cgi?p=nagios/ndoutils;a=commitdiff;h=9d9dcccab9690c896a7f1c3d2015064430c5157a par Hendrik Baecker) il y a une option de plus sur ndomod.cfg et ndo2db.cfg : use_ssl.

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.

Je n’ai pas réinventé la roue, j’ai emprunté le code à NRPE tout simplement. Je l’ai juste un peu adapté et mis au bon endroit.

Et voila, je suis dans le fichier THANKS de ndoutils maintenant :)

Shinken : 100K checks/5minutes

Posted in Nagios by Nap on October 13, 2009

Je viens de faire un test sur une “petite” machine : un Xeon 5140 (4coeurs, 3.1Ghz). J’ai réussi à dépasser la symbolique limite des 100000 (oui oui, 100K) checks en 5 minutes. J’ai un peu triché pour cela : j’ai exporté le broker et la base MySQL sur un autre serveur. J’arrive à un trafic à 50Ko/s entre le scheduler et le broker, ce qui est raisonnable vu le nombre de checks ;)

Petite preuve avec un ninja situé sur la machine avec la base :

100kPour ceux qui sont curieux : oui, Ninja rame un peu avec autant de services à gérer, mais cela reste acceptable ;)

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.

Moi je ne dirais qu’une chose : merci Python, mettre en place un pool de process est d’une simplicité monstrueuse. Maintenant, reste à faire de même avec Nagios (et de convaincre ses auteurs…). Qui sait, la barre des 200K sera peu être atteinte un jour?

Patch Nagios pour une gestion plus fine de la configuration

Posted in Nagios by Nap on July 2, 2009

Lorsque l’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’on souhaite gérer finement et effiacement sa configuration : les exeptions sur les services appliqués sur des groupes de noeuds.

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’est désormais plus nécessaire avec la nouvelle version de Nagios. J’ai proposé dernièrement un patch qui a été appliqué dans la 3.1.2.

Cette modification permet à un service appliqué sur un noeud de prendre le pas sur le service appliqué d’un groupe. Cette possibilité permet de définir très simplement une execptions d’un service, sans avoir à sortir un noeud d’un groupe et dupliquer tous les autres services qui y étaient acrochés.

Par exemple, avec la défiition suivante :

define service{
use     generic-service
hostgroup_name       all-server
service_description     service-test
check_command   check_ping
}

define service{
use     generic-s
ervice
host_name       srv-1
service_description     service-test
check_command   check_local_disk
}

Et bien maintenant c’est la seconde définition qui va gagner, ce qui est tout de même bien pratique :mrgreen:

Shinken : quand un python rencontre Nagios

Posted in Nagios by Nap on July 2, 2009

J’ai commencé voila quelques temps le projet Shinken. C’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’est pour cela que j’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 http://www.python.org/ et laissez vous emporter par ce super langage.

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’é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’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.

L’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.

Le nom du projet n’a pas été facile à trouver : je suis très long pour trouver des noms. Je peux dire merci à Wikipedia pour celui-là. je cherchai un nom de sabre japonais (j’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.

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 sourceforge. Et plus important encore, le logo est déjà prêt :)

shinken

Merci à l’auteur cisoun pour sa mascotte ouaaargh qui a servi de base à ce logo :)

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):

git clone git://shinken.git.sourceforge.net/gitroot/shinken/shinken

Patch Nagios pour un démarrage (bien plus) rapide

Posted in Nagios by Nap on July 2, 2009

Il y a de cela un an, j’ai pris au mot l’auteur de Nagios lorsqu’il écrit dans la documentation de Nagios concernant les vérifications effectuées au démarrage :
“That means all you CompSci graduate students who have been emailing me about doing your thesis on Nagios can contribute some code back. :-)
Je ne sais pas qui ils sont, mais j’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’ai même réussi.

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’administrateur a bien configuré ses serveurs pour qu’ils soient des fils du switch en question, il ne va recevoir qu’une seule alerte, celle du switch, plutôt que N alertes des serveurs. C’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’erreur! :evil:

Pour éviter cela, Nagios fait une vérification au démarrage afin de trouve les cycles dans cette configuration s’ils existent. Un premier algorithme naïf est en O(n²). Et bien dans Nagios arrivait à faire du O(n3)… Vous aller me dire que ce n’est pas si grave que ça. Et bien en fait si. Prenons une configuration “costaux” de 40000 hosts avec des relations de parentées. Et bien la vérification prends 70s sur un Core2 à 2.4Ghz. Ce n’est pas négligeable, car pendant ce temps, il n’y a pas de supervision…

J’ai donc décidé d’appliquer mes cours de théorie des graphes et de faire un simple parcours en profondeur, aussi nommé Deep First Search (DFS). C’est donc un algorithme récursif, ce qui n’a rien d’étonnant dans le monde des graphs :mrgreen:

Son fonctionnement est légèrement différent du DFS standard, car le but n’était pas de savoir si une boucle existait, mais de trouver TOUS les noeuds étant dans une boucle, afin d’aider l’utilisateur à corriger les problèmes en un passage.De plus, il n’y a pas de noeud root sur cet arbre de relation. On peut potentiellement partir en plein milieu de l’arbre, ce qui ne facilite pas les choses.

Les noeuds peuvent avoir plusieurs attributs :

DFS_UNCHECKED 0 valeur par défaut
DFS_TEMPORARY_CHECKED 1 a été parcouru une fois
DFS_OK 2 pas de problème
DFS_NEAR_LOOP 3 a des fils à problèmes
DFS_LOOP_INSIDE 4 fait parti d’une boucle

Nouveau test avec ce parcours en profondeur au lieu de l’algorithme initial : 0.006864 sec :-D

Après une longue période de non réponse de l’auteur de Nagios et le “coup de pied au cul” de Icinga avec leur tentative de Fork, de nouveaux développeurs ayant accès au CVS de Nagios ont été nommés. C’est ainsi que mon patch a été intégré dans la version 3.1.2 de Nagios et que des milliers d’administrateurs vont voir leur Nagios démarrer bien plus rapidement.

Reste à appliquer ce principes aux autres relations de dépendances dans Nagios…

FunkyPlayList : un script générateur de playlist

Posted in Divers by Nap on June 30, 2009

Ce script est parti d’un constat simple: j’avais besoin d’un programme qui me génère mes listes de lectures de mon répertoire de musique. La gestion de collection d’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’artistes différents. a “collection” d’Amarok me donne vraiment un gros mix d’albums, chose dont je ne suis pas un grand fan.
Donc j’ai fait un programme qui parcoure un répertoire, lorsqu’il trouve des musiques (mp3 ou ogg) il créé la liste de lecture avec comme nom le nom du répertoire tout simplement. C’est écrit en python, c’est simple (normal, c’est du Python…) et efficace.

Pyndsgest : gérer vos jeux NDS facilement

Posted in Divers by Nap on June 30, 2009

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 advanscene que je remercie chaleureusement. Ce programme permet aussi d’envoyer en un seul clic le jeu sur votre carte (DS-X ou M3 par exemple). Il permet au passage de gagner de l’espace car “trim” à la volée les données.

Les jeux peuvent être notées. De cette manière, n’apparaissent que ceux qui vous intéressent (qui veux d’un jeu en coréen? Non, vraiment ;) ).
Le programme utilise les librairies python URLGrabber et pylzma. Elles ne sont pas obligatoires, mais conseillées. La première permet d’utiliser un proxy, la seconde de lire les archives 7z.

Pour finir, une petite capture du programme :

PyNDSGest 0.6

PyNDSGest 0.6

Next Page »