From 9186438937f5451ddfdaa33c9dcb9ffe27b2a098 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Thu, 21 Nov 2013 13:57:07 +0000 Subject: [PATCH] builder/sysprep: Describe --password/--root-password option as "selector". It now appears in the respective man pages as: --root-password selector or: --password selector This avoids confusion from people who think these command line options take the password directly. --- builder/virt-builder.pod | 10 ++--- sysprep/sysprep_operation.ml | 51 ++++++++++++--------- sysprep/sysprep_operation.mli | 16 +++++-- sysprep/sysprep_operation_delete.ml | 8 ++-- sysprep/sysprep_operation_firstboot.ml | 7 +-- sysprep/sysprep_operation_hostname.ml | 6 ++- sysprep/sysprep_operation_password.ml | 61 +++++++++++--------------- sysprep/sysprep_operation_script.ml | 19 +++++--- 8 files changed, 98 insertions(+), 80 deletions(-) diff --git a/builder/virt-builder.pod b/builder/virt-builder.pod index 045adfa83..19dc3ea32 100644 --- a/builder/virt-builder.pod +++ b/builder/virt-builder.pod @@ -15,7 +15,7 @@ virt-builder - Build virtual machine images quickly virt-builder [-o|--output DISKIMAGE] [--size SIZE] [--format raw|qcow2] [--attach ISOFILE] - [--root-password ...] + [--root-password SELECTOR] [--hostname HOSTNAME] [--install PKG,[PKG...]] [--mkdir DIR] @@ -494,11 +494,11 @@ Print information about the template cache. See L. Don't print ordinary progress messages. -=item B<--root-password> PASSWORD +=item B<--root-password> SELECTOR Set the root password. -See L below for the format of the C +See L below for the format of the C field, and also how to set up user accounts. Note if you I set I<--root-password> then the guest is given @@ -686,8 +686,8 @@ Use the I<--attach> option to attach the CD: =head2 USERS AND PASSWORDS The I<--root-password> option is used to change the root password -(otherwise a random password is used). This option has the following -formats: +(otherwise a random password is used). This option takes a password +C in one of the following formats: =over 4 diff --git a/sysprep/sysprep_operation.ml b/sysprep/sysprep_operation.ml index e8af4160d..1fb4f1773 100644 --- a/sysprep/sysprep_operation.ml +++ b/sysprep/sysprep_operation.ml @@ -34,10 +34,16 @@ type operation = { heading : string; pod_description : string option; pod_notes : string option; - extra_args : ((Arg.key * Arg.spec * Arg.doc) * string) list; + extra_args : extra_arg list; perform_on_filesystems : callback option; perform_on_devices : callback option; } +and extra_arg = { + extra_argspec : Arg.key * Arg.spec * Arg.doc; + extra_pod_argval : string option; + extra_pod_description : string; +} + let defaults = { name = ""; enabled_by_default = false; @@ -148,7 +154,7 @@ let extra_args () = List.flatten ( List.map (fun { extra_args = extra_args } -> - List.map fst extra_args + List.map (fun { extra_argspec = argspec } -> argspec) extra_args ) !all_operations ) @@ -185,25 +191,28 @@ let dump_pod_options () = ) !all_operations in let args = List.flatten args in let args = List.map ( - fun (op_name, ((arg_name, spec, _), pod)) -> - match spec with - | Arg.Unit _ - | Arg.Bool _ - | Arg.Set _ - | Arg.Clear _ -> - let heading = sprintf "B<%s>" arg_name in - arg_name, (op_name, heading, pod) - | Arg.String _ - | Arg.Set_string _ - | Arg.Int _ - | Arg.Set_int _ - | Arg.Float _ - | Arg.Set_float _ -> - let heading = sprintf "B<%s> %s" arg_name (skip_dashes arg_name) in - arg_name, (op_name, heading, pod) - | Arg.Tuple _ - | Arg.Symbol _ - | Arg.Rest _ -> assert false (* XXX not implemented *) + function + | (op_name, + { extra_argspec = (arg_name, + (Arg.Unit _ | Arg.Bool _ | Arg.Set _ | Arg.Clear _), + _); + extra_pod_argval = None; + extra_pod_description = pod }) -> + let heading = sprintf "B<%s>" arg_name in + arg_name, (op_name, heading, pod) + + | (op_name, + { extra_argspec = (arg_name, + (Arg.String _ | Arg.Set_string _ | Arg.Int _ | + Arg.Set_int _ | Arg.Float _ | Arg.Set_float _), + _); + extra_pod_argval = Some arg_val; + extra_pod_description = pod }) -> + let heading = sprintf "B<%s> %s" arg_name arg_val in + arg_name, (op_name, heading, pod) + + | _ -> + failwith "sysprep_operation.ml: argument type not implemented" ) args in let args = diff --git a/sysprep/sysprep_operation.mli b/sysprep/sysprep_operation.mli index 8758e06ee..16eee648c 100644 --- a/sysprep/sysprep_operation.mli +++ b/sysprep/sysprep_operation.mli @@ -44,12 +44,11 @@ type operation = { (** POD-format notes, used for the man page to describe any problems, shortcomings or bugs with this operation. *) - extra_args : ((Arg.key * Arg.spec * Arg.doc) * string) list; + extra_args : extra_arg list; (** Extra command-line arguments, if any. eg. The [hostname] operation has an extra [--hostname] parameter. - Each element of the list is the argspec (see {!Arg.spec} etc.) - and the corresponding full POD documentation. + For a description of each list element, see {!extra_arg} below. You can decide the types of the arguments, whether they are mandatory etc. *) @@ -81,6 +80,17 @@ type operation = { operation to work directly on block devices, LVs etc. *) } +and extra_arg = { + extra_argspec : Arg.key * Arg.spec * Arg.doc; + (** The argspec. See OCaml [Arg] module. *) + + extra_pod_argval : string option; + (** The argument value, used only in the virt-sysprep man page. *) + + extra_pod_description : string; + (** The long description, used only in the virt-sysprep man page. *) +} + val defaults : operation (** This is so operations can write [let op = { defaults with ... }]. *) diff --git a/sysprep/sysprep_operation_delete.ml b/sysprep/sysprep_operation_delete.ml index 7cf1c397e..de78a876c 100644 --- a/sysprep/sysprep_operation_delete.ml +++ b/sysprep/sysprep_operation_delete.ml @@ -40,9 +40,11 @@ Delete specified files or directories. Use the I<--delete> option to specify a path to remove."); extra_args = [ - ("--delete", Arg.String add_paths, s_"path" ^ " " ^ s_"File or directory to be removed on guest"), - s_"\ -Delete (recursively) the specified C on guest."; + { extra_argspec = ("--delete", Arg.String add_paths, s_"path" ^ " " ^ s_"File or directory to be removed on guest"); + extra_pod_argval = Some "PATHNAME"; + extra_pod_description = s_"\ +Delete (recursively) the specified C in the guest."; + } ]; perform_on_filesystems = Some path_perform; diff --git a/sysprep/sysprep_operation_firstboot.ml b/sysprep/sysprep_operation_firstboot.ml index 3473c47a1..6be3e92b3 100644 --- a/sysprep/sysprep_operation_firstboot.ml +++ b/sysprep/sysprep_operation_firstboot.ml @@ -65,11 +65,12 @@ Currently this is only implemented for Linux guests using either SysVinit-style scripts, Upstart or systemd."); extra_args = [ - ("--firstboot", Arg.String (fun s -> files := s :: !files), - s_"script" ^ " " ^ s_"run script once next time guest boots"), - s_"\ + { extra_argspec = "--firstboot", Arg.String (fun s -> files := s :: !files), s_"script" ^ " " ^ s_"run script once next time guest boots"; + extra_pod_argval = Some "SCRIPT"; + extra_pod_description = s_"\ Run script(s) once next time the guest boots. You can supply the I<--firstboot> option as many times as needed." + } ]; perform_on_filesystems = Some firstboot_perform; diff --git a/sysprep/sysprep_operation_hostname.ml b/sysprep/sysprep_operation_hostname.ml index 086459299..3066623fa 100644 --- a/sysprep/sysprep_operation_hostname.ml +++ b/sysprep/sysprep_operation_hostname.ml @@ -46,9 +46,11 @@ to C."); Currently this can only set the hostname on Linux guests."); extra_args = [ - ("--hostname", Arg.Set_string hostname, s_"hostname" ^ " " ^ s_"New hostname"), - s_"\ + { extra_argspec = "--hostname", Arg.Set_string hostname, s_"hostname" ^ " " ^ s_"New hostname"; + extra_pod_argval = Some "HOSTNAME"; + extra_pod_description = s_"\ Change the hostname. If not given, defaults to C." + } ]; perform_on_filesystems = Some hostname_perform; diff --git a/sysprep/sysprep_operation_password.ml b/sysprep/sysprep_operation_password.ml index 6c4f5d672..bd06bd6a5 100644 --- a/sysprep/sysprep_operation_password.ml +++ b/sysprep/sysprep_operation_password.ml @@ -99,42 +99,29 @@ Currently this only works for glibc-based Linux guests that use shadow passwords."); extra_args = [ - ("--root-password", Arg.String set_root_password, - s_"..." ^ " " ^ s_"set root password (see man page)"), - s_"\ -Set the root password. The following formats may be used -for this option: + { extra_argspec = "--root-password", Arg.String set_root_password, s_"..." ^ " " ^ s_"set root password (see man page)"; + extra_pod_argval = Some "SELECTOR"; + extra_pod_description = s_"\ +Set the root password. See I<--password> above for the format +of C." + }; -=over 4 - -=item B<--root-password file:FILENAME> - -Read the root password from C. The whole -first line of this file is the replacement password. -Any other lines are ignored. You should create the file -with mode 0600 to ensure no one else can read it. - -=item B<--root-password password:PASSWORD> - -Set the root password to the literal string C. - -B since any user on the same machine -can see the cleartext password using L. - -=back"; - - ("--password", Arg.String set_user_password, - s_"..." ^ " " ^ s_"set user password (see man page)"), - s_"\ + { extra_argspec = "--password", Arg.String set_user_password, s_"..." ^ " " ^ s_"set user password (see man page)"; + extra_pod_argval = Some "USERNAME:SELECTOR"; + extra_pod_description = s_"\ Set a user password. The user must exist already (this option -does I create users). The following formats may be used -for this option: +does I create users). + +The I<--password> option takes C. The +I<--root-password> option takes just the C. The +format of the C is described below: =over 4 =item B<--password USERNAME:file:FILENAME> -Change the password for C. +=item B<--root-password file:FILENAME> + Read the password from C. The whole first line of this file is the replacement password. Any other lines are ignored. You should create the file @@ -142,17 +129,19 @@ with mode 0600 to ensure no one else can read it. =item B<--password USERNAME:password:PASSWORD> -Change the password for C. +=item B<--root-password password:PASSWORD> + Set the password to the literal string C. B since any user on the same machine can see the cleartext password using L. -=back"; +=back" + }; - ("--password-crypto", Arg.String set_password_crypto, - s_"md5|sha256|sha512" ^ " " ^ s_"set password crypto"), - s_"\ + { extra_argspec = "--password-crypto", Arg.String set_password_crypto, s_"md5|sha256|sha512" ^ " " ^ s_"set password crypto"; + extra_pod_argval = Some "md5|sha256|sha512"; + extra_pod_description = s_"\ Set the password encryption to C, C or C. C and C require glibc E 2.7 @@ -163,8 +152,8 @@ is not secure against modern attacks. The default is C unless libguestfs detects an old guest that didn't have support for SHA-512, in which case it will use C. -You can override libguestfs by specifying this option."; - +You can override libguestfs by specifying this option." + } ]; perform_on_filesystems = Some password_perform; diff --git a/sysprep/sysprep_operation_script.ml b/sysprep/sysprep_operation_script.ml index 08c870981..60586d4dd 100644 --- a/sysprep/sysprep_operation_script.ml +++ b/sysprep/sysprep_operation_script.ml @@ -133,24 +133,29 @@ B This is different from I<--firstboot> scripts (which run in the context of the guest when it is booting first time). I<--script> scripts run on the host, not in the guest."); extra_args = [ - ("--scriptdir", Arg.String set_scriptdir, s_"dir" ^ " " ^ s_"Mount point on host"), - s_"\ + { extra_argspec = "--scriptdir", Arg.String set_scriptdir, s_"dir" ^ " " ^ s_"Mount point on host"; + extra_pod_argval = Some "SCRIPTDIR"; + extra_pod_description = s_"\ The mount point (an empty directory on the host) used when the C