Comment lire l’adresse MAC d’un conteneur OpenVZ dans Proxmox

Supposons qu’on soit en train d’automatiser la création et la configuration d’un conteneur dans Proxmox, dans lequel il faut configurer une interface réseau virtuelle (veth). On peut avoir besoin de récupérer l’adresse MAC virtuelle de l’interface réseau du conteneur, par exemple pour y créer un fichier ifcfg-eth0 s’il est sous CentOS.

Le script ci-dessous s’exécute sur un noeud Proxmox et permet de lire l’adresse MAC d’une carte réseau virtuelle dans un conteneur OpenVZ. Pour des raisons de simplicité, les vérifications sur la présence des paramètres sont supprimées.

#!/bin/bash

# Le nom du noeud Proxmox à interroger
NODE=$1
# L'id du conteneur OpenVZ, par exemple 101
VMID=$2
# L'interface réseau, par exemple eth0
IFNAME=$3
pvesh get /nodes/${NODE}/openvz/${VMID}/config 2>/dev/null | grep netif | \
	sed -re "s/.*ifname\=${IFNAME}[^;]*\,mac\=(([0-9A-F]{2}:){5}[0-9A-F]{2}).*/\1/"

Maintenant voyons dans le détail ce que fait ce script.

D’abord, il y a la commande

pvesh get /nodes/${NODE}/openvz/${VMID}/config

qui affiche la configuration d’un conteneur sur un noeud Proxmox.

Le résultat ressemble à ceci pour un conteneur qui a une interface réseau eth0.

{
   "cpus" : 1,
   "cpuunits" : 1000,
   "digest" : "c90",
   "disk" : 50,
   "hostname" : "www.domainname.tld",
   "memory" : 1024,
   "nameserver" : "127.0.0.1",
   "netif" : "ifname=eth0,bridge=vmbr0,mac=C6:BD:74:7D:FF:81,host_ifname=veth105.0,host_mac=D2:83:D5:54:01:69",
   "onboot" : 0,
   "ostemplate" : "centos.tar.gz",
   "quotatime" : 0,
   "quotaugidlimit" : 0,
   "searchdomain" : "domainname.tld",
   "storage" : "local",
   "swap" : 512
}

Ou à ceci pour un conteneur qui a deux interfaces réseau eth0 et eth1.

{
   "cpus" : 1,
   "cpuunits" : 1000,
   "digest" : "c90",
   "disk" : 50,
   "hostname" : "www.domainname.tld",
   "memory" : 1024,
   "nameserver" : "127.0.0.1",
   "netif" : "ifname=eth0,bridge=vmbr0,mac=C6:BD:74:7D:FF:81,host_ifname=veth105.0,host_mac=D2:83:D5:54:01:69;ifname=eth1,bridge=vmbr1,mac=92:C5:0C:F2:BE:25,host_ifname=veth100.1,host_mac=4A:99:39:23:FB:CC",
   "onboot" : 0,
   "ostemplate" : "centos.tar.gz",
   "quotatime" : 0,
   "quotaugidlimit" : 0,
   "searchdomain" : "domainname.tld",
   "storage" : "local",
   "swap" : 512
}

La commande grep netif filtre ce texte pour ne retenir que la ligne qui contient les informations sur les interfaces réseau, et enfin la commande sed -re utilise une expression régulière pour extraire dans cette ligne l’adresse MAC recherchée.

Un mot sur l’expression régulière

s/.*ifname\=${IFNAME}[^;]*\,mac\=(([0-9A-F]{2}:){5}[0-9A-F]{2}).*/\1/

Le s qui la commence indique qu’on souhaite faire une substitution. On parcourt la ligne jusqu’à trouver la chaîne ifname=, suivie de notre interface. A partir de là, on saute tous les caractères jusqu’à trouver la chaîne ,mac=, suivie d’une adresse MAC que matche l’expression régulière ([0-9A-F]{2}:){5}[0-9A-F]{2}.

Il y’a deux remarques à faire à ce niveau. D’abord, il faut noter la présence de la virgule dans la chaîne ,mac=, qui est importante pour ne pas récupérer le paramètre host_mac à la place. Ensuite, les caractères qu’on saute entre le ifname= et le ,mac= doivent absolument être différents du point-virgule, car sinon à cause de la règle du longuest prefix match on récupère systématiquement la dernière adresse MAC présente dans la ligne, qui sera la mauvaise s’il y’en a plusieurs. D’où l’usage de l’expression [^;]*.

Pour que la commande sed renvoie uniquement l’adresse MAC, on utilise en plus de la substitution, une référence arrière. On demande à sed de mémoriser l’adresse MAC en mettant son expression régulière entre parenthèses, puis on fait en sorte que la ligne entière matche l’expression régulière en ajoutant un .* en début et en fin. Le /\1/ substitue la chaîne matchée par la première référence trouvée, et renvoie donc uniquement l’adresse MAC de l’interface réseau de notre conteneur.

Voilà.

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s