# 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);
output_filesystems ($root);
# Package format / management and applications.
- output_applications ($root, $distro, $major_version);
+ output_applications ($root);
$xml->endTag("operatingsystem");
$xml->startTag ("filesystems");
my @fses = $g->inspect_get_filesystems ($root);
+ @fses = sort @fses;
foreach (@fses) {
$xml->startTag ("filesystem",
dev => canonicalize ($_));
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>.
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>
<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 package types).
=cut
{
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.
- }
+ $package_format = $g->inspect_get_package_format ($root);
+ $package_management = $g->inspect_get_package_management ($root);
$xml->dataElement (package_format => $package_format)
- if defined $package_format;
+ if $package_format ne "unknown";
$xml->dataElement (package_management => $package_management)
- if defined $package_management;
+ if $package_management ne "unknown";
# 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.
+ if ($package_format eq "rpm") {
+ output_applications_rpm ($root);
+ }
+ elsif ($package_format eq "deb") {
+ output_applications_deb ($root);
}
}
}
}
+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 (<FILE>) {
+ 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