Skip to content

Commit 346f76c

Browse files
committed
CA-390277: Reduce record usage on CLI cross-pool migrations
Using records in cross-pool migration code is dangerous, as the code interacts with potentially newer hosts. This means that fields in the record might be different from what's expected. In particular adding an enum field can break the deserialization, and removing a field as well. With this change, only SR records are used. This is done to minimize the number of calls done. Signed-off-by: Pau Ruiz Safont <[email protected]>
1 parent 94a9965 commit 346f76c

File tree

2 files changed

+61
-56
lines changed

2 files changed

+61
-56
lines changed

ocaml/xapi-cli-server/cli_operations.ml

Lines changed: 60 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -4585,52 +4585,53 @@ let vm_migrate printer rpc session_id params =
45854585
let remote f = f ~rpc:remote_rpc ~session_id:remote_session in
45864586
finally
45874587
(fun () ->
4588-
let host, host_record =
4589-
let all = remote Client.Host.get_all_records in
4590-
if List.mem_assoc "host" params then
4591-
let x = List.assoc "host" params in
4592-
try
4593-
List.find
4594-
(fun (_, h) ->
4595-
h.API.host_hostname = x
4596-
|| h.API.host_name_label = x
4597-
|| h.API.host_uuid = x
4598-
)
4599-
all
4600-
with Not_found ->
4601-
failwith (Printf.sprintf "Failed to find host: %s" x)
4602-
else
4603-
List.hd all
4588+
let host =
4589+
let expr_match x =
4590+
Printf.sprintf
4591+
{|(field "hostname"="%s") or (field "name__label"="%s") or (field "uuid"="%s")|}
4592+
x x x
4593+
in
4594+
let expr, fail_msg =
4595+
match List.assoc_opt "host" params with
4596+
| Some x ->
4597+
(expr_match x, Printf.sprintf "Failed to find host: %s" x)
4598+
| None ->
4599+
("true", Printf.sprintf "Failed to find a suitable host")
4600+
in
4601+
match remote Client.Host.get_all_where ~expr with
4602+
| host :: _ ->
4603+
host
4604+
| [] ->
4605+
failwith fail_msg
46044606
in
4605-
let network, network_record =
4606-
let all = remote Client.Network.get_all_records in
4607-
if List.mem_assoc "remote-network" params then
4608-
let x = List.assoc "remote-network" params in
4609-
try
4610-
List.find
4611-
(fun (_, net) ->
4612-
net.API.network_bridge = x
4613-
|| net.API.network_name_label = x
4614-
|| net.API.network_uuid = x
4615-
)
4616-
all
4617-
with Not_found ->
4618-
failwith (Printf.sprintf "Failed to find network: %s" x)
4619-
else
4620-
let pifs = host_record.API.host_PIFs in
4621-
let management_pifs =
4622-
List.filter
4623-
(fun self -> remote Client.PIF.get_management ~self)
4624-
pifs
4625-
in
4626-
if List.length management_pifs = 0 then
4627-
failwith
4628-
(Printf.sprintf "Could not find management PIF on host %s"
4629-
host_record.API.host_uuid
4630-
) ;
4631-
let pif = List.hd management_pifs in
4632-
let net = remote Client.PIF.get_network ~self:pif in
4633-
(net, remote Client.Network.get_record ~self:net)
4607+
let network =
4608+
let expr x =
4609+
Printf.sprintf
4610+
{|(field "bridge"="%s") or (field "name__label"="%s") or (field "uuid"="%s")|}
4611+
x x x
4612+
in
4613+
match List.assoc_opt "remote-network" params with
4614+
| Some x -> (
4615+
match remote Client.Network.get_all_where ~expr:(expr x) with
4616+
| network :: _ ->
4617+
network
4618+
| [] ->
4619+
fail "Failed to find network: %s" x
4620+
)
4621+
| None -> (
4622+
let expr =
4623+
Printf.sprintf
4624+
{|(field "host"="%s") and (field "management"="true")|}
4625+
Ref.(string_of host)
4626+
in
4627+
let management_pifs = remote Client.PIF.get_all_where ~expr in
4628+
match management_pifs with
4629+
| [] ->
4630+
let host_uuid = remote Client.Host.get_uuid ~self:host in
4631+
fail "Could not find management PIF on host %s" host_uuid
4632+
| pif :: _ ->
4633+
remote Client.PIF.get_network ~self:pif
4634+
)
46344635
in
46354636
let vif_map =
46364637
List.map
@@ -4677,15 +4678,12 @@ let vm_migrate printer rpc session_id params =
46774678
{|(field "host"="%s") and (field "currently_attached"="true")|}
46784679
(Ref.string_of host)
46794680
in
4680-
let host_pbds = remote Client.PBD.get_all_records_where ~expr in
46814681
let srs =
4682-
List.map
4683-
(fun (_, pbd_rec) ->
4684-
( pbd_rec.API.pBD_SR
4685-
, remote Client.SR.get_record ~self:pbd_rec.API.pBD_SR
4686-
)
4687-
)
4688-
host_pbds
4682+
remote Client.PBD.get_all_where ~expr
4683+
|> List.map (fun pbd ->
4684+
let sr = remote Client.PBD.get_SR ~self:pbd in
4685+
(sr, remote Client.SR.get_record ~self:sr)
4686+
)
46894687
in
46904688
(* In the following loop, the current SR:sr' will be compared with previous checked ones,
46914689
first if it is an ISO type, then pass this one for selection, then the only shared one from this and
@@ -4784,13 +4782,20 @@ let vm_migrate printer rpc session_id params =
47844782
)
47854783
params
47864784
in
4785+
let host_name_label =
4786+
Client.Host.get_name_label ~rpc:remote_rpc ~session_id:remote_session
4787+
~self:host
4788+
in
4789+
let network_name_label =
4790+
Client.Network.get_name_label ~rpc:remote_rpc
4791+
~session_id:remote_session ~self:network
4792+
in
47874793
printer
47884794
(Cli_printer.PMsg
47894795
(Printf.sprintf
47904796
"Will migrate to remote host: %s, using remote network: %s. \
47914797
Here is the VDI mapping:"
4792-
host_record.API.host_name_label
4793-
network_record.API.network_name_label
4798+
host_name_label network_name_label
47944799
)
47954800
) ;
47964801
List.iter

quality-gate.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
set -e
44

55
list-hd () {
6-
N=312
6+
N=310
77
LIST_HD=$(git grep -r --count 'List.hd' -- **/*.ml | cut -d ':' -f 2 | paste -sd+ - | bc)
88
if [ "$LIST_HD" -eq "$N" ]; then
99
echo "OK counted $LIST_HD List.hd usages"

0 commit comments

Comments
 (0)