genvm : Génération de machines virtuelles

« genvm » Est un script de génération de machines virtuelles (VM) Debian personnalisées. Les images disque générées peuvent être utilisées sous Qemu/KVM, VirtualBox et VMWare (sous Windows, Mac OS ou Linux) en fonction du format d’image choisi. Le script accepte de nombreuses options permettant de personnaliser tous les paramètres de la VM générée.

Cet article n’abordera pas les principes de fonctionnement de l’outil décrit par Pierre-Arnaud dans « Création automatisée d’une machine virtuelle Debian » mais se bornera à l’utilisation du script « genvm ».

Bien qu’en version de développement l’outil « genvm » est déjà largement utilisé depuis des plates-formes d’intégration continue (TeamCity, Jenkins) pour la diffusion d’outils de recherche (ex : CosyVerif) ou pour la génération de machines virtuelles associées à certains événements internationaux (ex : « Model Checking Contest @ Petri Nets » en 2013, 2014, etc).

Installation

Aucune installation particulière n’est nécessaire, il s’agit d’un script à télécharger et à déposer où il vous plaira sur votre système :

aaricia ~ # wget -q https://downloads.sourceforge.net/project/genvm/genvm.tar.bz2 -O - | tar xjvf - -C /sbin/
genvm
aaricia ~ # chown root.root /sbin/genvm

Parmi les prérequis, qui seront testés lors d’un premier lancement, les points notables sont :

  • debootstrap l’installeur Debian disponible sur la plupart des distributions (voir AUR pour ArchLinux, EPEL pour les RedHat like, etc) ;
  • kpartx installé par défaut sur pas mal de distribs ;
  • qemu-img et qemu-nbd disponibles sur tous les linux.

Enfin le script nécessite les droits « root » pour fonctionner.

Une première machine virtuelle

Pour générer une machine virtuelle minimale, le script ne nécessite que le nom de l’image disque à générer (ici « firstvm.raw » sera créé dans « ~fhh/VirtualBox VMs/ ») :

aaricia ~ # time genvm ~fhh/VirtualBox\ VMs/firstvm.raw
Set password to root > 
Enter new UNIX password: 
Retype new UNIX password: 
passwd: password updated successfully
 
real    2m15.012s
user    0m47.003s
sys     0m5.410s
aaricia ~ # ls -l ~fhh/VirtualBox\ VMs/
total 557652
-rw------- 1 root root  5368709120 Nov 15 14:52 firstvm.raw

dans ce cas, le script s’arrête durant la construction de l’image disque pour demander le mot de passe administrateur de la future VM.

Note : non, les données ne sont pas erronées, sur Aaricia, portable Core i7, 8G de RAM, disque SSD et une bande passante « raisonnable », la génération d’une VM Debian complète prend moins de 2 minutes et 16 secondes. Sur une ligne ADSL classique, le temps de construction est plus proche de la dizaine de minute.

L’invocation du script sans argument affiche, entre autre, les valeurs par défaut utilisées pour la génération de notre première image disque :

