Compare commits

...

No commits in common. 'c9' and 'c9-beta' have entirely different histories.
c9 ... c9-beta

@ -1,68 +0,0 @@
From 88e4e0213f5dc9e60720f6a84edf36bffbea723e Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 16 May 2024 12:32:00 +0100
Subject: [PATCH] Update common submodule
Pulls in these commits, but they are not thought to be relevant to
virt-v2v.
Ben Brown (1):
Initialise bar->fp as NULL
Richard W.M. Jones (2):
mlcustomize: Update virt-customize generated files
options: Allow nbd+unix:// URIs
(cherry picked from commit 6513fcbec9a10652cb8b5690936e7265e9c8851c)
---
common | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Submodule common 0dba002c..93a7f3af:
diff --git a/common/mlcustomize/customize_cmdline.ml b/common/mlcustomize/customize_cmdline.ml
index 245d9960..48ee3344 100644
--- a/common/mlcustomize/customize_cmdline.ml
+++ b/common/mlcustomize/customize_cmdline.ml
@@ -157,7 +157,7 @@ let rec argspec () =
let len = String.length arg in
String.sub arg 0 i, String.sub arg (i+1) (len-(i+1))
and split_string_triplet option_name arg =
- match String.nsplit ~max:3 "," arg with
+ match String.nsplit ~max:3 ":" arg with
| [a; b; c] -> a, b, c
| _ ->
error (f_"invalid format for '--%s' parameter, see the man page")
diff --git a/common/options/uri.c b/common/options/uri.c
index 84d393c1..9180d6a2 100644
--- a/common/options/uri.c
+++ b/common/options/uri.c
@@ -99,7 +99,7 @@ is_uri (const char *arg)
return 0;
for (p--; p >= arg; p--) {
- if (!c_islower (*p))
+ if (! (c_islower (*p) || *p == '+'))
return 0;
}
@@ -148,7 +148,10 @@ parse (const char *arg, char **path_ret, char **protocol_ret,
}
*/
- *protocol_ret = strdup (uri->scheme);
+ if (STREQ (uri->scheme, "nbd+unix"))
+ *protocol_ret = strdup ("nbd");
+ else
+ *protocol_ret = strdup (uri->scheme);
if (*protocol_ret == NULL) {
perror ("strdup: protocol");
return -1;
@@ -194,7 +197,7 @@ parse (const char *arg, char **path_ret, char **protocol_ret,
if (path && path[0] == '/' &&
(STREQ (uri->scheme, "gluster") ||
STREQ (uri->scheme, "iscsi") ||
- STREQ (uri->scheme, "nbd") ||
+ STRPREFIX (uri->scheme, "nbd") ||
STREQ (uri->scheme, "rbd") ||
STREQ (uri->scheme, "sheepdog")))
path++;

@ -1,197 +0,0 @@
From 0c0055924a4564e15d9a69d468f315f84f30f140 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 16 May 2024 13:27:49 +0100
Subject: [PATCH] convert: windows: Install blnsvr from virtio-win
Also update the common module to get these two commits for the
implementation:
Richard W.M. Jones (2):
mlcustomize: Add virt-customize --inject-blnsvr generated files
mlcustomize: Add Inject_virtio_win.inject_blnsvr implementation
Fixes: https://issues.redhat.com/browse/RHEL-36591
Cherry picked from commit 70eec57765280032e08a1d738402926b14a851bf.
For the RHEL 9.4-z backport, remove blnsvr installation.
---
common | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Submodule common 93a7f3af..830cbdcf:
diff --git a/common/mlcustomize/customize-options.pod b/common/mlcustomize/customize-options.pod
index ff93630d..b2ac5752 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 bb0ce125..957de8cf 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 48ee3344..c4d6a77d 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 51a156ea..ee62961a 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 2a30b200..4e0ed0e0 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 d14f0497..d273c4dd 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. *)

@ -1,109 +0,0 @@
From 006bdf2599f4d56e0612192291b846b384675e96 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 25 Jul 2024 09:08:41 +0100
Subject: [PATCH] Update common submodule
This pulls in the commits below which simplify the installation of
Qemu Guest Agent on Windows.
Richard W.M. Jones (4):
mlcustomize: firstboot: Use Linux path for Powershell script path
mlcustomize: firstboot: Use powershell.exe instead of path
mlcustomize: firstboot: Use Powershell -NoProfile flag
mlcustomize: Revert delay installation of qemu-ga MSI
Fixes: https://issues.redhat.com/browse/RHEL-49761
(cherry picked from commit 4ba18d2d6d1155db7cd83641a650477c0a13dbec)
---
common | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Submodule common 830cbdcf..5d1f5b84:
diff --git a/common/mlcustomize/firstboot.ml b/common/mlcustomize/firstboot.ml
index 5dc01234..4b9b910b 100644
--- a/common/mlcustomize/firstboot.ml
+++ b/common/mlcustomize/firstboot.ml
@@ -387,16 +387,10 @@ let add_firstboot_powershell g root ?prio name code =
(* Create the temporary directory to put the Powershell file. *)
let tempdir = sprintf "%s/Temp" windows_systemroot in
g#mkdir_p tempdir;
+ let ps_path = sprintf "%s/%s" tempdir name in
let code = String.concat "\r\n" code ^ "\r\n" in
- g#write (sprintf "%s/%s" tempdir name) code;
+ g#write ps_path code;
- (* Powershell interpreter. Should we check this exists? XXX *)
- let ps_exe =
- windows_systemroot ^
- "\\System32\\WindowsPowerShell\\v1.0\\powershell.exe" in
-
- (* Windows path to the Powershell script. *)
- let ps_path = windows_systemroot ^ "\\Temp\\" ^ name in
-
- let fb = sprintf "%s -ExecutionPolicy ByPass -file %s" ps_exe ps_path in
+ let fb = sprintf "powershell.exe -ExecutionPolicy ByPass -NoProfile -file %s"
+ ps_path in
add_firstboot_script g root ?prio name fb
diff --git a/common/mlcustomize/inject_virtio_win.ml b/common/mlcustomize/inject_virtio_win.ml
index 4e0ed0e0..eee93669 100644
--- a/common/mlcustomize/inject_virtio_win.ml
+++ b/common/mlcustomize/inject_virtio_win.ml
@@ -575,40 +575,28 @@ and copy_from_libosinfo { g; i_osinfo; i_arch } destdir =
) driver.Libosinfo.files
with Not_found -> []
+(* Install qemu-ga. [files] is the non-empty list of possible qemu-ga
+ * installers we detected.
+ *)
and configure_qemu_ga t files =
+ let script = ref [] in
+ let add = List.push_back script in
+
+ add "# Virt-v2v script which installs QEMU Guest Agent";
+ add "";
+ add "# Uncomment this line for lots of debug output.";
+ add "# Set-PSDebug -Trace 2";
+ add "";
+ add "Write-Host Installing QEMU Guest Agent";
+ add "";
+ add "# Run qemu-ga installers";
List.iter (
fun msi_path ->
- (* Windows is a trashfire.
- * https://stackoverflow.com/a/18730884
- * https://bugzilla.redhat.com/show_bug.cgi?id=1895323
- *)
- let psh_script = ref [] in
- let add = List.push_back psh_script in
+ add (sprintf "C:\\%s /norestart /qn /l+*vx C:\\%s.log"
+ msi_path msi_path)
+ ) files;
- add "# Uncomment this line for lots of debug output.";
- add "# Set-PSDebug -Trace 2";
- add "";
- add "Write-Host Removing any previously scheduled qemu-ga installation";
- add "schtasks.exe /Delete /TN Firstboot-qemu-ga /F";
- add "";
- add (sprintf
- "Write-Host Scheduling delayed installation of qemu-ga from %s"
- msi_path);
- add "$d = (get-date).AddSeconds(120)";
- add "$dtfinfo = [System.Globalization.DateTimeFormatInfo]::CurrentInfo";
- add "$sdp = $dtfinfo.ShortDatePattern";
- add "$sdp = $sdp -replace 'y+', 'yyyy'";
- add "$sdp = $sdp -replace 'M+', 'MM'";
- add "$sdp = $sdp -replace 'd+', 'dd'";
- add "schtasks.exe /Create /SC ONCE `";
- add " /ST $d.ToString('HH:mm') /SD $d.ToString($sdp) `";
- add " /RU SYSTEM /TN Firstboot-qemu-ga `";
- add (sprintf " /TR \"C:\\%s /forcerestart /qn /l+*vx C:\\%s.log\""
- msi_path msi_path);
-
- Firstboot.add_firstboot_powershell t.g t.root
- (sprintf "install-%s.ps1" msi_path) !psh_script;
- ) files
+ Firstboot.add_firstboot_powershell t.g t.root "install-qemu-ga.ps1" !script
and configure_blnsvr t blnsvr =
let cmd = sprintf "\

