Migration

Comme vous pouvez le constater, le site à changé d’adresse en même temps que de serveur.
Il est maintenant hébergé à cette adresse : http://elentir.sleipnir.fr

Au passage, le serveur tourne sous Frugalware current et utilise Cherokee.

J’en ai profité pour faire un nettoyage du site et mettre à jour les pages.
J’ai aussi (enfin) trouvé le thème WordPress parfait : Portfolio-press. Propre, clair, sans fioritures, c’est ce que je cherchais depuis un moment!

Script d’extinction pour gestionnaire de fenêtre léger

L’un des principaux problèmes (qualité?) des gestionnaires de fenêtre léger du type Openbox, Fluxbox et consoeurs est qu’ils demandent un peu plus de travail pour certaines opérations. Il en est de l’extinction de l’ordinateur. Alors que des monstres comme KDE ou encore Gnome font ça tout seul, cela demande un peu plus de travail pour les autres. Je présente ici le script que j’utilise sous Openbox.

Ce sujet à été largement traité notamment ici. Néanmoins le script proposé ne me satisfaisais pas, d’une part car il nécessitait de configurer le fichier /etc/sudoers pour pouvoir appeler les fichiers /sbin/reboot, … via sudo sans mot de passe et d’autre part car il n’était pas joli à voir =).

Le premier problème peut se résoudre en passant par DBus. En effet l’interface DBus

/org/freedesktop/Hal/devices/computer org.freedesktop.Hal.Device.SystemPowerManagement

de Hal nous fournit les commandes de gestion de l’alimentation. Elle permet notamment de pouvoir redémarrer, éteindre ou encore mettre en veille son ordinateur. Il suffit pour cela d’appeler la fonction DBus correspondante. On peut par exemple le faire via la commande :

dbus-send --system --print-reply --dest=org.freedesktop.Hal /org/freedesktop/Hal/devices/computer org.freedesktop.Hal.Device.SystemPowerManagement.Reboot

pour redémarrer la machine.

En cherchant sur internet, j’ai trouvé ce script que j’ai complètement réécris. Il est écrit en Python et utilise PyGTK uniquement. Je lui ai ajouté le support de DBus. En effet Python fournit un binding pour DBus extrèmement puissant! Je l’ai rendu un peu plus joli lorsque l’on passe la souris sur les boutons même si il reste un peu à faire au niveau de l’effet qui n’est pas assez visible à mon goût.
Je l’ai aussi rendu assez configurable via un fichier de configuration pour le rendre indépendant du gestionnaire de login et du gestionnaire de fenêtre et assez facilement personalisable (police de caractère des titres, images des boutons, exécution des commandes personalisés, nombre de bouton par ligne et emplacement des lignes, taille des espacements entre boutons, etc.). Une dernière chose est qu’il marche assez correctement (il manque juste les titres des boutons pour le moment) sans fond d’écran.

Et voici le résultat :


et sans fond d’écran :

Le fichier de configuration est assez simple. La description d’un bouton est de cette forme :

[monbouton]
title=Titre de mon bouton
exec=Commande à éxécuter
tooltip=Le tooltip en cas de lancement sans fond d'écran ça peut être utile
image=chemin/vers/image

Je renvoi à l’exemple de fichier de configuration donné par défaut dans l’archive du script qui est largement commenté. Les boutons “hibernate”, “reboot” ou “shutdown” sont déjà préconfigurés pour utiliser DBus. Ils ne demandent que la configuration d’une image et d’un titre. A noter aussi que les boutons préconfigurés “hibernate” et “suspend” n’apparaissent que si l’ordinateur le supporte.
Le script utilise l’ordre des d’appartition dans le fichier de configuration comme ordre pour les boutons affichés à l’écran.

Pour finir le lien vers ce script.
Il suffit de s’assurer que le fichier de configuration est dans le même répertoire que le fichier “exitit” et de lancer ce fichier “exitit” pour démarrer le script.

Fwife 0.6 dans les bacs

