Compare commits
No commits in common. 'c9' and 'c9-beta' have entirely different histories.
@ -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,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,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
|
Loading…
Reference in new issue