On Tuesday, 9 August 2016 13:55:36 CEST Tomáš Golembiovský wrote:
On Mon, 8 Aug 2016 18:38:49 +0200
Pino Toscano <ptoscano(a)redhat.com> wrote:
> Implement the 'remove', 'file_list_of_package', and
'file_owner' methods
> of the Linux module for the "deb" package manager (dpkg basically, on
> Debian and derived distributions).
>
> Also allow it for the main conversion code.
> ---
> v2v/convert_linux.ml | 2 +-
> v2v/linux.ml | 23 +++++++++++++++++++++++
> 2 files changed, 24 insertions(+), 1 deletion(-)
>
> diff --git a/v2v/convert_linux.ml b/v2v/convert_linux.ml
> index 4b1ce99..65796d6 100644
> --- a/v2v/convert_linux.ml
> +++ b/v2v/convert_linux.ml
> @@ -79,7 +79,7 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect
source rcaps =
> | "sles" | "suse-based" | "opensuse" ->
`SUSE_family
> | _ -> assert false in
>
> - assert (inspect.i_package_format = "rpm");
> + assert (inspect.i_package_format = "rpm" || inspect.i_package_format =
"deb");
>
> (* We use Augeas for inspection and conversion, so initialize it early. *)
> Linux.augeas_init g;
> diff --git a/v2v/linux.ml b/v2v/linux.ml
> index ed639c1..5713f64 100644
> --- a/v2v/linux.ml
> +++ b/v2v/linux.ml
> @@ -48,6 +48,10 @@ and do_remove g inspect packages =
> assert (List.length packages > 0);
> let package_format = inspect.i_package_format in
> match package_format with
> + | "deb" ->
> + let cmd = [ "dpkg"; "--purge" ] @ packages in
> + let cmd = Array.of_list cmd in
> + ignore (g#command cmd);
> | "rpm" ->
> let cmd = [ "rpm"; "-e" ] @ packages in
> let cmd = Array.of_list cmd in
> @@ -61,6 +65,12 @@ let file_list_of_package (g : Guestfs.guestfs) inspect app =
> let package_format = inspect.i_package_format in
>
> match package_format with
> + | "deb" ->
> + let cmd = [| "dpkg"; "-L"; app.G.app2_name |] in
> + debug "%s" (String.concat " " (Array.to_list cmd));
> + let files = g#command_lines cmd in
> + let files = Array.to_list files in
> + List.sort compare files
> | "rpm" ->
> (* Since RPM allows multiple packages installed with the same
> * name, always check the full ENVR here (RHBZ#1161250).
> @@ -98,6 +108,19 @@ let file_list_of_package (g : Guestfs.guestfs) inspect app =
> let rec file_owner (g : G.guestfs) inspect path =
> let package_format = inspect.i_package_format in
> match package_format with
> + | "deb" ->
> + let cmd = [| "dpkg"; "-S"; path |] in
> + debug "%s" (String.concat " " (Array.to_list cmd));
> + let lines =
> + try g#command_lines cmd
This is not good. dpkg-query command behaves differently from rpm.
AFAIR, dpkg doesn't allow a file to be owned by different packages
(and even if it does, it will complain hard when the file is not exactly
the same in all the packages).
This is not what happens with directories, which can be owned by every
package (and indeed usually every debian package owns all the
directories, / included, that contain the shipped files).
There could be also multiarch to take into account, but that's something
that could be dealt with later.
First, the returned packages are all on one line separated by
commas.
What I came up with is this:
let cmd = [| "dpkg-query"; "-S"; path |] in
debug "%s" (String.concat " " (Array.to_list cmd));
(try
let pkg = g#command cmd in
(* What we get is a string of form "pkg1, pkg2:arch, pkg3: /path" *)
let len = String.length pkg in
let rec loop i =
if i >= len then
(* This is fishy. Internal bug? *)
error (f_"internal error: file_owner: failed to process string
'%s'") pkg
else if pkg.[i] = ' ' &&
(pkg.[i-1] = ':' || pkg.[i-1] = ',') then
String.sub pkg 0 (i-1)
else loop (i+1)
in loop 1
with Guestfs.Error msg as exn ->
if String.find msg "no path found matching pattern" >= 0 then
raise Not_found
else
raise exn
)
The other concern is, whether we should escape the argument somehow. The
fact is that dpkg-query accepts a glob expression, not just a simple
path. If you provide it with a pattern you will get all the matching
paths, each on a single line (prefixed by the package list).
rpm seems to accept glob expression too -- OTOH we seem to provide only
package names to Linux.remove calls (which were read from the package
manager itself).
--
Pino Toscano