aaricia ~ # genvm | grep default
        -a      : architecture : amd64, i386 (default : amd64)
        -f      : format of image : raw, qcow2, qcow, vmdk (default : raw)
        -k      : specify kernel version (default : linux-image-amd64)
        -n      : virtual machine name (default : aaricia)
        -o      : change default tmp dir location (path with no space ; default "/tmp")
        -p      : root password (default : ask to user)
        -s      : image size (default : 5G)
        -S      : server to download debian (default : http://ftp.debian.org/debian)
        -V      : debian version : jessie, wheezy, ... (default : wheezy)

L’image Debian Wheezy (« -V ») 64 bits (« -a ») au format raw (« -f ») de 5G (« -s ») est générée depuis le serveur « ftp.debian.org » (« -S ») et porte le même nom que la machine hôte (« -n »).
Le noyau implanté dans la VM est le noyau standard de la distribution (« -k »).
Le répertoire utilisé pour la construction est créé dans « /tmp » (« -o ») et le mot de passe administrateur est demandé à l’utilisateur pendant la construction de la VM (« -p »).

Avant d’utiliser l’image, root doit la « donner » à un utilisateur (via « chown ») :

aaricia ~ # chown fhh.users ~fhh/VirtualBox\ VMs/firstvm.raw

L’image est alors directement utilisable via Qemu/KVM (voir « Première approche de KVM (“Kernel-based Virtual Machine”) » pour le lancement d’une image) :

fhh@aaricia ~ $ qemu-system-x86_64 VirtualBox\ VMs/firstvm.raw &
[1] 32766

Note :

  • La machine virtuelle générée n’est, par défaut, pas connectée à internet et ne dispose pas de client DHCP.
  • Le clavier est en QWERTY.
  • Il s’agit d’une machine vraiment minimale, vous aurez le choix de tous les composants (aucun éditeur de texte installé par défaut, aucun gestionnaire de logs, aucun MTA, etc).

Une VM évoluée

Dans ce second exemple, nous installerons une liste de paquets additionnels sur notre machine. Nous utiliserons également l’option « -t » pour exécuter les scripts du répertoire « ~/scripts.genvm » pendant et après la génération de l’image. La machine virtuelle produite sera utilisée sous VirtualBox.

Liste de paquets additionnels

Les paquets à ajouter à l’installation de base peuvent être notifiés dans un fichier texte à raison d’un paquet par ligne. Le fichier est ensuite passé au script via l’option « -l » (comme liste).

aaricia ~ # cat > ~/scripts.genvm/lst.txt
openssh-server
vim
ifupdown
console-setup
^d

Une autre solution consiste à utiliser l’option « -A » suivie de la liste des paquets à ajouter séparés par une virgule (s’il n’y a pas trop de paquets a ajouter).

Scripts de personnalisation de la VM

Pour personnaliser la machine virtuelle, il est possible d’exécuter des scripts contenus dans un répertoire passé à « genvm » via l’option « -t ».
Les noms des scripts au format « DD.{chroot|host|post}.nom_du_script » renseignent sur leurs ordres et leurs contextes d’exécution :

3rd/
|- 01.chroot.norecommends
|- 01.host.java
...
|- 01.post.chown
`- 02.host.rc.local

Les scripts « XX.chroot.* » et « YY.host.* » seront exécutés en premiers et dans l’ordre. Les scripts préfixés par « XX.chroot.* » seront exécutés dans la VM. Les scripts préfixés par « XX.host.* » seront exécuté sur la machine générant l’image disque.

Dans l’exemple ci dessus, le script « 01.chroot.norecommends » sera exécuté en premier et dans la VM. « 01.host.java » Sera ensuite exécuté mais sur la machine générant l’image disque. Le dernier script exécuté durant la construction du système sera « 02.host.rc.local ».

Les scripts portant la mention « post » seront exécutés dans l’ordre après la génération de la VM (une fois l’image disque démontée).

Note : Les fichiers contenus dans le répertoire passé en argument à genvm mais ne respectant pas le format de nom décrit ci dessus ne seront pas appliqués.

Un certain nombre de variables et de fonctions peuvent être utilisées depuis les scripts de personnalisation telles que :

  • ${MOUNT_POINT} : point de montage de la racine de l’image générée ;
  • ${HD_IMG} : nom du fichier de l’image disque générée ;
  • set_passwd_to foo mdp : fonction attribuant le mot de passe « mdp » à l’utilisateur « foo » ;
  • etc.

Démarrer le réseau lors du boot de la VM

Le premier script appliqué à la machine virtuelle à pour but de démarrer le réseau et de le configurer en DHCP. Pour cela le fichier « /etc/network/interfaces » de la machine virtuelle sera adapté pendant la construction de l’image disque :

aaricia ~ # mkdir ~/scripts.genvm
aaricia ~ # cat > ~/scripts.genvm/01.host.network
cat > "${MOUNT_POINT}/etc/network/interfaces < <_eof_
auto lo eth0                    
 
iface lo inet loopback
 
iface eth0 inet dhcp
_eof_
^d

Le script est exécuté depuis la machine hôte et écrit dans « point_de_montage/etc/network/interfaces ».

Désactiver l’installation des paquets recommandés

Afin de conserver un système minimal, on désactive l’installation automatique des paquets recommandés.

aaricia ~ # cat > ~/scripts.genvm/01.chroot.norecommends
cat > /etc/apt/apt.conf.d/02norecommends < <_eof_
APT::Install-Recommends False;
_eof_
^d

Le script est exécuté dans la machine virtuelle et écrit dans « /etc/apt/apt.conf.d/02norecommends ».

Chargement du clavier français

Le clavier français sera chargé grâce au paquet « console-setup » (ajouté à la liste des paquets à installer) et à la modification du fichier « /etc/default/keyboard ».

aaricia ~ # cat > ~/scripts.genvm/03.chroot.keymap
cat > /etc/default/keyboard < <_eof_
XKBMODEL="pc105"
XKBLAYOUT="fr"
XKBVARIANT="oss_latin9"
XKBOPTIONS="terminate:ctrl_alt_bksp"
BACKSPACE="guess"
_eof_

Le fichier sera modifié depuis l’environnement de la machine virtuelle.

Création d’un utilisateur « fhh » mot de passe « truc »

Création de l’utilisateur dans la machine virtuelle :

aaricia ~ # cat > ~/scripts.genvm/02.chroot.createuser
useradd -c FHH -g users -m -s /bin/bash fhh

Initialisation du mot de passe pour l’utilisateur :

aaricia ~ # cat > ~/scripts.genvm/02.host.setpasswd2user
set_passwd_to fhh truc
^d

Changer les droits sur l’image disque

Un chown appliqué après la génération de l’image assume cette partie.

aaricia ~ # cat > ~/scripts.genvm/01.post.chown
chown fhh.users "${HD_IMG}"
^d

Attention : l’environnement chrooté contient très peu de chose par défaut; si vous souhaitez faire un « wget » depuis la machine virtuelle, installez wget, si vous souhaitez extraire un « tar.bz2 » installez bzip2, etc.

Génération de la machine virtuelle

Une fois les scripts de personnalisation terminés et la liste des paquets établie, le script est invoqué :

aaricia ~ # genvm -a amd64 -A isc-dhcp-client -f vmdk -l ~/scripts.genvm/lst.txt \
> -n vm -p toor -s 10G -S http://ftp.fr.debian.org/debian -t ~/scripts.genvm/ -v \
> -V jessie ~fhh/vm.vmdk
checking for "qemu-img" ... Ok
...
delete temporary mount point (if needed)
/home/root/scripts.genvm/01.post.chown
Running /home/root/scripts.genvm/01.post.chown after all

En plus des paquets du fichier « ~/scripts.genvm/lst.txt » l’option « -A » est utilisée pour ajouter le client dhcp. L’image Debian Jessie (« -V ») de 10G est générée au format « vmdk » pour être compatible avec VirtualBox. La machine générée est baptisée « vm » (option « -n »). Le mot de passe root est initialisé à « toor » (option « -p »).

Lancement de la machine virtuelle

Qemu/KVM

Sous Qemu/KVM, la VM peut, comme vu précédemment être lancée directement :

fhh@aaricia ~ $ qemu-system-x86_64 ~/vm.vmdk &
[1] 6556

VirtualBox

Sous VirtualBox, créer une nouvelle machine virtuelle et associez lui le disque au format VMDK généré.

Ouvrir VirtualBox et cliquer sur « New »

VBox Accueil

Sélectionner les paramètres adapté à la nouvelle image

Paramétrage d'une nouvelle VM

Choisir l’image disque fraîchement générée avant de créer la VM

Configuration du disque virtuel

Lancer la machine virtuelle comme n’importe quelle VM VirtualBox.

Fonctionnalités avancées

En plus des fonctionnalités déjà présentées, le script offre d’autres possibilités aidant à la personnalisation ou au débogage des scripts d’installation.

Le mode interactif

L’option « -i » permet de prendre la main en fin d’installation pour effectuer des actions complémentaires :

aaricia ~ # genvm -A isc-dhcp-client -p toor -f vmdk -i ~fhh/vm.vmdk
 
 
*** ENTERING IN INTERACTIVE SHELL ***
 
You are here : /home/root
Virtual machine is monted here : /tmp/tmp.qxiJkmmgvC
Press "Ctrl+d" or "exit" to exit
 
 
bash-4.2# # Toutes les commandes souhaitées ...
bash-4.2# # Possibilité de se chrooter dans la VM 
bash-4.2# exit
exit
 
 
*** END OF INTERACTIVE SEQUENCE ***

Lancement des scripts additionnels uniquement

Le plus long dans la construction d’une machine virtuelle de ce type est le téléchargement et l’installation des paquets. Pour déboguer les scripts de personnalisation, la reconstruction d’une VM complète devient vite fastidieuse. L’option « -T » permet de remédier à ce problème en n’exécutant QUE les scripts de personnalisation.

L’option s’utilise sur la même ligne que celle ayant généré la VM. Par exemple, pour une image disque générée par la commande :

aaricia ~ # genvm -p toor -l scripts.genvm/lst.txt -t scripts.genvm/ -f vmdk ~fhh/vm.vmdk

L’exécution des scripts de personnalisation uniquement est obtenue par l’ajout d’un « -T » à la commande :

aaricia ~ # genvm -T -p toor -l scripts.genvm/lst.txt -t scripts.genvm/ -f vmdk ~fhh/vm.vmdk

Pour du débogage ajouter un « -v » permettra de voir l’exécution des scripts :

aaricia ~ # genvm -T -v -p toor -l scripts.genvm/lst.txt -t scripts.genvm/ -f vmdk ~fhh/vm.vmdk
...

En réalité, seul le fichier de l’image générée le format de l’image et la localisation des scripts sont nécessaire :

aaricia ~ # genvm -T -v -t scripts.genvm/ -f vmdk ~fhh/vm.vmdk
...

Montage d’une VM générée

En combinant l’option « -i » pour l’interactivité et « -T » pour l’application des scripts de personnalisation uniquement, il est possible de monter automatiquement et d’accéder à la VM via genvm.

L’astuce consiste à utiliser conjointement les options « -i » et « -T » et à remplacer le répertoire des scripts de personnalisation par « /dev/null » (option « -f »).

aaricia ~ # genvm -T -i -t /dev/null -f vmdk ~fhh/vm.vmdk
 
 
*** ENTERING IN INTERACTIVE SHELL ***
 
You are here : /home/root
Virtual machine is monted here : /tmp/tmp.T9mWjcLTNs
Press "Ctrl+d" or "exit" to exit
 
 
bash-4.2# exit
 
 
*** END OF INTERACTIVE SEQUENCE ***

Une fois encore, seul le format de l’image (« -f ») et le fichier image sont nécessaires.

Conclusion

Dans l’état, le script permet de générer rapidement et/ou automatiquement de nombreuses machines virtuelles pour la réalisation de banc de tests ou la diffusion de projets quelques soient les niveaux de complexités désiré.

La gestion du partitionnement des images disque, prochainement intégrée, devrait permettre au script de générer des machines virtuelles de type serveur pouvant être mis en production directement.

Pour d’autres évolutions n’hésitez pas à demander et/ou à contribuer …

4 réflexions au sujet de « genvm : Génération de machines virtuelles »

  1. Sympa la pub pour CosyVerif 🙂

    Je vois que tu as pas mal amélioré ton script. Je l’essairais la prochaine fois que j’aurais besoin d’une VM.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *