Skip to content

Commit afc2368

Browse files
committed
Add an option to specify destination format during migration
This patch introduces two options for specifying a destination image format during migration. The first option, `dest-img-format`, is used by `vdi-pool-migrate`. The provided string is used to check whether the destination SR supports the expected format. If the check fails—or cannot be performed due to missing information on the destination SR—an error is returned. The second option is used by `vm-migrate`, and allows specifying the destination format for individual VDIs mapped to a destination SR. The format is `image-format:<source VDI UUID>=<destination image format>`. As with VDI pool migration, if the destination image format cannot be validated, an error is returned. Signed-off-by: Guillaume <[email protected]>
1 parent c512c0e commit afc2368

File tree

6 files changed

+151
-23
lines changed

6 files changed

+151
-23
lines changed

ocaml/idl/datamodel_vm.ml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1714,6 +1714,13 @@ let migrate_send =
17141714
; param_release= inverness_release
17151715
; param_default= Some (VMap [])
17161716
}
1717+
; {
1718+
param_type= Map (Ref _vdi, String)
1719+
; param_name= "image_format"
1720+
; param_doc= "Map of source VDI to destination image format"
1721+
; param_release= numbered_release "25.6.0-next"
1722+
; param_default= Some (VMap [])
1723+
}
17171724
]
17181725
~result:
17191726
(Ref _vm, "The reference of the newly created VM in the destination pool")
@@ -1781,6 +1788,13 @@ let assert_can_migrate =
17811788
; param_release= inverness_release
17821789
; param_default= Some (VMap [])
17831790
}
1791+
; {
1792+
param_type= Map (Ref _vdi, String)
1793+
; param_name= "image_format"
1794+
; param_doc= "Map of source VDI to destination image format"
1795+
; param_release= numbered_release "25.6.0-next"
1796+
; param_default= Some (VMap [])
1797+
}
17841798
]
17851799
~allowed_roles:_R_VM_POWER_ADMIN
17861800
~errs:[Api_errors.license_restriction]
@@ -1813,6 +1827,10 @@ let assert_can_migrate_sender =
18131827
, "Map of source vGPU to destination GPU group"
18141828
)
18151829
; (Map (String, String), "options", "Other parameters")
1830+
; ( Map (Ref _vdi, String)
1831+
, "image_format"
1832+
, "Map of source VDI to destination image format"
1833+
)
18161834
]
18171835
~allowed_roles:_R_VM_POWER_ADMIN ~hide_from_docs:true ()
18181836

