[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