[PATCH v2] launch: add support for autodetection of appliance image format
by Pavel Butsykin
This feature allows you to use different image formats for the fixed
appliance. The raw format is used by default.
Signed-off-by: Pavel Butsykin <pbutsykin(a)virtuozzo.com>
---
lib/launch-direct.c | 2 ++
lib/launch-libvirt.c | 19 ++++++++++++-------
m4/guestfs_appliance.m4 | 11 +++++++++++
3 files changed, 25 insertions(+), 7 deletions(-)
diff --git a/lib/launch-direct.c b/lib/launch-direct.c
index 0be662e25..b9b54857a 100644
--- a/lib/launch-direct.c
+++ b/lib/launch-direct.c
@@ -592,7 +592,9 @@ launch_direct (guestfs_h *g, void *datav, const char *arg)
append_list ("id=appliance");
append_list ("cache=unsafe");
append_list ("if=none");
+#ifndef APPLIANCE_FMT_AUTO
append_list ("format=raw");
+#endif
} end_list ();
start_list ("-device") {
append_list ("scsi-hd");
diff --git a/lib/launch-libvirt.c b/lib/launch-libvirt.c
index 4adb2cfb3..030ea6911 100644
--- a/lib/launch-libvirt.c
+++ b/lib/launch-libvirt.c
@@ -212,9 +212,10 @@ get_source_format_or_autodetect (guestfs_h *g, struct drive *drv)
/**
* Create a qcow2 format overlay, with the given C<backing_drive>
- * (file). The C<format> parameter, which must be non-NULL, is the
- * backing file format. This is used to create the appliance overlay,
- * and also for read-only drives.
+ * (file). The C<format> parameter is the backing file format.
+ * The C<format> parameter can be NULL, in this case the backing
+ * format will be determined automatically. This is used to create
+ * the appliance overlay, and also for read-only drives.
*/
static char *
make_qcow2_overlay (guestfs_h *g, const char *backing_drive,
@@ -223,8 +224,6 @@ make_qcow2_overlay (guestfs_h *g, const char *backing_drive,
char *overlay;
struct guestfs_disk_create_argv optargs;
- assert (format != NULL);
-
if (guestfs_int_lazy_make_tmpdir (g) == -1)
return NULL;
@@ -232,8 +231,10 @@ make_qcow2_overlay (guestfs_h *g, const char *backing_drive,
optargs.bitmask = GUESTFS_DISK_CREATE_BACKINGFILE_BITMASK;
optargs.backingfile = backing_drive;
- optargs.bitmask |= GUESTFS_DISK_CREATE_BACKINGFORMAT_BITMASK;
- optargs.backingformat = format;
+ if (format) {
+ optargs.bitmask |= GUESTFS_DISK_CREATE_BACKINGFORMAT_BITMASK;
+ optargs.backingformat = format;
+ }
if (guestfs_disk_create_argv (g, overlay, "qcow2", -1, &optargs) == -1) {
free (overlay);
@@ -461,7 +462,11 @@ launch_libvirt (guestfs_h *g, void *datav, const char *libvirt_uri)
/* Note that appliance can be NULL if using the old-style appliance. */
if (appliance) {
+#ifdef APPLIANCE_FMT_AUTO
+ params.appliance_overlay = make_qcow2_overlay (g, appliance, NULL);
+#else
params.appliance_overlay = make_qcow2_overlay (g, appliance, "raw");
+#endif
if (!params.appliance_overlay)
goto cleanup;
}
diff --git a/m4/guestfs_appliance.m4 b/m4/guestfs_appliance.m4
index 81c43879f..4e1ec8135 100644
--- a/m4/guestfs_appliance.m4
+++ b/m4/guestfs_appliance.m4
@@ -139,3 +139,14 @@ AC_SUBST([GUESTFS_DEFAULT_PATH])
AC_DEFINE_UNQUOTED([GUESTFS_DEFAULT_PATH], ["$GUESTFS_DEFAULT_PATH"],
[Define guestfs default path.])
+
+AC_ARG_ENABLE([appliance-fmt-auto],
+ [AS_HELP_STRING([--enable-appliance-fmt-auto],
+ [enable autodetection of appliance image format @<:@default=no@:>@])],
+ [ENABLE_APPLIANCE_FMT_AUTO="$enableval"],
+ [ENABLE_APPLIANCE_FMT_AUTO=no])
+
+if test "x$ENABLE_APPLIANCE_FMT_AUTO" = "xyes"; then
+ AC_DEFINE([APPLIANCE_FMT_AUTO], [1],
+ [Define to 1 if enabled autodetection of appliance image format.])
+fi
--
2.13.0
4 years, 9 months
1.39 proposal: Let's split up the libguestfs git repo and tarballs
by Richard W.M. Jones
My contention is that the libguestfs git repository is too large and
unwieldy. There are too many separate, unrelated projects and as a
result of that the source has too many dependencies and takes too long
to build and test.
The project divides (sort of) naturally into layers -- the library,
the bindings, the various virt tools -- and could be split along those
lines into separate projects which can then be released and evolve at
their own pace.
My suggested split would be something like this:
* libguestfs: The library, daemon and appliance. That would include
the following directories in a single project:
appliance
bash
contrib
daemon
docs
examples
gnulib
lib
logo
test-tool
tmp
utils
website
* 1 project for each language binding:
csharp
erlang
gobject
golang
haskell
java
lua
ocaml
php
perl
python
ruby
* virt-customize and related tools, we'd probably call this subproject
"virt-builder". It would include virt-builder, virt-customize and
virt-sysprep, since they share a lot of common code.
* 1 project for each of the following items:
small tools written in C
(virt-cat, virt-filesystems, virt-log, virt-ls, virt-tail,
virt-diff, virt-edit, virt-format, guestmount, virt-inspector,
virt-make-fs, virt-rescue)
guestfish
virt-alignment-scan and virt-df
virt-dib
virt-get-kernel
virt-resize
virt-sparsify
virt-v2v and virt-p2v
virt-win-reg
* I'd be inclined to drop the legacy Perl tools virt-tar,
virt-list-filesystems, virt-list-partitions unless someone
especially wished to step forward to maintain them.
* common code and generator: Off to the side we'd somehow need to
package up the common code and the generator for use by all of the
above projects. It wouldn't be a separate project for downstream
packagers, but instead the code would be included (ie. duplicated)
in tarballs and upstream available as a side git repo that you'd
need to include when building (git submodule?). This is somewhat
unspecified.
M4, PO, and tests would be split between the projects as appropriate.
My proposal would be to do this incrementally, rather than all at
once, moving the easier things out first.
Thoughts?
Rich.
--
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
4 years, 11 months
[PATCH nbdkit 0/7] server: Implement NBD_FLAG_CAN_MULTI_CONN.
by Richard W.M. Jones
First thing to say is that I need to do a *lot* more testing on this,
so this is just an early peek. In particular, although it passed
‘make check && make check-valgrind’ I have *not* tested it against a
multi-conn-aware client such as the Linux kernel >= 4.9.
This implements NBD_FLAG_CAN_MULTI_CONN, described in the protocol doc
as:
"NBD_FLAG_CAN_MULTI_CONN: Indicates that the server operates
entirely without cache, or that the cache it uses is shared among
all connections to the given device. In particular, if this flag is
present, then the effects of NBD_CMD_FLUSH and NBD_CMD_FLAG_FUA MUST
be visible across all connections when the server sends its reply to
that command to the client. In the absence of this flag, clients
SHOULD NOT multiplex their commands over more than one connection to
the export."
This is necessary to support the Linux nbd client -C option.
The only plugin which sets the flag so far is file. The ocaml, sh and
nbd plugins allow the flag to be controlled or passed through.
Notable also is that the blocksize filter has to filter out this flag,
because I'm not convinced that the bounce buffer is safe. However I
believe the other filters *are* safe (although not really certain
about the fua filter, and the new cache filter is tricky too).
My feeling is that we should set the flag unconditionally for all
readonly connections, but I can think of nasty corner cases where it
might not work. We should most probably set it in all plugins that
are readonly (eg. nbdkit-pattern-plugin).
Rich.
5 years, 6 months
Fedora 29 guestfish not working
by CHANU ROMAIN
Hello,
I tried to install guestfish on my Fedora 29 and used the commands from
documentation sudo dnf install libguestfs-tools but I got an error when
I tried to execute run. You will find below logs below:
************************************************************
* IMPORTANT NOTICE
*
* When reporting bugs, include the COMPLETE, UNEDITED
* output below in your bug report.
*
************************************************************
PATH=/usr/share/Modules/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/us
r/sbin:/home/romain/bin
XDG_RUNTIME_DIR=/run/user/1000
SELinux: Disabled
guestfs_get_append: (null)
guestfs_get_autosync: 1
guestfs_get_backend: libvirt
guestfs_get_backend_settings: []
guestfs_get_cachedir: /var/tmp
guestfs_get_hv: /usr/bin/qemu-kvm
guestfs_get_memsize: 500
guestfs_get_network: 0
guestfs_get_path: /usr/lib64/guestfs
guestfs_get_pgroup: 0
guestfs_get_program: libguestfs-test-tool
guestfs_get_recovery_proc: 1
guestfs_get_smp: 1
guestfs_get_sockdir: /run/user/1000
guestfs_get_tmpdir: /tmp
guestfs_get_trace: 0
guestfs_get_verbose: 1
host_cpu: x86_64
Launching appliance, timeout set to 600 seconds.
libguestfs: launch: program=libguestfs-test-tool
libguestfs: launch: version=1.39.11fedora=29,release=1.fc29,libvirt
libguestfs: launch: backend registered: unix
libguestfs: launch: backend registered: uml
libguestfs: launch: backend registered: libvirt
libguestfs: launch: backend registered: direct
libguestfs: launch: backend=libvirt
libguestfs: launch: tmpdir=/tmp/libguestfsH1Xvb3
libguestfs: launch: umask=0022
libguestfs: launch: euid=1000
libguestfs: libvirt version = 4007000 (4.7.0)
libguestfs: guest random name = guestfs-rakt1mfrsshbuiqs
libguestfs: connect to libvirt
libguestfs: opening libvirt handle: URI = qemu:///session, auth =
default+wrapper, flags = 0
libguestfs: successfully opened libvirt handle: conn = 0x55f938843730
libguestfs: qemu version (reported by libvirt) = 3000000 (3.0.0)
libguestfs: get libvirt capabilities
libguestfs: parsing capabilities XML
libguestfs: build appliance
libguestfs: begin building supermin appliance
libguestfs: run supermin
libguestfs: command: run: /usr/bin/supermin
libguestfs: command: run: \ --build
libguestfs: command: run: \ --verbose
libguestfs: command: run: \ --if-newer
libguestfs: command: run: \ --lock /var/tmp/.guestfs-1000/lock
libguestfs: command: run: \ --copy-kernel
libguestfs: command: run: \ -f ext2
libguestfs: command: run: \ --host-cpu x86_64
libguestfs: command: run: \ /usr/lib64/guestfs/supermin.d
libguestfs: command: run: \ -o /var/tmp/.guestfs-1000/appliance.d
supermin: version: 5.1.19
supermin: rpm: detected RPM version 4.14
supermin: package handler: fedora/rpm
supermin: acquiring lock on /var/tmp/.guestfs-1000/lock
supermin: build: /usr/lib64/guestfs/supermin.d
supermin: reading the supermin appliance
supermin: build: visiting /usr/lib64/guestfs/supermin.d/base.tar.gz
type gzip base image (tar)
supermin: build: visiting /usr/lib64/guestfs/supermin.d/daemon.tar.gz
type gzip base image (tar)
supermin: build: visiting /usr/lib64/guestfs/supermin.d/excludefiles
type uncompressed excludefiles
supermin: build: visiting /usr/lib64/guestfs/supermin.d/hostfiles type
uncompressed hostfiles
supermin: build: visiting /usr/lib64/guestfs/supermin.d/init.tar.gz
type gzip base image (tar)
supermin: build: visiting /usr/lib64/guestfs/supermin.d/packages type
uncompressed packages
supermin: build: visiting /usr/lib64/guestfs/supermin.d/udev-
rules.tar.gz type gzip base image (tar)
supermin: build: visiting /usr/lib64/guestfs/supermin.d/zz-packages-xfs
type uncompressed packages
supermin: mapping package names to installed packages
supermin: resolving full list of package dependencies
supermin: exception: Librpm.Multiple_matches(2)
libguestfs: error: /usr/bin/supermin exited with error status 1, see
debug messages above
libguestfs: clear_socket_create_context: setsockcreatecon failed: NULL:
Invalid argument [you can ignore this message if you are not using
SELinux + sVirt]
libguestfs: closing guestfs handle 0x55f938840880 (state 0)
libguestfs: command: run: rm
libguestfs: command: run: \ -rf /tmp/libguestfsH1Xvb3
What can I do?
Best regards,
5 years, 9 months
[PATCH 0/2] allow alternative guest tools directories for distributions
by Tomáš Golembiovský
First patch just fixes installing guest tools from directory that was broken.
Second patch revamps how virt-v2v chooses from which directory install guest
tools on Linux. Details in commit message.
Tomáš Golembiovský (2):
v2v: fix path to source when copying files from guest tools directory
v2v: allow alternative directories for distributions
v2v/windows_virtio.ml | 67 +++++++++++++++++++++++++------------------
1 file changed, 39 insertions(+), 28 deletions(-)
--
2.20.1
5 years, 9 months
[PATCH v3] v2v: linux: use NEVR for querying RPM packages (RHBZ#1669395)
by Pino Toscano
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 | 59 +++++++++++++++++++++++++++++++++-------------------
1 file changed, 38 insertions(+), 21 deletions(-)
diff --git a/v2v/linux.ml b/v2v/linux.ml
index 43449157b..99b0e0e7b 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,44 @@ 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 is_rpm_lt_4_11 () =
+ let ver =
+ try
+ let ver = List.find_map (
+ function
+ | { G.app2_name = name; G.app2_version = version }
+ when name = "rpm" -> Some version
+ | _ -> None
+ ) inspect.i_apps in
+ if PCRE.matches re_version ver then
+ (int_of_string (PCRE.sub 1), int_of_string (PCRE.sub 2))
+ else
+ (0, 0)
+ with Not_found ->
+ (* 'rpm' not installed? Hmm... *)
+ (0, 0) in
+ ver < (4, 11)
+ in
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
- else
- sprintf "%ld:%s" app.G.app2_epoch pkg_name
- ) else
- pkg_name in
+ 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
5 years, 9 months
[PATCH nbdkit] xz: Do not pass can_write through to the plugin.
by Richard W.M. Jones
I'm not sure that this fix is really correct.
An alternate way I can think to fix this would be for the core server
to maintain a readonly flag for each layer (instead of just per-
server).
You could also argue that our readonly test in
server/connections.c:compute_eflags is wrong and/or that the
implementations of server/plugins.c:plugin_can_write and
server/filters.c:filter_can_write have the wrong default - they should
consult the readonly flag which was passed to that layer's open call.
However the fix only affects one filter, and we're not maintaining an
API for filters, so maybe we can defer the problem.
Rich.
5 years, 9 months
[PATCH v3 0/7] RFC: switch v2v to ocaml-libvirt
by Pino Toscano
Hi,
this is a mostly done attempt to switch to ocaml-libvirt, embedding the
latest version of it from git. This way, it is possible to improve the
way v2v connects to libvirt for both input, and output modules, and
interacts with libvirt (e.g. no more virsh calls needed in virt-v2v).
As side effect, virt-v2v now requires libvirt, as keeping it optional
would create too much burden.
I could not test all the libvirt input modes (like VDDK, and Xen), but
VMware and libvirtxml work fine as before.
Changes from v2:
- rebase on master
Changes from v1:
- rebase on master
- update ocaml-libvirt from libvirt-ocaml.git on libvirt.org, and adjust
the code to it
- pass again the URI to input_libvirt_vddk, so an error message is
preserved
Pino Toscano (7):
v2v: require libvirt
common: Bundle the libvirt-ocaml library for use by virt-v2v
v2v: switch to ocaml-libvirt
v2v: -o libvirt: use a Lazy for the connection
v2v: -o libvirt: switch away from virsh
v2v: test-harness: stop using the external ocaml-libvirt
build: stop looking for ocaml-libvirt
.gitignore | 2 +
Makefile.am | 5 +-
common/mllibvirt/Makefile.am | 102 ++
common/mllibvirt/generator.pl | 908 +++++++++++++
common/mllibvirt/libvirt.README | 9 +
common/mllibvirt/libvirt.ml | 1661 ++++++++++++++++++++++++
common/mllibvirt/libvirt.mli | 1626 +++++++++++++++++++++++
common/mllibvirt/libvirt_c_epilogue.c | 462 +++++++
common/mllibvirt/libvirt_c_oneoffs.c | 1698 +++++++++++++++++++++++++
common/mllibvirt/libvirt_c_prologue.c | 134 ++
configure.ac | 1 +
docs/C_SOURCE_FILES | 1 -
m4/guestfs-ocaml.m4 | 4 -
po/POTFILES | 1 -
v2v/Makefile.am | 26 +-
v2v/copy_to_local.ml | 7 +-
v2v/dummy.c | 2 +
v2v/input_libvirt.ml | 20 +-
v2v/input_libvirt_other.ml | 27 +-
v2v/input_libvirt_other.mli | 5 +-
v2v/input_libvirt_vcenter_https.ml | 13 +-
v2v/input_libvirt_vcenter_https.mli | 2 +-
v2v/input_libvirt_vddk.ml | 15 +-
v2v/input_libvirt_vddk.mli | 4 +-
v2v/input_libvirt_xen_ssh.ml | 13 +-
v2v/input_libvirt_xen_ssh.mli | 2 +-
v2v/input_libvirtxml.ml | 3 +-
v2v/libvirt_utils-c.c | 539 --------
v2v/libvirt_utils.ml | 95 +-
v2v/libvirt_utils.mli | 51 +-
v2v/output_libvirt.ml | 56 +-
v2v/parse_libvirt_xml.ml | 14 +-
v2v/parse_libvirt_xml.mli | 11 +-
v2v/test-harness/Makefile.am | 5 +-
v2v/v2v.ml | 12 +-
35 files changed, 6838 insertions(+), 698 deletions(-)
create mode 100644 common/mllibvirt/Makefile.am
create mode 100755 common/mllibvirt/generator.pl
create mode 100644 common/mllibvirt/libvirt.README
create mode 100644 common/mllibvirt/libvirt.ml
create mode 100644 common/mllibvirt/libvirt.mli
create mode 100644 common/mllibvirt/libvirt_c_epilogue.c
create mode 100644 common/mllibvirt/libvirt_c_oneoffs.c
create mode 100644 common/mllibvirt/libvirt_c_prologue.c
create mode 100644 v2v/dummy.c
delete mode 100644 v2v/libvirt_utils-c.c
--
2.20.1
5 years, 9 months
[PATCH v2] v2v: linux: use NEVR for querying RPM packages (RHBZ#1669395)
by Pino Toscano
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
5 years, 9 months
[PATCH] v2v: linux: use NEVR for querying RPM packages (RHBZ#1669395)
by Pino Toscano
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 | 52 +++++++++++++++++++++++++++++++---------------------
1 file changed, 31 insertions(+), 21 deletions(-)
diff --git a/v2v/linux.ml b/v2v/linux.ml
index 43449157b..4cf498d29 100644
--- a/v2v/linux.ml
+++ b/v2v/linux.ml
@@ -80,29 +80,39 @@ 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 rpm_major, rpm_minor =
+ let ver = List.find_map (
+ function
+ | { G.app2_name = name; G.app2_version = version }
+ when name = "rpm" -> Some version
+ | _ -> None
+ ) inspect.i_apps in
+ match String.nsplit "." ver with
+ | [major] -> int_of_string major, 0
+ | major :: minor :: _ -> int_of_string major, int_of_string minor
+ | _ -> error (f_"unrecognized RPM version: %s") ver in
+ let is_rpm_lt_4_11 =
+ rpm_major < 4 || (rpm_major = 4 && rpm_minor < 11) in
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
- else
- sprintf "%ld:%s" app.G.app2_epoch pkg_name
- ) else
- pkg_name in
+ if is_rpm_lt_4_11 || app.G.app2_epoch = Int32.zero 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
5 years, 9 months