[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