Voilà, c’est fait, après de nombreux retards (voilà ce qui arrive à faire trop de maths :p), j’ai enfin sorti la version 0.6 de Fwife. Cette version est accompagné d’une nouvelle version des cd d’installations disponible sur le site de votre serviteur 😉

Je vais présenter les principaux changements :
— j’ai ajouté une fonction permettant de scanner les points d’accès WiFi :


Si l’ESSID n’est pas caché, c’est souvent plus rapide que de le retrouver pour l’écrire à la main.
— affichage du status des mirroirs comme ceci :

Cela permet d’éviter de sélectionner les mirroirs qui ne fonctionnent pas (par défaut lorsqu’un mirroir ne fonctionne pas, pacman-g2 prend le suivant sur sa liste, et d’après l’un des corollaires de la loi de Murphy, c’est toujours le plus lent!). A noter que pour l’instant, la fonction est très manichéenne, les mirroirs trop long à répondre seront affichés avec un point rouge. La prochaine version de fwife devrait les considérer différemment (par exemple avec un point orange :D). Cette modification devrait être assez triviale.

Coté modifications “moins visuelles”, j’ai réorganisé le plugin de configuration réseau en essayant de tenir compte des remarques qui m’ont été faite sur le forum de Cyrille Borne. Je crois que ce plugin est le seul à avoir subi tant de changements et réecritures successives au cours des différentes versions. Je n’arrive pas à trouver par quel bout le prendre. Pour cette fois j’ai laissé tombé la recherche dhcp sur le réseau que j’avais introduite dans la version précédente; trop dépendante de la version de dhcpcd utilisée, et très lent si le réseau n’utilise pas dhcp. De plus, la cascade de boîtes de dialogues au lancement de ce plugin était assez confuse. J’ai finalement implémenté une fonction permettant de détecter les configurations actives sachant que dhcpcd laisse toujours une trace permettant de trouver sur quelles interfaces réseaux il est lancé. L’idée étant, pour le CD, de lancer dhcpcd au démarrage et Fwife s’occupera ensuite de trouver si dhcpcd a réussi à se lancer sur une des interfaces réseaux.
Autre modification importante, Fwife supporte enfin correctement la branche “stable” de Frugalware, ce qui n’étais pas le cas de la version précédente. Je sortirai des CD installant la version “stable” de Frugalware juste avant la sortie de la de la version 1.2 Locris, c’est à dire au mois de mars.

Pour cette version j’ai réecrit une grande quantité du code : plus propre, plus simple (parfois on se complique la vie alors que la solution simple est sous notre nez) et plus rapide pour certaines fonctions (lecture de la base de donnée de paquets par exemple). Le revers de la médaille est que des régréssions ont pu être ajoutées par rapport à la version précédente. Néanmoins j’espère en avoir corrigés plus que ce que j’en ai ajoutés.

Petit aperçu du futur maintenant :
Une version 0.6.1 devrait sortir lorsque suffisamments de bugs de cette version auront été corrigés. Elle ne devrait pas inclure de nouvelles fonctionnalités majeures. Pour la prochaine version (0.7), je pense que je vais pousser la gestion des différents environnements de bureaux (Gnome, KDE, …). D’abord ajouter les environnements de bureaux moins utilisés du type Openbox (mon préféré =) ) dans une section du type “Autres environnements de bureaux” ou quelque chose comme ça. Peut-être inclure une configuration automatique du gestionnaire de login (par exemple pour Slim, il faut toucher au fichier /etc/slim.conf) suivant l’environnement de bureau choisi et aussi ajouter le petit nouveau : lxdm.
Autre élément important, le CD est prêt à être supporté officiellement dans Frugalware depuis octobre dernier. La dernière étape avant de l’intégrer est le merge du dépôt xorgtesting (Xorg 7.5) qui est bloqué depuis plusieurs mois à cause du driver propriétaire (fglrx) d’ATI qui ne supporte pas Xorg 7.5 (et ils n’ont pas l’air d’être trop pressés!).
En espérant que la situation se débloque rapidement! (peut-être avec les prochain mesa?)

