SUSE VMDP comes with a replacement for rhsrvany.exe named pvvxsvc.exe.
Check for either one of them instead of only rhsrvany.
---
builder/virt-builder.pod | 13 +++-
customize/firstboot.ml | 169 +++++++++++++++++++++++--------------------
customize/virt-customize.pod | 6 ++
sysprep/virt-sysprep.pod | 6 ++
v2v/virt-v2v.pod | 6 ++
5 files changed, 117 insertions(+), 83 deletions(-)
diff --git a/builder/virt-builder.pod b/builder/virt-builder.pod
index 9a49138..be5b568 100644
--- a/builder/virt-builder.pod
+++ b/builder/virt-builder.pod
@@ -840,16 +840,17 @@ F<~root/virt-sysprep-firstboot.log>.
=item Windows
F<rhsrvany.exe>, available from sources at
-L<https://github.com/rwmjones/rhsrvany>, is installed to run the
+L<https://github.com/rwmjones/rhsrvany>, or F<pvvxsvc.exe>, available
+with SUSE VMDP is installed to run the
first boot scripts. It is required, and the setup of first boot
scripts will fail if it is not present.
-F<rhsrvany.exe> is copied from the location pointed to by the
+F<rhsrvany.exe> or F<pvvxsvc.exe> is copied from the location pointed to by
the
C<VIRT_TOOLS_DATA_DIR> environment variable; if not set, a compiled-in
default will be used (something like F</usr/share/virt-tools>).
The output of the first boot scripts is available in the guest as
-F<C:\Program Files\Red Hat\Firstboot\log.txt>.
+F<C:\Program Files\Guestfs\Firstboot\log.txt>.
=back
@@ -1820,6 +1821,12 @@ I<--firstboot> or I<--firstboot-command> options with
Windows guests.
See also:
C<https://github.com/rwmjones/rhsrvany>
+=item F<pvvxsvc.exe>
+
+This is a Windows binary shipped with SUSE VMDP, 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.
+
=back
=item C<XDG_CACHE_HOME>
diff --git a/customize/firstboot.ml b/customize/firstboot.ml
index aa5b694..d7d791c 100644
--- a/customize/firstboot.ml
+++ b/customize/firstboot.ml
@@ -185,44 +185,52 @@ module Windows = struct
try Sys.getenv "VIRT_TOOLS_DATA_DIR"
with Not_found -> Guestfs_config.datadir // "virt-tools" in
- (* rhsrvany.exe must exist.
+ (* either rhsrvany.exe or pvvxsvc.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 (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 = sprintf "\
+ let services = ["rhsrvany.exe"; "pvvxsvc.exe"] in
+ let srvany = (
+ try
+ List.find (
+ fun service -> (
+ try
+ let chan = open_in (virt_tools_data_dir // service) in
+ close_in chan;
+ true
+ with _ ->
+ false
+ )
+ ) services
+ with Not_found ->
+ error (f_"One of rhsrvany.exe or pvvxsvc.exe is missing in %s. One of them
is required in order to install Windows firstboot scripts. You can get one by building
rhsrvany (
https://github.com/rwmjones/rhsrvany)")
+ virt_tools_data_dir
+ ) in (
+
+ (* 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"; "Guestfs";
"Firstboot"] in
+
+ g#mkdir_p (firstboot_dir // "scripts");
+
+ (* Copy pvvxsvc or rhsrvany to the guest. *)
+ g#upload (virt_tools_data_dir // srvany) (firstboot_dir // srvany);
+
+ (* 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 = sprintf "\
@echo off
setlocal EnableDelayedExpansion
@@ -253,51 +261,52 @@ for %%%%f in (\"%%scripts%%\"\\*.bat) do (
)
echo uninstalling firstboot service
-rhsrvany.exe -s firstboot uninstall
-" firstboot_dir_win in
-
- g#write (firstboot_dir // "firstboot.bat") (unix2dos 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
+%s -s firstboot uninstall
+" firstboot_dir_win srvany in
+
+ g#write (firstboot_dir // "firstboot.bat") (unix2dos 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 (sprintf "%s\\%s -s firstboot" firstboot_dir_win srvany);
+ "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
diff --git a/customize/virt-customize.pod b/customize/virt-customize.pod
index 8fb9931..7654fee 100644
--- a/customize/virt-customize.pod
+++ b/customize/virt-customize.pod
@@ -250,6 +250,12 @@ I<--firstboot> or I<--firstboot-command> options with
Windows guests.
See also:
C<https://github.com/rwmjones/rhsrvany>
+=item F<pvvxsvc.exe>
+
+This is a Windows binary shipped with SUSE VMDP, 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.
+
=back
=back
diff --git a/sysprep/virt-sysprep.pod b/sysprep/virt-sysprep.pod
index 4bbba9a..d86b1e4 100644
--- a/sysprep/virt-sysprep.pod
+++ b/sysprep/virt-sysprep.pod
@@ -550,6 +550,12 @@ I<--firstboot> or I<--firstboot-command> options with
Windows guests.
See also:
C<https://github.com/rwmjones/rhsrvany>
+=item F<pvvxsvc.exe>
+
+This is a Windows binary shipped with SUSE VMDP, 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.
+
=back
=back
diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod
index bce79c1..894f5ac 100644
--- a/v2v/virt-v2v.pod
+++ b/v2v/virt-v2v.pod
@@ -1879,6 +1879,12 @@ script in the guest during conversion of Windows guests.
See also:
C<https://github.com/rwmjones/rhsrvany>
+=item F<pvvxsvc.exe>
+
+This is a Windows binary shipped with SUSE VMDP, 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.
+
=item F<rhev-apt.exe>
(Optional)
--
2.6.2