You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
241 lines
9.7 KiB
241 lines
9.7 KiB
3 months ago
|
From bebc18c317a46cc99f50d1f6932c81df4e7da1fb Mon Sep 17 00:00:00 2001
|
||
|
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||
|
Date: Thu, 1 Aug 2024 09:01:47 +0100
|
||
|
Subject: [PATCH] convert: More robust qemu-ga installation, change paths
|
||
|
|
||
|
Add a commit from the common submodule to attempt to make qemu-ga
|
||
|
installation more robust on Windows.
|
||
|
|
||
|
Rename network configuration Powershell script from "v2vnetcf" to
|
||
|
"network-configuration". I also dropped the ".ps1" extension as the
|
||
|
modified Firstboot.add_firstboot_powershell function now adds this.
|
||
|
|
||
|
Update the common submodule to get these changes:
|
||
|
|
||
|
Richard W.M. Jones (3):
|
||
|
mlcustomize: Use Start-Process -Wait to run qemu-ga installer
|
||
|
mlcustomize: Add Firstboot.firstboot_dir function
|
||
|
mlcustomize: Place powershell scripts into <firstboot_dir>\Temp
|
||
|
|
||
|
(cherry picked from commit c57ec4fd5d4942d2320aec4a6b01977dabb87f83)
|
||
|
---
|
||
|
common | 2 +-
|
||
|
convert/convert_windows.ml | 4 ++--
|
||
|
2 files changed, 3 insertions(+), 3 deletions(-)
|
||
|
|
||
|
Submodule common 5d1f5b84..d489469f:
|
||
|
diff --git a/common/mlcustomize/firstboot.ml b/common/mlcustomize/firstboot.ml
|
||
|
index 4b9b910b..3bbba714 100644
|
||
|
--- a/common/mlcustomize/firstboot.ml
|
||
|
+++ b/common/mlcustomize/firstboot.ml
|
||
|
@@ -239,7 +239,22 @@ WantedBy=%s
|
||
|
end
|
||
|
|
||
|
module Windows = struct
|
||
|
- let rec install_service (g : Guestfs.guestfs) root =
|
||
|
+ (* Create and return the firstboot directory. *)
|
||
|
+ let create_firstboot_dir (g : Guestfs.guestfs) =
|
||
|
+ 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"]
|
||
|
+
|
||
|
+ let rec install_service (g : Guestfs.guestfs) root
|
||
|
+ firstboot_dir firstboot_dir_win =
|
||
|
(* Either rhsrvany.exe or pvvxsvc.exe must exist.
|
||
|
*
|
||
|
* (Check also that it's not a dangling symlink but a real file).
|
||
|
@@ -254,20 +269,7 @@ module Windows = struct
|
||
|
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
|
||
|
-
|
||
|
+ (* Create a directory for firstboot scripts in the guest. *)
|
||
|
g#mkdir_p (firstboot_dir // "scripts");
|
||
|
|
||
|
(* Copy pvvxsvc or rhsrvany to the guest. *)
|
||
|
@@ -339,11 +341,25 @@ echo uninstalling firstboot service
|
||
|
"PWD", REG_SZ firstboot_dir_win ];
|
||
|
] in
|
||
|
reg_import reg regedits
|
||
|
- );
|
||
|
-
|
||
|
- firstboot_dir
|
||
|
+ )
|
||
|
end
|
||
|
|
||
|
+let firstboot_dir (g : Guestfs.guestfs) root =
|
||
|
+ let typ = g#inspect_get_type root in
|
||
|
+
|
||
|
+ match typ with
|
||
|
+ | "linux" ->
|
||
|
+ let dir = Linux.firstboot_dir in
|
||
|
+ g#mkdir_p dir;
|
||
|
+ dir, None
|
||
|
+
|
||
|
+ | "windows" ->
|
||
|
+ let dir, dir_win = Windows.create_firstboot_dir g in
|
||
|
+ dir, Some dir_win
|
||
|
+
|
||
|
+ | _ ->
|
||
|
+ error (f_"guest type %s is not supported") typ
|
||
|
+
|
||
|
let script_count = ref 0
|
||
|
|
||
|
let add_firstboot_script (g : Guestfs.guestfs) root ?(prio = 5000) name
|
||
|
@@ -363,7 +379,8 @@ let add_firstboot_script (g : Guestfs.guestfs) root ?(prio = 5000) name
|
||
|
g#chmod 0o755 filename
|
||
|
|
||
|
| "windows", _ ->
|
||
|
- let firstboot_dir = Windows.install_service g root in
|
||
|
+ let firstboot_dir, firstboot_dir_win = Windows.create_firstboot_dir g in
|
||
|
+ Windows.install_service g root firstboot_dir firstboot_dir_win;
|
||
|
let filename = firstboot_dir // "scripts" // filename ^ ".bat" in
|
||
|
g#write filename (String.unix2dos content)
|
||
|
|
||
|
@@ -382,15 +399,18 @@ let add_firstboot_powershell g root ?prio name code =
|
||
|
*)
|
||
|
assert (g#inspect_get_type root = "windows");
|
||
|
|
||
|
- let windows_systemroot = g#inspect_get_windows_systemroot root in
|
||
|
-
|
||
|
- (* Create the temporary directory to put the Powershell file. *)
|
||
|
- let tempdir = sprintf "%s/Temp" windows_systemroot in
|
||
|
+ (* Place the Powershell script into firstboot_dir/Temp *)
|
||
|
+ let firstboot_dir, firstboot_dir_win = Windows.create_firstboot_dir g in
|
||
|
+ let tempdir = sprintf "%s/Temp" firstboot_dir in
|
||
|
g#mkdir_p tempdir;
|
||
|
- let ps_path = sprintf "%s/%s" tempdir name in
|
||
|
+
|
||
|
+ let ps_path = sprintf "%s/%s.ps1" tempdir name in
|
||
|
+ let ps_path_win = sprintf "%s\\Temp\\%s.ps1" firstboot_dir_win name in
|
||
|
let code = String.concat "\r\n" code ^ "\r\n" in
|
||
|
g#write ps_path code;
|
||
|
|
||
|
- let fb = sprintf "powershell.exe -ExecutionPolicy ByPass -NoProfile -file %s"
|
||
|
- ps_path in
|
||
|
+ (* Create a regular firstboot bat that just invokes powershell *)
|
||
|
+ let fb =
|
||
|
+ sprintf "powershell.exe -ExecutionPolicy ByPass -NoProfile -file \"%s\""
|
||
|
+ ps_path_win in
|
||
|
add_firstboot_script g root ?prio name fb
|
||
|
diff --git a/common/mlcustomize/firstboot.mli b/common/mlcustomize/firstboot.mli
|
||
|
index 8231af65..34ff0690 100644
|
||
|
--- a/common/mlcustomize/firstboot.mli
|
||
|
+++ b/common/mlcustomize/firstboot.mli
|
||
|
@@ -16,6 +16,23 @@
|
||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||
|
*)
|
||
|
|
||
|
+val firstboot_dir : Guestfs.guestfs -> string -> string * string option
|
||
|
+(** [firstboot_dir g root]
|
||
|
+ returns the path of the firstboot directory, creating it in
|
||
|
+ the guest if necessary.
|
||
|
+
|
||
|
+ This returns the name of the directory as a guestfs path, and
|
||
|
+ optionally the name as a Windows path (only for Windows guests).
|
||
|
+
|
||
|
+ For Linux this could be [/usr/lib/virt-sysprep, None]
|
||
|
+
|
||
|
+ For Windows this could be ["/Program Files/Guestfs/Firstboot",
|
||
|
+ Some "C:\Program Files\Guestfs\Firstboot"]
|
||
|
+
|
||
|
+ Additional files that are used during firstboot can be placed
|
||
|
+ in this directory, but be careful not to conflict with files
|
||
|
+ and scripts added by the firstboot process itself. *)
|
||
|
+
|
||
|
val add_firstboot_script : Guestfs.guestfs -> string -> ?prio:int -> string ->
|
||
|
string -> unit
|
||
|
(** [add_firstboot_script g root prio name content] adds a firstboot
|
||
|
diff --git a/common/mlcustomize/inject_virtio_win.ml b/common/mlcustomize/inject_virtio_win.ml
|
||
|
index eee93669..b04a3b38 100644
|
||
|
--- a/common/mlcustomize/inject_virtio_win.ml
|
||
|
+++ b/common/mlcustomize/inject_virtio_win.ml
|
||
|
@@ -592,11 +592,11 @@ and configure_qemu_ga t files =
|
||
|
add "# Run qemu-ga installers";
|
||
|
List.iter (
|
||
|
fun msi_path ->
|
||
|
- add (sprintf "C:\\%s /norestart /qn /l+*vx C:\\%s.log"
|
||
|
+ add (sprintf "Start-Process -Wait -FilePath \"C:\\%s\" -ArgumentList \"/norestart\",\"/qn\",\"/l+*vx\",\"C:\\%s.log\""
|
||
|
msi_path msi_path)
|
||
|
) files;
|
||
|
|
||
|
- Firstboot.add_firstboot_powershell t.g t.root "install-qemu-ga.ps1" !script
|
||
|
+ Firstboot.add_firstboot_powershell t.g t.root "install-qemu-ga" !script
|
||
|
|
||
|
and configure_blnsvr t blnsvr =
|
||
|
let cmd = sprintf "\
|
||
|
diff --git a/common/mldrivers/linux_kernels.ml b/common/mldrivers/linux_kernels.ml
|
||
|
index 23ff76a5..e0b6b8a0 100644
|
||
|
--- a/common/mldrivers/linux_kernels.ml
|
||
|
+++ b/common/mldrivers/linux_kernels.ml
|
||
|
@@ -102,7 +102,7 @@ let detect_kernels (g : G.guestfs) root bootloader apps =
|
||
|
) apps in
|
||
|
if verbose () then (
|
||
|
let names = List.map (fun { G.app2_name = name } -> name) kernel_pkgs in
|
||
|
- eprintf "candidate kernel packages in this guest: %s%!\n"
|
||
|
+ eprintf "info: candidate kernel packages in this guest: %s%!\n"
|
||
|
(String.concat " " names)
|
||
|
);
|
||
|
List.filter_map (
|
||
|
@@ -306,7 +306,7 @@ let detect_kernels (g : G.guestfs) root bootloader apps =
|
||
|
) kernel_pkgs in
|
||
|
|
||
|
if verbose () then (
|
||
|
- eprintf "installed kernel packages in this guest:\n";
|
||
|
+ eprintf "info: installed kernel packages in this guest:\n";
|
||
|
List.iter (print_kernel_info stderr "\t") installed_kernels;
|
||
|
flush stderr
|
||
|
);
|
||
|
@@ -343,7 +343,7 @@ let detect_kernels (g : G.guestfs) root bootloader apps =
|
||
|
) vmlinuzes in
|
||
|
|
||
|
if verbose () then (
|
||
|
- eprintf "kernels offered by the bootloader in this guest (first in list is default):\n";
|
||
|
+ eprintf "info: kernels offered by the bootloader in this guest (first in list is default):\n";
|
||
|
List.iter (print_kernel_info stderr "\t") bootloader_kernels;
|
||
|
flush stderr
|
||
|
);
|
||
|
diff --git a/convert/convert_windows.ml b/convert/convert_windows.ml
|
||
|
index 34cf341b..2ff60bad 100644
|
||
|
--- a/convert/convert_windows.ml
|
||
|
+++ b/convert/convert_windows.ml
|
||
|
@@ -391,7 +391,7 @@ let convert (g : G.guestfs) _ inspect i_firmware block_driver _ static_ips =
|
||
|
%systemroot%\\Sysnative\\PnPutil -i -a \
|
||
|
%systemroot%\\Drivers\\Virtio\\*.inf" in
|
||
|
|
||
|
- (* Set priority higher than that of "v2vnetcf.ps1" firstboot script. *)
|
||
|
+ (* Set priority higher than that of "network-configure" firstboot script. *)
|
||
|
Firstboot.add_firstboot_script g inspect.i_root ~prio:2000
|
||
|
"pnputil install drivers" fb_script;
|
||
|
|
||
|
@@ -668,7 +668,7 @@ let convert (g : G.guestfs) _ inspect i_firmware block_driver _ static_ips =
|
||
|
* Powershell script which runs at boot.
|
||
|
*)
|
||
|
if static_ips <> [] then (
|
||
|
- let psh_filename = "v2vnetcf.ps1" in
|
||
|
+ let psh_filename = "network-configure" in
|
||
|
let psh = ref [] in
|
||
|
let add = List.push_back psh in
|
||
|
|