Le format de projet v3 : des projets écrits en texte
Ce texte fait foi ; la version anglaise en est la traduction.
Cette note s’adresse aux enseignants qui conservent une collection de projets .mar, par exemple
les réseaux de départ de leurs séances de TP. Depuis 2026, Marionnet enregistre ses projets dans un
nouveau format, le format v3, écrit en texte. Rien ne change dans l’utilisation du logiciel, et
les anciens projets s’ouvrent comme avant ; en revanche, un ancien projet enregistré par la nouvelle
version ne peut plus être ouvert par une version antérieure de Marionnet. Si l’une de vos salles,
ou l’un de vos collègues, utilise encore une telle version, gardez donc une copie de chaque projet
avant de l’enregistrer (cf. § 3).
1. Ce qui change
Un projet Marionnet, c’est-à-dire un fichier .mar, est une archive compressée qui contient deux
choses : la description du réseau virtuel (ses composants, ses câbles, ses adresses, son dessin) et
les disques des machines, ou plus exactement ce qui a changé sur chacun d’eux par rapport à l’image
d’origine. Jusqu’ici, la description était écrite dans le format binaire interne d’OCaml, le
langage de Marionnet, autrement dit une copie brute de structures de données du programme : elle
était illisible en dehors de Marionnet, impossible à comparer d’une version à l’autre, et fragile,
puisqu’une modification du programme pouvait rendre un ancien projet illisible, sans aucun
avertissement.
Dans le format v3, la description est écrite en texte : en JSON pour les fichiers qui
décrivent le réseau, et sous forme de simples scripts pour les scripts de démarrage des
composants. Les disques, quant à eux, restent des images binaires, ce qu’ils sont par nature.
Il en découle deux propriétés utiles :
- une fois l’archive dépaquetée (
tar xzf tp.mar), un projet se lit, se compare (diff) et se conserve sous un gestionnaire de versions commegit: deux versions d’un TP qui ne diffèrent que par une adresse ne diffèrent que d’une ligne ; - un projet ouvert puis enregistré sans modification est réécrit à l’identique, alors que
jusqu’ici l’ordre des composants s’inversait à chaque enregistrement, ce qui rendait toute
comparaison inutile. Un seul fichier fait exception,
states/ifconfig-counters.json, qui porte un champ obsolète tiré au hasard à chaque enregistrement :diffle signale donc à chaque fois, et vous pouvez l’ignorer.
2. Les anciens projets s’ouvrent toujours
Marionnet lit tous les formats qu’il a écrits depuis ses débuts (v0, v1 et v2). Lorsqu’il
ouvre un ancien projet, il en adapte ce qui doit l’être, par exemple en remplaçant un noyau qui
n’est plus livré par un noyau disponible, exactement comme il le faisait déjà. Le fichier reste
d’ailleurs une archive .mar ordinaire, que vous pouvez copier, envoyer par courriel ou archiver
comme d’habitude.
3. Avant d’enregistrer un ancien projet
Ouvrir un ancien projet ne modifie rien sur le disque ; c’est l’enregistrement qui le fait. Le
projet est alors écrit dans le format v3, et une version antérieure de Marionnet ne pourra plus
l’ouvrir. Marionnet le signale d’ailleurs à l’ouverture d’un tel projet, par l’avertissement qu’il
affiche depuis toujours lorsqu’un projet est sur le point de changer de format :
Projet dans un ancien format — Ce projet va être automatiquement traduit dans un format incompatible avec les versions précédentes de ce logiciel. Si vous voulez préserver la compatibilité ne le sauvez pas ou sauvez-le sous un autre nom.
Ce qui se passe ensuite a été vérifié, et non supposé. Face à un projet v3, une version antérieure
de Marionnet refuse de l’ouvrir et l’indique (Échec lors du chargement du projet) ; elle ne
s’arrête pas pour autant, n’affiche aucun réseau à moitié chargé, et surtout laisse le fichier
intact, car un refus n’endommage jamais un projet. L’échec est donc sans conséquence pour le
fichier, mais le projet reste inutilisable sur ce poste, et il n’existe aucun moyen de revenir en
arrière : un projet v3 ne peut pas être reconverti dans un ancien format.
Par conséquent, si certains postes utilisent encore une version antérieure de Marionnet (une salle de TP qui n’a pas encore été mise à jour, un collègue, ou une machine virtuelle que vous gardez pour un cours), gardez une copie de chaque projet avant de l’enregistrer avec la nouvelle version :
cp tp.mar tp-v2.mar
Reconnaître le format d'un projet
Le format est noté dans un petit fichier, version, à l’intérieur de l’archive :
$ tar xzf tp.mar -O --wildcards '*/version'; echo
v2
Ce fichier ne contient que le nom du format, sans même un saut de ligne, d’où le echo final. Les
formats v0, v1 et v2 sont les anciens formats binaires, et v3 le format texte : la même
commande, appliquée à un projet enregistré par la nouvelle version, répond donc v3.
4. Convertir toute une collection de projets
La conversion n’est pas nécessaire, puisque Marionnet ouvre les anciens projets ; elle ne sert que
si vous voulez comparer vos projets ou les conserver sous git dès maintenant.
Marionnet ne fournit pas d’outil de conversion séparé, et ce n’est pas un oubli : le seul programme
autorisé à écrire un projet Marionnet est Marionnet lui-même. Convertir un projet, c’est donc
l’ouvrir puis l’enregistrer, ce qu’un script peut faire sans que personne ne clique, grâce au
pilotage par script. Le script se lance dans votre session graphique,
puisque Marionnet y ouvre sa fenêtre comme d’habitude, et mrnctl, le client du pilotage par
script, est installé avec Marionnet :
# mrnctl lit le chemin du point de rendez-vous dans cette variable :
export MARIONNET_CONTROL_SOCKET=/tmp/marionnet.sock
marionnet --control-socket "$MARIONNET_CONTROL_SOCKET" &
until mrnctl status > /dev/null 2>&1; do sleep 0.5; done
mkdir -p ~/tp-v2
for f in ~/tp/*.mar; do
# D'abord la copie, dans un répertoire à part (cf. § 3) :
cp "$f" ~/tp-v2/
mrnctl open "$f" --timeout=120 &&
mrnctl close --save --timeout=120 || break
done
mrnctl quit
Notons trois choses à propos de cette boucle. D’abord, l’ouverture d’un ancien projet peut
l’adapter (le remplacement d’un noyau, par exemple) : mrnctl open énumère ces adaptations dans
sa réponse, et elles font partie de ce qui sera enregistré. Ensuite, l’option --timeout=120
n’est pas décorative. En effet, un ordre qui n’en porte pas est limité à cinq secondes, or
l’enregistrement d’un gros projet, ou sur une machine chargée, peut dépasser ce délai : le script
annoncerait alors l’échec d’une opération qui était simplement lente. Enfin, si l’ouverture ou
l’enregistrement échoue vraiment, mrnctl rend un code d’erreur et la boucle s’arrête (|| break)
au lieu de passer au projet suivant ; dans le cas de l’enregistrement, close --save ne ferme
pas le projet, de sorte que rien n’est perdu. Les copies, quant à elles, gardent leur nom en
.mar : une version antérieure de Marionnet les ouvre donc telles quelles.
Le contenu d'une archive .mar
| Dans l’archive | Contenu |
|---|---|
version |
le nom du format (v3) |
netmodel/network.json |
le réseau lui-même : machines, routeurs, switchs, câbles |
netmodel/dotoptions.json |
le dessin du réseau (disposition, zoom, câbles inversés) |
states/ifconfig.json |
les adresses, une ligne par carte réseau |
states/ifconfig-counters.json |
les compteurs qui servent à attribuer l’adresse suivante |
states/defects.json |
les défauts simulés (pertes, délais, duplications) |
states/states-forest.json |
les états des disques des machines |
states/texts.json |
les documents attachés au projet |
states/rc_config.* |
les scripts de démarrage, un fichier par composant qui en a un |
Les scripts de démarrage sont des fichiers à part entière plutôt qu’un champ de la description du réseau, de façon que chacun puisse s’ouvrir dans un éditeur, comme n’importe quel autre fichier.
5. Pour en savoir plus
- Piloter Marionnet par un script ou par une IA, le guide du pilotage par script.
- La conception du format et les raisons de ses choix, pour les développeurs :
docs/migration-marshal-to-text.md, dans les sources de Marionnet sur Launchpad (en français).