Enfin, j’aimerai signaler un bug important du CD (déjà :) ), lié au point ci-dessus : la configuration du serveur X (tout à la fin de l’installation) à tendance à freezer sur certaines configurations (notamment avec VirtualBox). Cela semble due à la différence de version de Xorg entre la version utilisée par le CD (Xorg 7.5 donc) et celle installé par l’installateur (qui installe la branche “current” de frugalware donc une ancienne version de Xorg). Ce problème devrait être lui aussi résolu lors du merge de xorgtesting.

Optimisation de pacman-g2 : Mettre l’oiseau en cage

Voici l’adaptation (que j’utilise depuis déjà un moment :) ) du script “pacman-cage” d’Arch Linux (Lien) pour pacman-g2, qui permet d’éviter une trop grande fragmentation des fichiers de la base de donnée et un ralentissement notamment lors des recherches (“pacman -Ss”). Le système de fichier utilisé par le script est ext2, j’en ai donc profité pour ajouter le support du sytème de fichier reiserfs, connu pour ses performances dans la gestion d’un grand nombre de petits fichiers. Je voulais voir si il existait une différence de performances entre les deux dans le cas de la base de donnée de pacman-g2.

Attention peux casser la base de donnée de pacman-g2 : utilisez à vos risques et périls.

L’utilisation du script est très simple, lancer avec les droits roots :

pacman-g2-cage

pour cager le pacman-g2 (par défaut le système de fichier utilisé est reiserfs) ou

pacman-g2-cage ext2

pour utiliser ext2.
Si vous voulez revenir en arrière utilisez :

pacman-g2-uncage

Voici deux résultats représentatifs (dans le sens de la médiane sur les résultats obtenus) :
Configuration : Athlon64 1800+, 1Go DDR.

time pacman -Ss titi  ( normal )
real	1m6.462s
user	0m0.712s
sys	0m1.287s

time pacman -Ss titi  ( ext2 )
real	0m5.129s
user	0m0.539s
sys	0m0.333s

time pacman -Ss titi ( reiserfs )
real	0m4.673s
user	0m0.507s
sys	0m0.456s

Et voici un autre :

time pacman -Ss tint2  ( ext2 )
real	0m5.028s
user	0m0.535s
sys	0m0.356s

time pacman -Ss tint2  ( reiserfs )
real	0m4.716s
user	0m0.534s
sys	0m0.455s

Attention n’oubliez pas de vider les caches lors des tests :

echo 3 > /proc/sys/vm/drop_caches

On note ainsi un léger avantage pour reiserfs de l’ordre en moyenne du tiers de seconde, ce qui n’est que peu significatif. Sur mon laptop (Core 2 Duo 2 Ghz, 3Go DDR2), les résultats obtenus sont globalement équivalents, l’avantage de reiserfs tombe à moins de deux dixièmes de secondes.
Notons que l’écart se creuse à mesure que le nombre d’éléments dans la base de donnée augmente. A noter aussi que le script d’autocomplétion présenté dans l’article précédent est aussi bien plus rapide 😉

Lien vers le script pacman-g2-cage
Lien vers le script pacman-g2-uncage

Autocomplétion pacman-g2 en bash

