Pino Toscano
2019-Jan-30 12:28 UTC
[Libguestfs] [PATCH v2] v2v: linux: use NEVR for querying RPM packages (RHBZ#1669395)
Use NEVR when querying RPM for the list of files of a package, instead of ENVR. Also, use the epoch only when non-zero, and version of RPM supports it. The approach is basically copied from what supermin does in its RPM package handler. --- v2v/linux.ml | 55 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/v2v/linux.ml b/v2v/linux.ml index 43449157b..63489c334 100644 --- a/v2v/linux.ml +++ b/v2v/linux.ml @@ -27,6 +27,8 @@ open Utils module G = Guestfs +let re_version = PCRE.compile "(\\d+)\\.(\\d+)" + let augeas_reload g g#aug_load (); debug_augeas_errors g @@ -80,29 +82,40 @@ let file_list_of_package (g : Guestfs.guestfs) inspect app | "rpm" -> (* Since RPM allows multiple packages installed with the same - * name, always check the full ENVR here (RHBZ#1161250). + * name, always check the full NEVR here (RHBZ#1161250). + * + * 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 pkg_name - sprintf "%s-%s-%s" app.G.app2_name - app.G.app2_version app.G.app2_release in - let pkg_name - if app.G.app2_epoch > 0_l then ( - (* RHEL 3/4 'rpm' does not support using the epoch prefix. - * (RHBZ#1170685). - *) - let is_rhel_lt_5 - match inspect with - | { i_type = "linux"; - i_distro = "rhel" | "centos" | "scientificlinux" | - "oraclelinux" | "redhat-based"; - i_major_version = v } when v < 5 -> true - | _ -> false in - if is_rhel_lt_5 then - pkg_name + let is_rpm_lt_4_11 () + let ver = List.find_map ( + function + | { G.app2_name = name; G.app2_version = version } + when name = "rpm" -> Some version + | _ -> None + ) inspect.i_apps in + let ver + if PCRE.matches re_version ver then + (int_of_string (PCRE.sub 1), int_of_string (PCRE.sub 2)) else - sprintf "%ld:%s" app.G.app2_epoch pkg_name - ) else - pkg_name in + (0, 0) in + ver < (4, 11) + in + let pkg_name + if app.G.app2_epoch = Int32.zero || is_rpm_lt_4_11 () then + sprintf "%s-%s-%s" app.G.app2_name app.G.app2_version + app.G.app2_release + else + sprintf "%s-%ld:%s-%s" app.G.app2_name app.G.app2_epoch + app.G.app2_version app.G.app2_release in let cmd = [| "rpm"; "-ql"; pkg_name |] in debug "%s" (String.concat " " (Array.to_list cmd)); let files = g#command_lines cmd in -- 2.20.1
Richard W.M. Jones
2019-Jan-30 14:40 UTC
Re: [Libguestfs] [PATCH v2] v2v: linux: use NEVR for querying RPM packages (RHBZ#1669395)
On Wed, Jan 30, 2019 at 01:28:51PM +0100, Pino Toscano wrote:> Use NEVR when querying RPM for the list of files of a package, instead > of ENVR. Also, use the epoch only when non-zero, and version of RPM > supports it. > > The approach is basically copied from what supermin does in its RPM > package handler. > --- > v2v/linux.ml | 55 ++++++++++++++++++++++++++++++++-------------------- > 1 file changed, 34 insertions(+), 21 deletions(-) > > diff --git a/v2v/linux.ml b/v2v/linux.ml > index 43449157b..63489c334 100644 > --- a/v2v/linux.ml > +++ b/v2v/linux.ml > @@ -27,6 +27,8 @@ open Utils > > module G = Guestfs > > +let re_version = PCRE.compile "(\\d+)\\.(\\d+)" > + > let augeas_reload g > g#aug_load (); > debug_augeas_errors g > @@ -80,29 +82,40 @@ let file_list_of_package (g : Guestfs.guestfs) inspect app > > | "rpm" -> > (* Since RPM allows multiple packages installed with the same > - * name, always check the full ENVR here (RHBZ#1161250). > + * name, always check the full NEVR here (RHBZ#1161250). > + * > + * 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 pkg_name > - sprintf "%s-%s-%s" app.G.app2_name > - app.G.app2_version app.G.app2_release in > - let pkg_name > - if app.G.app2_epoch > 0_l then ( > - (* RHEL 3/4 'rpm' does not support using the epoch prefix. > - * (RHBZ#1170685). > - *) > - let is_rhel_lt_5 > - match inspect with > - | { i_type = "linux"; > - i_distro = "rhel" | "centos" | "scientificlinux" | > - "oraclelinux" | "redhat-based"; > - i_major_version = v } when v < 5 -> true > - | _ -> false in > - if is_rhel_lt_5 then > - pkg_name > + let is_rpm_lt_4_11 () > + let ver = List.find_map ( > + function > + | { G.app2_name = name; G.app2_version = version } > + when name = "rpm" -> Some version > + | _ -> None > + ) inspect.i_apps inI really think we should catch the Not_found case. I know that an RPM-based guest should have an rpm package - that's obvious - but we have to deal with all kinds of weirdness, and Not_found exceptions are an absolute pain to track down when they happen. The patch is fine with the addition of a suitable try/catch around this function call. Rich.> + let ver > + if PCRE.matches re_version ver then > + (int_of_string (PCRE.sub 1), int_of_string (PCRE.sub 2)) > else > - sprintf "%ld:%s" app.G.app2_epoch pkg_name > - ) else > - pkg_name in > + (0, 0) in > + ver < (4, 11) > + in > + let pkg_name > + if app.G.app2_epoch = Int32.zero || is_rpm_lt_4_11 () then > + sprintf "%s-%s-%s" app.G.app2_name app.G.app2_version > + app.G.app2_release > + else > + sprintf "%s-%ld:%s-%s" app.G.app2_name app.G.app2_epoch > + app.G.app2_version app.G.app2_release in > let cmd = [| "rpm"; "-ql"; pkg_name |] in > debug "%s" (String.concat " " (Array.to_list cmd)); > let files = g#command_lines cmd in > -- > 2.20.1 > > _______________________________________________ > Libguestfs mailing list > Libguestfs@redhat.com > https://www.redhat.com/mailman/listinfo/libguestfs-- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com libguestfs lets you edit virtual machines. Supports shell scripting, bindings from many languages. http://libguestfs.org
Apparently Analagous Threads
- [PATCH v3] v2v: linux: use NEVR for querying RPM packages (RHBZ#1669395)
- [PATCH] v2v: linux: use NEVR for querying RPM packages (RHBZ#1669395)
- Re: [PATCH] v2v: linux: use NEVR for querying RPM packages (RHBZ#1669395)
- [PATCH] v2v: Fix kernel disambiguation by dropping Epoch field (RHBZ#1669395).
- [PATCH v2 0/3] New inspect_list_applications2 API