Rien de tel pour tester un paquet debian qu'une machine vierge de toute installation préalable, et pour disposer de machines à volonté la libvirt est bien utile. J'ai sur mon disque une image de chaque version de Debian en install version minimale que je clone à loisir suivant mes besoins. J'ai même au boot une génération de 4 machines vierges. Seulement lors du clonage l'option --name de virt-clone s'arrête au nom du fichier xml de la machine, la nouvelle machine clonée se nomme donc comme l'originale. J'ai souhaité automatiser le nommage automatique des clones, et cela dans un environnement réseau simple, à savoir pas de dépendance d'une ressource extérieure et valable pour tous les modes de réseau des VM. Il me fallait donc trouver un stockage du nom de la machine depuis l'hôte accessible par la machine virtuelle. J'ai pour habitude de nommer mes machines le plus simplement possible, pour les clônes j'utilise une numération simple mais néanmoins élégamment verbalisable au travers du bibi-binaire (merci Boby) ! Mes clones pour Squeeze se nomment par exemple haka, hake, haki ce qui donne respectivement 25,26 et 27 ; utile pour paramétrer le DHCP en statique.

Si vous avez suivi toutes les étapes vous êtes peut-être arrivé au même résultat que moi, la machine se nomme heke et son IP est déclarée dans le serveur DHCP, nous allons donc stocker le nom de la machine dans l'adresse mac.

De plus virt-clone permet de spécifier celle-ci avec l'option --mac. Reste à utiliser celle-ci au boot de la machine, une légère modification des scripts rc et le tour sera joué.

Lors du boot le nom de la machine est définit par /etc/rcS.d/S02hostname.sh, assez tôt somme toute, nous allons le redéfinir en S39 par exemple en créant un fichier exécutable /etc/rcS.d/S39bibihostname :

[shell]
#!/bin/sh
### BEGIN INIT INFO
# Short-Description: Set hostname based on the mac address
# Description:       Execute /usr/bin/bibidec and write it's
#                    output to /etc/hostname
### END INIT INFO

echo "# Automatically set by /usr/bin/bibidec" > /etc/hostname

/usr/bin/bibidec >> /etc/hostname

hostname -F /etc/hostname

Vous remarquerez l'appel au script bibidec, il faut donc inclure aussi celui-ci, ici il est écrit en perl, les animaux à sang froids sauront le ré-écrire assez facilement.

[perl]
#!/usr/bin/perl

use strict;
use vars qw ($mac);

open(FNAME,"-|",'/sbin/ifconfig eth0 | head -1 | awk "{ print \$5 }" | cut -d : -f 6');
$mac = <FNAME>;
close(FNAME);

chop($mac);

my @bibi = ('ho','ha','he','hi',
            'bo','ba','be','bi',
            'ko','ka','ke','ki',
            'do','da','de','di');

my @array = split(//,sprintf "%s",$mac);

printf "%s", @bibi[hex($_)] foreach  (@array);

print "\n";

L'ordre de lancement de ce script varie suivants les différentes version de Debian, l'exemple ici est pour Squeeze, à adapter suivant les cas. Je l'exécute assez tard car je souhaite écrire le nom de la machine dans /etc/hostname, il faut donc que les filesystems soient montés en RW ;-)

Pour l'encodage j'utilise ce script, qui prend en entrée un entier entre 17 et 254, ceci afin de limiter le nom à 2 syllables. Le résultat en sortie est le nom de la VM et son adresse mac.

[perl]
#!/usr/bin/perl

use strict;
use vars qw ($addr);

my $num = shift;

die "Must be beetween 16 and 256" if ($num < 16 || $num > 254);

my $prefix = "00:16:36:00:56";

my @bibi = ('ho','ha','he','hi',
            'bo','ba','be','bi',
            'ko','ka','ke','ki',
            'do','da','de','di');

my @array = split(//,sprintf"%s",sprintf "%x",$num);

$addr .= sprintf "%s", @bibi[hex($_)] foreach  (@array);

printf "%s %s:%s\n", $addr, $prefix,sprintf "%x",$num;

Ecrit dans le train lors d'un aller-retour Auray-Nantes ce hack convient à mon utilisation particulière de VM jetables, il est largement optimisable, je le livre ici dans l'état, libre à vous de l'adapter. Une variante possible serait d'utiliser la table ASCII pour avoir des noms moins Bobysé ;-)

Dans la machine modèle pensez à supprimer les règles udev qui fixent le nom de l'interface en fonction de l'adresse mac, faute de quoi lors du démarrage d'un clone son interface sera montée en eth1.

Si vous changer l'adresse mac d'une VM depuis son fichier de définition xml pensez à faire un virsh define sur le fichier, faute de quoi la nouvelle adresse n'est pas prise en compte.

Je me suis bien amusé sur ce petit hack, j'espère qu'il vous sera utile autant qu'à moi.

Je n'ai pas inclus les notices de copyright, mais tous le code publié dans ce billet l'est sous GPL v3.