Ainsi que certains ont pu le remarquer, il n’existe pas d’autocomplétion pour la commande pacman-g2. Cette fonctionnalité est pourtant bien pratique! Nous allons voir dans cet article comment fonctionne l’autocomplétion avec bash (pas de zsh et autres pour l’instant pacman-g2. Nous resterons pour l’instant dans un cadre simple : compléter le nom des paquets.
L’autocomplétion n’est pas une fonctionnalité par défaut de bash. Dans le cas de Frugalware, vous devez installer, si ce n’est déjà fait, le paquet bash-completion :

pacman-g2 -S bash-completion

Le fonctionnement de l’autocomplétion est assez simple : on associe
à une commande quelconque, une «fonction de complétion»
prenant en entrée la liste des paramètres déjà tapés, et en sortie une
liste contenant les complétions possibles.
Ces “scripts” sont situés dans le répertoire “/etc/bash_completion.d/”.
Dans le cas de pacman-g2, voici le script en question :

# Programmable bash completion for Pacman-g2.
#
# Copyright 2009 Albar Boris "elentir ^ frugalware.org"
#
# Distributed under the terms of the GNU General Public License v2.
#

_pacman-g2 ()
{
	local cur prev first cmd repos

	repos=$(grep '\[' /etc/pacman-g2.conf | grep -v -e 'options' -e '^#' | tr -d '[]' )

	# follows the inclusions
	Includes=$(cat /etc/pacman-g2.conf | grep "^Include[' ']*=" | sed "s/Include[' ']*=[' ']*//")
	for i in $Includes; do
		repos+=" $(grep '\[' $i | grep -v -e 'options' -e '^#' | tr -d '[]' )"
	done

	COMPREPLY=()
	cur=${COMP_WORDS[COMP_CWORD]}
	prev=${COMP_WORDS[COMP_CWORD-1]}
	first=${COMP_WORDS[1]}

	cmd=""
	case "$first" in
	-*S*|-*R*) # we expect at least one package now
		for i in $repos; do
			if [[ "$cur" == " " ]]; then
				fileSync=$(ls /var/lib/pacman-g2/$i)
			else
				fileSync=$(ls /var/lib/pacman-g2/$i | grep ^$cur)
			fi
			for j in $fileSync; do
				cmd+=$(echo "${j%-*-*} ")
			done
		done
		;;
	-Qo)
		;;
	-*Q*)
		if [[ "$cur" == " " ]]; then
			fileSync=$(ls /var/lib/pacman-g2/local/$i)
		else
			fileSync=$(ls /var/lib/pacman-g2/local/$i | grep ^$cur)
		fi
		for i in $fileSync; do
			cmd+=$(echo ${i%-*-*})
			cmd+=' '
		done
		;;
	-*A*)
		cmd=$(ls | grep .fpm$)
		;;
	*)
		;;
	esac

	COMPREPLY=( $( compgen -W "$cmd"  -- $cur ) )
	return 0
}
complete -F _pacman-g2 -o default pacman-g2
complete -F _pacman-g2 -o default pacman

Voyons dans un premier temps les variables qui entrent en jeu :

COMP_WORDS est un tableau contenant les divers paramètres déjà entrés, par exemple si on a tapé :

pacman-g2 -Si alsa

le tableau contiendra alors les éléments “-Si” et “alsa”.

COMP_CWORDS indique l’index du dernier élément du tableau précédent (dans le cas de l’exemple ci-dessus : 2)

De ces deux variables, on en déduit l’élément à compléter (le dernier) que l’on appelle “cur” et qui est définit par :

cur=${COMP_WORDS[COMP_CWORD]}

COMPREPLY qui comme son nom
l’indique contient la liste des possibilité de complétion. On peut
considérer cette variable comme la “valeur de retour” de la
fonction.

Toute la difficulté désormais consiste à renvoyer la bonne liste de possibilités en fonctions des commandes entrées.
Nous allons nous limiter aux fonctions les plus couramment utilisés de pacman-g2 sans nous préoccuper des cas particuliers. Nous considèrerons pour cela qu’une commande de pacman-g2 est toujours de la forme :

pacman-g2 -Opération paquet1 paquet2 ...

sauf pour la commande

pacman -Qo

qui prend en paramètre un fichier et non un nom de paquet.

Un petit rappel sur le fonctionnement de pacman-g2 nous indique que la base de donnée de paquets est situé dans le répertoire “/var/lib/pacman-g2″. Chaque paquet est identifié par un dossier unique de la forme :

"nom du dépôt"/"nom du paquet"-"version"-"pkgrel"

chaque dossier contenant les informations propres au paquet considéré.
Les paquets déjà installés sur la machine, quant à eux, sont listés dans le dépôt /var/lib/pacman-g2/local”. On utilise uniquement ce dépôt pour les commandes du type pacman-g2 -Q *” puisque ces commandes s’adressent spécifiquement à ces paquets.

