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 _______________________________________________ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs