Matthew Booth
2010-Feb-12 14:22 UTC
[Libguestfs] [PATCH] GuestOS: Fix _is_installed to return 0 if the package isn't installed
_is_installed was only checking if an existing package was newer than the target. If the package wasn't installed at all it was returning an error. --- lib/Sys/VirtV2V/GuestOS/RedHat.pm | 29 +++++++++++++++++++++++++++-- 1 files changed, 27 insertions(+), 2 deletions(-) diff --git a/lib/Sys/VirtV2V/GuestOS/RedHat.pm b/lib/Sys/VirtV2V/GuestOS/RedHat.pm index 9561338..8410ca2 100644 --- a/lib/Sys/VirtV2V/GuestOS/RedHat.pm +++ b/lib/Sys/VirtV2V/GuestOS/RedHat.pm @@ -710,8 +710,33 @@ sub _is_installed # Search installed rpms matching <name>.<arch> my $found = 0; - foreach my $installed ($g->command_lines(['rpm', '-q', '--qf', - '%{EPOCH} %{VERSION} %{RELEASE}', "$name.$arch"])) { + + my $rpmcmd = ['rpm', '-q', '--qf', '%{EPOCH} %{VERSION} %{RELEASE}\n', + "$name.$arch"]; + my @output; + eval { + @output = $g->command_lines($rpmcmd); + }; + + if ($@) { + # RPM command returned non-zero. This might be because there was + # actually an error, or might just be because the package isn't + # installed. + # Unfortunately, rpm sent its error to stdout instead of stderr, and + # command_lines only gives us stderr in $@. To get round this we'll + # execute the command again, sending all output to stdout and ignoring + # failure. If the output contains 'not installed', we'll assume it's not + # a real error. + my $error = $g->sh(join(' ', @$rpmcmd).' 2>&1 ||:'); + + return 0 if ($error =~ /not installed/); + + die(user_message(__x("Error running {command}: {error}", + command => join(' ', @$rpmcmd), + error => $error))); + } + + foreach my $installed (@output) { $installed =~ /^(\S+)\s+(\S+)\s+(\S+)$/ or die("Unexpected return from rpm command: $installed"); my ($iepoch, $iversion, $irelease) = ($1, $2, $3); -- 1.6.6
Richard W.M. Jones
2010-Feb-12 14:42 UTC
[Libguestfs] [PATCH] GuestOS: Fix _is_installed to return 0 if the package isn't installed
On Fri, Feb 12, 2010 at 02:22:43PM +0000, Matthew Booth wrote:> + my $error = $g->sh(join(' ', @$rpmcmd).' 2>&1 ||:');Do we need more quoting here?> + return 0 if ($error =~ /not installed/);I guess this works because LANG=C in the appliance. If we ever enabled locales in the appliance it might break though. It could therefore be a good idea to add LANG=C to the beginning of the shell command above. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones virt-top is 'top' for virtual machines. Tiny program with many powerful monitoring features, net stats, disk stats, logging, etc. http://et.redhat.com/~rjones/virt-top
Apparently Analagous Threads
- [PATCH] Config: Change config to lookup dependencies by name
- [PATCH] Move all interaction with the config file into Sys::VirtV2V::Config
- [PATCH] GuestOS: Reload augeas after rpm installation and removal
- [PATCH] GuestOS: Fix error when checking for rpm which isn't installed
- [PATCH] GuestOS: Delete blkid.tab if it's present