ocaml/xapi-cli-server/cli_frontend.ml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1574,6 +1574,7 @@ let rec cmdtable_data : (string * cmd_spec) list =
15741574
; "compress"
15751575
; "vif:"
15761576
; "vdi:"
1577+
; "image-format:"
15771578
]
15781579
; help=
15791580
"Migrate the selected VM(s). The parameter '--live' will migrate the \
@@ -1587,7 +1588,9 @@ let rec cmdtable_data : (string * cmd_spec) list =
15871588
'copy=true' will enable the copy mode so that a stopped vm can be \
15881589
copied, instead of migrating, to the destination pool. The vif and \
15891590
vdi mapping parameters take the form 'vif:<source vif uuid>=<dest \
1590-
network uuid>' and 'vdi:<source vdi uuid>=<dest sr uuid>'. \
1591+
network uuid>' and 'vdi:<source vdi uuid>=<dest sr uuid>'. You can \
1592+
also specify the destination image format of the VDI using \
1593+
image-format:<source vdi uuid>=<destination image format>. \
15911594
Unfortunately, destination uuids cannot be tab-completed."
15921595
; implementation= No_fd Cli_operations.vm_migrate
15931596
; flags= [Standard; Vm_selectors]
@@ -2409,7 +2412,7 @@ let rec cmdtable_data : (string * cmd_spec) list =
24092412
; ( "vdi-pool-migrate"
24102413
, {
24112414
reqd= ["uuid"; "sr-uuid"]
2412-
; optn= []
2415+
; optn= ["dest-img-format"]
24132416
; help=
24142417
"Migrate a VDI to a specified SR, while the VDI is attached to a \
24152418
running guest."

ocaml/xapi-cli-server/cli_operations.ml

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ let waiter printer rpc session_id params task =
135135
Works for key which is not follow by a ':',
136136
also match old syntax 'device-config-key' for backwards compatability *)
137137
let read_map_params name params =
138+
debug "GTNDEBUG: read_map_params name: %s" name ;
139+
List.iter (fun (p, _) -> debug "GTNDEBUG: params: %s" p) params ;
138140
let len = String.length name + 1 in
139141
(* include ':' *)
140142
let filter_params =
@@ -2060,7 +2062,13 @@ let vdi_pool_migrate printer rpc session_id params =
20602062
Client.VDI.get_by_uuid ~rpc ~session_id ~uuid:(List.assoc "uuid" params)
20612063
and sr =
20622064
Client.SR.get_by_uuid ~rpc ~session_id ~uuid:(List.assoc "sr-uuid" params)
2063-
and options = [] (* no options implemented yet *) in
2065+
and options =
2066+
[
2067+
List.assoc_opt "dest-img-format" params
2068+
|> Option.map (fun fmt -> ("dest_img_format", "&dest-img-format=" ^ fmt))
2069+
]
2070+
|> List.filter_map (fun x -> x)
2071+
in
20642072
let newvdi = Client.VDI.pool_migrate ~rpc ~session_id ~vdi ~sr ~options in
20652073
let newuuid = Client.VDI.get_uuid ~rpc ~session_id ~self:newvdi in
20662074
printer (Cli_printer.PList [newuuid])
@@ -4544,6 +4552,7 @@ let vm_migrate_sxm_params =
45444552
; "remote-network"
45454553
; "vdi"
45464554
; "vgpu"
4555+
; "image-format"
45474556
]
45484557

