Es geht aber auch wirklich zu einfach: VMs anlegen, Platten klonen, alles mit nur einem Mausklick erledigt. Doch am Ende bleiben oft die Images zurück, mit denen man nur eben etwas ausprobieren wollte. Mit den Libvirt-Tools lassen sich solche Images unter Linux auffinden, allerdings muss man dazu ein kleines bisschen programmieren. Zunächst einmal lassen sich die vorhandenen VMs mit dem Tool "virsh" auflisten, das die Option "--name" bietet, um die Ausgabe so zu formatieren, dass man sie weiterverarbeiten kann:
virsh list --all --name
Dank "--all" werden auch virtuelle Maschinen angezeigt, die gerade nicht laufen. An dieser Stelle endet allerdings auch schon der Komfort der Virt-Tools, denn die Speicher-Images der VM muss man sich schon aus der XML-Konfiguration zusammensuchen. Hierbei hilft das schon in einem ADMIN-Tipp vorgestellte "xmlstarlet" , das es erlaubt, mit XPath-Ausdrücken XML-Attribute aus einer Datei zu extrahieren:
xmlstarlet sel -t -m "//devices/disk/source" -v "@file"
Dieser Ausdruck gibt alle Devices einer VM aus, hängt sie aber nicht einmal durch Leerzeichen getrennt hintereinander. Wie in dem oben referenzierten ADMIN-Tipp beschrieben, muss man hier die "concat"-Funktion mit einem Newline-Zeichen verwenden, um etwas Ordnung in die Ausgabe zu bringen.
Mit diesen Grundelementen kann man über alle VMs und Disks iterieren und das Ergebnis in einem Array speichern, wenn man die Bash-Shell verwendet. Ein zweite Schleife über den Inhalt des Verzeichnisses "/var/lib/libvirt/images" gleicht die vorhandenen Images mit den in den VMs verwendeten Images ab, die in dem Array gespeichert sind.
#!/bin/bash declare -a used_images for vm in $(virsh list --all --name); do for disk in $(virsh dumpxml $vm | xmlstarlet sel -t -m "//devices/disk/source" -v "concat(@file,' ')"); do used_images=("${used_images[@]}" $disk) done done existing_files=(/var/lib/libvirt/images/*) for file in ${existing_files[@]}; do index=0 for key in ${used_images[@]}; do if [ "$file" = "$key" ]; then unset existing_files[$index] break fi let index++ done done echo ${existing_files[@]}
Etwas strukturierter lässt sich die Aufgabe auch mit der Libvirt-Python-API erledigen. Das Ergebnis ist im Github-Repository von ITA-NET zu finden.