fish: Fix memory leak in handling of encrypted volumes by -i option.
[libguestfs.git] / inspector / virt-inspector
index 71a8884..c721b1d 100755 (executable)
@@ -189,6 +189,8 @@ $xml->startTag ("operatingsystems");
 
 my $root;
 foreach $root (@roots) {
+    # Note that output_applications requires the filesystems
+    # to be mounted up.
     my %fses = $g->inspect_get_mountpoints ($root);
     my @fses = sort { length $a <=> length $b } keys %fses;
     foreach (@fses) {
@@ -200,19 +202,23 @@ foreach $root (@roots) {
     # Basic OS fields.
     $xml->dataElement (root => canonicalize ($root));
 
-    my ($s, $distro, $major_version);
+    my $s;
     $s = $g->inspect_get_type ($root);
     $xml->dataElement (name => $s) if $s ne "unknown";
     $s = $g->inspect_get_arch ($root);
     $xml->dataElement (arch => $s) if $s ne "unknown";
-    $distro = $g->inspect_get_distro ($root);
-    $xml->dataElement (distro => $distro) if $distro ne "unknown";
+    $s = $g->inspect_get_distro ($root);
+    $xml->dataElement (distro => $s) if $s ne "unknown";
     $s = $g->inspect_get_product_name ($root);
     $xml->dataElement (product_name => $s) if $s ne "unknown";
-    $major_version = $g->inspect_get_major_version ($root);
-    $xml->dataElement (major_version => $major_version);
+    $s = $g->inspect_get_major_version ($root);
+    $xml->dataElement (major_version => $s);
     $s = $g->inspect_get_minor_version ($root);
     $xml->dataElement (minor_version => $s);
+    $s = $g->inspect_get_package_format ($root);
+    $xml->dataElement (package_format => $s) if $s ne "unknown";
+    $s = $g->inspect_get_package_management ($root);
+    $xml->dataElement (package_management => $s) if $s ne "unknown";
 
     eval {
         $s = $g->inspect_get_windows_systemroot ($root);
@@ -226,7 +232,7 @@ foreach $root (@roots) {
     output_filesystems ($root);
 
     # Package format / management and applications.
-    output_applications ($root, $distro, $major_version);
+    output_applications ($root);
 
     $xml->endTag("operatingsystem");
 
@@ -305,6 +311,7 @@ sub output_filesystems
     $xml->startTag ("filesystems");
 
     my @fses = $g->inspect_get_filesystems ($root);
+    @fses = sort @fses;
     foreach (@fses) {
         $xml->startTag ("filesystem",
                         dev => canonicalize ($_));
@@ -338,8 +345,8 @@ sub output_filesystems
 The related elements E<lt>package_formatE<gt>,
 E<lt>package_managementE<gt> and E<lt>applicationsE<gt> describe
 applications installed in the virtual machine.  At the moment we are
-only able to list RPMs installed, but in future we will support other
-Linux distros and Windows.
+only able to list RPMs and Debian packages installed, but in future we
+will support other Linux distros and Windows.
 
 E<lt>package_formatE<gt>, if present, describes the packaging
 system used.  Typical values would be C<rpm> and C<deb>.
@@ -348,7 +355,7 @@ E<lt>package_managementE<gt>, if present, describes the package
 manager.  Typical values include C<yum>, C<up2date> and C<apt>
 
 E<lt>applicationsE<gt> lists the packages or applications
-installed.  At present this simply lists them by name:
+installed.
 
  <operatingsystems>
    <operatingsystem>
@@ -356,9 +363,13 @@ installed.  At present this simply lists them by name:
      <applications>
        <application>
          <name>coreutils</name>
+         <version>8.5</version>
+         <release>1</release>
        </application>
 
-In future we will also include the version here.
+The version and release fields may not be available for some types
+guests.  Other fields are possible, see
+L<guestfs(3)/guestfs_inspect_list_applications>.
 
 =cut
 
@@ -366,93 +377,34 @@ sub output_applications
 {
     local $_;
     my $root = shift;
-    my $distro = shift;
-    my $major_version = shift;
-
-    # Based on the distro, take a guess at the package format
-    # and package management.
-    my ($package_format, $package_management);
-    if (defined $distro) {
-        if ($distro eq "debian") {
-            $package_format = "deb";
-            $package_management = "apt";
-        }
-        elsif ($distro eq "fedora") {
-            $package_format = "rpm";
-            $package_management = "yum";
-        }
-        elsif ($distro =~ /redhat/ || $distro =~ /rhel/) {
-            if ($major_version >= 5) {
-                $package_format = "rpm";
-                $package_management = "yum";
-            } else {
-                $package_format = "rpm";
-                $package_management = "up2date";
-            }
-        }
-        # else unknown.
-    }
-
-    $xml->dataElement (package_format => $package_format)
-        if defined $package_format;
-    $xml->dataElement (package_management => $package_management)
-        if defined $package_management;
-
-    # Do we know how to get a list of applications?
-    if (defined $package_format) {
-        if ($package_format eq "rpm") {
-            output_applications_rpm ($root);
-        }
-        # else no we don't.
-    }
-}
 
-sub output_applications_rpm
-{
-    local $_;
-    my $root = shift;
-
-    # Previous virt-inspector ran the 'rpm' program from the guest.
-    # This is insecure, and unnecessary because we can get the same
-    # information directly from the RPM database.
-
-    my @applications;
+    my @apps = $g->inspect_list_applications ($root);
 
-    eval {
-        my ($fh, $filename) = tempfile (UNLINK => 1);
-        my $fddev = "/dev/fd/" . fileno ($fh);
-        $g->download ("/var/lib/rpm/Name", $fddev);
-        close $fh or die "close: $!";
-
-        # Read the database with the Berkeley DB dump tool.
-        my $cmd = "db_dump -p '$filename'";
-        open PIPE, "$cmd |" or die "close: $!";
-        while (<PIPE>) {
-            chomp;
-            last if /^HEADER=END$/;
-        }
-        while (<PIPE>) {
-            chomp;
-            last if /^DATA=END$/;
-
-            # First character on each data line is a space.
-            if (length $_ > 0 && substr ($_, 0, 1) eq ' ') {
-                $_ = substr ($_, 1);
-            }
-            # Name should never contain non-printable chars.
-            die "name contains non-printable chars" if /\\/;
-            push @applications, $_;
-
-            $_ = <PIPE>; # discard value
-        }
-        close PIPE or die "close: $!";
-    };
-    if (!$@ && @applications > 0) {
-        @applications = sort @applications;
+    if (@apps) {
         $xml->startTag ("applications");
-        foreach (@applications) {
+        foreach (@apps) {
             $xml->startTag ("application");
-            $xml->dataElement (name => $_);
+            $xml->dataElement (name => $_->{app_name});
+            $xml->dataElement (display_name => $_->{app_display_name})
+                if $_->{app_display_name} ne "";
+            $xml->dataElement (epoch => $_->{app_epoch})
+                if $_->{app_epoch} != 0;
+            $xml->dataElement (version => $_->{app_version})
+                if $_->{app_version} ne "";
+            $xml->dataElement (release => $_->{app_release})
+                if $_->{app_release} ne "";
+            $xml->dataElement (install_path => $_->{app_install_path})
+                if $_->{app_install_path} ne "";
+            $xml->dataElement (publisher => $_->{app_publisher})
+                if $_->{app_publisher} ne "";
+            $xml->dataElement (url => $_->{app_url})
+                if $_->{app_url} ne "";
+            $xml->dataElement (source_package => $_->{app_source_package})
+                if $_->{app_source_package} ne "";
+            $xml->dataElement (summary => $_->{app_summary})
+                if $_->{app_summary} ne "";
+            $xml->dataElement (description => $_->{app_description})
+                if $_->{app_description} ne "";
             $xml->endTag ("application");
         }
         $xml->endTag ("applications");