45494558
let vm_migrate printer rpc session_id params =
@@ -4691,6 +4700,17 @@ let vm_migrate printer rpc session_id params =
46914700
)
46924701
(read_map_params "vdi" params)
46934702
in
4703+
let image_format =
4704+
List.map
4705+
(fun (vdi_uuid, img_format) ->
4706+
let vdi =
4707+
Client.VDI.get_by_uuid ~rpc ~session_id ~uuid:vdi_uuid
4708+
in
4709+
(* TODO: check that image format is valid by checking the SR-UUID *)
4710+
(vdi, img_format)
4711+
)
4712+
(read_map_params "image-format" params)
4713+
in
46944714
let vgpu_map =
46954715
List.map
46964716
(fun (vgpu_uuid, gpu_group_uuid) ->
@@ -4853,7 +4873,8 @@ let vm_migrate printer rpc session_id params =
48534873
rpc session_id
48544874
(fun vm ->
48554875
Client.VM.migrate_send ~rpc ~session_id ~vm:(vm.getref ())
4856-
~dest:token ~live:true ~vdi_map ~vif_map ~options ~vgpu_map
4876+
~dest:token ~live:true ~vdi_map ~vif_map ~vgpu_map ~options
4877+
~image_format
48574878
)
48584879
params
48594880
(["host"; "host-uuid"; "host-name"; "live"; "force"; "copy"]

ocaml/xapi/message_forwarding.ml

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2516,16 +2516,16 @@ functor
25162516
update_vif_operations ~__context ~vm
25172517

25182518
let assert_can_migrate_sender ~__context ~vm ~dest ~live ~vdi_map ~vif_map
2519-
~vgpu_map ~options =
2519+
~vgpu_map ~options ~image_format =
25202520
info "VM.assert_can_migrate_sender: VM = '%s'" (vm_uuid ~__context vm) ;
25212521
let local_fn =
25222522
Local.VM.assert_can_migrate_sender ~vm ~dest ~live ~vdi_map ~vif_map
2523-
~vgpu_map ~options
2523+
~vgpu_map ~options ~image_format
25242524
in
25252525
try
25262526
forward_vm_op ~local_fn ~__context ~vm (fun session_id rpc ->
25272527
Client.VM.assert_can_migrate_sender ~rpc ~session_id ~vm ~dest
2528-
~live ~vdi_map ~vif_map ~vgpu_map ~options
2528+
~live ~vdi_map ~vif_map ~vgpu_map ~options ~image_format
25292529
)
25302530
with
25312531
| Api_errors.Server_error (code, _)
@@ -2536,26 +2536,26 @@ functor
25362536
assuming it can ignore this check."
25372537

25382538
let assert_can_migrate ~__context ~vm ~dest ~live ~vdi_map ~vif_map
2539-
~options ~vgpu_map =
2539+
~options ~vgpu_map ~image_format =
25402540
info "VM.assert_can_migrate: VM = '%s'" (vm_uuid ~__context vm) ;
25412541
(* Run the checks that can be done using just the DB directly on the master *)
25422542
Local.VM.assert_can_migrate ~__context ~vm ~dest ~live ~vdi_map ~vif_map
2543-
~vgpu_map ~options ;
2543+
~vgpu_map ~options ~image_format ;
25442544
(* Run further checks on the sending host *)
25452545
assert_can_migrate_sender ~__context ~vm ~dest ~live ~vdi_map ~vif_map
2546-
~vgpu_map ~options
2546+
~vgpu_map ~options ~image_format
25472547

25482548
let migrate_send ~__context ~vm ~dest ~live ~vdi_map ~vif_map ~options
2549-
~vgpu_map =
2549+
~vgpu_map ~image_format =
25502550
info "VM.migrate_send: VM = '%s'" (vm_uuid ~__context vm) ;
25512551
let source_host = Db.VM.get_resident_on ~__context ~self:vm in
25522552
let local_fn =
25532553
Local.VM.migrate_send ~vm ~dest ~live ~vdi_map ~vif_map ~vgpu_map
2554-
~options
2554+
~options ~image_format
25552555
in
25562556
let op session_id rpc =
25572557
Client.VM.migrate_send ~rpc ~session_id ~vm ~dest ~live ~vdi_map
2558-
~vif_map ~options ~vgpu_map
2558+
~vif_map ~options ~vgpu_map ~image_format
25592559
in
25602560
let migration_type =
25612561
if Xapi_vm_lifecycle_helpers.is_live ~__context ~self:vm then
@@ -2576,6 +2576,7 @@ functor
25762576
(fun () ->
25772577
Client.InternalAsync.VM.migrate_send ~rpc ~session_id ~vm
25782578
~dest ~live ~vdi_map ~vif_map ~options ~vgpu_map
2579+
~image_format
25792580
)
25802581
(fun () -> op session_id rpc)
25812582
)
@@ -2614,7 +2615,7 @@ functor
26142615
Server_helpers.exec_with_subtask ~__context
26152616
"VM.assert_can_migrate" (fun ~__context ->
26162617
assert_can_migrate ~__context ~vm ~dest ~live ~vdi_map
2617-
~vif_map ~vgpu_map ~options
2618+
~vif_map ~vgpu_map ~options ~image_format
26182619
) ;
26192620
forward_migrate_send ()
26202621
)
@@ -5455,6 +5456,10 @@ functor
54555456
)
54565457

54575458
let pool_migrate ~__context ~vdi ~sr ~options =
5459+
debug "GTNDEBUG: pool_migrate from message forwarder...." ;
5460+
List.iter
5461+
(fun (s1, s2) -> debug "GTNDEBUG: options (%s, %s)" s1 s2)
5462+
options ;
54585463
let vbds =
54595464
let expr =
54605465
Xapi_database.Db_filter_types.(

ocaml/xapi/xapi_host.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2518,7 +2518,7 @@ let sync_pif_currently_attached ~__context ~host ~bridges =
25182518
)
25192519
pifs
25202520

2521-
let migrate_receive ~__context ~host ~network ~options:_ =
2521+
let migrate_receive ~__context ~host ~network ~options =
25222522
Xapi_vm_migrate.assert_licensed_storage_motion ~__context ;
25232523
let session_id = Context.get_session_id __context in
25242524
let session_rec = Db.Session.get_record ~__context ~self:session_id in

0 commit comments

Comments
 (0)