On Mon, Jan 13, 2014 at 02:39:24PM +0100, Pino Toscano wrote:
Add a new --operation parameter which, similarly to --enable, can be
used to enable operations, but also to remove them, and to add/remove
the default operations and all the available ones.
---
sysprep/main.ml | 36 +++++++++++++++++++++++++++
sysprep/sysprep_operation.ml | 24 ++++++++++++++++++
sysprep/sysprep_operation.mli | 21 ++++++++++++++++
sysprep/virt-sysprep.pod | 57 +++++++++++++++++++++++++++++++++++++------
4 files changed, 131 insertions(+), 7 deletions(-)
diff --git a/sysprep/main.ml b/sysprep/main.ml
index 689a394..49750a9 100644
--- a/sysprep/main.ml
+++ b/sysprep/main.ml
@@ -87,6 +87,40 @@ let debug_gc, operations, g, selinux_relabel, quiet, mount_opts =
exit 1
) Sysprep_operation.empty_set ops in
operations := Some opset
+ and set_operations op_string =
+ let currentopset =
+ match !operations with
+ | Some x -> x
+ | None -> Sysprep_operation.empty_set
+ in
+ let ops = string_nsplit "," op_string in
+ let opset = List.fold_left (
+ fun opset op_name ->
+ let op =
+ if string_prefix op_name "-" then
+ `Remove (String.sub op_name 1 (String.length op_name - 1))
+ else
+ `Add op_name in
+ match op with
+ | `Add "" | `Remove "" ->
+ eprintf (f_"%s: --operations: empty operation name\n")
+ prog;
+ exit 1
+ | `Add "defaults" -> Sysprep_operation.add_defaults_to_set opset
+ | `Remove "defaults" -> Sysprep_operation.remove_defaults_from_set
opset
+ | `Add "all" -> Sysprep_operation.add_all_to_set opset
+ | `Remove "all" -> Sysprep_operation.remove_all_from_set opset
+ | `Add n | `Remove n ->
+ let f = match op with
+ | `Add n -> Sysprep_operation.add_to_set
+ | `Remove n -> Sysprep_operation.remove_from_set in
+ try f n opset with
+ | Not_found ->
+ eprintf (f_"%s: --operations: '%s' is not a known
operation\n")
+ prog n;
+ exit 1
+ ) currentopset ops in
+ operations := Some opset
and force_selinux_relabel () =
selinux_relabel := `Force
and no_force_selinux_relabel () =
@@ -114,6 +148,8 @@ let debug_gc, operations, g, selinux_relabel, quiet, mount_opts =
"--list-operations", Arg.Unit list_operations, " " ^
s_"List supported operations";
"--long-options", Arg.Unit display_long_options, " " ^
s_"List long options";
"--mount-options", Arg.Set_string mount_opts, s_"opts" ^ "
" ^ s_"Set mount options (eg /:noatime;/var:rw,noatime)";
+ "--operation", Arg.String set_operations, " " ^
s_"Enable/disable specific operations";
+ "--operations", Arg.String set_operations, " " ^
s_"Enable/disable specific operations";
"-q", Arg.Set quiet, " " ^ s_"Don't
print log messages";
"--quiet", Arg.Set quiet, " " ^ s_"Don't
print log messages";
"--selinux-relabel", Arg.Unit force_selinux_relabel, " " ^
s_"Force SELinux relabel";
diff --git a/sysprep/sysprep_operation.ml b/sysprep/sysprep_operation.ml
index 1fb4f17..572a65f 100644
--- a/sysprep/sysprep_operation.ml
+++ b/sysprep/sysprep_operation.ml
@@ -68,10 +68,34 @@ type set = OperationSet.t
let empty_set = OperationSet.empty
+let opset_of_oplist li =
+ List.fold_left (
+ fun acc elem ->
+ OperationSet.add elem acc
+ ) empty_set li
+
let add_to_set name set =
let op = List.find (fun { name = n } -> name = n) !all_operations in
OperationSet.add op set
+let add_defaults_to_set set =
+ OperationSet.union set (opset_of_oplist !enabled_by_default_operations)
+
+let add_all_to_set set =
+ opset_of_oplist !all_operations
+
+let remove_from_set name set =
+ let name_filter = fun { name = n } -> name = n in
+ if List.exists name_filter !all_operations <> true then
+ raise Not_found;
+ OperationSet.diff set (OperationSet.filter name_filter set)
+
+let remove_defaults_from_set set =
+ OperationSet.diff set (opset_of_oplist !enabled_by_default_operations)
+
+let remove_all_from_set set =
+ empty_set
+
let register_operation op =
all_operations := op :: !all_operations;
if op.enabled_by_default then
diff --git a/sysprep/sysprep_operation.mli b/sysprep/sysprep_operation.mli
index 16eee64..61dde72 100644
--- a/sysprep/sysprep_operation.mli
+++ b/sysprep/sysprep_operation.mli
@@ -128,6 +128,27 @@ val add_to_set : string -> set -> set
Note that this will raise [Not_found] if [name] is not
a valid operation name. *)
+val add_defaults_to_set : set -> set
+(** [add_defaults_to_set set] adds to [set] all the operations enabled
+ by default. *)
+
+val add_all_to_set : set -> set
+(** [add_all_to_set set] adds to [set] all the available operations. *)
+
+val remove_from_set : string -> set -> set
+(** [remove_from_set name set] remove the operation named [name] from [set].
+
+ Note that this will raise [Not_found] if [name] is not
+ a valid operation name. *)
+
+val remove_defaults_from_set : set -> set
+(** [remove_defaults_from_set set] removes from [set] all the operations
+ enabled by default. *)
+
+val remove_all_from_set : set -> set
+(** [remove_all_from_set set] removes from [set] all the available
+ operations. *)
+
val perform_operations_on_filesystems : ?operations:set -> ?quiet:bool ->
Guestfs.guestfs -> string -> flag list
(** Perform all operations, or the subset listed in the [operations] set. *)
diff --git a/sysprep/virt-sysprep.pod b/sysprep/virt-sysprep.pod
index afabcc9..a042db4 100755
--- a/sysprep/virt-sysprep.pod
+++ b/sysprep/virt-sysprep.pod
@@ -107,6 +107,47 @@ version of virt-sysprep.
See L</OPERATIONS> below for a list and an explanation of each
operation.
+=item B<--operation> operations
+
+=item B<--operations> operations
+
+Choose which sysprep operations to perform. Give a comma-separated
+list of operations, for example:
+
+ --operations ssh-hostkeys,udev-persistent-net
+
+would enable ONLY C<ssh-hostkeys> and C<udev-persistent-net> operations.
+
+I<--operations> allows you to enable and disable any operation, including
+the default ones (which would be tried when specifying neither
+I<--operations> nor I<--enable>) and all the available ones; prepending
+a C<-> in front of an operation name removes it from the list of enabled
+operations, while the meta-names C<defaults> and C<all> represent
+respectively the operations enabled by default and all the available ones.
+For example:
+
+ --operations delete,defaults,-hostname
+
+would enable the C<delete> operation (regardless whether it is enabled by
+default), all the default ones, and disable the C<hostname> operation.
+
+I<--operations> can be specified multiple times; the first time the set
+of enabled operations is empty, while any further I<--operations> affects
+the operations enabled so far.
+
+If the I<--operations> option is not given, then we default to trying most
+sysprep operations (see I<--list-operations> to show which are
+enabled).
+
+Regardless of the I<--operations> option, sysprep operations are skipped
+for some guest types.
+
+Use I<--list-operations> to list operations supported by a particular
+version of virt-sysprep.
+
+See L</OPERATIONS> below for a list and an explanation of each
+operation.
+
=item B<--format> raw|qcow2|..
=item B<--format> auto
@@ -209,24 +250,26 @@ __EXTRA_OPTIONS__
=head1 OPERATIONS
-If the I<--enable> option is I<not> given, then most sysprep
-operations are enabled.
+If the I<--enable>/I<--operations> option is I<not> given,
+then most sysprep operations are enabled.
Use C<virt-sysprep --list-operations> to list all operations for your
virt-sysprep binary. The ones which are enabled by default are marked
-with a C<*> character. Regardless of the I<--enable> option, sysprep
-operations are skipped for some guest types.
+with a C<*> character. Regardless of the I<--enable>/I<--operations>
+options, sysprep operations are skipped for some guest types.
-Operations can be individually enabled using the I<--enable> option.
+Operations can be individually enabled using the
+I<--enable>/I<--operations> options.
Use a comma-separated list, for example:
- virt-sysprep --enable=ssh-hostkeys,udev-persistent-net [etc..]
+ virt-sysprep --operations=ssh-hostkeys,udev-persistent-net [etc..]
Future versions of virt-sysprep may add more operations. If you are
using virt-sysprep and want predictable behaviour, specify only the
operations that you want to have enabled.
-C<*> = enabled by default when no I<--enable> option is given.
+C<*> = enabled by default when no I<--enable>/I<--operations> option
+is given.
ACK.
Rich.
--
Richard Jones, Virtualization Group, Red Hat
http://people.redhat.com/~rjones
virt-df lists disk usage of guests without needing to install any
software inside the virtual machine. Supports Linux and Windows.
http://people.redhat.com/~rjones/virt-df/