@ -1,124 +0,0 @@
From 22691e516898b0d54ad4100c9f04beb1e70f9dc0 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Sun, 28 Jul 2024 14:49:42 +0100
Subject: [PATCH] v2v: --mac: Allow gw and len fields to be empty
Even if these appear in the middle of the list, allow them to be
empty. For example this is now permitted whereas previously it was an
error:
virt-v2v --mac <MAC>:ip:<ADDR>,,,nameserver
Reported-by: Arik Hadas
(cherry picked from commit 159fda411d2f75b087106e7293d273ae142c9fbe)
---
in-place/in_place.ml | 12 +++++++-----
inspector/inspector.ml | 12 +++++++-----
v2v/v2v.ml | 12 +++++++-----
3 files changed, 21 insertions(+), 15 deletions(-)
diff --git a/in-place/in_place.ml b/in-place/in_place.ml
index 2049db16..a61d9795 100644
--- a/in-place/in_place.ml
+++ b/in-place/in_place.ml
@@ -90,10 +90,10 @@ let rec main () =
| "ip" ->
(match String.nsplit "," out with
| [] -> error (f_"invalid --mac ip option")
- | [ip] -> add_static_ip mac ip None None []
- | [ip; gw] -> add_static_ip mac ip (Some gw) None []
+ | [ip] -> add_static_ip mac ip "" "" []
+ | [ip; gw] -> add_static_ip mac ip gw "" []
| ip :: gw :: len :: nameservers ->
- add_static_ip mac ip (Some gw) (Some len) nameservers
+ add_static_ip mac ip gw len nameservers
)
| _ -> assert false
and add_static_ip if_mac_addr if_ip_address if_default_gateway
@@ -108,12 +108,14 @@ let rec main () =
an IP address") what addr
in
error_unless_ip_addr "ipaddr" if_ip_address;
+ let if_default_gateway =
+ match if_default_gateway with "" -> None | gw -> Some gw in
Option.iter (error_unless_ip_addr "gw") if_default_gateway;
List.iter (error_unless_ip_addr "nameserver") if_nameservers;
let if_prefix_length =
match if_prefix_length_str with
- | None -> None
- | Some len ->
+ | "" -> None
+ | len ->
let len =
try int_of_string len with
| Failure _ -> error (f_"cannot parse --mac ip prefix length \
diff --git a/inspector/inspector.ml b/inspector/inspector.ml
index 02d1a0e7..417b31c5 100644
--- a/inspector/inspector.ml
+++ b/inspector/inspector.ml
@@ -97,10 +97,10 @@ let rec main () =
| "ip" ->
(match String.nsplit "," out with
| [] -> error (f_"invalid --mac ip option")
- | [ip] -> add_static_ip mac ip None None []
- | [ip; gw] -> add_static_ip mac ip (Some gw) None []
+ | [ip] -> add_static_ip mac ip "" "" []
+ | [ip; gw] -> add_static_ip mac ip gw "" []
| ip :: gw :: len :: nameservers ->
- add_static_ip mac ip (Some gw) (Some len) nameservers
+ add_static_ip mac ip gw len nameservers
)
| _ -> assert false
and add_static_ip if_mac_addr if_ip_address if_default_gateway
@@ -115,12 +115,14 @@ let rec main () =
is an IP address") what addr
in
error_unless_ip_addr "ipaddr" if_ip_address;
+ let if_default_gateway =
+ match if_default_gateway with "" -> None | gw -> Some gw in
Option.iter (error_unless_ip_addr "gw") if_default_gateway;
List.iter (error_unless_ip_addr "nameserver") if_nameservers;
let if_prefix_length =
match if_prefix_length_str with
- | None -> None
- | Some len ->
+ | "" -> None
+ | len ->
let len =
try int_of_string len with
| Failure _ -> error (f_"cannot parse --mac ip prefix \
diff --git a/v2v/v2v.ml b/v2v/v2v.ml
index 89c08fc5..6d9e3792 100644
--- a/v2v/v2v.ml
+++ b/v2v/v2v.ml
@@ -109,10 +109,10 @@ let rec main () =
| "ip" ->
(match String.nsplit "," out with
| [] -> error (f_"invalid --mac ip option")
- | [ip] -> add_static_ip mac ip None None []
- | [ip; gw] -> add_static_ip mac ip (Some gw) None []
+ | [ip] -> add_static_ip mac ip "" "" []
+ | [ip; gw] -> add_static_ip mac ip gw "" []
| ip :: gw :: len :: nameservers ->
- add_static_ip mac ip (Some gw) (Some len) nameservers
+ add_static_ip mac ip gw len nameservers
)
| _ -> assert false
and add_static_ip if_mac_addr if_ip_address if_default_gateway
@@ -127,12 +127,14 @@ let rec main () =
is an IP address") what addr
in
error_unless_ip_addr "ipaddr" if_ip_address;
+ let if_default_gateway =
+ match if_default_gateway with "" -> None | gw -> Some gw in
Option.iter (error_unless_ip_addr "gw") if_default_gateway;
List.iter (error_unless_ip_addr "nameserver") if_nameservers;
let if_prefix_length =
match if_prefix_length_str with
- | None -> None
- | Some len ->
+ | "" -> None
+ | len ->
let len =
try int_of_string len with
| Failure _ -> error (f_"cannot parse --mac ip prefix length field \

@ -1,29 +0,0 @@
From 48c49139b94b1081c6392ab3b14fbb72c024f18d Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Wed, 31 Jul 2024 10:09:50 +0100
Subject: [PATCH] docs: Note that --mac len field is now optional
Reported-by: Ming Xie
Updates: commit 159fda411d2f75b087106e7293d273ae142c9fbe
(cherry picked from commit 7800049c5612e6ffb30be7f8862d147d82976ae8)
---
docs/virt-v2v.pod | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod
index 021ac897..c173563b 100644
--- a/docs/virt-v2v.pod
+++ b/docs/virt-v2v.pod
@@ -372,9 +372,9 @@ Force a particular interface (controlled by its MAC address) to have a
static IP address after boot.
The fields in the parameter are: C<ipaddr> is the IP address. C<gw>
-is the optional gateway IP address. C<len> is the subnet mask length
-(an integer). The final parameters are zero or more nameserver IP
-addresses.
+is the optional gateway IP address. C<len> is the optional subnet
+mask length (an integer). The final parameters are zero or more
+nameserver IP addresses.
This option can be supplied zero or more times.

@ -1,240 +0,0 @@
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

@ -1,118 +0,0 @@
From 692354df0bf2915955d8c66705685f66f5f44844 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 1 Aug 2024 10:36:52 +0100
Subject: [PATCH] common: mlcustomize: Inject qemu-ga & blnsvr into
<firstboot_dir>/Temp
Update common submodule to pick up this further change which should
mean that for all Windows conversions, everything is confined to
C:\Program Files\Guestfs\Firstboot (except the virtio drivers
themselves).
Richard W.M. Jones (1):
mlcustomize: Inject qemu-ga & blnsvr into <firstboot_dir>/Temp
(cherry picked from commit 168eacf977ca49e96bc63ddc4109c27515ac0277)
---
common | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Submodule common d489469f..04116678:
diff --git a/common/mlcustomize/inject_virtio_win.ml b/common/mlcustomize/inject_virtio_win.ml
index b04a3b38..2981bff5 100644
--- a/common/mlcustomize/inject_virtio_win.ml
+++ b/common/mlcustomize/inject_virtio_win.ml
@@ -263,14 +263,28 @@ let rec inject_virtio_win_drivers ({ g } as t) reg =
}
)
-and inject_qemu_ga t =
- let msi_files = copy_qemu_ga t in
+and inject_qemu_ga ({ g; root } as t) =
+ (* Copy the qemu-ga MSI(s) 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 msi_files = copy_qemu_ga t tempdir in
if msi_files <> [] then
- configure_qemu_ga t msi_files;
+ configure_qemu_ga t tempdir_win msi_files;
msi_files <> [] (* return true if we found some qemu-ga MSI files *)
-and inject_blnsvr t =
- let files = copy_blnsvr t in
+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. *)
@@ -278,7 +292,7 @@ and inject_blnsvr t =
* drivers/by-driver). Pick the first.
*)
| blnsvr :: _ ->
- configure_blnsvr t blnsvr;
+ configure_blnsvr t tempdir_win blnsvr;
true
and add_guestor_to_registry t ((g, root) as reg) drv_name drv_pciid =
@@ -360,13 +374,13 @@ and copy_drivers t driverdir =
(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_qemu_ga t =
- copy_from_virtio_win t "/" "/" (virtio_iso_path_matches_qemu_ga t)
+and copy_qemu_ga t tempdir =
+ copy_from_virtio_win t "/" tempdir (virtio_iso_path_matches_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)
+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."))
@@ -578,7 +592,7 @@ and copy_from_libosinfo { g; i_osinfo; i_arch } destdir =
(* Install qemu-ga. [files] is the non-empty list of possible qemu-ga
* installers we detected.
*)
-and configure_qemu_ga t files =
+and configure_qemu_ga t tempdir_win files =
let script = ref [] in
let add = List.push_back script in
@@ -591,16 +605,17 @@ and configure_qemu_ga t files =
add "";
add "# Run qemu-ga installers";
List.iter (
- fun msi_path ->
- add (sprintf "Start-Process -Wait -FilePath \"C:\\%s\" -ArgumentList \"/norestart\",\"/qn\",\"/l+*vx\",\"C:\\%s.log\""
- msi_path msi_path)
+ fun msi ->
+ (* [`] is an escape char for quotes *)
+ add (sprintf "Start-Process -Wait -FilePath \"%s\\%s\" -ArgumentList \"/norestart\",\"/qn\",\"/l+*vx\",\"`\"%s\\%s.log`\"\""
+ tempdir_win msi tempdir_win msi)
) files;
Firstboot.add_firstboot_powershell t.g t.root "install-qemu-ga" !script
-and configure_blnsvr t blnsvr =
+and configure_blnsvr t tempdir_win 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
+ \"%s\\%s\" -i\n" blnsvr tempdir_win blnsvr in
+ Firstboot.add_firstboot_script t.g t.root "install-blnsvr" cmd

@ -1,46 +0,0 @@
From 696060ba5e89da4d60a7ee1187c8cfd298d50031 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Mon, 5 Aug 2024 10:08:34 +0100
Subject: [PATCH] docs: Add a note about removal of VMware Tools on Windows
We use VMware's recommended method for removal, but we know from
experience that this rarely works. The alternate method being
proposed involves making very invasive changes to the Registry and
filesystem, which are inappropriate for virt-v2v to do and highly
risky. Therefore simply document this, with notes for the virt-v2v
user if they want to try the risky method.
Fixes: https://issues.redhat.com/browse/RHEL-51169
Thanks: Yan Vugenfirer
Reported-by: Ming Xie
(cherry picked from commit c952f310c902e438a8b0b5240a4b486b698bede8)
---
docs/virt-v2v.pod | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod
index c173563b..6df9d88b 100644
--- a/docs/virt-v2v.pod
+++ b/docs/virt-v2v.pod
@@ -1248,6 +1248,21 @@ B<N.B.> Take care not to interrupt the automatic driver installation
process when logging in to the guest for the first time, as this may
prevent the guest from subsequently booting correctly.
+=head3 Removing VMware Tools from Windows guests
+
+Virt-v2v attempts to remove VMware Tools. For Windows guests this is
+supposed to happen during the first boot after conversion.
+
+We use VMware's recommended uninstallation method as that is the
+safest choice. However our experience has shown that this method
+usually fails. If so, VMware Tools must be removed by some other
+method.
+
+One possible method is described here:
+L<https://gist.github.com/broestls/f872872a00acee2fca02017160840624>
+You should carefully check this script since it makes very invasive
+changes to the Windows Registry and filesystem.
+
=head2 Free space for conversion
=head3 Free space in the guest

@ -1,27 +0,0 @@
From 03249203b25d946358e73d0e418805f293bb43bb Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Mon, 5 Aug 2024 10:18:31 +0100
Subject: [PATCH] Update common submodule
Richard W.M. Jones (1):
mlcustomize: Write qemu-ga log file name to log.txt
(cherry picked from commit 7bc9b115baba6df2969451cd6907e2d7543ef22d)
---
common | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Submodule common 04116678..7b84a370:
diff --git a/common/mlcustomize/inject_virtio_win.ml b/common/mlcustomize/inject_virtio_win.ml
index 2981bff5..afec1e45 100644
--- a/common/mlcustomize/inject_virtio_win.ml
+++ b/common/mlcustomize/inject_virtio_win.ml
@@ -606,6 +606,8 @@ and configure_qemu_ga t tempdir_win files =
add "# Run qemu-ga installers";
List.iter (
fun msi ->
+ add (sprintf "Write-Host \"Writing log to %s\\%s.log\""
+ tempdir_win msi);
(* [`] is an escape char for quotes *)
add (sprintf "Start-Process -Wait -FilePath \"%s\\%s\" -ArgumentList \"/norestart\",\"/qn\",\"/l+*vx\",\"`\"%s\\%s.log`\"\""
tempdir_win msi tempdir_win msi)

@ -1,80 +0,0 @@
From a6b8794cd8b90b7f100964ff8534eb24a1b32d4b Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 8 Aug 2024 10:40:24 +0100
Subject: [PATCH] Pull in a fix to make Windows firstboot more reliable.
Update the common submodule to get:
Richard W.M. Jones (2):
mlcustomize: Add some comments to firstboot batch file
mlcustomize: Reboot Windows between each firstboot script
Document that Windows may now reboot several times after conversion.
(cherry picked from commit 50f005f8b7034916588855c15b10a0195bf54b23)
---
common | 2 +-
docs/virt-v2v.pod | 9 ++++++---
2 files changed, 7 insertions(+), 4 deletions(-)
Submodule common 7b84a370..a7883967:
diff --git a/common/mlcustomize/firstboot.ml b/common/mlcustomize/firstboot.ml
index 3bbba714..52e76401 100644
--- a/common/mlcustomize/firstboot.ml
+++ b/common/mlcustomize/firstboot.ml
@@ -278,6 +278,9 @@ module Windows = struct
(* 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.
+ *
+ * XXX It would be better to use powershell here. For some ideas see
+ * https://github.com/HCK-CI/HLK-Setup-Scripts/
*)
let firstboot_script = sprintf "\
@echo off
@@ -299,6 +302,7 @@ if not exist \"%%scripts_done%%\" (
mkdir \"%%scripts_done%%\"
)
+:: Pick the next script to run.
for %%%%f in (\"%%scripts%%\"\\*.bat) do (
echo running \"%%%%f\"
move \"%%%%f\" \"%%scripts_done%%\"
@@ -307,8 +311,17 @@ for %%%%f in (\"%%scripts%%\"\\*.bat) do (
set elvl=!errorlevel!
echo .... exit code !elvl!
popd
+
+ :: Reboot the computer. This is necessary to free any locked
+ :: files which may prevent later scripts from running.
+ shutdown /r /t 0 /y
+
+ :: Exit the script (in case shutdown returns before rebooting).
+ :: On next boot, the whole firstboot service will be called again.
+ exit /b
)
+:: Fallthrough here if there are no scripts.
echo uninstalling firstboot service
\"%%firstboot%%\\%s\" -s firstboot uninstall
" firstboot_dir_win srvany in
diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod
index 6df9d88b..7912c6b1 100644
--- a/docs/virt-v2v.pod
+++ b/docs/virt-v2v.pod
@@ -1244,9 +1244,12 @@ The guest will be bootable after the offline conversion stage, but
will not yet have all necessary drivers installed to work correctly.
These will be installed automatically the first time the guest boots.
-B<N.B.> Take care not to interrupt the automatic driver installation
-process when logging in to the guest for the first time, as this may
-prevent the guest from subsequently booting correctly.
+B<N.B.> Windows may reboot 4 or more times the first time after
+conversion. This is required to install the required drivers, guest
+agents, remove VMware Tools, and configure the network. Take care not
+to interrupt the automatic driver installation process when logging in
+to the guest for the first time, as this may prevent the guest from
+subsequently booting correctly.
=head3 Removing VMware Tools from Windows guests

@ -1,31 +0,0 @@
From 8bcdddcaa612feb05c4ae5033bf9440b046ef63e Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 8 Aug 2024 10:56:16 +0100
Subject: [PATCH] docs: Restate position on removal of VMware Tools
With the "reboot after every step" change made in the previous commit,
it seems removal of VMware Tools is now more reliable. Update the
notes about this.
Updates: commit c952f310c902e438a8b0b5240a4b486b698bede8
(cherry picked from commit e9c0d63b22bcb4c31cfaac00fc1271713c8bd3b3)
---
docs/virt-v2v.pod | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod
index 7912c6b1..50285cad 100644
--- a/docs/virt-v2v.pod
+++ b/docs/virt-v2v.pod
@@ -1257,9 +1257,8 @@ Virt-v2v attempts to remove VMware Tools. For Windows guests this is
supposed to happen during the first boot after conversion.
We use VMware's recommended uninstallation method as that is the
-safest choice. However our experience has shown that this method
-usually fails. If so, VMware Tools must be removed by some other
-method.
+safest choice. If this fails, VMware Tools must be manually removed
+by some other method.
One possible method is described here:
L<https://gist.github.com/broestls/f872872a00acee2fca02017160840624>

@ -1,25 +0,0 @@
From 919e2fdf65377bc2496a696cb10eac3881324611 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 9 Jul 2024 11:30:09 +0100
Subject: [PATCH] RHEL: Add warning about virt-v2v-in-place not being supported
Fixes: https://issues.redhat.com/browse/RHEL-40903
(cherry picked from commit 1dec94e52974e45fd3962dcbd51882fde7e9c306)
---
in-place/in_place.ml | 3 +++
1 file changed, 3 insertions(+)
diff --git a/in-place/in_place.ml b/in-place/in_place.ml
index a61d9795..d55f49a0 100644
--- a/in-place/in_place.ml
+++ b/in-place/in_place.ml
@@ -197,6 +197,9 @@ read the man page virt-v2v-in-place(1).
let opthandle = create_standard_options argspec ~anon_fun ~key_opts:true ~machine_readable:true usage_msg in
Getopt.parse opthandle.getopt;
+ warning "virt-v2v-in-place is NOT SUPPORTED for command line use. \
+ It is almost always better to use virt-v2v instead of this tool.";
+
(* Print the version, easier than asking users to tell us. *)
debug "%s: %s %s (%s)"
prog Config.package_name Config.package_version_full

@ -1,93 +0,0 @@
From c36ec998cc50124300ae0b31ef844b193b2db00f Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 27 Aug 2024 12:36:41 +0100
Subject: [PATCH] convert: windows: Online all virtio disks at first boot
Windows 2022 (and possibly earlier versions back to around 2019) will
force offline any non-boot disks which change bus, apparently as a
security mitigation. The effect of this is that although the system
drive (C:) is present after conversion, other drives may seem to
disappear.
Running a Powershell script to bring all disks online seems risky.
The compromise is to bring online only virtio disks at first boot.
To further reduce risk, we only do this if there are non-system disks
(ie. > 1 disks in total), and only if we installed virtio drivers.
Fixes: https://issues.redhat.com/browse/RHEL-55763
Fixes: https://issues.redhat.com/browse/RHEL-55837
Related: https://issues.redhat.com/browse/MTV-1299
Related: https://bugzilla.redhat.com/show_bug.cgi?id=1662286
Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
Thanks: Martin Necas
Acked-by: Martin Necas
(cherry picked from commit cb56f6f94dc153051515fc7aa0d9ca646f5e2340)
---
convert/convert_windows.ml | 39 +++++++++++++++++++++++++++++++++++++-
1 file changed, 38 insertions(+), 1 deletion(-)
diff --git a/convert/convert_windows.ml b/convert/convert_windows.ml
index 2ff60bad..28f81e23 100644
--- a/convert/convert_windows.ml
+++ b/convert/convert_windows.ml
@@ -38,7 +38,8 @@ module G = Guestfs
* time the Windows VM is booted on KVM.
*)
-let convert (g : G.guestfs) _ inspect i_firmware block_driver _ static_ips =
+let convert (g : G.guestfs) source inspect i_firmware
+ block_driver _ static_ips =
(*----------------------------------------------------------------------*)
(* Inspect the Windows guest. *)
@@ -272,6 +273,8 @@ let convert (g : G.guestfs) _ inspect i_firmware block_driver _ static_ips =
Registry.with_hive_write g inspect.i_windows_software_hive
update_software_hive;
+ configure_online_disks block_driver;
+
configure_network_interfaces net_driver;
fix_ntfs_heads ();
@@ -662,6 +665,40 @@ let convert (g : G.guestfs) _ inspect i_firmware block_driver _ static_ips =
warning (f_"could not find registry key \
HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion")
+ and configure_online_disks block_driver =
+ (* If there are > 1 disks, run a script which will force Windows
+ * to bring them all online. Windows 2022 will offline non-boot disks
+ * where the bus changes as some sort of "security" mitigation.
+ * https://issues.redhat.com/browse/RHEL-55837
+ * https://issues.redhat.com/browse/MTV-1299
+ * https://bugzilla.redhat.com/show_bug.cgi?id=1662286
+ *)
+ let virtio_installed =
+ match block_driver with
+ | Inject_virtio_win.Virtio_blk | Virtio_SCSI -> true
+ | IDE -> false in
+ let more_than_one_disk = List.length source.s_disks > 1 in
+
+ if virtio_installed && more_than_one_disk then (
+ let psh_filename = "online-disks" in
+ let psh = ref [] in
+ let add = List.push_back psh in
+
+ add "# Uncomment this line for lots of debug output.";
+ add "# Set-PSDebug -Trace 1";
+ add "";
+ add "Write-Host \"Online all virtio disks\"";
+ add "";
+ add "Get-Disk | Where { $_.FriendlyName -like '*VirtIO*' } | % {";
+ add " Write-Host (' - ' + $_.Number + ': ' + $_.FriendlyName + '(' + [math]::Round($_.Size/1GB,2) + 'GB)')";
+ add " $_ | Set-Disk -IsOffline $false";
+ add " $_ | Set-Disk -IsReadOnly $false";
+ add "}";
+
+ (* Install the Powershell script to run late at firstboot. *)
+ Firstboot.add_firstboot_powershell g inspect.i_root psh_filename !psh
+ )
+
and configure_network_interfaces net_driver =
(* If we were asked to force network interfaces to have particular
* static IP addresses then it is done here by installing a

@ -16,7 +16,7 @@
Name: virt-v2v Name: virt-v2v
Epoch: 1 Epoch: 1
Version: 2.4.0 Version: 2.4.0
Release: 4%{?dist} Release: 2%{?dist}
Summary: Convert a virtual machine to run on KVM Summary: Convert a virtual machine to run on KVM
License: GPL-2.0-or-later AND LGPL-2.0-or-later License: GPL-2.0-or-later AND LGPL-2.0-or-later
@ -62,19 +62,6 @@ Patch0023: 0023-RHEL-Remove-the-in-place-option.patch
Patch0024: 0024-RHEL-9-oo-compressed-Remove-nbdcopy-version-check-an.patch Patch0024: 0024-RHEL-9-oo-compressed-Remove-nbdcopy-version-check-an.patch
Patch0025: 0025-RHEL-9-tests-Remove-btrfs-test.patch Patch0025: 0025-RHEL-9-tests-Remove-btrfs-test.patch
Patch0026: 0026-RHEL-9-Remove-block-driver-option.patch Patch0026: 0026-RHEL-9-Remove-block-driver-option.patch
Patch0027: 0027-Update-common-submodule.patch
Patch0028: 0028-convert-windows-Install-blnsvr-from-virtio-win.patch
Patch0029: 0029-Update-common-submodule.patch
Patch0030: 0030-v2v-mac-Allow-gw-and-len-fields-to-be-empty.patch
Patch0031: 0031-docs-Note-that-mac-len-field-is-now-optional.patch
Patch0032: 0032-convert-More-robust-qemu-ga-installation-change-path.patch
Patch0033: 0033-common-mlcustomize-Inject-qemu-ga-blnsvr-into-firstb.patch
Patch0034: 0034-docs-Add-a-note-about-removal-of-VMware-Tools-on-Win.patch
Patch0035: 0035-Update-common-submodule.patch
Patch0036: 0036-Pull-in-a-fix-to-make-Windows-firstboot-more-reliabl.patch
Patch0037: 0037-docs-Restate-position-on-removal-of-VMware-Tools.patch
Patch0038: 0038-RHEL-Add-warning-about-virt-v2v-in-place-not-being-s.patch
Patch0039: 0039-convert-windows-Online-all-virtio-disks-at-first-boo.patch
%if !0%{?rhel} %if !0%{?rhel}
# libguestfs hasn't been built on i686 for a while since there is no # libguestfs hasn't been built on i686 for a while since there is no
@ -288,10 +275,8 @@ ln -sf ../../i686-w64-mingw32/sys-root/mingw/bin/pnp_wait.exe
popd popd
%if 0%{?rhel} %if 0%{?rhel}
# On RHEL move virt-v2v-in-place to libexec since it is not supported, # On RHEL remove virt-v2v-in-place.
# and remove the documentation. rm $RPM_BUILD_ROOT%{_bindir}/virt-v2v-in-place
mkdir -p $RPM_BUILD_ROOT%{_libexecdir}
mv $RPM_BUILD_ROOT%{_bindir}/virt-v2v-in-place $RPM_BUILD_ROOT%{_libexecdir}/
rm $RPM_BUILD_ROOT%{_mandir}/man1/virt-v2v-in-place.1* rm $RPM_BUILD_ROOT%{_mandir}/man1/virt-v2v-in-place.1*
%endif %endif
@ -344,8 +329,6 @@ make -C tests TESTS=test-v2v-fedora-luks-on-lvm-conversion.sh check
%{_bindir}/virt-v2v %{_bindir}/virt-v2v
%if !0%{?rhel} %if !0%{?rhel}
%{_bindir}/virt-v2v-in-place %{_bindir}/virt-v2v-in-place
%else
%{_libexecdir}/virt-v2v-in-place
%endif %endif
%{_bindir}/virt-v2v-inspector %{_bindir}/virt-v2v-inspector
%{_mandir}/man1/virt-v2v.1* %{_mandir}/man1/virt-v2v.1*
@ -383,19 +366,6 @@ make -C tests TESTS=test-v2v-fedora-luks-on-lvm-conversion.sh check
%changelog %changelog
* Tue Aug 27 2024 Richard W.M. Jones <rjones@redhat.com> - 1:2.4.0-4
- convert: windows: Online all virtio disks at first boot
resolves: RHEL-55837
- Bundle virt-v2v-in-place for use by MTV
resolves: RHEL-55823
* Tue Aug 13 2024 Richard W.M. Jones <rjones@redhat.com> - 1:2.4.0-3
- Fixes to improve installation of QEMU Guest Agent and removal
of VMware Tools
resolves: RHEL-54150, RHEL-54151
- Allow --mac gw and len fields to be optional
resolves: RHEL-54152
* Mon Jan 22 2024 Richard W.M. Jones <rjones@redhat.com> - 1:2.4.0-2 * Mon Jan 22 2024 Richard W.M. Jones <rjones@redhat.com> - 1:2.4.0-2
- Rebase to virt-v2v 2.4.0 - Rebase to virt-v2v 2.4.0
- -it ssh: Double quote ssh command which tests remote file exists - -it ssh: Double quote ssh command which tests remote file exists

Loading…
Cancel
Save