[Libguestfs] [PATCH V2] sysprep: remove user accounts

Richard W.M. Jones rjones at redhat.com
Sun Apr 22 14:53:04 UTC 2012


On Sun, Apr 22, 2012 at 09:21:02PM +0800, Wanlong Gao wrote:
> Remove user accounts from /etc/passwd, /etc/group,
> /etc/shadow, and the home directory of the user,
> except the root user.

I wrote a small patch last night to implement the 'enabled_by_default'
feature.  See the attachment.  If applied, it would require minor
changes to your new operation.

Rich.

> Signed-off-by: Wanlong Gao <gaowanlong at cn.fujitsu.com>
> ---
>  sysprep/Makefile.am                       |    2 +
>  sysprep/sysprep_operation_user_account.ml |   71 +++++++++++++++++++++++++++++
>  2 files changed, 73 insertions(+)
>  create mode 100644 sysprep/sysprep_operation_user_account.ml
> 
> diff --git a/sysprep/Makefile.am b/sysprep/Makefile.am
> index f51fc07..9b06804 100644
> --- a/sysprep/Makefile.am
> +++ b/sysprep/Makefile.am
> @@ -48,6 +48,7 @@ SOURCES = \
>  	sysprep_operation_ssh_hostkeys.ml \
>  	sysprep_operation_ssh_userdir.ml \
>  	sysprep_operation_udev_persistent_net.ml \
> +	sysprep_operation_user_account.ml \
>  	sysprep_operation_utmp.ml \
>  	sysprep_operation_yum_uuid.ml \
>  	utils.ml
> @@ -73,6 +74,7 @@ OBJECTS = \
>  	sysprep_operation_ssh_hostkeys.cmx \
>  	sysprep_operation_ssh_userdir.cmx \
>  	sysprep_operation_udev_persistent_net.cmx \
> +	sysprep_operation_user_account.ml \
>  	sysprep_operation_utmp.cmx \
>  	sysprep_operation_yum_uuid.cmx \
>  	main.cmx
> diff --git a/sysprep/sysprep_operation_user_account.ml b/sysprep/sysprep_operation_user_account.ml
> new file mode 100644
> index 0000000..45c05d7
> --- /dev/null
> +++ b/sysprep/sysprep_operation_user_account.ml
> @@ -0,0 +1,71 @@
> +(* virt-sysprep
> + * Copyright (C) 2012 FUJITSU LIMITED
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License along
> + * with this program; if not, write to the Free Software Foundation, Inc.,
> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + *)
> +
> +open Sysprep_operation
> +open Utils
> +
> +module G = Guestfs
> +
> +let user_account_perform g root =
> +  let typ = g#inspect_get_type root in
> +  if typ <> "windows" then (
> +    g#aug_init "/" 0;
> +    let uid_min = g#aug_get "/files/etc/login.defs/UID_MIN" in
> +    let uid_max = g#aug_get "/files/etc/login.defs/UID_MAX" in
> +    let users = Array.to_list (g#aug_ls "/files/etc/passwd") in
> +    List.iter (
> +      fun user ->
> +        let uid = user ^ "/uid" in
> +        let uid = g#aug_get uid in
> +        if int_of_string uid >= int_of_string uid_min then (
> +          if int_of_string uid <= int_of_string uid_max then (
> +            let user' = Array.of_list (string_split "/" user) in
> +            let user = user'.(4) in
> +            let user_prefix = user ^ ":" in
> +            let filenames = [ "/etc/passwd";
> +                          "/etc/shadow";
> +                          "/etc/group" ] in
> +            List.iter (
> +              fun filename ->
> +                let lines = Array.to_list (g#read_lines filename) in
> +                let lines = List.filter (
> +                  fun line -> not (string_prefix line user_prefix)
> +                ) lines in
> +                let file = String.concat "\n" lines ^ "\n" in
> +                g#write filename file
> +            ) filenames;
> +            g#rm_rf ("/home/" ^ user);
> +          )
> +        )
> +    ) users;
> +    []
> +  )
> +  else []
> +
> +let user_account_op = {
> +  name = "user-account";
> +  pod_description = "\
> +Remove the user accounts except \"root\" in the guest.
> +
> +Remove the user accounts and their home directory except
> +the \"root\" account.";
> +  extra_args = [];
> +  perform = user_account_perform;
> +}
> +
> +let () = register_operation user_account_op
> -- 
> 1.7.10

-- 
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
libguestfs lets you edit virtual machines.  Supports shell scripting,
bindings from many languages.  http://libguestfs.org
-------------- next part --------------
From 8d41470b6fc81b742896996393812b274514bca2 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones at redhat.com>
Date: Sat, 21 Apr 2012 22:27:39 +0100
Subject: [PATCH] sysprep: Don't enable every option by default.

All current operations are enabled by default.

Also:

* The POD description is split into a heading and the description body.

* An 'enabled_by_default' flag is added to the structure.
---
 sysprep/sysprep_operation.ml                     |   70 +++++++++++++++-------
 sysprep/sysprep_operation.mli                    |   11 +++-
 sysprep/sysprep_operation_bash_history.ml        |    6 +-
 sysprep/sysprep_operation_cron_spool.ml          |    4 +-
 sysprep/sysprep_operation_dhcp_client_state.ml   |    4 +-
 sysprep/sysprep_operation_dhcp_server_state.ml   |    4 +-
 sysprep/sysprep_operation_hostname.ml            |    8 ++-
 sysprep/sysprep_operation_logfiles.ml            |    9 ++-
 sysprep/sysprep_operation_mail_spool.ml          |    4 +-
 sysprep/sysprep_operation_net_hwaddr.ml          |    8 ++-
 sysprep/sysprep_operation_random_seed.ml         |    4 +-
 sysprep/sysprep_operation_rhn_systemid.ml        |    4 +-
 sysprep/sysprep_operation_script.ml              |    4 +-
 sysprep/sysprep_operation_smolt_uuid.ml          |    4 +-
 sysprep/sysprep_operation_ssh_hostkeys.ml        |    6 +-
 sysprep/sysprep_operation_ssh_userdir.ml         |    6 +-
 sysprep/sysprep_operation_udev_persistent_net.ml |    4 +-
 sysprep/sysprep_operation_utmp.ml                |    6 +-
 sysprep/sysprep_operation_yum_uuid.ml            |    6 +-
 sysprep/virt-sysprep.pod                         |   40 ++++++++++---
 20 files changed, 148 insertions(+), 64 deletions(-)

diff --git a/sysprep/sysprep_operation.ml b/sysprep/sysprep_operation.ml
index b48d8f8..d3a12fe 100644
--- a/sysprep/sysprep_operation.ml
+++ b/sysprep/sysprep_operation.ml
@@ -24,12 +24,15 @@ type flag = [ `Created_files ]
 
 type operation = {
   name : string;
-  pod_description : string;
+  enabled_by_default : bool;
+  heading : string;
+  pod_description : string option;
   extra_args : ((Arg.key * Arg.spec * Arg.doc) * string) list;
   perform : Guestfs.guestfs -> string -> flag list;
 }
 
-let ops = ref []
+let all_operations = ref []
+let enabled_by_default_operations = ref []
 
 module OperationSet = Set.Make (
   struct
@@ -42,17 +45,21 @@ type set = OperationSet.t
 let empty_set = OperationSet.empty
 
 let add_to_set name set =
-  let op = List.find (fun { name = n } -> name = n) !ops in
+  let op = List.find (fun { name = n } -> name = n) !all_operations in
   OperationSet.add op set
 
-let register_operation op = ops := op :: !ops
+let register_operation op =
+  all_operations := op :: !all_operations;
+  if op.enabled_by_default then
+    enabled_by_default_operations := op :: !enabled_by_default_operations
 
 let baked = ref false
 let rec bake () =
-  let ops' = List.sort (fun { name = a } { name = b } -> compare a b) !ops in
-  check_no_dupes ops';
-  List.iter check ops';
-  ops := ops';
+  let ops =
+    List.sort (fun { name = a } { name = b } -> compare a b) !all_operations in
+  check_no_dupes ops;
+  List.iter check ops;
+  all_operations := ops;
   baked := true
 and check_no_dupes ops =
   ignore (
@@ -78,14 +85,28 @@ and check op =
       eprintf "virt-sysprep: disallowed character (%c) in operation name\n" c;
       exit 1
   done;
-  let n = String.length op.pod_description in
+  let n = String.length op.heading in
   if n = 0 then (
-    eprintf "virt-sysprep: operation %s has no POD\n" op.name;
+    eprintf "virt-sysprep: operation %s has no heading\n" op.name;
     exit 1
   );
-  if op.pod_description.[n-1] = '\n' then (
-    eprintf "virt-sysprep: POD for %s must not end with newline\n" op.name;
+  if op.heading.[n-1] = '\n' || op.heading.[n-1] = '.' then (
+    eprintf "virt-sysprep: heading for %s must not end with newline or period\n"
+      op.name;
     exit 1
+  );
+  (match op.pod_description with
+  | None -> ()
+  | Some description ->
+    let n = String.length description in
+    if n = 0 then (
+      eprintf "virt-sysprep: operation %s has no POD\n" op.name;
+      exit 1
+    );
+    if description.[n-1] = '\n' then (
+      eprintf "virt-sysprep: POD for %s must not end with newline\n" op.name;
+      exit 1
+    )
   )
 
 let extra_args () =
@@ -94,7 +115,7 @@ let extra_args () =
   List.flatten (
     List.map (fun { extra_args = extra_args } ->
       List.map fst extra_args
-    ) !ops
+    ) !all_operations
   )
 
 (* These internal functions are used to generate the man page. *)
@@ -104,9 +125,14 @@ let dump_pod () =
   List.iter (
     fun op ->
       printf "=head2 B<%s>\n" op.name;
+      if op.enabled_by_default then printf "*\n";
       printf "\n";
-      printf "%s\n\n" op.pod_description
-  ) !ops
+      printf "%s.\n\n" op.heading;
+      (match op.pod_description with
+      | None -> ()
+      | Some description -> printf "%s\n\n" description
+      )
+  ) !all_operations
 
 let dump_pod_options () =
   assert !baked;
@@ -114,7 +140,7 @@ let dump_pod_options () =
   let args = List.map (
     fun { name = op_name; extra_args = extra_args } ->
       List.map (fun ea -> op_name, ea) extra_args
-  ) !ops in
+  ) !all_operations in
   let args = List.flatten args in
   let args = List.map (
     fun (op_name, ((arg_name, spec, _), pod)) ->
@@ -152,17 +178,19 @@ let dump_pod_options () =
 let list_operations () =
   assert !baked;
 
-  (* For compatibility with old shell version, list just the operation
-   * names, sorted.
-   *)
-  List.iter (fun op -> print_endline op.name ) !ops
+  List.iter (
+    fun op ->
+      printf "%s %s %s\n" op.name
+        (if op.enabled_by_default then "*" else " ")
+        op.heading
+  ) !all_operations
 
 let perform_operations ?operations ?(quiet = false) g root =
   assert !baked;
 
   let ops =
     match operations with
-    | None -> !ops (* all operations *)
+    | None -> !enabled_by_default_operations
     | Some opset -> (* just the operation names listed *)
       OperationSet.elements opset in
 
diff --git a/sysprep/sysprep_operation.mli b/sysprep/sysprep_operation.mli
index 0f58510..ab7da93 100644
--- a/sysprep/sysprep_operation.mli
+++ b/sysprep/sysprep_operation.mli
@@ -26,8 +26,15 @@ type operation = {
       line.  Must contain only alphanumeric and '-' (dash)
       character. *)
 
-  pod_description : string;
-  (** POD-format description, used for the man page. *)
+  enabled_by_default : bool;
+  (** If true, then enabled by default when no [--enable] option is
+      given on the command line. *)
+
+  heading : string;
+  (** One-line description, NO trailing period. *)
+
+  pod_description : string option;
+  (** POD-format long description, used for the man page. *)
 
   extra_args : ((Arg.key * Arg.spec * Arg.doc) * string) list;
   (** Extra command-line arguments, if any.  eg. The [hostname]
diff --git a/sysprep/sysprep_operation_bash_history.ml b/sysprep/sysprep_operation_bash_history.ml
index 4367973..dbd6c50 100644
--- a/sysprep/sysprep_operation_bash_history.ml
+++ b/sysprep/sysprep_operation_bash_history.ml
@@ -34,9 +34,9 @@ let bash_history_perform g root =
 
 let bash_history_op = {
   name = "bash-history";
-  pod_description = "\
-Remove the bash history in the guest.
-
+  enabled_by_default = true;
+  heading = "Remove the bash history in the guest";
+  pod_description = Some "\
 Remove the bash history of user \"root\" and any other users
 who have a C<.bash_history> file in their home directory.";
   extra_args = [];
diff --git a/sysprep/sysprep_operation_cron_spool.ml b/sysprep/sysprep_operation_cron_spool.ml
index e67688b..daa3c68 100644
--- a/sysprep/sysprep_operation_cron_spool.ml
+++ b/sysprep/sysprep_operation_cron_spool.ml
@@ -26,7 +26,9 @@ let cron_spool_perform g root =
 
 let cron_spool_op = {
   name = "cron-spool";
-  pod_description = "Remove user at-jobs and cron-jobs.";
+  enabled_by_default = true;
+  heading = "Remove user at-jobs and cron-jobs";
+  pod_description = None;
   extra_args = [];
   perform = cron_spool_perform;
 }
diff --git a/sysprep/sysprep_operation_dhcp_client_state.ml b/sysprep/sysprep_operation_dhcp_client_state.ml
index e3e87cb..279893d 100644
--- a/sysprep/sysprep_operation_dhcp_client_state.ml
+++ b/sysprep/sysprep_operation_dhcp_client_state.ml
@@ -31,7 +31,9 @@ let dhcp_client_state_perform g root =
 
 let dhcp_client_state_op = {
   name = "dhcp-client-state";
-  pod_description = "Remove DHCP client leases.";
+  enabled_by_default = true;
+  heading = "Remove DHCP client leases";
+  pod_description = None;
   extra_args = [];
   perform = dhcp_client_state_perform;
 }
diff --git a/sysprep/sysprep_operation_dhcp_server_state.ml b/sysprep/sysprep_operation_dhcp_server_state.ml
index c5251ce..b28aa69 100644
--- a/sysprep/sysprep_operation_dhcp_server_state.ml
+++ b/sysprep/sysprep_operation_dhcp_server_state.ml
@@ -26,7 +26,9 @@ let dhcp_server_state_perform g root =
 
 let dhcp_server_state_op = {
   name = "dhcp-server-state";
-  pod_description = "Remove DHCP server leases.";
+  enabled_by_default = true;
+  heading = "Remove DHCP server leases";
+  pod_description = None;
   extra_args = [];
   perform = dhcp_server_state_perform;
 }
diff --git a/sysprep/sysprep_operation_hostname.ml b/sysprep/sysprep_operation_hostname.ml
index 51f9386..395691c 100644
--- a/sysprep/sysprep_operation_hostname.ml
+++ b/sysprep/sysprep_operation_hostname.ml
@@ -52,9 +52,11 @@ let hostname_perform g root =
 
 let hostname_op = {
   name = "hostname";
-  pod_description = "\
-Changes the hostname of the guest to the value given in the I<--hostname>
-parameter.
+  enabled_by_default = true;
+  heading = "Change the hostname of the guest";
+  pod_description = Some "\
+This operation changes the hostname of the guest to the value
+given in the I<--hostname> parameter.
 
 If the I<--hostname> parameter is not given, then the hostname is changed
 to C<localhost.localdomain>.";
diff --git a/sysprep/sysprep_operation_logfiles.ml b/sysprep/sysprep_operation_logfiles.ml
index b4c6ea9..2ad3726 100644
--- a/sysprep/sysprep_operation_logfiles.ml
+++ b/sysprep/sysprep_operation_logfiles.ml
@@ -59,10 +59,13 @@ let logfiles_perform g root =
 
 let logfiles_op = {
   name = "logfiles";
-  pod_description = sprintf "\
-Remove many log files.  On Linux the following files are removed:
+  enabled_by_default = true;
+  heading = "Remove many log files from the guest";
+  pod_description = Some (
+    sprintf "\
+On Linux the following files are removed:
 
-%s" globs_as_pod;
+%s" globs_as_pod);
   extra_args = [];
   perform = logfiles_perform;
 }
diff --git a/sysprep/sysprep_operation_mail_spool.ml b/sysprep/sysprep_operation_mail_spool.ml
index 74f2d94..25f4272 100644
--- a/sysprep/sysprep_operation_mail_spool.ml
+++ b/sysprep/sysprep_operation_mail_spool.ml
@@ -31,7 +31,9 @@ let mail_spool_perform g root =
 
 let mail_spool_op = {
   name = "mail-spool";
-  pod_description = "Remove email from the local mail spool directory.";
+  enabled_by_default = true;
+  heading = "Remove email from the local mail spool directory";
+  pod_description = None;
   extra_args = [];
   perform = mail_spool_perform;
 }
diff --git a/sysprep/sysprep_operation_net_hwaddr.ml b/sysprep/sysprep_operation_net_hwaddr.ml
index 02e3b5e..57ca2b9 100644
--- a/sysprep/sysprep_operation_net_hwaddr.ml
+++ b/sysprep/sysprep_operation_net_hwaddr.ml
@@ -44,9 +44,11 @@ let net_hwaddr_perform g root =
 
 let net_hwaddr_op = {
   name = "net-hwaddr";
-  pod_description = "\
-Remove HWADDR (hard-coded MAC address) configuration.  For Fedora and
-Red Hat Enterprise Linux, this is removed from C<ifcfg-*> files.";
+  enabled_by_default = true;
+  heading = "Remove HWADDR (hard-coded MAC address) configuration";
+  pod_description = Some "\
+For Fedora and Red Hat Enterprise Linux,
+this is removed from C<ifcfg-*> files.";
   extra_args = [];
   perform = net_hwaddr_perform;
 }
diff --git a/sysprep/sysprep_operation_random_seed.ml b/sysprep/sysprep_operation_random_seed.ml
index 989ffe8..c6e8d85 100644
--- a/sysprep/sysprep_operation_random_seed.ml
+++ b/sysprep/sysprep_operation_random_seed.ml
@@ -45,7 +45,9 @@ let random_seed_perform g root =
 
 let random_seed_op = {
   name = "random-seed";
-  pod_description = "\
+  enabled_by_default = true;
+  heading = "Generate random seed for guest";
+  pod_description = Some "\
 Write some random bytes from the host into the random seed file of the
 guest.
 
diff --git a/sysprep/sysprep_operation_rhn_systemid.ml b/sysprep/sysprep_operation_rhn_systemid.ml
index 35849e4..9d9f2f8 100644
--- a/sysprep/sysprep_operation_rhn_systemid.ml
+++ b/sysprep/sysprep_operation_rhn_systemid.ml
@@ -32,7 +32,9 @@ let rhn_systemid_perform g root =
 
 let rhn_systemid_op = {
   name = "rhn-systemid";
-  pod_description = "Remove the RHN system ID.";
+  enabled_by_default = true;
+  heading = "Remove the RHN system ID";
+  pod_description = None;
   extra_args = [];
   perform = rhn_systemid_perform;
 }
diff --git a/sysprep/sysprep_operation_script.ml b/sysprep/sysprep_operation_script.ml
index 977d41f..bcbba73 100644
--- a/sysprep/sysprep_operation_script.ml
+++ b/sysprep/sysprep_operation_script.ml
@@ -113,7 +113,9 @@ trap cleanup INT TERM QUIT EXIT ERR\n"
 
 let script_op = {
   name = "script";
-  pod_description = "\
+  enabled_by_default = true;
+  heading = "Run arbitrary scripts against the guest";
+  pod_description = Some "\
 The C<script> module lets you run arbitrary shell scripts or programs
 against the guest.
 
diff --git a/sysprep/sysprep_operation_smolt_uuid.ml b/sysprep/sysprep_operation_smolt_uuid.ml
index a85aa9b..85e788e 100644
--- a/sysprep/sysprep_operation_smolt_uuid.ml
+++ b/sysprep/sysprep_operation_smolt_uuid.ml
@@ -36,7 +36,9 @@ let smolt_uuid_perform g root =
 
 let smolt_uuid_op = {
   name = "smolt-uuid";
-  pod_description = "Remove the Smolt hardware UUID.";
+  enabled_by_default = true;
+  heading = "Remove the Smolt hardware UUID";
+  pod_description = None;
   extra_args = [];
   perform = smolt_uuid_perform;
 }
diff --git a/sysprep/sysprep_operation_ssh_hostkeys.ml b/sysprep/sysprep_operation_ssh_hostkeys.ml
index 8da405b..db45b44 100644
--- a/sysprep/sysprep_operation_ssh_hostkeys.ml
+++ b/sysprep/sysprep_operation_ssh_hostkeys.ml
@@ -31,9 +31,9 @@ let ssh_hostkeys_perform g root =
 
 let ssh_hostkeys_op = {
   name = "ssh-hostkeys";
-  pod_description = "\
-Remove the SSH host keys in the guest.
-
+  enabled_by_default = true;
+  heading = "Remove the SSH host keys in the guest";
+  pod_description = Some "\
 The SSH host keys are regenerated (differently) next time the guest is
 booted.
 
diff --git a/sysprep/sysprep_operation_ssh_userdir.ml b/sysprep/sysprep_operation_ssh_userdir.ml
index 962ea8b..9ea1017 100644
--- a/sysprep/sysprep_operation_ssh_userdir.ml
+++ b/sysprep/sysprep_operation_ssh_userdir.ml
@@ -34,9 +34,9 @@ let ssh_userdir_perform g root =
 
 let ssh_userdir_op = {
   name = "ssh-userdir";
-  pod_description = "\
-Remove C<.ssh> directories in the guest.
-
+  enabled_by_default = true;
+  heading = "Remove \".ssh\" directories in the guest";
+  pod_description = Some "\
 Remove the C<.ssh> directory of user \"root\" and any other
 users who have a C<.ssh> directory in their home directory.";
   extra_args = [];
diff --git a/sysprep/sysprep_operation_udev_persistent_net.ml b/sysprep/sysprep_operation_udev_persistent_net.ml
index e54e140..95133d1 100644
--- a/sysprep/sysprep_operation_udev_persistent_net.ml
+++ b/sysprep/sysprep_operation_udev_persistent_net.ml
@@ -31,7 +31,9 @@ let udev_persistent_net_perform g root =
 
 let udev_persistent_net_op = {
   name = "udev-persistent-net";
-  pod_description = "\
+  enabled_by_default = true;
+  heading = "Remove udev persistent net rules";
+  pod_description = Some "\
 Remove udev persistent net rules which map the guest's existing MAC
 address to a fixed ethernet device (eg. eth0).
 
diff --git a/sysprep/sysprep_operation_utmp.ml b/sysprep/sysprep_operation_utmp.ml
index 69867e1..cdcf01f 100644
--- a/sysprep/sysprep_operation_utmp.ml
+++ b/sysprep/sysprep_operation_utmp.ml
@@ -30,9 +30,9 @@ let utmp_perform g root =
 
 let utmp_op = {
   name = "utmp";
-  pod_description = "\
-Remove the utmp file.
-
+  enabled_by_default = true;
+  heading = "Remove the utmp file";
+  pod_description = Some "\
 This file records who is currently logged in on a machine.  In modern
 Linux distros it is stored in a ramdisk and hence not part of the
 virtual machine's disk, but it was stored on disk in older distros.";
diff --git a/sysprep/sysprep_operation_yum_uuid.ml b/sysprep/sysprep_operation_yum_uuid.ml
index 396cac5..cc5fec1 100644
--- a/sysprep/sysprep_operation_yum_uuid.ml
+++ b/sysprep/sysprep_operation_yum_uuid.ml
@@ -30,9 +30,9 @@ let yum_uuid_perform g root =
 
 let yum_uuid_op = {
   name = "yum-uuid";
-  pod_description = "\
-Remove the yum UUID.
-
+  enabled_by_default = true;
+  heading = "Remove the yum UUID";
+  pod_description = Some "\
 Yum creates a fresh UUID the next time it runs when it notices that the
 original UUID has been erased.";
   extra_args = [];
diff --git a/sysprep/virt-sysprep.pod b/sysprep/virt-sysprep.pod
index a8cffb6..e5b89dc 100755
--- a/sysprep/virt-sysprep.pod
+++ b/sysprep/virt-sysprep.pod
@@ -86,8 +86,11 @@ list of operations, for example:
 
 would enable ONLY C<ssh-hostkeys> and C<udev-persistent-net> operations.
 
-If the I<--enable> option is not given, then we default to trying all
-possible sysprep operations.  But some sysprep operations are skipped
+If the I<--enable> 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<--enable> option, sysprep operations are skipped
 for some guest types.
 
 Use I<--list-operations> to list operations supported by a particular
@@ -124,6 +127,24 @@ security problem with malicious guests (CVE-2010-3851).
 
 List the operations supported by the virt-sysprep program.
 
+These are listed one per line, with one or more single-space-separated
+fields, eg:
+
+ $ virt-sysprep --list-operations
+ bash-history * Remove the bash history in the guest
+ cron-spool * Remove user at-jobs and cron-jobs
+ dhcp-client-state * Remove DHCP client leases
+ dhcp-server-state * Remove DHCP server leases
+ [etc]
+
+The first field is the operation name, which can be supplied
+to I<--enable>.  The second field is a C<*> character if the
+operation is enabled by default or blank if not.  Subsequent
+fields on the same line are the description of the operation.
+
+Before libguestfs 1.17.33 only the first (operation name) field was
+shown and all operations were enabled by default.
+
 =item B<-q>
 
 =item B<--quiet>
@@ -164,22 +185,25 @@ Enable tracing of libguestfs API calls.
 
 =head1 OPERATIONS
 
-If the I<--enable> option is I<not> given, then
-I<all sysprep operations are enabled>, although some are skipped
-depending on the type of guest.
+If the I<--enable> 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.
 
 Operations can be individually enabled using the I<--enable> option.
 Use a comma-separated list, for example:
 
  virt-sysprep --enable=ssh-hostkeys,udev-persistent-net [etc..]
 
-To list the operations supported by the current version of
-virt-sysprep, use I<--list-operations>.
-
 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.
+
 @OPERATIONS@
 
 =head1 COPYING AND CLONING
-- 
1.7.9.3



More information about the Libguestfs mailing list