|
|
da373f |
From 9a8246e91ac0fa38d96691dc6025cb8b117f9cb2 Mon Sep 17 00:00:00 2001
|
|
|
3efd08 |
From: Pino Toscano <ptoscano@redhat.com>
|
|
|
3efd08 |
Date: Mon, 4 May 2020 15:14:46 +0200
|
|
|
3efd08 |
Subject: [PATCH] mltools: add run_in_guest_command helper
|
|
|
3efd08 |
|
|
|
3efd08 |
Add an helper function to run a command in the guest, checking for the
|
|
|
3efd08 |
host/guest compatibility. This is mostly extracted from the internal
|
|
|
3efd08 |
do_run helper currently in the Customize_run module of virt-customize.
|
|
|
3efd08 |
|
|
|
3efd08 |
(cherry picked from commit e73eca3b73f7d0a54615c5dc55eadd09dc170035
|
|
|
3efd08 |
in libguestfs-common)
|
|
|
3efd08 |
---
|
|
|
3efd08 |
common/mltools/tools_utils.ml | 50 ++++++++++++++++++++++++++++++++++
|
|
|
3efd08 |
common/mltools/tools_utils.mli | 10 +++++++
|
|
|
3efd08 |
2 files changed, 60 insertions(+)
|
|
|
3efd08 |
|
|
|
3efd08 |
diff --git a/common/mltools/tools_utils.ml b/common/mltools/tools_utils.ml
|
|
|
3efd08 |
index 127180225..d54ec581e 100644
|
|
|
3efd08 |
--- a/common/mltools/tools_utils.ml
|
|
|
3efd08 |
+++ b/common/mltools/tools_utils.ml
|
|
|
3efd08 |
@@ -679,3 +679,53 @@ let with_timeout op timeout ?(sleep = 2) fn =
|
|
|
3efd08 |
loop ()
|
|
|
3efd08 |
in
|
|
|
3efd08 |
loop ()
|
|
|
3efd08 |
+
|
|
|
3efd08 |
+let run_in_guest_command g root ?logfile ?incompatible_fn cmd =
|
|
|
3efd08 |
+ (* Is the host_cpu compatible with the guest arch? ie. Can we
|
|
|
3efd08 |
+ * run commands in this guest?
|
|
|
3efd08 |
+ *)
|
|
|
3efd08 |
+ let guest_arch = g#inspect_get_arch root in
|
|
|
3efd08 |
+ let guest_arch_compatible = guest_arch_compatible guest_arch in
|
|
|
3efd08 |
+ if not guest_arch_compatible then (
|
|
|
3efd08 |
+ match incompatible_fn with
|
|
|
3efd08 |
+ | None -> ()
|
|
|
3efd08 |
+ | Some fn -> fn ()
|
|
|
3efd08 |
+ )
|
|
|
3efd08 |
+ else (
|
|
|
3efd08 |
+ (* Add a prologue to the scripts:
|
|
|
3efd08 |
+ * - Pass environment variables through from the host.
|
|
|
3efd08 |
+ * - Optionally send stdout and stderr to a log file so we capture
|
|
|
3efd08 |
+ * all output in error messages.
|
|
|
3efd08 |
+ * - Use setarch when running x86_64 host + i686 guest.
|
|
|
3efd08 |
+ *)
|
|
|
3efd08 |
+ let env_vars =
|
|
|
3efd08 |
+ List.filter_map (
|
|
|
3efd08 |
+ fun name ->
|
|
|
3efd08 |
+ try Some (sprintf "export %s=%s" name (quote (Sys.getenv name)))
|
|
|
3efd08 |
+ with Not_found -> None
|
|
|
3efd08 |
+ ) [ "http_proxy"; "https_proxy"; "ftp_proxy"; "no_proxy" ] in
|
|
|
3efd08 |
+ let env_vars = String.concat "\n" env_vars ^ "\n" in
|
|
|
3efd08 |
+
|
|
|
3efd08 |
+ let cmd =
|
|
|
3efd08 |
+ match Guestfs_config.host_cpu, guest_arch with
|
|
|
3efd08 |
+ | "x86_64", ("i386"|"i486"|"i586"|"i686") ->
|
|
|
3efd08 |
+ sprintf "setarch i686 <<\"__EOCMD\"
|
|
|
3efd08 |
+%s
|
|
|
3efd08 |
+__EOCMD
|
|
|
3efd08 |
+" cmd
|
|
|
3efd08 |
+ | _ -> cmd in
|
|
|
3efd08 |
+
|
|
|
3efd08 |
+ let logfile_redirect =
|
|
|
3efd08 |
+ match logfile with
|
|
|
3efd08 |
+ | None -> ""
|
|
|
3efd08 |
+ | Some logfile -> sprintf "exec >>%s 2>&1" (quote logfile) in
|
|
|
3efd08 |
+
|
|
|
3efd08 |
+ let cmd = sprintf "\
|
|
|
3efd08 |
+%s
|
|
|
3efd08 |
+%s
|
|
|
3efd08 |
+%s
|
|
|
3efd08 |
+" (logfile_redirect) env_vars cmd in
|
|
|
3efd08 |
+
|
|
|
3efd08 |
+ debug "running command:\n%s" cmd;
|
|
|
3efd08 |
+ ignore (g#sh cmd)
|
|
|
3efd08 |
+ )
|
|
|
3efd08 |
diff --git a/common/mltools/tools_utils.mli b/common/mltools/tools_utils.mli
|
|
|
3efd08 |
index ab70f583e..102abff4d 100644
|
|
|
3efd08 |
--- a/common/mltools/tools_utils.mli
|
|
|
3efd08 |
+++ b/common/mltools/tools_utils.mli
|
|
|
3efd08 |
@@ -212,3 +212,13 @@ val with_timeout : string -> int -> ?sleep:int -> (unit -> 'a option) -> 'a
|
|
|
3efd08 |
calls {!error} and the program exits. The error message will
|
|
|
3efd08 |
contain the diagnostic string [op] to identify the operation
|
|
|
3efd08 |
which timed out. *)
|
|
|
3efd08 |
+
|
|
|
3efd08 |
+val run_in_guest_command : Guestfs.guestfs -> string -> ?logfile:string -> ?incompatible_fn:(unit -> unit) -> string -> unit
|
|
|
3efd08 |
+(** [run_in_guest_command g root ?incompatible_archs_fn cmd]
|
|
|
3efd08 |
+ runs a command in the guest, which is already mounted for the
|
|
|
3efd08 |
+ specified [root]. The command is run directly in case the
|
|
|
3efd08 |
+ architecture of the host and the guest are compatible, optionally
|
|
|
3efd08 |
+ calling [?incompatible_fn] in case they are not.
|
|
|
3efd08 |
+
|
|
|
3efd08 |
+ [?logfile] is an optional file in the guest to where redirect
|
|
|
3efd08 |
+ stdout and stderr of the command. *)
|
|
|
3efd08 |
--
|
|
|
da373f |
2.18.4
|
|
|
3efd08 |
|