[Pkg-libvirt-commits] [libguestfs] 28/266: customize: Add the ability to use --firstboot for Windows guests.
Hilko Bengen
bengen at moszumanska.debian.org
Fri Oct 3 14:41:35 UTC 2014
This is an automated email from the git hooks/post-receive script.
bengen pushed a commit to annotated tag debian/1%1.27.35-1
in repository libguestfs.
commit f4698575cced4c45136635daa31821e6d55e7c77
Author: Richard W.M. Jones <rjones at redhat.com>
Date: Tue Jul 8 21:31:06 2014 +0100
customize: Add the ability to use --firstboot for Windows guests.
This allows you to add potentially multiple --firstboot
scripts to a Windows guest.
---
builder/Makefile.am | 1 +
builder/virt-builder.pod | 22 +++++++++
customize/Makefile.am | 1 +
customize/firstboot.ml | 114 +++++++++++++++++++++++++++++++++++++++++++
customize/virt-customize.pod | 30 ++++++++++++
sysprep/Makefile.am | 1 +
sysprep/virt-sysprep.pod | 30 ++++++++++++
7 files changed, 199 insertions(+)
diff --git a/builder/Makefile.am b/builder/Makefile.am
index 1c2206f..0b4acd7 100644
--- a/builder/Makefile.am
+++ b/builder/Makefile.am
@@ -91,6 +91,7 @@ deps = \
$(top_builddir)/mllib/fsync-c.o \
$(top_builddir)/mllib/fsync.cmx \
$(top_builddir)/mllib/planner.cmx \
+ $(top_builddir)/mllib/regedit.cmx \
$(top_builddir)/mllib/uri-c.o \
$(top_builddir)/mllib/uRI.cmx \
$(top_builddir)/mllib/mkdtemp-c.o \
diff --git a/builder/virt-builder.pod b/builder/virt-builder.pod
index 323016c..02bf181 100644
--- a/builder/virt-builder.pod
+++ b/builder/virt-builder.pod
@@ -1642,6 +1642,28 @@ are actually interpreted by L<curl(1)>, not virt-builder.
Used to determine the location of the template cache, and the location
of the user' sources. See L</CACHING> and L</SOURCES OF TEMPLATES>.
+=item C<VIRT_TOOLS_DATA_DIR>
+
+This can point to the directory containing data files used for Windows
+firstboot installation.
+
+Normally you do not need to set this. If not set, a compiled-in
+default will be used (something like C</usr/share/virt-tools>).
+
+This directory may contain the following files:
+
+=over 4
+
+=item C<rhsrvany.exe>
+
+This is the RHSrvAny Windows binary, used to install a "firstboot"
+script in Windows guests. It is required if you intend to use the
+I<--firstboot> or I<--firstboot-command> options with Windows guests.
+
+See also: C<https://github.com/rwmjones/rhsrvany>
+
+=back
+
=item C<XDG_CACHE_HOME>
Used to determine the location of the template cache. See L</CACHING>.
diff --git a/customize/Makefile.am b/customize/Makefile.am
index d1cbc14..3c81f34 100644
--- a/customize/Makefile.am
+++ b/customize/Makefile.am
@@ -65,6 +65,7 @@ deps = \
$(top_builddir)/mllib/common_gettext.cmx \
$(top_builddir)/mllib/common_utils.cmx \
$(top_builddir)/mllib/config.cmx \
+ $(top_builddir)/mllib/regedit.cmx \
$(top_builddir)/mllib/uri-c.o \
$(top_builddir)/mllib/uRI.cmx \
crypt-c.o
diff --git a/customize/firstboot.ml b/customize/firstboot.ml
index 9122b0f..142eab4 100644
--- a/customize/firstboot.ml
+++ b/customize/firstboot.ml
@@ -21,6 +21,8 @@ open Printf
open Common_utils
open Common_gettext.Gettext
+open Regedit
+
(* For Linux guests. *)
module Linux = struct
let firstboot_dir = "/usr/lib/virt-sysprep"
@@ -154,6 +156,111 @@ WantedBy=default.target
"/etc/rc5.d/S99virt-sysprep-firstboot"
end
+module Windows = struct
+
+ let rec install_service ~prog (g : Guestfs.guestfs) root =
+ (* Get the data directory. *)
+ let virt_tools_data_dir =
+ try Sys.getenv "VIRT_TOOLS_DATA_DIR"
+ with Not_found -> Config.datadir // "virt-tools" in
+
+ (* rhsrvany.exe must exist.
+ *
+ * (Check also that it's not a dangling symlink but a real file).
+ *)
+ let rhsrvany_exe = virt_tools_data_dir // "rhsrvany.exe" in
+ (try
+ let chan = open_in rhsrvany_exe in
+ close_in chan
+ with
+ Sys_error msg ->
+ error ~prog (f_"'%s' is missing. This file is required in order to install Windows firstboot scripts. You can get it by building rhsrvany (https://github.com/rwmjones/rhsrvany). Original error: %s")
+ rhsrvany_exe msg
+ );
+
+ (* Create a directory for firstboot files in the guest. *)
+ let firstboot_dir, firstboot_dir_win =
+ let rec loop firstboot_dir firstboot_dir_win = function
+ | [] -> firstboot_dir, firstboot_dir_win
+ | dir :: path ->
+ let firstboot_dir =
+ if firstboot_dir = "" then "/" ^ dir else firstboot_dir // dir in
+ let firstboot_dir_win = firstboot_dir_win ^ "\\" ^ dir in
+ let firstboot_dir = g#case_sensitive_path firstboot_dir in
+ g#mkdir_p firstboot_dir;
+ loop firstboot_dir firstboot_dir_win path
+ in
+ loop "" "C:" ["Program Files"; "Red Hat"; "Firstboot"] in
+
+ g#mkdir_p (firstboot_dir // "scripts");
+
+ (* Copy rhsrvany to the guest. *)
+ g#upload rhsrvany_exe (firstboot_dir // "rhsrvany.exe");
+
+ (* Write a firstboot.bat control script which just runs the other
+ * scripts in the directory. Note we need to use CRLF line endings
+ * in this script.
+ *)
+ let firstboot_script = [
+ "@echo off";
+ "echo starting firstboot service >>log.txt";
+ (* Notes:
+ * - You have to use double %% inside the batch file, but NOT
+ * when typing the same commands on the command line.
+ * - You have to use 'call' in front of every external command
+ * else it basically exec's the command and never returns.
+ * FFS.
+ *)
+ "for /f %%f in ('dir /b scripts') do call \"scripts\\%%f\" >>log.txt";
+ "echo uninstalling firstboot service >>log.txt";
+ "rhsrvany.exe -s firstboot uninstall >>log.txt";
+ ] in
+ let firstboot_script = String.concat "\r\n" firstboot_script ^ "\r\n" in
+ g#write (firstboot_dir // "firstboot.bat") firstboot_script;
+
+ (* Open the SYSTEM hive. *)
+ let systemroot = g#inspect_get_windows_systemroot root in
+ let filename = sprintf "%s/system32/config/SYSTEM" systemroot in
+ let filename = g#case_sensitive_path filename in
+ g#hivex_open ~write:true filename;
+
+ let root_node = g#hivex_root () in
+
+ (* Find the 'Current' ControlSet. *)
+ let current_cs =
+ let select = g#hivex_node_get_child root_node "Select" in
+ let valueh = g#hivex_node_get_value select "Current" in
+ let value = int_of_le32 (g#hivex_value_value valueh) in
+ sprintf "ControlSet%03Ld" value in
+
+ (* Add a new rhsrvany service to the system registry to execute firstboot.
+ * NB: All these edits are in the HKLM\SYSTEM hive. No other
+ * hive may be modified here.
+ *)
+ let regedits = [
+ [ current_cs; "services"; "firstboot" ],
+ [ "Type", REG_DWORD 0x10_l;
+ "Start", REG_DWORD 0x2_l;
+ "ErrorControl", REG_DWORD 0x1_l;
+ "ImagePath",
+ REG_SZ (firstboot_dir_win ^ "\\rhsrvany.exe -s firstboot");
+ "DisplayName", REG_SZ "Virt tools firstboot service";
+ "ObjectName", REG_SZ "LocalSystem" ];
+
+ [ current_cs; "services"; "firstboot"; "Parameters" ],
+ [ "CommandLine",
+ REG_SZ ("cmd /c \"" ^ firstboot_dir_win ^ "\\firstboot.bat\"");
+ "PWD", REG_SZ firstboot_dir_win ];
+ ] in
+ reg_import g root_node regedits;
+
+ g#hivex_commit None;
+ g#hivex_close ();
+
+ firstboot_dir
+
+end
+
let add_firstboot_script ~prog (g : Guestfs.guestfs) root i content =
let typ = g#inspect_get_type root in
let distro = g#inspect_get_distro root in
@@ -166,5 +273,12 @@ let add_firstboot_script ~prog (g : Guestfs.guestfs) root i content =
g#write filename content;
g#chmod 0o755 filename
+ | "windows", _ ->
+ let firstboot_dir = Windows.install_service ~prog g root in
+ let t = Int64.of_float (Unix.time ()) in
+ let r = string_random8 () in
+ let filename = sprintf "%s/scripts/%04d-%Ld-%s.bat" firstboot_dir i t r in
+ g#write filename content
+
| _ ->
error ~prog (f_"guest type %s/%s is not supported") typ distro
diff --git a/customize/virt-customize.pod b/customize/virt-customize.pod
index 58c13c2..a666be7 100644
--- a/customize/virt-customize.pod
+++ b/customize/virt-customize.pod
@@ -213,6 +213,36 @@ __CUSTOMIZE_OPTIONS__
This program returns 0 on success, or 1 if there was an error.
+=head1 ENVIRONMENT VARIABLES
+
+=over 4
+
+=item C<VIRT_TOOLS_DATA_DIR>
+
+This can point to the directory containing data files used for Windows
+firstboot installation.
+
+Normally you do not need to set this. If not set, a compiled-in
+default will be used (something like C</usr/share/virt-tools>).
+
+This directory may contain the following files:
+
+=over 4
+
+=item C<rhsrvany.exe>
+
+This is the RHSrvAny Windows binary, used to install a "firstboot"
+script in Windows guests. It is required if you intend to use the
+I<--firstboot> or I<--firstboot-command> options with Windows guests.
+
+See also: C<https://github.com/rwmjones/rhsrvany>
+
+=back
+
+=back
+
+For other environment variables, see L<guestfs(3)/ENVIRONMENT VARIABLES>.
+
=head1 SEE ALSO
L<guestfs(3)>,
diff --git a/sysprep/Makefile.am b/sysprep/Makefile.am
index 06eec86..97166b5 100644
--- a/sysprep/Makefile.am
+++ b/sysprep/Makefile.am
@@ -88,6 +88,7 @@ deps = \
$(top_builddir)/mllib/config.cmx \
$(top_builddir)/mllib/mkdtemp-c.o \
$(top_builddir)/mllib/mkdtemp.cmx \
+ $(top_builddir)/mllib/regedit.cmx \
$(top_builddir)/customize/crypt-c.o \
$(top_builddir)/customize/crypt.cmx \
$(top_builddir)/customize/urandom.cmx \
diff --git a/sysprep/virt-sysprep.pod b/sysprep/virt-sysprep.pod
index f40f91d..47de963 100644
--- a/sysprep/virt-sysprep.pod
+++ b/sysprep/virt-sysprep.pod
@@ -515,6 +515,36 @@ See L<guestfs(3)/WINDOWS HIBERNATION AND WINDOWS 8 FAST STARTUP>.
This program returns 0 on success, or 1 if there was an error.
+=head1 ENVIRONMENT VARIABLES
+
+=over 4
+
+=item C<VIRT_TOOLS_DATA_DIR>
+
+This can point to the directory containing data files used for Windows
+firstboot installation.
+
+Normally you do not need to set this. If not set, a compiled-in
+default will be used (something like C</usr/share/virt-tools>).
+
+This directory may contain the following files:
+
+=over 4
+
+=item C<rhsrvany.exe>
+
+This is the RHSrvAny Windows binary, used to install a "firstboot"
+script in Windows guests. It is required if you intend to use the
+I<--firstboot> or I<--firstboot-command> options with Windows guests.
+
+See also: C<https://github.com/rwmjones/rhsrvany>
+
+=back
+
+=back
+
+For other environment variables, see L<guestfs(3)/ENVIRONMENT VARIABLES>.
+
=head1 SEE ALSO
L<guestfs(3)>,
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-libvirt/libguestfs.git
More information about the Pkg-libvirt-commits
mailing list