[Libguestfs] [common PATCH] mltools: add run_in_guest_command helper
Richard W.M. Jones
rjones at redhat.com
Mon May 4 15:25:16 UTC 2020
On Mon, May 04, 2020 at 03:22:37PM +0200, Pino Toscano wrote:
> Add an helper function to run a command in the guest, checking for the
> host/guest compatibility. This is mostly extracted from the internal
> do_run helper currently in the Customize_run module of virt-customize.
> ---
> mltools/tools_utils.ml | 50 +++++++++++++++++++++++++++++++++++++++++
> mltools/tools_utils.mli | 10 +++++++++
> 2 files changed, 60 insertions(+)
>
> diff --git a/mltools/tools_utils.ml b/mltools/tools_utils.ml
> index 1271802..d54ec58 100644
> --- a/mltools/tools_utils.ml
> +++ b/mltools/tools_utils.ml
> @@ -679,3 +679,53 @@ let with_timeout op timeout ?(sleep = 2) fn =
> loop ()
> in
> loop ()
> +
> +let run_in_guest_command g root ?logfile ?incompatible_fn cmd =
> + (* Is the host_cpu compatible with the guest arch? ie. Can we
> + * run commands in this guest?
> + *)
> + let guest_arch = g#inspect_get_arch root in
> + let guest_arch_compatible = guest_arch_compatible guest_arch in
> + if not guest_arch_compatible then (
> + match incompatible_fn with
> + | None -> ()
> + | Some fn -> fn ()
> + )
> + else (
> + (* Add a prologue to the scripts:
> + * - Pass environment variables through from the host.
> + * - Optionally send stdout and stderr to a log file so we capture
> + * all output in error messages.
> + * - Use setarch when running x86_64 host + i686 guest.
> + *)
> + let env_vars =
> + List.filter_map (
> + fun name ->
> + try Some (sprintf "export %s=%s" name (quote (Sys.getenv name)))
> + with Not_found -> None
> + ) [ "http_proxy"; "https_proxy"; "ftp_proxy"; "no_proxy" ] in
> + let env_vars = String.concat "\n" env_vars ^ "\n" in
> +
> + let cmd =
> + match Guestfs_config.host_cpu, guest_arch with
> + | "x86_64", ("i386"|"i486"|"i586"|"i686") ->
> + sprintf "setarch i686 <<\"__EOCMD\"
> +%s
> +__EOCMD
> +" cmd
> + | _ -> cmd in
> +
> + let logfile_redirect =
> + match logfile with
> + | None -> ""
> + | Some logfile -> sprintf "exec >>%s 2>&1" (quote logfile) in
> +
> + let cmd = sprintf "\
> +%s
> +%s
> +%s
> +" (logfile_redirect) env_vars cmd in
> +
> + debug "running command:\n%s" cmd;
> + ignore (g#sh cmd)
> + )
> diff --git a/mltools/tools_utils.mli b/mltools/tools_utils.mli
> index ab70f58..102abff 100644
> --- a/mltools/tools_utils.mli
> +++ b/mltools/tools_utils.mli
> @@ -212,3 +212,13 @@ val with_timeout : string -> int -> ?sleep:int -> (unit -> 'a option) -> 'a
> calls {!error} and the program exits. The error message will
> contain the diagnostic string [op] to identify the operation
> which timed out. *)
> +
> +val run_in_guest_command : Guestfs.guestfs -> string -> ?logfile:string -> ?incompatible_fn:(unit -> unit) -> string -> unit
> +(** [run_in_guest_command g root ?incompatible_archs_fn cmd]
> + runs a command in the guest, which is already mounted for the
> + specified [root]. The command is run directly in case the
> + architecture of the host and the guest are compatible, optionally
> + calling [?incompatible_fn] in case they are not.
> +
> + [?logfile] is an optional file in the guest to where redirect
> + stdout and stderr of the command. *)
Pretty much a straightforward copy of the virt-sysprep function.
ACK.
Thanks,
Rich.
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
virt-builder quickly builds VMs from scratch
http://libguestfs.org/virt-builder.1.html
More information about the Libguestfs
mailing list