50190c84b7
resolves: RHEL-56812
255 lines
11 KiB
Diff
255 lines
11 KiB
Diff
From d3153501860dd9327cdd9c9f5ead0883918b0643 Mon Sep 17 00:00:00 2001
|
||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||
Date: Thu, 16 May 2024 12:49:24 +0100
|
||
Subject: [PATCH] customize: Implement --inject-blnsvr operation
|
||
|
||
Also updates the common submodule with the generated changes from
|
||
libguestfs, and the implementation of Inject_virtio_win.inject_blnsvr.
|
||
|
||
(cherry picked from commit 80d258baa49214c8e59b91d6085595c9b989fc0d)
|
||
---
|
||
common | 2 +-
|
||
customize/customize_run.ml | 13 +++++++++++--
|
||
2 files changed, 12 insertions(+), 3 deletions(-)
|
||
|
||
Submodule common 7cbb3ba35...a78839676:
|
||
diff --git a/common/mlcustomize/customize-options.pod b/common/mlcustomize/customize-options.pod
|
||
index ff93630d8..b2ac57526 100644
|
||
--- a/common/mlcustomize/customize-options.pod
|
||
+++ b/common/mlcustomize/customize-options.pod
|
||
@@ -193,6 +193,18 @@ L<virt-builder(1)/INSTALLING PACKAGES>.
|
||
Set the hostname of the guest to C<HOSTNAME>. You can use a
|
||
dotted hostname.domainname (FQDN) if you want.
|
||
|
||
+=item B<--inject-blnsvr> METHOD
|
||
+
|
||
+Inject the Balloon Server (F<blnsvr.exe>) into a Windows guest.
|
||
+This operation also injects a firstboot script so that the Balloon
|
||
+Server is installed when the guest boots.
|
||
+
|
||
+The parameter is the same as used by the I<--inject-virtio-win> operation.
|
||
+
|
||
+Note that to do a full conversion of a Windows guest from a
|
||
+foreign hypervisor like VMware (which involves many other operations)
|
||
+you should use the L<virt-v2v(1)> tool instead of this.
|
||
+
|
||
=item B<--inject-qemu-ga> METHOD
|
||
|
||
Inject the QEMU Guest Agent into a Windows guest. The guest
|
||
diff --git a/common/mlcustomize/customize-synopsis.pod b/common/mlcustomize/customize-synopsis.pod
|
||
index bb0ce1255..957de8cf2 100644
|
||
--- a/common/mlcustomize/customize-synopsis.pod
|
||
+++ b/common/mlcustomize/customize-synopsis.pod
|
||
@@ -3,16 +3,16 @@
|
||
[--copy SOURCE:DEST] [--copy-in LOCALPATH:REMOTEDIR]
|
||
[--delete PATH] [--edit FILE:EXPR] [--firstboot SCRIPT]
|
||
[--firstboot-command 'CMD+ARGS'] [--firstboot-install PKG,PKG..]
|
||
- [--hostname HOSTNAME] [--inject-qemu-ga METHOD]
|
||
- [--inject-virtio-win METHOD] [--install PKG,PKG..]
|
||
- [--link TARGET:LINK[:LINK..]] [--mkdir DIR] [--move SOURCE:DEST]
|
||
- [--password USER:SELECTOR] [--root-password SELECTOR]
|
||
- [--run SCRIPT] [--run-command 'CMD+ARGS'] [--scrub FILE]
|
||
- [--sm-attach SELECTOR] [--sm-register] [--sm-remove]
|
||
- [--sm-unregister] [--ssh-inject USER[:SELECTOR]]
|
||
- [--tar-in TARFILE:REMOTEDIR] [--timezone TIMEZONE] [--touch FILE]
|
||
- [--truncate FILE] [--truncate-recursive PATH]
|
||
- [--uninstall PKG,PKG..] [--update] [--upload FILE:DEST]
|
||
- [--write FILE:CONTENT] [--no-logfile]
|
||
+ [--hostname HOSTNAME] [--inject-blnsvr METHOD]
|
||
+ [--inject-qemu-ga METHOD] [--inject-virtio-win METHOD]
|
||
+ [--install PKG,PKG..] [--link TARGET:LINK[:LINK..]] [--mkdir DIR]
|
||
+ [--move SOURCE:DEST] [--password USER:SELECTOR]
|
||
+ [--root-password SELECTOR] [--run SCRIPT]
|
||
+ [--run-command 'CMD+ARGS'] [--scrub FILE] [--sm-attach SELECTOR]
|
||
+ [--sm-register] [--sm-remove] [--sm-unregister]
|
||
+ [--ssh-inject USER[:SELECTOR]] [--tar-in TARFILE:REMOTEDIR]
|
||
+ [--timezone TIMEZONE] [--touch FILE] [--truncate FILE]
|
||
+ [--truncate-recursive PATH] [--uninstall PKG,PKG..] [--update]
|
||
+ [--upload FILE:DEST] [--write FILE:CONTENT] [--no-logfile]
|
||
[--password-crypto md5|sha256|sha512] [--no-selinux-relabel]
|
||
[--selinux-relabel] [--sm-credentials SELECTOR]
|
||
diff --git a/common/mlcustomize/customize_cmdline.ml b/common/mlcustomize/customize_cmdline.ml
|
||
index 48ee33445..c4d6a77d5 100644
|
||
--- a/common/mlcustomize/customize_cmdline.ml
|
||
+++ b/common/mlcustomize/customize_cmdline.ml
|
||
@@ -61,6 +61,8 @@ and op = [
|
||
(* --firstboot-install PKG,PKG.. *)
|
||
| `Hostname of string
|
||
(* --hostname HOSTNAME *)
|
||
+ | `InjectBalloonServer of string
|
||
+ (* --inject-blnsvr METHOD *)
|
||
| `InjectQemuGA of string
|
||
(* --inject-qemu-ga METHOD *)
|
||
| `InjectVirtioWin of string
|
||
@@ -286,6 +288,12 @@ let rec argspec () =
|
||
s_"Set the hostname"
|
||
),
|
||
Some "HOSTNAME", "Set the hostname of the guest to C<HOSTNAME>. You can use a\ndotted hostname.domainname (FQDN) if you want.";
|
||
+ (
|
||
+ [ L"inject-blnsvr" ],
|
||
+ Getopt.String (s_"METHOD", fun s -> List.push_front (`InjectBalloonServer s) ops),
|
||
+ s_"Inject the Balloon Server into a Windows guest"
|
||
+ ),
|
||
+ Some "METHOD", "Inject the Balloon Server (F<blnsvr.exe>) into a Windows guest.\nThis operation also injects a firstboot script so that the Balloon\nServer is installed when the guest boots.\n\nThe parameter is the same as used by the I<--inject-virtio-win> operation.\n\nNote that to do a full conversion of a Windows guest from a\nforeign hypervisor like VMware (which involves many other operations)\nyou should use the L<virt-v2v(1)> tool instead of this.";
|
||
(
|
||
[ L"inject-qemu-ga" ],
|
||
Getopt.String (s_"METHOD", fun s -> List.push_front (`InjectQemuGA s) ops),
|
||
diff --git a/common/mlcustomize/customize_cmdline.mli b/common/mlcustomize/customize_cmdline.mli
|
||
index 51a156eae..ee62961a1 100644
|
||
--- a/common/mlcustomize/customize_cmdline.mli
|
||
+++ b/common/mlcustomize/customize_cmdline.mli
|
||
@@ -53,6 +53,8 @@ and op = [
|
||
(* --firstboot-install PKG,PKG.. *)
|
||
| `Hostname of string
|
||
(* --hostname HOSTNAME *)
|
||
+ | `InjectBalloonServer of string
|
||
+ (* --inject-blnsvr METHOD *)
|
||
| `InjectQemuGA of string
|
||
(* --inject-qemu-ga METHOD *)
|
||
| `InjectVirtioWin of string
|
||
diff --git a/common/mlcustomize/inject_virtio_win.ml b/common/mlcustomize/inject_virtio_win.ml
|
||
index 0a4b8dac0..afec1e456 100644
|
||
--- a/common/mlcustomize/inject_virtio_win.ml
|
||
+++ b/common/mlcustomize/inject_virtio_win.ml
|
||
@@ -24,6 +24,8 @@ open Common_gettext.Gettext
|
||
|
||
open Regedit
|
||
|
||
+let re_blnsvr = PCRE.compile ~caseless:true "\\bblnsvr\\.exe$"
|
||
+
|
||
type t = {
|
||
g : Guestfs.guestfs; (** guestfs handle *)
|
||
|
||
@@ -274,6 +276,25 @@ and inject_qemu_ga ({ g; root } as t) =
|
||
configure_qemu_ga t tempdir_win msi_files;
|
||
msi_files <> [] (* return true if we found some qemu-ga MSI files *)
|
||
|
||
+and inject_blnsvr ({ g; root } as t) =
|
||
+ (* Copy the files to the guest. *)
|
||
+ let dir, dir_win = Firstboot.firstboot_dir g root in
|
||
+ let dir_win = Option.value dir_win ~default:dir in
|
||
+ let tempdir = sprintf "%s/Temp" dir in
|
||
+ let tempdir_win = sprintf "%s\\Temp" dir_win in
|
||
+ g#mkdir_p tempdir;
|
||
+
|
||
+ let files = copy_blnsvr t tempdir in
|
||
+ match files with
|
||
+ | [] -> false (* Didn't find or install anything. *)
|
||
+
|
||
+ (* We usually find blnsvr.exe in two locations (drivers/by-os and
|
||
+ * drivers/by-driver). Pick the first.
|
||
+ *)
|
||
+ | blnsvr :: _ ->
|
||
+ configure_blnsvr t tempdir_win blnsvr;
|
||
+ true
|
||
+
|
||
and add_guestor_to_registry t ((g, root) as reg) drv_name drv_pciid =
|
||
let ddb_node = g#hivex_node_get_child root "DriverDatabase" in
|
||
|
||
@@ -358,6 +379,11 @@ and copy_qemu_ga t tempdir =
|
||
(fun () ->
|
||
error (f_"root directory ‘/’ is missing from the virtio-win directory or ISO.\n\nThis should not happen and may indicate that virtio-win or virt-v2v is broken in some way. Please report this as a bug with a full debug log."))
|
||
|
||
+and copy_blnsvr t tempdir =
|
||
+ copy_from_virtio_win t "/" tempdir (virtio_iso_path_matches_blnsvr t)
|
||
+ (fun () ->
|
||
+ error (f_"root directory ‘/’ is missing from the virtio-win directory or ISO.\n\nThis should not happen and may indicate that virtio-win or virt-v2v is broken in some way. Please report this as a bug with a full debug log."))
|
||
+
|
||
(* Copy all files from virtio_win directory/ISO located in [srcdir]
|
||
* subdirectory and all its subdirectories to the [destdir]. The directory
|
||
* hierarchy is not preserved, meaning all files will be directly in [destdir].
|
||
@@ -452,10 +478,7 @@ and virtio_iso_path_matches_guest_os t path =
|
||
* "./drivers/amd64/Win2012R2/netkvm.sys".
|
||
* Note we check lowercase paths.
|
||
*)
|
||
- let pathelem elem =
|
||
- String.find lc_path ("/" ^ elem ^ "/") >= 0 ||
|
||
- String.is_prefix lc_path (elem ^ "/")
|
||
- in
|
||
+ let pathelem elem = String.find lc_path ("/" ^ elem ^ "/") >= 0 in
|
||
let p_arch =
|
||
if pathelem "x86" || pathelem "i386" then "i386"
|
||
else if pathelem "amd64" then "x86_64"
|
||
@@ -499,11 +522,7 @@ and virtio_iso_path_matches_guest_os t path =
|
||
else
|
||
raise Not_found in
|
||
|
||
- let p_sriov = pathelem "sriov" in
|
||
-
|
||
- arch = p_arch &&
|
||
- not p_sriov && (* always ignored, see RHEL-56383 *)
|
||
- os_major = p_os_major && os_minor = p_os_minor &&
|
||
+ arch = p_arch && os_major = p_os_major && os_minor = p_os_minor &&
|
||
match_os_variant os_variant &&
|
||
match_osinfo osinfo
|
||
|
||
@@ -527,6 +546,10 @@ and virtio_iso_path_matches_qemu_ga t path =
|
||
| ("x86_64", "rhev-qga64.msi") -> true
|
||
| _ -> false
|
||
|
||
+(* Find blnsvr for the current Windows version. *)
|
||
+and virtio_iso_path_matches_blnsvr t path =
|
||
+ virtio_iso_path_matches_guest_os t path && PCRE.matches re_blnsvr path
|
||
+
|
||
(* Look up in libosinfo for the OS, and copy all the locally
|
||
* available files specified as drivers for that OS to the [destdir].
|
||
*
|
||
@@ -591,3 +614,10 @@ and configure_qemu_ga t tempdir_win files =
|
||
) files;
|
||
|
||
Firstboot.add_firstboot_powershell t.g t.root "install-qemu-ga" !script
|
||
+
|
||
+and configure_blnsvr t tempdir_win blnsvr =
|
||
+ let cmd = sprintf "\
|
||
+ @echo off\n\
|
||
+ echo Installing %s\n\
|
||
+ \"%s\\%s\" -i\n" blnsvr tempdir_win blnsvr in
|
||
+ Firstboot.add_firstboot_script t.g t.root "install-blnsvr" cmd
|
||
diff --git a/common/mlcustomize/inject_virtio_win.mli b/common/mlcustomize/inject_virtio_win.mli
|
||
index d14f04973..d273c4dd3 100644
|
||
--- a/common/mlcustomize/inject_virtio_win.mli
|
||
+++ b/common/mlcustomize/inject_virtio_win.mli
|
||
@@ -93,3 +93,11 @@ val inject_qemu_ga : t -> bool
|
||
the MSI(s).
|
||
|
||
Returns [true] iff we were able to inject qemu-ga. *)
|
||
+
|
||
+val inject_blnsvr : t -> bool
|
||
+(** Inject the Balloon Server ([blnsvr.exe]) into a Windows guest.
|
||
+
|
||
+ A firstboot script is also injected which should install
|
||
+ the server by running [blnsvr -i].
|
||
+
|
||
+ Returns [true] iff we were able to inject the Balloon Server. *)
|
||
diff --git a/customize/customize_run.ml b/customize/customize_run.ml
|
||
index 1314d6e30..1d7c13eaf 100644
|
||
--- a/customize/customize_run.ml
|
||
+++ b/customize/customize_run.ml
|
||
@@ -113,8 +113,8 @@ let run (g : G.guestfs) root (ops : ops) =
|
||
Hashtbl.replace passwords user pw
|
||
in
|
||
|
||
- (* Helper function to convert --inject-qemu-ga/--inject-virtio-win
|
||
- * method parameter into a virtio-win handle.
|
||
+ (* Helper function to convert --inject-blnsvr/--inject-qemu-ga/
|
||
+ * --inject-virtio-win method parameter into a virtio-win handle.
|
||
*)
|
||
let get_virtio_win_handle op meth =
|
||
if g#inspect_get_type root <> "windows" then (
|
||
@@ -216,6 +216,15 @@ let run (g : G.guestfs) root (ops : ops) =
|
||
if not (Hostname.set_hostname g root hostname) then
|
||
warning (f_"hostname could not be set for this type of guest")
|
||
|
||
+ | `InjectBalloonServer meth ->
|
||
+ (match get_virtio_win_handle "--inject-blnsvr" meth with
|
||
+ | None -> ()
|
||
+ | Some t ->
|
||
+ if not (Inject_virtio_win.inject_blnsvr t) then
|
||
+ warning (f_"--inject-blnsvr: blnsvr.exe not found in \
|
||
+ virtio-win source that you specified")
|
||
+ )
|
||
+
|
||
| `InjectQemuGA meth ->
|
||
(match get_virtio_win_handle "--inject-qemu-ga" meth with
|
||
| None -> ()
|