guestfs-tools/0014-customize-Implement-in...

223 lines
9.9 KiB
Diff
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

From d326f1080aafe32d47b49064099f2e9d7759b2a0 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 93a7f3af5..830cbdcf4:
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 2a30b2008..4e0ed0e0e 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 *)
@@ -267,6 +269,18 @@ and inject_qemu_ga t =
configure_qemu_ga t msi_files;
msi_files <> [] (* return true if we found some qemu-ga MSI files *)
+and inject_blnsvr t =
+ let files = copy_blnsvr t 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 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
@@ -351,6 +365,11 @@ and copy_qemu_ga 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."))
+and copy_blnsvr t =
+ copy_from_virtio_win t "/" "/" (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].
@@ -513,6 +532,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].
*
@@ -586,3 +609,10 @@ and configure_qemu_ga t files =
Firstboot.add_firstboot_powershell t.g t.root
(sprintf "install-%s.ps1" msi_path) !psh_script;
) files
+
+and configure_blnsvr t blnsvr =
+ let cmd = sprintf "\
+ @echo off\n\
+ echo Installing %s\n\
+ c:\\%s -i\n" blnsvr blnsvr in
+ Firstboot.add_firstboot_script t.g t.root (sprintf "install-%s" 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 -> ()