[Libguestfs] [supermin PATCH 2/5] rpm: fix version comparison

Pino Toscano ptoscano at redhat.com
Fri Apr 12 10:56:48 UTC 2019


When comparing two RPMs, also the epoch, and the release must be taken
into account.  Hence, add a new helper to get the EVR string of a
package, and use it when sorting each list of installed packages.

The mapping is done to avoid recreating the EVR strings at every
comparison.
---
 src/ph_rpm.ml | 29 ++++++++++++++++++++++++++---
 1 file changed, 26 insertions(+), 3 deletions(-)

diff --git a/src/ph_rpm.ml b/src/ph_rpm.ml
index 6769e7b..a8bcf7c 100644
--- a/src/ph_rpm.ml
+++ b/src/ph_rpm.ml
@@ -136,21 +136,44 @@ let rpm_of_pkg, pkg_of_rpm = get_memo_functions ()
 (* Memo of rpm_package_of_string. *)
 let rpmh = Hashtbl.create 13
 
+let rpm_to_evr_string rpm =
+  (* In RPM < 4.11 query commands that use the epoch number in the
+   * package name did not work.
+   *
+   * For example:
+   * RHEL 6 (rpm 4.8.0):
+   *   $ rpm -q tar-2:1.23-11.el6.x86_64
+   *   package tar-2:1.23-11.el6.x86_64 is not installed
+   * Fedora 20 (rpm 4.11.2):
+   *   $ rpm -q tar-2:1.26-30.fc20.x86_64
+   *   tar-1.26-30.fc20.x86_64
+   *
+   *)
+  let is_rpm_lt_4_11 =
+    !rpm_major < 4 || (!rpm_major = 4 && !rpm_minor < 11) in
+
+  if is_rpm_lt_4_11 || rpm.epoch = 0 then
+    sprintf "%s-%s" rpm.version rpm.release
+  else
+    sprintf "%d:%s-%s"
+      rpm.epoch rpm.version rpm.release
+
 let rpm_package_of_string str =
   let query rpm =
     let rpms = Array.to_list (rpm_installed (get_rpm ()) rpm) in
+    let rpms = List.map (fun rpm -> (rpm, rpm_to_evr_string rpm)) rpms in
     (* RPM will return multiple hits when either multiple versions or
      * multiple arches are installed at the same time.  We are only
      * interested in the highest version with the best
      * architecture.
      *)
-    let cmp pkg1 pkg2 =
-      let i = rpm_vercmp pkg2.version pkg1.version in
+    let cmp (pkg1, evr1) (pkg2, evr2) =
+      let i = rpm_vercmp evr2 evr2 in
       if i <> 0 then i
       else compare_architecture pkg2.arch pkg1.arch
     in
     let rpms = List.sort cmp rpms in
-    List.hd rpms
+    fst (List.hd rpms)
   in
 
   try
-- 
2.20.1




More information about the Libguestfs mailing list