{"version":"https:\/\/jsonfeed.org\/version\/1","title":"[Blog] Nicolas Busseneau","home_page_url":"https:\/\/nicolas.busseneau.fr\/fr\/blog","feed_url":"https:\/\/nicolas.busseneau.fr\/fr\/blog.json","description":"Je suis passionn\u00e9 de logiciel\/mat\u00e9riel informatique, halt\u00e9rophile et gamer. J\u2019esp\u00e8re que vous appr\u00e9cierez ce que j\u2019ai trouv\u00e9 suffisamment int\u00e9ressant pour bloguer.","author":{"name":"Nicolas Busseneau"},"items":[{"title":"Th\u00e9orie des graphes en FFA","date_published":"2023-09-03T11:21:00+02:00","id":"https:\/\/nicolas.busseneau.fr\/fr\/blog\/2023\/09\/using-graph-theory-for-ffa-games","url":"https:\/\/nicolas.busseneau.fr\/fr\/blog\/2023\/09\/using-graph-theory-for-ffa-games","content_html":"
Beyond All Reason<\/a> est un super RTS<\/abbr> et descendant de Total Annihilation 🤖\nLe jeu est basé sur le moteur Recoil<\/a> (précédemment SpringRTS<\/a>) et donc entièrement open source, le rendant doublement intéressant puisqu’on peut directement participer à l’améliorer.<\/p>\n Comme sur tous les jeux RTS<\/abbr> classiques, un des modes de jeu disponibles est le FFA<\/abbr> jusqu’à 16 joueurs (extrêmement fun).\nDans ce mode de jeu, les joueurs se voient automatiquement attribués une position de départ au lancement de la partie, et j’était légèrement frustré par le manque de flexibilité du système : en bref, un ensemble statique de points de départ est défini sur chaque carte, et au lancement de la partie, le système sélectionnait les X premiers points et les attribuait aléatoirement aux joueurs.<\/p>\n En pratique, au lancement d’un FFA<\/abbr> à 12 joueurs sur une carte avec 16 positions, le jeu choisissait systématiquement les positions de départ 1 à 12, et donc les positions de départ pour 12 sur cette carte étaient toujours les mêmes, les positions 13 à 16 n’étant jamais utilisées.\nJ’ai décidé de l’améliorer en ajoutant la possibilité de définir plusieurs dispositions pour X joueurs par carte, donnant ainsi plus de flexibilité dans la définition de dispositions équitables et imprévisibles pour différentes tailles de FFA<\/abbr> sur une même carte.<\/p>\n En guise d’illustration, la carte suivante permet de jouer des matchs FFA<\/abbr> équitables de différentes tailles (3 joueurs, 5 joueurs, 7 joueurs, etc.) grâce à son design à triple cercles concentriques.\nCependant, le système par défaut n’était pas suffisamment flexible pour permettre de jouer à 3 ou à 5 vu qu’il sélectionnait toujours les X premiers points pour X joueurs, résultant en des positions de départ inéquitables. Le nouveau système résout ce problème en définissant des dispositions appropriées pour toutes tailles de FFA<\/abbr>.<\/p>\n <\/a><\/p>\n Celles-ci furent faciles à définir sur la plupart des cartes, comme dans l’exemple ci-dessus, mais bien sûr ce ne fut pas le cas pour toutes, et notamment pour les cartes asymétriques.\nL’une d’elles en particulier est unique car c’est la seule carte du jeu avec plus que 16 positions de départ : elle en a 32.<\/p>\n <\/a><\/p>\n Étant donné que des ressources stratégiques sont disponibles sur chaque point de départ, il faut veiller à répartir les joueurs de telle sorte qu’aucun n’ait accès à considérablement plus ou moins de ressources qu’un autre, ce qui peut naïvement être fait en essayant d’éviter que 2 joueurs ne démarrent l’un à côté de l’autre.\nMais essayer de déterminer manuellement des dispositions équitables sur cette carte était un cauchemar, et pour cause, compte tenu du nombre de 16-combinaisons<\/a> possibles sur 32 points de départ :<\/p>\n \\[\nC(32, 16) = {32 \\choose 16} = {\\frac{32!}{16!16!}} = 601\\,080\\,390\\]<\/p>\n J’ai donc décidé d’utiliser la théorie des graphes pour m’aider.\nLa carte peut être représentée sous forme de graphe où chaque point de départ est un nœud et le voisinage est matérialisé par une arête :<\/p>\n <\/a><\/p>\n<\/div>\n Partant de là, on peut :<\/p>\n Guide de suppression d’une matrice Si jamais vous avez un besoin similaire, voici comment je m’en suis sorti. Il va de soi que vous devriez sauvegarder les données avant de faire quoi que ce soit, à défaut vous acceptez le risque de tout perdre. Hic sunt dracones<\/em> 🐉<\/p>\n Un serveur dédié SoYouStart avec deux disques, pour héberger des machines virtuelles via VMware ESXi.\nMalheureusement VMware ESXi ne prend pas en charge le RAID logiciel : comme solution de contournement, on peut attacher deux VMDK (disque virtuel) à chaque VM, chaque VMDK étant stocké sur un datastore<\/em> (disque matériel) distinct, et configurer un RAID1<\/abbr> logiciel directement depuis la VM via Cette ennuyeuse limitation fut d’ailleurs l’une des principales motivations pour migrer de VMware ESXi vers Promox VE<\/a>, ce dernier prenant en charge le RAID1<\/abbr> logiciel via ZFS<\/a>. Le RAID étant désormais géré au niveau de l’hôte, plus besoin que les machines virtuelles gèrent elles-mêmes un RAID logiciel, et on peut ne conserver qu’un seul disque pour chaque VM.<\/p>\n On va retirer des partitions de la matrice, puis faire en sorte que Tout d’abord, inspecter partitions et disques pour identifier où se trouve quoi et ce qui doit être fait :<\/p>\n Par exemple, ici :<\/p>\n Une fois que tout est décidé :<\/p>\n Dans notre cas, on a d’abord supprimé la partition de swap<\/em> Si on s’arrêtait ici, J’ai récemment migré des machines virtuelles depuis VMware ESXi vers Proxmox VE et rencontré quelques problèmes au cours du processus.\nVoici mes notes au cas où ça pourrait aider.<\/p>\n VMware ESXi et Proxmox VE sont tous deux compatibles OVF<\/a>.\nLe but est d’exporter une VM au format OVF depuis VMware ESXi puis d’importer l’OVF sur Proxmox VE.<\/p>\n\n Si VMware ESXi est accessible depuis Proxmox VE, on peut utiliser VMware OVF Tool<\/a> directement depuis Proxmox VE afin d’exporter et copier l’OVF en un seul coup.<\/p>\n Utilisation :<\/p>\n Si on utilise SSL avec un certificat auto-signé, ajouter OVF Tool demandera le mot de passe et listera les objets disponibles :<\/p>\n On peut récursivement lister les objets, e.g. ici avec un répertoire :<\/p>\n Lors de l’accès à une VM, les détails de la VM à exporter via OVF s’affichent :<\/p>\n Une fois la VM à exporter identifiée, on peut enregistrer l’OVF dans un fichier local sur Proxmox VE :<\/p>\n Pour certaines VM, j’ai eu cette erreur :<\/p>\n Avec l’OVF disponible localement, on peut importer la VM via l’outil en ligne de commande Utilisation :<\/p>\n On peut également spécifier Depuis plusieurs années OVH propose des serveurs dédiés via trois gammes :<\/p>\n Lors de la création d’un serveur dédié, on peut choisir parmi des modèles d’installation modifiables dans une certaine mesure (e.g. schéma de partition ou exécution d’un script post-installation), mais on se retrouve bloqué si besoin de quelque chose de spécial – un autre système d’exploitation, un système de fichiers spécifique, etc.<\/p>\n <\/a><\/p>\n Une astuce est d’utiliser IPMI, disponible sur la plupart des serveurs OVH et permettant d’installer une image ISO [1]<\/a>[2]<\/a>.\nÉtant donné que SoYouStart propose essentiellement du matériel OVH à la retraite, certains de leurs serveurs ont également IPMI, et je m’attend à ce qu’il en soit de même pour Kimsufi au fil du temps.<\/p>\n Mais si IPMI n’est pas disponible (ou ne fonctionne pas à cause de ce satané Java<\/abbr>) et qu’on ne souhaite pas payer pour un KVM IP<\/a>, une solution consiste à démarrer une image ISO depuis le mode rescue via QEMU KVM.<\/p>\n Devrait marcher aussi bien chez OVH et SoYouStart que Kimsufi.<\/p>\n Une fois connecté au mode rescue, on peut nettoyer les disques avant l’installation.\nLa plupart des programmes d’installation peuvent repartitionner les disques donc ce n’est pas strictement nécessaire, mais on s’assure ainsi de gérer de suite les éventuels problèmes de RAID \/ montage.<\/p>\n En cas d’erreurs Les disques désormais nettoyés, on peut préparer l’installation proprement dite.<\/p>\n Les communautés open source<\/em> sur plateformes collaboratives Git (e.g. Github, GitLab) demandent généralement aux contributeurs de soumettre leurs modifications au dépôt upstream<\/em> depuis un fork<\/em>.<\/p>\n À l’inverse d’un véritable fork<\/em> qui bifurque de l’upstream<\/em> et a une vie propre, un fork contributif<\/abbr> est un simple conteneur pour branches contributives : son cycle de vie est étroitement lié à l’upstream<\/em>.\nOn attend des contributeurs qu’ils soumettent des modifications basées sur une version récente du dépôt upstream<\/em>.\nLorsque le fork<\/em> est obsolète, ils doivent se synchroniser avec l’upstream<\/em> et rebase<\/em> leur travail.<\/p>\n C’est là que ça se complique.\nIl existe autant d’approches pour synchroniser que de contributeurs.\nLa documentation GitHub a même une entrée dédiée à la synchronisation d’un fork<\/em><\/a>.<\/p>\n De mon côté, je pense qu’une approche « sans synchro » est la meilleure 😄<\/p>\n Deux types de branches sur un fork contributif<\/abbr> :<\/p>\n En pratique, les branches miroirs sont inutiles : elles servent uniquement de point de départ aux branches contributives.\nLa nécessité de les maintenir à jour avec l’upstream<\/em> génère de l’intendance supplémentaire au niveau de la gestion de branches.<\/p>\n Peut-on contribuer sans avoir à synchroniser le fork<\/em> ?\nC’est l’idée derrière l’approche « sans synchro ».<\/p>\n Cette étape est commune aux approches habituelles avec synchronisation.<\/p>\n Par défaut, quand on clone un dépôt, une remote<\/em> On est automatiquement placés sur une branche locale par défaut, qui traque la branche par défaut sur S’agissant d’un fork<\/em>, on peut basculer vers n’importe quelle branche miroir disponible :<\/p>\n Note : dans ce billet je vais utiliser Comme un dépôt Git peut interagir avec plusieurs dépôts Git distants, ajoutons le dépôt upstream<\/em> comme remote<\/em> On peut désormais récupérer les branches de l’upstream<\/em> :<\/p>\n J’ai la chance de posséder une ASUS TUF RTX 3080 OC depuis janvier.\nC’est une super carte de jeu mais j’étais légèrement étonné des performances thermiques de la mémoire, avec des pics \\(T_{junction}\\)<\/span> à 104°C dans certaines circonstances (coucou DLSS + Ray Tracing).\nApparemment ça reste dans des limites acceptables (voir l’excellente enquête d’igor’sLAB sur le sujet<\/a>), mais on s’approche du \n
mdadm<\/code> RAID1<\/abbr> tout en préservant les données existantes de la partition, évitant ainsi d’avoir à réinstaller ou copier des fichiers.<\/p>\n
Contexte<\/a><\/h1>\n
mdadm<\/code> .<\/p>\n
Mode facile<\/a><\/h1>\n
mdadm<\/code> se satisfasse d’une matrice RAID1<\/abbr> composée d’une seule partition.<\/p>\n
\n
mdadm<\/code> et sur quels disques.<\/li>\n
# lsblk\nNAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT\nsda 8:0 0 100G 0 disk\n├─sda1 8:1 0 953M 0 part [SWAP]\n└─sda2 8:2 0 99.1G 0 part\n └─md0 9:0 0 99.1G 0 raid1 \/\nsdb 8:16 0 100G 0 disk\n├─sdb1 8:17 0 953M 0 part \/var\/tmp\n└─sdb2 8:18 0 99.1G 0 part\n └─md0 9:0 0 99.1G 0 raid1 \/\n# cat \/proc\/mdstat\nmd0 : active raid1 sda2[0] sdb2[1]\n 103872512 blocks super 1.2 [2\/2] [UU]\n# mdadm --detail \/dev\/md0\nState : active<\/code><\/pre>\n
\n
\/var\/tmp<\/code>.<\/li>\n
md0<\/code> est répartie sur
sda2<\/code> et
sdb2<\/code>.<\/li>\n
sda<\/code> et conserver
sdb2<\/code>.<\/li>\n<\/ul>\n
\n
# mdadm \/dev\/md0 --fail \/dev\/sda2\nmdadm: set \/dev\/sda2 faulty in \/dev\/md0\n# mdadm \/dev\/md0 --remove \/dev\/sda2\nmdadm: hot removed \/dev\/sda2 from \/dev\/md0\n# mdadm --zero-superblock \/dev\/sda2<\/code><\/pre>\n
sda1<\/code> (non illustré ci-dessus : désactivée avec
swapoff<\/code> et mise à jour de
\/etc\/fstab<\/code>), puis supprimé
sda2<\/code> de la matrice.<\/p>\n
mdadm...<\/code><\/p>","summary":"Guide de suppression d'une matrice mdadm RAID1 (Linux) tout en pr\u00e9servant les donn\u00e9es existantes de la partition.","tags":["raid","linux"]},{"title":"Migration de machines virtuelles depuis VMware ESXi vers Proxmox VE","date_published":"2021-07-25T19:54:00+02:00","id":"https:\/\/nicolas.busseneau.fr\/fr\/blog\/2021\/07\/esxi-to-proxmox-migration","url":"https:\/\/nicolas.busseneau.fr\/fr\/blog\/2021\/07\/esxi-to-proxmox-migration","content_html":"
Prérequis<\/a><\/h1>\n
\n
\n
.bundle<\/code> (nécessite un compte VMware, qu’on peut créer gratuitement).<\/li>\n
chmod +x<\/code> puis l’éxecuter.<\/li>\n<\/ul><\/li>\n
Exporter une VM depuis VMware ESXi<\/a><\/h1>\n
# ovftool vi:\/\/<username>@<host>:<port>\/<\/code><\/pre>\n
--noSSLVerify<\/code>.<\/p>\n
# ovftool --noSSLVerify vi:\/\/root@XXX.XXX.XXX.XXX:443\/\nEnter login information for source vi:\/\/XXX.XXX.XXX.XXX\/\nUsername: root\nPassword: ***************\nError: Found wrong kind of object (ResourcePool). Possible completions are:\n vm1\n vm2\n dir1\/\n dir2\/<\/code><\/pre>\n
# ovftool --noSSLVerify vi:\/\/root@XXX.XXX.XXX.XXX:443\/dir1\/\nEnter login information for source vi:\/\/XXX.XXX.XXX.XXX\/\nUsername: root\nPassword: ***************\nError: Found wrong kind of object (ResourcePool). Possible completions are:\n vm3<\/code><\/pre>\n
# ovftool --noSSLVerify vi:\/\/root@XXX.XXX.XXX.XXX:443\/dir1\/vm3\nEnter login information for source vi:\/\/XXX.XXX.XXX.XXX\/\nUsername: root\nPassword: ***************\nOVF version: 1.0\nVirtualApp: false\nName: vm3\n\nDownload Size: Unknown\n\nDeployment Sizes:\n Flat disks: 100.00 GB\n Sparse disks: Unknown\n\nNetworks:\n Name: Foo\n Description: Bar\n\nVirtual Machines:\n Name: vm3\n Operating System: debian10_64guest\n Virtual Hardware:\n Families: vmx-13\n Number of CPUs: 4\n Cores per socket: 4\n Memory: 6.00 GB\n\n Disks:\n Index: 0\n Instance ID: 9\n Capacity: 50.00 GB\n Disk Types: SCSI-VirtualSCSI\n\n Index: 1\n Instance ID: 10\n Capacity: 50.00 GB\n Disk Types: SCSI-VirtualSCSI\n\n NICs:\n Adapter Type: VmxNet3\n Connection: Foo\n\nReferences:\n File: \/12\/ParaVirtualSCSIController0:0\n File: \/12\/ParaVirtualSCSIController0:1<\/code><\/pre>\n
# ovftool --noSSLVerify vi:\/\/root@XXX.XXX.XXX.XXX:443\/dir2\/vm4 .\nEnter login information for source vi:\/\/XXX.XXX.XXX.XXX\/\nUsername: root\nPassword: ***************\nOpening VI source: vi:\/\/root@XXX.XXX.XXX.XXX:443\/dir2\/vm4\nOpening VI source: vi:\/\/root@XXX.XXX.XXX.XXX:443\/dir2\/vm4\nOpening OVF target: .\nWriting OVF package: .\/vm4\/vm4.ovf\nDisk progress: 12%\n[...]\nTransfer Completed\nCompleted successfully<\/code><\/pre>\n
Problèmes<\/a><\/h2>\n
# ovftool --noSSLVerify vi:\/\/root@XXX.XXX.XXX.XXX:443\/dir2\/vm4\nEnter login information for source vi:\/\/XXX.XXX.XXX.XXX\/\nUsername: root\nPassword: ***************\nError: Fault cause: vim.fault.FileNotFound<\/code><\/pre>\n
\n
Importer une VM sur Proxmox VE<\/a><\/h1>\n
qm<\/code><\/a>.<\/p>\n
qm importovf <id> path\/to\/file.ovf <proxmox_storage><\/code><\/pre>\n
--format <qcow2 | raw | vmdk><\/code> pour utiliser un format d’image disque spécifique lors de l’import.\nÀ noter que cela n’aura aucun effet si on importe dans un stockage ZFS car ce dernier...<\/span><\/p>","summary":"Compte-rendu de mon exp\u00e9rience de migration de machines virtuelles depuis VMware ESXi vers Proxmox VE, et solutions \u00e0 quelques probl\u00e8mes.","tags":["virtualisation","linux"]},{"title":"Installation d'une image ISO sur serveur d\u00e9di\u00e9 OVH \/ SoYouStart","date_published":"2021-07-24T14:10:00+02:00","id":"https:\/\/nicolas.busseneau.fr\/fr\/blog\/2021\/07\/ovh-soyoustart-install-iso-image","url":"https:\/\/nicolas.busseneau.fr\/fr\/blog\/2021\/07\/ovh-soyoustart-install-iso-image","content_html":"
\n
Activer le mode rescue<\/a><\/h1>\n
\n
# ssh root@XXX.XXX.XXX.XXX<\/code><\/pre>\n
\n
# uname -a\nLinux rescue.ovh.net 4.19.84-mod-std-ipv6-64-rescue #1387440 SMP Fri Aug 21 12:01:09 UTC 2020 x86_64 GNU\/Linux\n# lsb_release -a\nNo LSB modules are available.\nDistributor ID: Debian\nDescription: Debian GNU\/Linux 8.9 (jessie)\nRelease: 8.9\nCodename: jessie<\/code><\/pre>\n
Effacer les disques<\/a><\/h1>\n
\n
# lsblk\n# cat \/proc\/mdstat<\/code><\/pre>\n
\n
md0 : active raid1 sda2[0] sdb2[1]<\/code>), démonter le RAID et l’arrêter :<\/li>\n<\/ul>\n
# umount \/dev\/md0\n# mdadm --stop \/dev\/md0<\/code><\/pre>\n
umount: \/dev\/md0: target is busy<\/code> ou
mdadm: Cannot get exclusive access to \/dev\/md0:Perhaps a running process, mounted filesystem or active volume group?<\/code>, vérifier les volume groups<\/em> via
vgdisplay<\/code> et
\/dev\/mapper\/<\/code>, puis les détruire avec
dmsetup remove vg-name<\/code> si nécessaire.<\/span><\/p>\n
\n
1M * 10<\/code> devrait être suffisant):<\/li>\n<\/ul>\n
# dd if=\/dev\/zero of=\/dev\/sda bs=1M count=10\n# dd if=\/dev\/zero of=\/dev\/sdb bs=1M count=10<\/code><\/pre>\n
Démarrer l’ISO via QEMU KVM<\/a><\/h1>\n
\n
# wget http:\/\/download.proxmox.com\/iso\/proxmox-ve_7.0-1.iso\n# sha256sum proxmox-ve_7.0-1.iso<\/code><\/pre>\n
\n
# apt-get update\n# apt-get install qemu...<\/code><\/pre>","summary":"Utilisation de QEMU KVM pour d\u00e9marrer une image ISO sur serveur d\u00e9di\u00e9 OVH \/ SoYouStart \/ Kimsufi et installer les disques via VNC.","tags":["h\u00e9bergement","linux"],"image":"\/user\/pages\/01.blog\/2021\/07\/ovh-soyoustart-install-iso-image\/01_tightvnc.png"},{"title":"Git : gestion de branches \u00ab sans synchro \u00bb pour *forks* contributifs","date_published":"2021-05-15T23:34:00+02:00","id":"https:\/\/nicolas.busseneau.fr\/fr\/blog\/2021\/05\/branch-management-in-git-forks","url":"https:\/\/nicolas.busseneau.fr\/fr\/blog\/2021\/05\/branch-management-in-git-forks","content_html":"
Observation<\/a><\/h1>\n
\n
Contexte<\/a><\/h1>\n
Mise en place de la remote<\/em>
upstream<\/code><\/a><\/h2>\n
origin<\/code> pointant vers le dépôt source est enregistrée dans le dépôt local.\nIci, je clone un fork<\/em> personnel de cilium\/cilium<\/a> :<\/p>\n
$ git clone git@github.com:nbusseneau\/cilium.git\nCloning into 'cilium'...\n[...]\n$ cd cilium\n$ git remote -v\norigin git@github.com:nbusseneau\/cilium.git (fetch)\norigin git@github.com:nbusseneau\/cilium.git (push)<\/code><\/pre>\n
origin<\/code> :<\/p>\n
$ git branch -vv\n* master 1070b19ab [origin\/master] Add missing Demo App reference<\/code><\/pre>\n
$ git switch v1.10\nBranch 'v1.10' set up to track remote branch 'v1.10' from 'origin'.\nSwitched to a new branch 'v1.10'\n$ git branch -vv\n master 1070b19ab [origin\/master] Add missing Demo App reference\n* v1.10 75b4ed957 [origin\/v1.10] build(deps): bump docker\/setup-buildx-action<\/code><\/pre>\n
git switch<\/code> plutôt que
git checkout<\/code>, mais les deux sont interchangeables<\/a>.<\/span><\/p>\n
upstream<\/code> :<\/p>\n
$ git remote add upstream git@github.com:cilium\/cilium.git\n$ git remote -v\norigin git@github.com:nbusseneau\/cilium.git (fetch)\norigin git@github.com:nbusseneau\/cilium.git (push)\nupstream git@github.com:cilium\/cilium.git (fetch)\nupstream git@github.com:cilium\/cilium.git (push)<\/code><\/pre>\n
$ git fetch upstream\n[...]\nFrom github.com:cilium\/cilium\n * [new branch] master -> upstream\/master\n * [new branch] v1.9 -> upstream\/v1.9\n * [new branch] v1.10...<\/code><\/pre>","summary":"Astuces pour la gestion de branches avec de multiples d\u00e9p\u00f4ts distants, notamment depuis les forks contributifs.","tags":["git","gitlab","github"]},{"title":"Remplacement des pads thermiques sur ASUS TUF RTX 3080","date_published":"2021-05-02T16:12:00+02:00","id":"https:\/\/nicolas.busseneau.fr\/fr\/blog\/2021\/05\/asus-tuf-rtx-3080-thermal-pads-replacement","url":"https:\/\/nicolas.busseneau.fr\/fr\/blog\/2021\/05\/asus-tuf-rtx-3080-thermal-pads-replacement","content_html":"