X-Git-Url: http://git.annexia.org/?p=libguestfs.git;a=blobdiff_plain;f=inspector%2Fvirt-inspector;h=7f9d220e4cef75ec98092619574a012355f21cab;hp=a53c76a91b894ce9ce04e666f62987d7fd345c2e;hb=a0f85ba643990da25b6afe6a2bbd2407cf312c73;hpb=237627df37b97c18362755f646bbe1c4b05ee692 diff --git a/inspector/virt-inspector b/inspector/virt-inspector index a53c76a..7f9d220 100755 --- a/inspector/virt-inspector +++ b/inspector/virt-inspector @@ -146,6 +146,42 @@ if (@roots == 0) { prog => basename ($0)); } +=head1 XML FORMAT + +The virt-inspector XML is described precisely in a RELAX NG schema +which is supplied with libguestfs. This section is just an overview. + +The top-level element is EoperatingsystemsE, and it contains +one or more EoperatingsystemE elements. You would only see +more than one EoperatingsystemE element if the virtual machine +is multi-boot, which is vanishingly rare in real world VMs. + +=head2 EoperatingsystemE + +In the EoperatingsystemE tag are various optional fields that +describe the operating system, its architecture, the descriptive +"product name" string, the type of OS and so on, as in this example: + + + + /dev/sda2 + windows + i386 + windows + Windows 7 Enterprise + 6 + 1 + /Windows + +These fields are derived from the libguestfs inspection API, and +you can find more details in L. + +The ErootE element is the root filesystem device, but from the +point of view of libguestfs (block devices may have completely +different names inside the VM itself). + +=cut + # Start the XML output. my $xml = new XML::Writer (DATA_MODE => 1, DATA_INDENT => 2); @@ -201,6 +237,27 @@ foreach $root (@roots) { $xml->endTag ("operatingsystems"); $xml->end (); +=head2 EmountpointsE + +Un*x-like guests typically have multiple filesystems which are mounted +at various mountpoints, and these are described in the +EmountpointsE element which looks like this: + + + + ... + + / + /boot + + +As with ErootE, devices are from the point of view of +libguestfs, and may have completely different names inside the guest. +Only mountable filesystems appear in this list, not things like swap +devices. + +=cut + sub output_mountpoints { local $_; @@ -216,6 +273,30 @@ sub output_mountpoints $xml->endTag ("mountpoints"); } +=head2 EfilesystemsE + +EfilesystemsE is like EmountpointsE but covers I +filesystems belonging to the guest, including swap and empty +partitions. (In the rare case of a multi-boot guest, it covers +filesystems belonging to this OS or shared by this OS and other OSes). + +You might see something like this: + + + + ... + + + ext4 + + e6a4db1e-15c2-477b-ac2a-699181c396aa + + +The optional elements within EfilesystemE are the filesystem +type, the label, and the UUID. + +=cut + sub output_filesystems { local $_; @@ -252,6 +333,38 @@ sub output_filesystems $xml->endTag ("filesystems"); } +=head2 EapplicationsE + +The related elements Epackage_formatE, +Epackage_managementE and EapplicationsE describe +applications installed in the virtual machine. At the moment we are +only able to list RPMs and Debian packages installed, but in future we +will support other Linux distros and Windows. + +Epackage_formatE, if present, describes the packaging +system used. Typical values would be C and C. + +Epackage_managementE, if present, describes the package +manager. Typical values include C, C and C + +EapplicationsE lists the packages or applications +installed. + + + + ... + + + coreutils + 8.5 + 1 + + +(The version and release fields may not be available for +some package types). + +=cut + sub output_applications { local $_; @@ -264,7 +377,7 @@ sub output_applications my ($package_format, $package_management); if (defined $distro) { if ($distro eq "debian") { - $package_format = "dpkg"; + $package_format = "deb"; $package_management = "apt"; } elsif ($distro eq "fedora") { @@ -293,7 +406,9 @@ sub output_applications if ($package_format eq "rpm") { output_applications_rpm ($root); } - # else no we don't. + elsif ($package_format eq "deb") { + output_applications_deb ($root); + } } } @@ -349,6 +464,58 @@ sub output_applications_rpm } } +sub output_applications_deb +{ + local $_; + my $root = shift; + + my @applications; + + eval { + my ($fh, $filename) = tempfile (UNLINK => 1); + my $fddev = "/dev/fd/" . fileno ($fh); + $g->download ("/var/lib/dpkg/status", $fddev); + close $fh or die "close: $!"; + + # Read the file. Each package is separated by a blank line. + open FILE, $filename or die "$filename: $!"; + my ($name, $installed, $version, $release); + while () { + chomp; + if (/^Package: (.*)/) { + $name = $1; + } elsif (/^Status: .*\binstalled\b/) { + $installed = 1; + } elsif (/^Version: (.*?)-(.*)/) { + $version = $1; + $release = $2; + } elsif ($_ eq "") { + if ($installed && + defined $name && defined $version && defined $release) { + push @applications, [ $name, $version, $release ]; + } + $name = undef; + $installed = undef; + $version = undef; + $release = undef; + } + } + close FILE or die "$filename: $!"; + }; + if (!$@ && @applications > 0) { + @applications = sort { $a->[0] cmp $b->[0] } @applications; + $xml->startTag ("applications"); + foreach (@applications) { + $xml->startTag ("application"); + $xml->dataElement (name => $_->[0]); + $xml->dataElement (version => $_->[1]); + $xml->dataElement (release => $_->[2]); + $xml->endTag ("application"); + } + $xml->endTag ("applications"); + } +} + # The reverse of device name translation, see # BLOCK DEVICE NAMING in guestfs(3). sub canonicalize @@ -361,6 +528,25 @@ sub canonicalize $_; } +=head1 USING XPATH + +You can use the XPath query language, and/or the xpath tool, in order +to select parts of the XML. + +For example: + + $ virt-inspector Guest | xpath //filesystems + Found 1 nodes: + -- NODE -- + + + ext4 + [etc] + + $ virt-inspector Guest | \ + xpath "string(//filesystem[@dev='/dev/sda1']/type)" + Query didn't return a nodeset. Value: ext4 + =head1 SHELL QUOTING Libvirt guest names can contain arbitrary characters, some of which @@ -375,6 +561,7 @@ L, L, L, L, +L, L. =head1 AUTHORS