diff options
author | CoprDistGit <infra@openeuler.org> | 2024-08-06 02:26:06 +0000 |
---|---|---|
committer | CoprDistGit <infra@openeuler.org> | 2024-08-06 02:26:06 +0000 |
commit | 5957157a0edfe9f07583bdb7530b172da2d7adfd (patch) | |
tree | 3bbe9ee8b02c4b84782d71167ed57549c008ce92 /0022-generator-Add-chown-option-for-virt-customize.patch | |
parent | 568b42b6ea0df8c498b6d8583c24caf101a47dd8 (diff) |
automatic import of libguestfsopeneuler24.03_LTS
Diffstat (limited to '0022-generator-Add-chown-option-for-virt-customize.patch')
-rw-r--r-- | 0022-generator-Add-chown-option-for-virt-customize.patch | 398 |
1 files changed, 398 insertions, 0 deletions
diff --git a/0022-generator-Add-chown-option-for-virt-customize.patch b/0022-generator-Add-chown-option-for-virt-customize.patch new file mode 100644 index 0000000..df841df --- /dev/null +++ b/0022-generator-Add-chown-option-for-virt-customize.patch @@ -0,0 +1,398 @@ +From 64c1716c4120e8dc69d0106b6ebcf6ccb9d4fc24 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" <rjones@redhat.com> +Date: Thu, 29 Jun 2023 13:33:04 +0100 +Subject: [PATCH] generator: Add --chown option for virt-customize + +Also this updates the common submodule to include the changes. + +Fixes: https://github.com/rwmjones/guestfs-tools/issues/12 +Acked-by: Laszlo Ersek <lersek@redhat.com> +(cherry picked from commit d8e48bff212f9b0558480ffedf8158157360d0d5) +--- + common | 2 +- + generator/customize.ml | 28 ++++++++++++++++++++++++++++ + 2 files changed, 29 insertions(+), 1 deletion(-) + +Submodule common d61cd820..bbb54714: +diff --git a/common/mlcustomize/customize-options.pod b/common/mlcustomize/customize-options.pod +index 22a96e04..22724600 100644 +--- a/common/mlcustomize/customize-options.pod ++++ b/common/mlcustomize/customize-options.pod +@@ -63,6 +63,30 @@ Change the permissions of C<FILE> to C<PERMISSIONS>. + I<Note>: C<PERMISSIONS> by default would be decimal, unless you prefix + it with C<0> to get octal, ie. use C<0700> not C<700>. + ++=item B<--chown> UID.GID:PATH ++ ++Change the owner user and group ID of a file or directory in the guest. ++Note: ++ ++=over 4 ++ ++=item * ++ ++Only numeric UIDs and GIDs will work, and these may not be the same ++inside the guest as on the host. ++ ++=item * ++ ++This will not work with Windows guests. ++ ++=back ++ ++For example: ++ ++ virt-customize --chown '0.0:/var/log/audit.log' ++ ++See also: I<--upload>. ++ + =item B<--commands-from-file> FILENAME + + Read the customize commands from a file, one (and its arguments) +diff --git a/common/mlcustomize/customize-synopsis.pod b/common/mlcustomize/customize-synopsis.pod +index d04f421e..e20b12d4 100644 +--- a/common/mlcustomize/customize-synopsis.pod ++++ b/common/mlcustomize/customize-synopsis.pod +@@ -1,15 +1,15 @@ + [--append-line FILE:LINE] [--chmod PERMISSIONS:FILE] +- [--commands-from-file FILENAME] [--copy SOURCE:DEST] +- [--copy-in LOCALPATH:REMOTEDIR] [--delete PATH] [--edit FILE:EXPR] +- [--firstboot SCRIPT] [--firstboot-command 'CMD+ARGS'] +- [--firstboot-install PKG,PKG..] [--hostname HOSTNAME] +- [--inject-qemu-ga METHOD] [--inject-virtio-win METHOD] +- [--install PKG,PKG..] [--link TARGET:LINK[:LINK..]] [--mkdir DIR] +- [--move SOURCE:DEST] [--password USER:SELECTOR] +- [--root-password SELECTOR] [--run SCRIPT] +- [--run-command 'CMD+ARGS'] [--scrub FILE] [--sm-attach SELECTOR] +- [--sm-register] [--sm-remove] [--sm-unregister] +- [--ssh-inject USER[:SELECTOR]] [--truncate FILE] ++ [--chown UID.GID:PATH] [--commands-from-file FILENAME] ++ [--copy SOURCE:DEST] [--copy-in LOCALPATH:REMOTEDIR] ++ [--delete PATH] [--edit FILE:EXPR] [--firstboot SCRIPT] ++ [--firstboot-command 'CMD+ARGS'] [--firstboot-install PKG,PKG..] ++ [--hostname HOSTNAME] [--inject-qemu-ga METHOD] ++ [--inject-virtio-win METHOD] [--install PKG,PKG..] ++ [--link TARGET:LINK[:LINK..]] [--mkdir DIR] [--move SOURCE:DEST] ++ [--password USER:SELECTOR] [--root-password SELECTOR] ++ [--run SCRIPT] [--run-command 'CMD+ARGS'] [--scrub FILE] ++ [--sm-attach SELECTOR] [--sm-register] [--sm-remove] ++ [--sm-unregister] [--ssh-inject USER[:SELECTOR]] [--truncate FILE] + [--truncate-recursive PATH] [--timezone TIMEZONE] [--touch FILE] + [--uninstall PKG,PKG..] [--update] [--upload FILE:DEST] + [--write FILE:CONTENT] [--no-logfile] +diff --git a/common/mlcustomize/customize_cmdline.ml b/common/mlcustomize/customize_cmdline.ml +index 3c24315d..fd3074ad 100644 +--- a/common/mlcustomize/customize_cmdline.ml ++++ b/common/mlcustomize/customize_cmdline.ml +@@ -41,6 +41,8 @@ and op = [ + (* --append-line FILE:LINE *) + | `Chmod of string * string + (* --chmod PERMISSIONS:FILE *) ++ | `Chown of string * string ++ (* --chown UID.GID:PATH *) + | `CommandsFromFile of string + (* --commands-from-file FILENAME *) + | `Copy of string * string +@@ -187,6 +189,17 @@ let rec argspec () = + s_"Change the permissions of a file" + ), + Some "PERMISSIONS:FILE", "Change the permissions of C<FILE> to C<PERMISSIONS>.\n\nI<Note>: C<PERMISSIONS> by default would be decimal, unless you prefix\nit with C<0> to get octal, ie. use C<0700> not C<700>."; ++ ( ++ [ L"chown" ], ++ Getopt.String ( ++ s_"UID.GID:PATH", ++ fun s -> ++ let p = split_string_pair "chown" s in ++ List.push_front (`Chown p) ops ++ ), ++ s_"Change the owner user and group ID of a file or directory" ++ ), ++ Some "UID.GID:PATH", "Change the owner user and group ID of a file or directory in the guest.\nNote:\n\n=over 4\n\n=item *\n\nOnly numeric UIDs and GIDs will work, and these may not be the same\ninside the guest as on the host.\n\n=item *\n\nThis will not work with Windows guests.\n\n=back\n\nFor example:\n\n virt-customize --chown '0.0:/var/log/audit.log'\n\nSee also: I<--upload>."; + ( + [ L"commands-from-file" ], + Getopt.String ( +diff --git a/common/mlcustomize/customize_cmdline.mli b/common/mlcustomize/customize_cmdline.mli +index 0cc166e6..5883bbe0 100644 +--- a/common/mlcustomize/customize_cmdline.mli ++++ b/common/mlcustomize/customize_cmdline.mli +@@ -33,6 +33,8 @@ and op = [ + (* --append-line FILE:LINE *) + | `Chmod of string * string + (* --chmod PERMISSIONS:FILE *) ++ | `Chown of string * string ++ (* --chown UID.GID:PATH *) + | `CommandsFromFile of string + (* --commands-from-file FILENAME *) + | `Copy of string * string +diff --git a/common/mltools/curl.ml b/common/mltools/curl.ml +index 6dba9753..73eed903 100644 +--- a/common/mltools/curl.ml ++++ b/common/mltools/curl.ml +@@ -20,11 +20,13 @@ open Printf + + open Std_utils + open Tools_utils ++open Common_gettext.Gettext + + type t = { + curl : string; + args : args; + tmpdir : string option; ++ url : string; + } + and args = (string * string option) list + +@@ -40,11 +42,17 @@ let args_of_proxy = function + | SystemProxy -> [] + | ForcedProxy url -> [ "proxy", Some url; "noproxy", Some "" ] + +-let create ?(curl = "curl") ?(proxy = SystemProxy) ?tmpdir args = ++let create ?(curl = "curl") ?(proxy = SystemProxy) ?tmpdir args url = ++ (* The ["url"] key must not appear in [args]. This was how the ++ * previous version of this module worked, so lets check there ++ * are no callers still doing this. ++ *) ++ List.iter (function "url", _ -> assert false | _ -> ()) args; ++ + let args = safe_args @ args_of_proxy proxy @ args in +- { curl = curl; args = args; tmpdir = tmpdir } ++ { curl; args; tmpdir; url } + +-let run { curl; args; tmpdir } = ++let run { curl; args; tmpdir; url } = + let config_file, chan = Filename.open_temp_file ?temp_dir:tmpdir + "guestfscurl" ".conf" in + List.iter ( +@@ -67,15 +75,16 @@ let run { curl; args; tmpdir } = + | c -> output_char chan c + done; + fprintf chan "\"\n" +- ) args; ++ ) (("url", Some url) :: args); + close_out chan; + + let cmd = sprintf "%s -q --config %s" (quote curl) (quote config_file) in +- let lines = external_command ~echo_cmd:false cmd in ++ let help = sprintf (f_"downloading %s") url in ++ let lines = external_command ~echo_cmd:false ~help cmd in + Unix.unlink config_file; + lines + +-let to_string { curl; args } = ++let to_string { curl; args; url } = + let b = Buffer.create 128 in + bprintf b "%s -q" (quote curl); + List.iter ( +@@ -85,7 +94,7 @@ let to_string { curl; args } = + | "user", Some _ -> bprintf b " --user <hidden>" + | name, Some value -> bprintf b " --%s %s" name (quote value) + ) args; +- bprintf b "\n"; ++ bprintf b " %s\n" (quote url); + Buffer.contents b + + let print chan t = output_string chan (to_string t) +diff --git a/common/mltools/curl.mli b/common/mltools/curl.mli +index a3e98dc6..1606a79a 100644 +--- a/common/mltools/curl.mli ++++ b/common/mltools/curl.mli +@@ -27,13 +27,16 @@ type proxy = + | SystemProxy (** Use the system settings. *) + | ForcedProxy of string (** The proxy is forced to the specified URL. *) + +-val create : ?curl:string -> ?proxy:proxy -> ?tmpdir:string -> args -> t ++val create : ?curl:string -> ?proxy:proxy -> ?tmpdir:string -> args -> string ++ -> t + (** Create a curl command handle. + + The curl arguments are a list of key, value pairs corresponding + to curl command line parameters, without leading dashes, + eg. [("user", Some "user:password")]. + ++ The string parameter is the URL (which is required). ++ + The optional [?curl] parameter controls the name of the curl + binary (default ["curl"]). + +diff --git a/common/mltools/tools_utils.ml b/common/mltools/tools_utils.ml +index 8b611e77..23f16c51 100644 +--- a/common/mltools/tools_utils.ml ++++ b/common/mltools/tools_utils.ml +@@ -435,8 +435,12 @@ let create_standard_options argspec ?anon_fun ?(key_opts = false) + let getopt = Getopt.create argspec ?anon_fun usage_msg in + { getopt; ks; debug_gc } + ++let external_command_failed help cmd reason = ++ let help_prefix = match help with None -> "" | Some str -> str ^ ": " in ++ error "%s%s ‘%s’: %s" help_prefix (s_"external command") cmd reason ++ + (* Run an external command, slurp up the output as a list of lines. *) +-let external_command ?(echo_cmd = true) cmd = ++let external_command ?(echo_cmd = true) ?help cmd = + if echo_cmd then + debug "%s" cmd; + let chan = Unix.open_process_in cmd in +@@ -448,15 +452,18 @@ let external_command ?(echo_cmd = true) cmd = + (match stat with + | Unix.WEXITED 0 -> () + | Unix.WEXITED i -> +- error (f_"external command ‘%s’ exited with error %d") cmd i ++ let reason = sprintf (f_"exited with error %d") i in ++ external_command_failed help cmd reason + | Unix.WSIGNALED i -> +- error (f_"external command ‘%s’ killed by signal %d") cmd i ++ let reason = sprintf (f_"killed by signal %d") i in ++ external_command_failed help cmd reason + | Unix.WSTOPPED i -> +- error (f_"external command ‘%s’ stopped by signal %d") cmd i ++ let reason = sprintf (f_"stopped by signal %d") i in ++ external_command_failed help cmd reason + ); + lines + +-let rec run_commands ?(echo_cmd = true) cmds = ++let rec run_commands ?(echo_cmd = true) ?help cmds = + let res = Array.make (List.length cmds) 0 in + let pids = + List.mapi ( +@@ -482,21 +489,21 @@ let rec run_commands ?(echo_cmd = true) cmds = + let matching_pair = List.hd matching_pair in + let idx, _, app, outfd, errfd = matching_pair in + pids := new_pids; +- res.(idx) <- do_teardown app outfd errfd stat ++ res.(idx) <- do_teardown help app outfd errfd stat + ); + done; + Array.to_list res + +-and run_command ?(echo_cmd = true) ?stdout_fd ?stderr_fd args = ++and run_command ?(echo_cmd = true) ?help ?stdout_fd ?stderr_fd args = + let run_res = do_run args ~echo_cmd ?stdout_fd ?stderr_fd in + match run_res with + | Either (pid, app, outfd, errfd) -> + let _, stat = Unix.waitpid [] pid in +- do_teardown app outfd errfd stat ++ do_teardown help app outfd errfd stat + | Or code -> + code + +-and do_run ?(echo_cmd = true) ?stdout_fd ?stderr_fd args = ++and do_run ?(echo_cmd = true) ?help ?stdout_fd ?stderr_fd args = + let app = List.hd args in + let get_fd default = function + | None -> +@@ -522,16 +529,18 @@ and do_run ?(echo_cmd = true) ?stdout_fd ?stderr_fd args = + debug "%s: %s: executable not found" app fn; + Or 127 + +-and do_teardown app outfd errfd exitstat = ++and do_teardown help app outfd errfd exitstat = + Option.iter Unix.close outfd; + Option.iter Unix.close errfd; + match exitstat with + | Unix.WEXITED i -> +- i ++ i + | Unix.WSIGNALED i -> +- error (f_"external command ‘%s’ killed by signal %d") app i ++ let reason = sprintf (f_"killed by signal %d") i in ++ external_command_failed help app reason + | Unix.WSTOPPED i -> +- error (f_"external command ‘%s’ stopped by signal %d") app i ++ let reason = sprintf (f_"stopped by signal %d") i in ++ external_command_failed help app reason + + let shell_command ?(echo_cmd = true) cmd = + if echo_cmd then +diff --git a/common/mltools/tools_utils.mli b/common/mltools/tools_utils.mli +index ec900e63..193ba7b6 100644 +--- a/common/mltools/tools_utils.mli ++++ b/common/mltools/tools_utils.mli +@@ -103,13 +103,17 @@ val create_standard_options : Getopt.speclist -> ?anon_fun:Getopt.anon_fun -> ?k + + Returns a new {!cmdline_options} structure. *) + +-val external_command : ?echo_cmd:bool -> string -> string list ++val external_command : ?echo_cmd:bool -> ?help:string -> string -> string list + (** Run an external command, slurp up the output as a list of lines. + + [echo_cmd] specifies whether to output the full command on verbose +- mode, and it's on by default. *) ++ mode, and it's on by default. + +-val run_commands : ?echo_cmd:bool -> (string list * Unix.file_descr option * Unix.file_descr option) list -> int list ++ [help] is an optional string which is printed as a prefix in ++ case the external command fails, eg as a hint to the user about ++ what we were trying to do. *) ++ ++val run_commands : ?echo_cmd:bool -> ?help:string -> (string list * Unix.file_descr option * Unix.file_descr option) list -> int list + (** Run external commands in parallel without using a shell, + and return a list with their exit codes. + +@@ -126,16 +130,24 @@ val run_commands : ?echo_cmd:bool -> (string list * Unix.file_descr option * Uni + end of the execution of the command for which it was specified. + + [echo_cmd] specifies whether output the full command on verbose +- mode, and it's on by default. *) ++ mode, and it's on by default. + +-val run_command : ?echo_cmd:bool -> ?stdout_fd:Unix.file_descr -> ?stderr_fd:Unix.file_descr -> string list -> int ++ [help] is an optional string which is printed as a prefix in ++ case the external command fails, eg as a hint to the user about ++ what we were trying to do. *) ++ ++val run_command : ?echo_cmd:bool -> ?help:string -> ?stdout_fd:Unix.file_descr -> ?stderr_fd:Unix.file_descr -> string list -> int + (** Run an external command without using a shell, and return its exit code. + + If [stdout_fd] or [stderr_fd] is specified, the file descriptor + is automatically closed after executing the command. + + [echo_cmd] specifies whether output the full command on verbose +- mode, and it's on by default. *) ++ mode, and it's on by default. ++ ++ [help] is an optional string which is printed as a prefix in ++ case the external command fails, eg as a hint to the user about ++ what we were trying to do. *) + + val shell_command : ?echo_cmd:bool -> string -> int + (** Run an external shell command, and return its exit code. +diff --git a/generator/customize.ml b/generator/customize.ml +index aa7ac8e8..8d3dec3e 100644 +--- a/generator/customize.ml ++++ b/generator/customize.ml +@@ -95,6 +95,34 @@ I<Note>: C<PERMISSIONS> by default would be decimal, unless you prefix + it with C<0> to get octal, ie. use C<0700> not C<700>."; + }; + ++ { op_name = "chown"; ++ op_type = StringPair "UID.GID:PATH"; ++ op_discrim = "`Chown"; ++ op_shortdesc = "Change the owner user and group ID of a file or directory"; ++ op_pod_longdesc = "\ ++Change the owner user and group ID of a file or directory in the guest. ++Note: ++ ++=over 4 ++ ++=item * ++ ++Only numeric UIDs and GIDs will work, and these may not be the same ++inside the guest as on the host. ++ ++=item * ++ ++This will not work with Windows guests. ++ ++=back ++ ++For example: ++ ++ virt-customize --chown '0.0:/var/log/audit.log' ++ ++See also: I<--upload>."; ++ }; ++ + { op_name = "commands-from-file"; + op_type = StringFn ("FILENAME", "customize_read_from_file"); + op_discrim = "`CommandsFromFile"; |