La suite n’est que du bash, on récupère le nom des dépôts dans le fichier “/etc/pacman-g2.conf” :

repos=$(grep ‘\[' /etc/pacman-g2.conf | grep -v -e 'options' -e '^#' | tr -d '[]‘ )

Puis on cherche le nom des dossiers commençant par $cur (càd le mot à compléter) dans chaque dépôt avec :

ls | grep ^$cur"

On supprime ensuite le numéro de version et le pkgrel du nom des dossiers avec un commande avec un “echo” approprié :

echo ${i%-*-*}

Les différentes commandes de pacman ( “-S”, “-Q” ou autres ) sont traités les différents cas dans une
simple commande “case”.

A partir de cette liste, on utilise la commande compgen qui génère la liste que l’on met dans la variable COMPREPLY.

Enfin les deux dernières commandes du script permettent d’associer aux commandes pacman et pacman-g2 (sous frugalware pacman est un lien vers pacman-g2), la fonction de complétion que l’on a définit ci-dessus.

Voilà, nous avons vu un script qui reste très basique, mais rien
n’empèche maintenant de l’améliorer en rajoutant la complétion de
toutes les options de pacman-g2 et en tenant compte de toutes les possibilités d’options.

A priori la couleur n’est pas supporté dans la complétion bash, il
serait intéressant de voir si on ne peut pas ajouter un support des
couleurs dans bash-completion.
Peut-être le sujet d’un prochain article…

Lien vers le script

Voyage au pays des groupes

Hier soir,  j’ai poussé Gap sur le dépôt current de Frugalware. C’est un logiciel permettant de faire des calculs en algèbre notamment en théorie des groupes et théorie des corps.  C’est une belle occasion, pour ce premier article, d’approcher un peu ses fonctionnalités, et un beau prétexte pour faire un petit détour par la théorie des groupes.
Pour cette introduction à Gap, nous allons prendre un problème classique : Définir le groupe le groupe alterné A_5, et vérifier qu’il est simple et non résoluble.

Le groupe A_5 peut se définir à partir du groupe symétrique S_5 :

Définissons donc S_5 :

S5 := SymmetricGroup(5);
Sym( [ 1 .. 5 ] )

comme le groupe symétrique d’indice 5; C’est le groupe des permutations d’un ensemble de 5 éléments. Il est d’ordre 5!=120 comme on peut le voir avec :

Order(S5);
120

On peut visualiser ses éléments avec la commande :

Elements(S5)

On peut alors définir le groupe alterné A_5 de plusieurs manières :

– soit comme l’ensemble des permutations d’ordre pair (c’est à dire décomposable en un nombre pair de transpositions);
– soit comme le noyau du morphisme signature;
– soit dériver le groupe S_5;

On va utiliser la dernière manière :

A5:=DerivedSubgroup(S5);
Group([ (1,3,2), (2,4,3), (2,3)(4,5) ])

On vérifie rapidement qu’il s’agit bien de A_5 :

C’est d’abord bien un sous-groupe distingué de S_5 :

IsSubgroup(S5,A5);
true
IsNormal(S5,A5);
true

De plus il est composé de permutations paires et d’ordre \frac{(5!)}{2}=60 :

List(Elements(A5),x -> SignPerm(x));
[ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ]
Order(A5);
60

Une autre manière plus rapide aurait-été de définir directement :

A5 := AlternatingGroup(5);
Alt( [ 1 .. 5 ] )

Voyons maintenant les propriétés interessantes qu’il a :

IsSimple(A5);
true
IsCyclic(A5);
false
IsSolvable(A5);
false

Il est donc simple, non cyclique et non résoluble ! Une conséquence importante de ce résultat est qu’il existe des équations de degré 5 qui ne sont pas résoluble par radicaux. Considérons en effet le groupe de Galois du polynôme qui n’est autre que S_5 qui n’est pas résoluble puisque A_5 ne l’est pas.