Vagrant-Libvirt sur Apple Silicon (M1 et M2)
Salut à tous ! 👋
Aujourd’hui, je vais partager mon retour d’expérience sur l’installation du plugin Vagrant-libvirt sur un Macbook Air M2.
Je vais être honnête avec vous : ça n’a pas été de tout repos. J’ai rencontré un gros problème en chemin : les Macbook et leurs architectures processeur ARM64
ne sont pas encore officiellement supportés par Hashicorp Vagrant et son plugin Vagrant-libvirt.
Pour trouver une solution et faire fonctionner tout ça, j’ai dû sacrifier quelques heures de sommeil, quelques repas et sorties au cinéma. 😅
Mon homelab faisant tourner libvirt/kvm est important pour moi, car c’est sur lui que j’excerce en créant des VMs pour écrire des articles et partager mes expériences.
Dans cet article, je vais essayer de vous expliquer la procédure d’installation étape par étape. Si vous êtes dans la même situation que moi, j’espère que ça vous sera utile !
Je tiens à préciser que [Hashicorp Vagrant][hv] et son plugin [Vagrant-libvirt][vl] sont codés en Ruby, et que je n’ai aucune expérience dans ce langage de programmation et son écosystème. Cela signifie qu’il est possible que certaines étapes de ma procédure soient bancales ou incomplètes. Si vous êtes un expert en Ruby et que vous repérez des erreurs ou des manques dans mon article, n’hésitez pas à me le faire savoir ! En outre, si vous repérez des erreurs ou des imprécisions, je me ferai un plaisir de les corriger afin de rendre cette article le plus qualitatif et intelligible possible pour d’autres personnes dans la même situation que moi.
Bon à savoir avant de commencer
Je vais partager avec vous une procédure que j’ai écrite et testée sur mon setup personnel.
J’utilise un MacBook Air M2 et j’ai installé macOS Ventura 13.1. Je tiens à préciser que j’ai toujours les dernières mises à jour et que mes paquets brew
sont à jour aussi.
Et enfin, 2 petits détails qui ont leurs importances :
- Je ne suis pas sur
ZSH
mais sur le bon vieuxBASH
- Aucun logiciel de virtualisation n’est présent sur ma machine (virtualbox, parallels, etc…)
Donc si vous avez un setup similaire, ça devrait bien fonctionner pour vous aussi !
Prérequis
- Avant de passer à l’installation il va nous falloir installer via
brew
les paquets suivants:
brew install libvirt qemu gnupg
- Clonez les 3 repositories github à l’endroit de votre choix ! Pour ma part, c’est dans
~/.vagrant
.
mkdir ~/.vagrant
pushd ~/.vagrant
git clone https://github.com/hashicorp/vagrant-spec.git hashicorp/vagrant-spec \
&& git -C ./hashicorp/vagrant-spec checkout 259c55e
git clone -b v2.3.4 https://github.com/hashicorp/vagrant.git hashicorp/vagrant
git clone -b 0.11.2 https://github.com/vagrant-libvirt/vagrant-libvirt.git vagrant-libvirt/vagrant-libvirt
popd
- Installer Ruby Version Manager (
RVM
)
Do NOT use the system Ruby - use a Ruby version manager like rvm or chruby By the Hashicorp team! 👮♂️
# Dans un premier temps, installez les clés GPG utilisées pour vérifier le paquet d'installation
curl -sSL https://rvm.io/mpapis.asc | gpg --import -
curl -sSL https://rvm.io/pkuczynski.asc | gpg --import -
# Installe la version stable de RVM avec Ruby
curl -sSL https://get.rvm.io | bash -s stable --ruby
# Dans mon cas, je suis sur un shell bash et non zsh,
# je copie donc cette ligne dans mon ~/.bash_profile
echo '[ -f ~/.profile ] && source ~/.profile' >> ~/.bash_profile \
&& source ~/.bash_profile
# Et enfin créez un environnement virtuel Ruby en version 3.1.x
rvm install 3.1.3
Installation
Comme je l’ai mentionné au début de l’article, HashiCorp Vagrant et son plugin Vagrant-libvirt ne supportent pas officiellement les Apple Silicon (M1 et M2) et leur architecture ARM64. Seul la version AMD64 de Hashicorp Vagrant nous est proposé en téléchargement depuis le repo officiel, et non Rossetta2 ne fera pas l’affaire 😡 !. Pour rendre Hashicorp Vagrant, Vagrant-libvirt et Vagrant-spec compatibles avec l’architecture ARM64, nous allons devoir compiler les sources que nous avons préalablement clonées. Dans la suite de cette section, je vais vous expliquer comment faire.
Vagrant-spec
À noté que vagrant-spec
est une dépendance clé de vagrant
!
- Rendez-vous dans votre répertoire
~/.vagrant/hashicorp/vagrant-spec
que vous venez de cloner et assurez-vous d’avoir fait un checkout sur le commit ID259c55e
. Ensuite, fixez la version de la dépendancegrpc
à1.47.0
, qu’est à ce jour la seule version récente compatible avecruby-3.x
.
sed -i ' ' '26 s/$/ spec.add_dependency "grpc", "= 1.47.0"\n/' vagrant-spec.gemspec
sed -i ' ' '27 s/$/ spec.add_dependency "grpc-tools", "= 1.41"\n/' vagrant-spec.gemspec
- Créer le Gemset
3.1.3@vagrant-spec
!Un gemset est comme un environnement virtuel qui permet de séparer les différentes versions de gems (bibliothèques logicielles) utilisées par une application Ruby.
rvm use ruby-3.1.3@vagrant-spec --create
- Installez tous les gems nécessaires à l’application
bundle install
- Maintenant, passons à la prochaine étape : transformons ça en un gem que nous utiliserons lors de l’installation de
vagrant
. Si on laissevagrant
s’en occuper tout seul en lançantbundle install
, on risque de se retrouver dans une situation où le processus va échouer. En effet, il va essayer d’installer une version degrpc
qui n’est pas égale à1.47.0
, et on se rappelle que cette version n’est pas compatible avec notre version deruby 3.1.3
! Pour éviter ce genre de désagrément, mieux vaut prendre les devants et faire en sorte que tout soit en ordre dès le départ.
bundle exec rake build
Le gem généré se trouvera ici: pkg/vagrant-spec-0.0.1.gem
, nous-y reviendrons dans 1 minute.
Vagrant
- Rendez-vous dans votre repository
~/.vagrant/hashicorp/vagrant
fraichement cloné et assurez-vous d’avoir checkout surv2.3.4
puis fixer la version de la dépendancegrpc
à1.47.0
, pour les mêmes raisons que je vous ai mentionnées plus haut.
sed -i '' '23 s/"grpc"$/"grpc", "= 1.47.0"\n/g' vagrant.gemspec
- Créer le Gemset
3.1.3@vagrant
!
rvm use ruby-3.1.3@vagrant --create
- Installer le gem de
vagrant-spec
précédemment généré
bundle exec gem install ../vagrant-spec/pkg/vagrant-spec-0.0.1.gem
Ne paniquez pas les amis, si vous rencontrez l'erreur suivante, pas de souci ! On a tous été là. Il est possible que cette erreur soit liée à une configuration particulière de votre environnement, mais on va se sortir de là ensemble. Suivons simplement les étapes suivantes et tout ira bien.
Could not find gem 'grpc-tools (= 1.41)' in locally installed gems.
Run `bundle install` to install missing gems.
- Installons ensuite les gems nécessaires à l’application
bundle install
Bonne nouvelle ! À ce stade, vagrant
est opérationnel. Si vous lancez la commande ci-dessous, vous devriez voir s’afficher la page d’aide de vagrant
lui-même. Essayez-le, c’est rassurant de voir que tout fonctionne comme prévu après toutes les manips qu’on vient de faire.
bundle exec vagrant help
Ne paniquez pas les amis, si vous rencontrez l'erreur suivante, pas de souci ! Exécutez la commande `bundle exec vagrant plugin update` si l'erreur ci-dessous apparaît avant de retenter la commande présenter à l'étape `4`.
Error message given during initialization: Unable to resolve dependency: user requested 'vagrant-hostmanager (= 1.8.9)'
Cela devrait vous donner une idée de toutes les commandes et les options disponibles pour utiliser vagrant.
Voilà qui est fait, revenons à ~/.vagrant/hashicorp/vagrant
un peu plus tard dans la procédure…
Vagrant-libvirt
Et hop, c’est parti ! Maintenant que nous avons un vagrant
qui fonctionne, compilé directement pour et depuis une architecture ARM64, passons à l’installation de son plugin vagrant-libvirt
.
C’est la prochaine étape logique après avoir réussi à faire fonctionner vagrant
, l’utilisation de plugin vient compléter les fonctionnalités de base de vagrant. Il est temps de continuer à avancer dans notre projet.
- Rendez-vous dans votre repository
~/.vagrant/vagrant-libvirt/vagrant-libvirt
assurez-vous d’avoir checkout sur0.11.2
puis fixer la version de la dépendancegrpc
à1.47.0
.
sed -i ' ' '28 s/$/ s.add_runtime_dependency "grpc", "= 1.47.0"\n/' vagrant-libvirt.gemspec
sed -i ' ' '29 s/$/ s.add_runtime_dependency "grpc-tools", "= 1.41"\n/' vagrant-libvirt.gemspec
- Toujours en étant dans le gemset
3.1.3@vagrant
, installez le bundlevagrant-libvirt
bundle install
- Transformons ça en un gem que nous utiliserons lors de l’installation en tant que plugin
vagrant
.
bundle exec rake build
Le gem généré se trouvera ici: pkg/vagrant-libvirt-0.11.2.gem
, nous-y reviendrons dans 1 minute.
Installer vagrant-libvirt
en tant que plugin de vagrant
Vous êtes toujours là avec moi ? Tout s’est déroulé sans problème ? Cool continuons… 😛
- Bon bah lançons les dernières commandes tant attendu
pushd ~/.vagrant/hashicorp/vagrant
# Installer le plugin depuis le gem précédemment généré
rvm 3.1.3@vagrant do bundle exec vagrant plugin install ~/.vagrant/vagrant-libvirt/vagrant-libvirt/pkg/vagrant-libvirt-0.11.2.gem
# Vérifions que tout s'est bien déroulé, listons les plugins installés et voyant si notre petit est présent.
rvm 3.1.3@vagrant do bundle exec vagrant plugin list
popd
Félicitations, vous êtes un vrai champion voilà vagrant-libvirt
et prêt à vous rendre de fiers service !
Je suis fier de vous, si si c’est vrai 🙃 Cela montre que vous avez été patient et persévérant (et accessoirement que mon article vous plaît :D) !
Configuration de l’environnement utilisateur
Maintenant que nous y sommes, vous avez peut-être remarqué que lorsque vous ouvrez un nouveau shell en dehors d’un contexte de Gemset RVM, l’exécution de la commande vagrant
génère une erreur.
C’est normal, car RVM ne gère pas les contexts de manière permanente. Il est donc nécessaire de l’initialiser à chaque ouverture de shell avec rvm use 3.1.3@vagrant
et se rendre dans le dossier ~/.vagrant/hashicorp/vagrant
avant d’executer la commande bundle exec vagrant <action> [options]
si vous souhaitez continuer à utiliser vagrant
.
Qu’on se le disent, c’est très embétant ! D’autant plus que notre répertoire de travail dans lequel se trouve notre Vagrantfile
n’est certainement pas dans ~/.vagrant/hashicorp/vagrant
, et je n’ose même pas évoquer l’autocompletion que l’on perd ! Bref, on peut mieux faire et c’est ce que je propose de faire maintenant. :)
Rester dans votre répertoire projet pour faire appel à la commande vagrant
- Ouvrez votre fichier
~/.bashrc
et ajouter ces lignes.
function vagrant() {
# Pour commencer, récupérez le chemin du répertoire de projet courant où se
# trouve le Vagrantfile et passez-le à VAGRANT_CWD
local current_project_directory=$(pwd)
# Désactiver les messages d'avertissement indiquant que le chemin de
# l'exécutable vagrant n'est pas dans notre $PATH
local rvm_silence_path_mismatch_check_flag=1
# Pour poursuivre, déplacez-vous dans le dossier où se trouve vagrant pour
# que l'appel à la commande vagrant puisse réussir
pushd ~/.vagrant/hashicorp/vagrant >/dev/null
# Finalement, exécutez vagrant en lui transmettant les arguments supplémentaires `$@`
# founir à l'appel de la commande hv() tout en définissant la variable d'environnement
# VAGRANT_CWD sur $current_project_directory pour que vagrant sache où il se trouve.
# https://developer.hashicorp.com/vagrant/docs/other/environmental-variables#vagrant_cwd
VAGRANT_CWD=$current_project_directory \
VAGRANT_INSTALLER_ENV="silent" \
rvm 3.1.3@vagrant do bundle exec vagrant $@
popd >/dev/null
}
- Demander l’ajout de l’autocompletion à votre
~/.bashrc
pushd ~/.vagrant/hashicorp/vagrant
rvm 3.1.3@vagrant do bundle exec vagrant autocomplete install
popd
Enfin, pour que tous ces changements soient pris en compte, éxecutez la commande source ~/.bashrc
pour mettre à jour votre environnement.
- Allez dans votre répertoire projet pour tester que tout fonctionne comme prévu avant de me laisser un commentaire. Cela me permettra de savoir si cette solution fonctionne pour vous et si vous avez des remarques pour améliorer cette méthode.
cd /chemin/du/répertoire/projet
vagrant help
vagrant status
vagrant up
vagrant status
vagrant destroy
Envoy !