summaryrefslogtreecommitdiff
path: root/0022-generator-Add-chown-option-for-virt-customize.patch
diff options
context:
space:
mode:
authorCoprDistGit <infra@openeuler.org>2024-08-06 02:26:06 +0000
committerCoprDistGit <infra@openeuler.org>2024-08-06 02:26:06 +0000
commit5957157a0edfe9f07583bdb7530b172da2d7adfd (patch)
tree3bbe9ee8b02c4b84782d71167ed57549c008ce92 /0022-generator-Add-chown-option-for-virt-customize.patch
parent568b42b6ea0df8c498b6d8583c24caf101a47dd8 (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.patch398
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";