Richard W.M. Jones
2012-Aug-16 17:34 UTC
[Libguestfs] [PATCH 0/4] Add customization capabilities to virt-sysprep
In the TODO file there's a discussion of perhaps writing a new 'virt-customize' tool. I think it's probably better (or at any rate, easier) to just add this functionality into virt-sysprep. That is what this small series of patches aims to achieve. Note these are not very well tested at the moment. The first patch adds a generic and useful '--firstboot' flag. The intended use is to add programs/scripts that run at first boot, for example: virt-sysprep -d some_guest \ --firstboot ./yum-update.sh \ --firstboot ./add-users.sh This is implemented by installing a systemd or sysvinit service into the guest which runs the scripts when the guest boots, deleting them after they have run. [Dan: Is the systemd unit correct?] Patches 2/4 and 3/4 implement another customization: setting the login screen background image. When I actually started investigating how to do this, I realized it is fearsomely complicated because basically every guest type has its own method to do this, and they even change frequently between versions (eg. gconf -> dconf, GNOME vs KDE etc). Since the --firstboot parameter effectively gives this capability to system administrators (albeit they need to work out how to do it themselves), I think it may be a good idea to invest the time making sure --firstboot is bullet-proof, and *not* implement specific customizations like this. What do people think? Patch 4/4 updates the man page to reflect the new capabilities of virt-sysprep. Comments welcome. Rich.
Richard W.M. Jones
2012-Aug-16 17:34 UTC
[Libguestfs] [PATCH 1/4] sysprep: Add --firstboot functionality.
From: "Richard W.M. Jones" <rjones at redhat.com> This allows you to add scripts that run in the context of the guest the first time it boots. --- TODO | 2 - po/POTFILES-ml | 2 + sysprep/Makefile.am | 40 +++++++++++-- sysprep/firstboot.ml | 102 ++++++++++++++++++++++++++++++++ sysprep/firstboot.mli | 27 +++++++++ sysprep/sysprep_operation_firstboot.ml | 86 +++++++++++++++++++++++++++ sysprep/sysprep_operation_script.ml | 6 +- sysprep/utils.ml | 12 ++++ sysprep/utils.mli | 3 + sysprep/virt-sysprep.pod | 26 ++++++++ 10 files changed, 297 insertions(+), 9 deletions(-) create mode 100644 sysprep/firstboot.ml create mode 100644 sysprep/firstboot.mli create mode 100644 sysprep/sysprep_operation_firstboot.ml diff --git a/TODO b/TODO index 3832371..1232e4d 100644 --- a/TODO +++ b/TODO @@ -383,7 +383,6 @@ virt-sysprep ideas - Windows sysprep (see: https://github.com/clalancette/oz/blob/e74ce83283d468fd987583d6837b441608e5f8f0/oz/Windows.py ) - (librarian suggests ...) - . install a firstboot script virt-sysprep --script=/tmp/foo.sh . run external guestfish script virt-sysprep --fish=/tmp/foo.fish - if drives are encrypted, then dm-crypt key should be changed and drives all re-encrypted @@ -421,7 +420,6 @@ customized with the organization logo etc. Some ideas: - change the background image to some custom desktop - change the sign-on messages (/etc/issue.net etc) - - firstboot script (as suggested by librarian above) - Windows login script/service Launch remote sessions over ssh diff --git a/po/POTFILES-ml b/po/POTFILES-ml index 7f75dc8..76043a0 100644 --- a/po/POTFILES-ml +++ b/po/POTFILES-ml @@ -7,6 +7,7 @@ sparsify/progress.ml sparsify/sparsify.ml sparsify/sparsify_gettext.ml sparsify/utils.ml +sysprep/firstboot.ml sysprep/main.ml sysprep/sysprep_gettext.ml sysprep/sysprep_operation.ml @@ -18,6 +19,7 @@ sysprep/sysprep_operation_cron_spool.ml sysprep/sysprep_operation_dhcp_client_state.ml sysprep/sysprep_operation_dhcp_server_state.ml sysprep/sysprep_operation_dovecot_data.ml +sysprep/sysprep_operation_firstboot.ml sysprep/sysprep_operation_flag_reconfiguration.ml sysprep/sysprep_operation_hostname.ml sysprep/sysprep_operation_kerberos_data.ml diff --git a/sysprep/Makefile.am b/sysprep/Makefile.am index 50c6e11..5551c2d 100644 --- a/sysprep/Makefile.am +++ b/sysprep/Makefile.am @@ -39,16 +39,43 @@ CLEANFILES = \ # Filenames sysprep_operation_<name>.ml in alphabetical order. operations = \ - abrt_data bash_history blkid_tab ca_certificates cron_spool \ - dhcp_client_state dhcp_server_state dovecot_data flag_reconfiguration \ - hostname kerberos_data lvm_uuids logfiles machine_id mail_spool \ - net_hwaddr pacct_log package_manager_cache pam_data puppet_data_log \ - random_seed rhn_systemid samba_db_log script smolt_uuid ssh_hostkeys \ - ssh_userdir sssd_db_log udev_persistent_net user_account \ + abrt_data \ + bash_history \ + blkid_tab \ + ca_certificates \ + cron_spool \ + dhcp_client_state \ + dhcp_server_state \ + dovecot_data \ + flag_reconfiguration \ + firstboot \ + hostname \ + kerberos_data \ + lvm_uuids \ + logfiles \ + machine_id \ + mail_spool \ + net_hwaddr \ + pacct_log \ + package_manager_cache \ + pam_data \ + puppet_data_log \ + random_seed \ + rhn_systemid \ + samba_db_log \ + script \ + smolt_uuid \ + ssh_hostkeys \ + ssh_userdir \ + sssd_db_log \ + udev_persistent_net \ + user_account \ utmp yum_uuid # Alphabetical order. SOURCES = \ + firstboot.ml \ + firstboot.mli \ main.ml \ sysprep_gettext.ml \ sysprep_operation.ml \ @@ -63,6 +90,7 @@ if HAVE_OCAML OBJECTS = \ sysprep_gettext.cmx \ utils.cmx \ + firstboot.cmx \ sysprep_operation.cmx \ $(patsubst %,sysprep_operation_%.cmx,$(operations)) \ main.cmx diff --git a/sysprep/firstboot.ml b/sysprep/firstboot.ml new file mode 100644 index 0000000..c551bd5 --- /dev/null +++ b/sysprep/firstboot.ml @@ -0,0 +1,102 @@ +(* virt-sysprep + * Copyright (C) 2012 Red Hat Inc. + * + * 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 Printf + +open Utils +open Sysprep_operation +open Sysprep_gettext.Gettext + +(* For Linux guests. *) +let firstboot_dir = "/usr/lib/virt-sysprep" + +let firstboot_sh = sprintf "\ +#!/bin/sh - + +d=%s/scripts +logfile=~root/virt-sysprep-firstboot.log + +for f in $d/* ; do + echo '=== Running' $f '===' >>$logfile + $f >>$logfile 2>&1 + rm $f +done +" firstboot_dir + +let firstboot_service = sprintf "\ +[Unit] +Description=virt-sysprep firstboot service +After=syslog.target network.target +Before=prefdm.service + +[Service] +Type=oneshot +ExecStart=%s/firstboot.sh +RemainAfterExit=yes + +[Install] +WantedBy=default.target +" firstboot_dir + +let failed fs + ksprintf (fun msg -> failwith (s_"firstboot: failed: " ^ msg)) fs + +let rec install_service g root + g#mkdir_p firstboot_dir; + g#mkdir_p (sprintf "%s/scripts" firstboot_dir); + g#write (sprintf "%s/firstboot.sh" firstboot_dir) firstboot_sh; + g#chmod 0o755 (sprintf "%s/firstboot.sh" firstboot_dir); + + (* systemd, else assume sysvinit *) + if g#is_dir "/etc/systemd" then + install_systemd_service g root + else + install_sysvinit_service g root + +(* Install the systemd firstboot service, if not installed already. *) +and install_systemd_service g root + g#write (sprintf "%s/firstboot.service" firstboot_dir) firstboot_service; + g#mkdir_p "/etc/systemd/system/default.target.wants"; + g#ln_sf (sprintf "%s/firstboot.service" firstboot_dir) + "/etc/systemd/system/default.target.wants" + +and install_sysvinit_service g root + g#mkdir_p "/etc/rc.d/rc2.d"; + g#mkdir_p "/etc/rc.d/rc3.d"; + g#mkdir_p "/etc/rc.d/rc5.d"; + g#ln_sf (sprintf "%s/firstboot.sh" firstboot_dir) + "/etc/rc.d/rc2.d/99virt-sysprep-firstboot"; + g#ln_sf (sprintf "%s/firstboot.sh" firstboot_dir) + "/etc/rc.d/rc3.d/99virt-sysprep-firstboot"; + g#ln_sf (sprintf "%s/firstboot.sh" firstboot_dir) + "/etc/rc.d/rc5.d/99virt-sysprep-firstboot" + +let add_firstboot_script g root id content + let typ = g#inspect_get_type root in + let distro = g#inspect_get_distro root in + match typ, distro with + | "linux", _ -> + install_service g root; + let filename + sprintf "%s/scripts/%g-%s-%s" + firstboot_dir (Unix.time ()) (string_random8 ()) id in + g#write filename content; + g#chmod 0o755 filename + + | _ -> + failed "guest type %s/%s is not supported" typ distro diff --git a/sysprep/firstboot.mli b/sysprep/firstboot.mli new file mode 100644 index 0000000..910dd75 --- /dev/null +++ b/sysprep/firstboot.mli @@ -0,0 +1,27 @@ +(* virt-sysprep + * Copyright (C) 2012 Red Hat Inc. + * + * 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. + *) + +val add_firstboot_script : Guestfs.guestfs -> string -> string -> string -> unit + (** [add_firstboot_script g root id content] adds a firstboot + script called [shortname] containing [content]. + + NB. [content] is the contents of the script, {b not} a filename. + + [id] should be a short name containing only 7 bit ASCII [-a-z0-9]. + + You should make sure the filesystem is relabelled after calling this. *) diff --git a/sysprep/sysprep_operation_firstboot.ml b/sysprep/sysprep_operation_firstboot.ml new file mode 100644 index 0000000..d0f3293 --- /dev/null +++ b/sysprep/sysprep_operation_firstboot.ml @@ -0,0 +1,86 @@ +(* virt-sysprep + * Copyright (C) 2012 Red Hat Inc. + * + * 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 Printf + +open Utils +open Sysprep_operation +open Sysprep_gettext.Gettext + +module G = Guestfs + +let files = ref [] + +let make_id_from_filename filename + let ret = String.copy filename in + for i = 0 to String.length ret - 1 do + let c = String.unsafe_get ret i in + if not ((c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + (c >= '0' && c <= '9')) then + String.unsafe_set ret i '-' + done; + ret + +let firstboot_perform g root + (* Read the files and add them using the {!Firstboot} module. *) + List.iter ( + fun filename -> + let content = read_whole_file filename in + let basename = Filename.basename filename in + let id = make_id_from_filename basename in + Firstboot.add_firstboot_script g root id content + ) !files; + [ `Created_files ] + +let firstboot_op = { + name = "firstboot"; + + (* enabled_by_default because we only do anything if the + * --firstboot parameter is used. + *) + enabled_by_default = true; + + heading = s_"Add scripts to run once at next boot"; + pod_description = Some (s_"\ +Supply one of more shell scripts (using the I<--firstboot> option). + +These are run the first time the guest boots, and then are +deleted. So these are useful for performing last minute +configuration that must run in the context of the guest +operating system, for example C<yum update>. + +Output or errors from the scripts are written to +C<~root/virt-sysprep-firstboot.log> (in the guest). + +Currently this is only implemented for Linux guests using +either System V init, or systemd."); + + extra_args = [ + ("--firstboot", Arg.String (fun s -> files := s :: !files), + s_"script" ^ " " ^ s_"run script once next time guest boots"), + 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; + perform_on_devices = None; +} + +let () = register_operation firstboot_op diff --git a/sysprep/sysprep_operation_script.ml b/sysprep/sysprep_operation_script.ml index 9337701..a49bc3c 100644 --- a/sysprep/sysprep_operation_script.ml +++ b/sysprep/sysprep_operation_script.ml @@ -134,7 +134,11 @@ guest's DNS configuration file, but C<rm /etc/resolv.conf> would (try to) remove the host's file. Normally a temporary mount point for the guest is used, but you -can choose a specific one by using the I<--scriptdir> parameter."); +can choose a specific one by using the I<--scriptdir> parameter. + +B<Note:> 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_"\ diff --git a/sysprep/utils.ml b/sysprep/utils.ml index 3b3ad8a..6f76713 100644 --- a/sysprep/utils.ml +++ b/sysprep/utils.ml @@ -86,3 +86,15 @@ let skip_dashes str let compare_command_line_args a b compare (String.lowercase (skip_dashes a)) (String.lowercase (skip_dashes b)) + +let read_whole_file path + let buf = Buffer.create 1024 in + let chan = open_in path in + let rec loop () + let line = input_line chan in + Buffer.add_string buf line; + loop () + in + (try loop () with End_of_file -> ()); + close_in chan; + Buffer.contents buf diff --git a/sysprep/utils.mli b/sysprep/utils.mli index 0ecb8da..351b936 100644 --- a/sysprep/utils.mli +++ b/sysprep/utils.mli @@ -52,3 +52,6 @@ val compare_command_line_args : string -> string -> int (** Compare two command line arguments (eg. ["-a"] and ["--V"]), ignoring leading dashes and case. Note this assumes the strings are 7 bit ASCII. *) + +val read_whole_file : string -> string +(** Read whole file into memory. *) diff --git a/sysprep/virt-sysprep.pod b/sysprep/virt-sysprep.pod index 66bc710..71900ca 100755 --- a/sysprep/virt-sysprep.pod +++ b/sysprep/virt-sysprep.pod @@ -383,6 +383,32 @@ to pay for disk space), then instead of copying the template, you can run L<virt-resize(1)>. Virt-resize performs a copy and resize, and thus is ideal for cloning guests from a template. +=head1 FIRSTBOOT VS SCRIPT + +The two options I<--firstboot> and I<--script> both supply shell +scripts that are run against the guest. However these two options are +significantly different. + +I<--firstboot script> uploads the file C<script> into the guest +and arranges that it will run, in the guest, when the guest is +next booted. (The script will only run once, at the "first boot"). + +I<--script script> runs the shell C<script> I<on the host>, with its +current directory inside the guest filesystem. + +If you needed, for example, to C<yum install> new packages, then you +I<must not> use I<--script> for this, since that would (a) run the +C<yum> command on the host and (b) wouldn't have access to the same +resources (repositories, keys, etc.) as the guest. Any command that +needs to run on the guest I<must> be run via I<--firstboot>. + +On the other hand if you need to make adjustments to the guest +filesystem (eg. copying in files), then I<--script> is ideal since (a) +it has access to the host filesystem and (b) you will get immediate +feedback on errors. + +Either or both options can be used multiple times on the command line. + =head1 SECURITY Although virt-sysprep removes some sensitive information from the -- 1.7.10.4
Richard W.M. Jones
2012-Aug-16 17:34 UTC
[Libguestfs] [PATCH 2/4] sysprep: Add `Dconf_needs_update flag.
From: "Richard W.M. Jones" <rjones at redhat.com> If an operation returns this, then 'dconf update' will be run in the guest (using firstboot). This is useful for doing GNOME configuration. --- sysprep/main.ml | 7 +++++++ sysprep/sysprep_operation.ml | 2 +- sysprep/sysprep_operation.mli | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/sysprep/main.ml b/sysprep/main.ml index 0e8ea20..49c1df3 100644 --- a/sysprep/main.ml +++ b/sysprep/main.ml @@ -214,8 +214,10 @@ let do_sysprep () (* Parse flags. *) let relabel = ref false in + let dconf_update = ref false in List.iter (function | `Created_files -> relabel := true + | `Dconf_needs_update -> dconf_update := true; relabel := true ) flags; (* SELinux relabel? *) @@ -234,6 +236,11 @@ let do_sysprep () | _ -> () ); + (* Run dconf update? *) + if !dconf_update then + Firstboot.add_firstboot_script g root "dconf-update" + "#!/bin/sh\ndconf update"; + (* Unmount everything in this guest. *) g#umount_all (); diff --git a/sysprep/sysprep_operation.ml b/sysprep/sysprep_operation.ml index 24b868c..e0b6ff8 100644 --- a/sysprep/sysprep_operation.ml +++ b/sysprep/sysprep_operation.ml @@ -22,7 +22,7 @@ open Printf open Sysprep_gettext.Gettext -type flag = [ `Created_files ] +type flag = [ `Created_files | `Dconf_needs_update ] type callback = Guestfs.guestfs -> string -> flag list diff --git a/sysprep/sysprep_operation.mli b/sysprep/sysprep_operation.mli index 87a0b9a..6fd178e 100644 --- a/sysprep/sysprep_operation.mli +++ b/sysprep/sysprep_operation.mli @@ -18,7 +18,7 @@ (** Structure used to describe sysprep operations. *) -type flag = [ `Created_files ] +type flag = [ `Created_files | `Dconf_needs_update ] type callback = Guestfs.guestfs -> string -> flag list -- 1.7.10.4
Richard W.M. Jones
2012-Aug-16 17:34 UTC
[Libguestfs] [PATCH 3/4] sysprep: Add --background-login-screen for customization of guests.
From: "Richard W.M. Jones" <rjones at redhat.com> --- po/POTFILES-ml | 1 + sysprep/Makefile.am | 1 + .../sysprep_operation_background_login_screen.ml | 124 ++++++++++++++++++++ 3 files changed, 126 insertions(+) create mode 100644 sysprep/sysprep_operation_background_login_screen.ml diff --git a/po/POTFILES-ml b/po/POTFILES-ml index 76043a0..8702efd 100644 --- a/po/POTFILES-ml +++ b/po/POTFILES-ml @@ -12,6 +12,7 @@ sysprep/main.ml sysprep/sysprep_gettext.ml sysprep/sysprep_operation.ml sysprep/sysprep_operation_abrt_data.ml +sysprep/sysprep_operation_background_login_screen.ml sysprep/sysprep_operation_bash_history.ml sysprep/sysprep_operation_blkid_tab.ml sysprep/sysprep_operation_ca_certificates.ml diff --git a/sysprep/Makefile.am b/sysprep/Makefile.am index 5551c2d..4f9d2c6 100644 --- a/sysprep/Makefile.am +++ b/sysprep/Makefile.am @@ -40,6 +40,7 @@ CLEANFILES = \ # Filenames sysprep_operation_<name>.ml in alphabetical order. operations = \ abrt_data \ + background_login_screen \ bash_history \ blkid_tab \ ca_certificates \ diff --git a/sysprep/sysprep_operation_background_login_screen.ml b/sysprep/sysprep_operation_background_login_screen.ml new file mode 100644 index 0000000..6045ba8 --- /dev/null +++ b/sysprep/sysprep_operation_background_login_screen.ml @@ -0,0 +1,124 @@ +(* virt-sysprep + * Copyright (C) 2012 Red Hat Inc. + * + * 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 Printf + +open Utils +open Sysprep_operation +open Sysprep_gettext.Gettext + +module G = Guestfs + +let set_file, get_file + let file = ref None in + let set_file name + if !file <> None then ( + failwith (s_"--background-login-screen option can only be given once") + ); + + (* Check the file is readable to avoid an error later on. *) + (try Unix.access name [Unix.R_OK] + with Unix.Unix_error _ -> + failwithf + (f_"background-login-screen: image file '%s' is not readable") name + ); + file := Some name + in + let get_file () = !file in + set_file, get_file + +(* Since the user used the --background-login-screen option, we + * should fail here because they probably want to know that this + * guest type is not supported. + *) +let failed_to_set fs + ksprintf + (fun msg -> failwith (s_"background-login-screen: failed: " ^ msg)) + fs + +(* Upload the image file. The filename is supplied by the user, so + * don't use it directly. Return the final path. + *) +let upload_image_file g file + let dir = "/usr/share/background" in + let path = sprintf "%s/sysprep.img" dir in + g#mkdir_p dir; + g#upload file path; + path + +let do_dconf g file + let path = upload_image_file g file in + let settings = sprintf "\ +# Created by virt-sysprep background-login-screen module. + +[org/gnome/settings-daemon/plugins/background] +active=false + +[org/gnome/desktop/background] +picture-uri='file://%s' +picture-options='scaled' +" path in + g#mkdir_p "/etc/dconf/db/gdm.d"; + g#write "/etc/dconf/db/gdm.d/99-virt-sysprep-desktop" settings + +let background_login_screen_perform g root + match get_file () with + | None -> [] + | Some file -> + let typ = g#inspect_get_type root in + let distro = g#inspect_get_distro root in + match typ, distro with + | "linux", ("fedora"|"rhel"|"centos"|"scientificlinux"|"redhat-based") -> + if g#is_dir "/etc/dconf" then ( (* Guest is using dconf? *) + do_dconf g file; + [`Created_files; `Dconf_needs_update] + ) else + failed_to_set "guest is not using dconf"; + + | _ -> + failed_to_set "guest type %s/%s is not supported" typ distro + +let background_login_screen_op = { + name = "background-login-screen"; + + (* enabled_by_default because we only do anything if the + * --background-login-screen parameter is used. + *) + enabled_by_default = true; + + heading = s_"Customize background on login screen"; + pod_description = Some (s_"\ +Set the background of the login screen. Supply a suitably +sized image file using the I<--background-login-screen> parameter. + +Currently this is only implemented for Red Hat Enterprise Linux +and Fedora guests running the GNOME display manager and dconf +(ie. RHEL E<ge> 7, Fedora E<ge> 15)."); + + extra_args = [ + ("--background-login-screen", Arg.String set_file, + s_"image" ^ " " ^ s_"file to use as background of login screen"), + s_"\ +Set the background of the login screen." + ]; + + perform_on_filesystems = Some background_login_screen_perform; + perform_on_devices = None; +} + +let () = register_operation background_login_screen_op -- 1.7.10.4
Richard W.M. Jones
2012-Aug-16 17:34 UTC
[Libguestfs] [PATCH 4/4] sysprep: docs: virt-sysprep can now be used to customize a guest.
From: "Richard W.M. Jones" <rjones at redhat.com> --- sysprep/virt-sysprep.pod | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/sysprep/virt-sysprep.pod b/sysprep/virt-sysprep.pod index 71900ca..fbd6f86 100755 --- a/sysprep/virt-sysprep.pod +++ b/sysprep/virt-sysprep.pod @@ -2,7 +2,7 @@ =head1 NAME -virt-sysprep - Reset or unconfigure a virtual machine so clones can be made +virt-sysprep - Reset, unconfigure or customize a virtual machine so clones can be made =head1 SYNOPSIS @@ -12,16 +12,17 @@ virt-sysprep - Reset or unconfigure a virtual machine so clones can be made =head1 DESCRIPTION -Virt-sysprep "resets" or "unconfigures" a virtual machine so that +Virt-sysprep can resets or unconfigure a virtual machine so that clones can be made from it. Steps in this process include removing SSH host keys, removing persistent network MAC configuration, and -removing user accounts. Each step can be enabled or disabled as -required. +removing user accounts. Virt-sysprep can also customize a virtual +machine, for instance by adding SSH keys, users and setting desktop +backgrounds. Each step can be enabled or disabled as required. Virt-sysprep modifies the guest or disk image I<in place>. The guest must be shut down. If you want to preserve the existing contents of -the guest, you I<must snapshot, copy or clone the disk first>. -See L</COPYING AND CLONING> below. +the guest, I<you must snapshot, copy or clone the disk first>. See +L</COPYING AND CLONING> below. You do I<not> need to run virt-sysprep as root. In fact we'd generally recommend that you don't. The time you might want to run it @@ -310,6 +311,17 @@ There are some smarter (and faster) ways too: \-----> guests \----> +You may want to run virt-sysprep twice, once to reset the guest (to +make a template) and a second time to customize the guest for a +specific user: + + virt-sysprep virt-sysprep + (reset) (add user, keys, background) + | | + dd v dd v + original guest ----> template ---------> copied ------> custom + template guest + =over 4 =item * -- 1.7.10.4
Richard W.M. Jones
2012-Aug-16 17:40 UTC
[Libguestfs] [PATCH 0/4] Add customization capabilities to virt-sysprep
On Thu, Aug 16, 2012 at 06:34:22PM +0100, Richard W.M. Jones wrote:> When I actually started investigating how to do this, I realized it is > fearsomely complicated because basically every guest type has its own > method to do this, and they even change frequently between versions > (eg. gconf -> dconf, GNOME vs KDE etc). Since the --firstboot > parameter effectively gives this capability to system administrators > (albeit they need to work out how to do it themselves), I think it may > be a good idea to invest the time making sure --firstboot is > bullet-proof, and *not* implement specific customizations like this.The contrary argument being that we ought to do the hard work on behalf of system administrators, in case that wasn't clear. 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://et.redhat.com/~rjones/virt-df/