This complicated bit of refactoring abstracts the target file so it is allowed to be either a filename or a QEMU URI. --- v2v/create_libvirt_xml.ml | 9 +++-- v2v/output_glance.ml | 10 ++++-- v2v/output_libvirt.ml | 5 +-- v2v/output_local.ml | 5 +-- v2v/output_null.ml | 2 +- v2v/output_qemu.ml | 17 ++++++--- v2v/output_rhv.ml | 7 +++- v2v/output_vdsm.ml | 6 +++- v2v/types.ml | 9 +++-- v2v/types.mli | 6 +++- v2v/v2v.ml | 90 ++++++++++++++++++++++++++++++----------------- 11 files changed, 116 insertions(+), 50 deletions(-)
diff --git a/v2v/create_libvirt_xml.ml b/v2v/create_libvirt_xml.ml index ecf0d14c5..c6b47538e 100644 --- a/v2v/create_libvirt_xml.ml +++ b/v2v/create_libvirt_xml.ml @@ -178,6 +178,11 @@ let create_libvirt_xml ?pool source target_buses guestcaps | BusSlotEmpty -> Comment (sprintf "%s slot %d is empty" bus_name i) | BusSlotTarget t -> + let target_file = + match t.target_file with + | TargetFile s -> s + | TargetURI _ -> assert false in + e "disk" [ "type", if pool = None then "file" else "volume"; "device", "disk" @@ -190,12 +195,12 @@ let create_libvirt_xml ?pool source target_buses guestcaps (match pool with | None -> e "source" [ - "file", absolute_path t.target_file; + "file", absolute_path target_file; ] [] | Some pool -> e "source" [ "pool", pool; - "volume", Filename.basename t.target_file; + "volume", Filename.basename target_file; ] [] ); e "target" [ diff --git a/v2v/output_glance.ml b/v2v/output_glance.ml index d00011eb5..6f9defc3e 100644 --- a/v2v/output_glance.ml +++ b/v2v/output_glance.ml @@ -63,8 +63,8 @@ object (* Write targets to a temporary local file - see above for reason. *) List.map ( fun t -> - let target_file = tmpdir // t.target_overlay.ov_sd in - { t with target_file = target_file } + let target_file = TargetFile (tmpdir // t.target_overlay.ov_sd) in + { t with target_file } ) targets method create_metadata source targets _ guestcaps inspect target_firmware = @@ -157,6 +157,12 @@ object fun (k, v) -> [ "--property"; sprintf "%s=%s" k v ] ) common_properties ) in + + let target_file = + match target_file with + | TargetFile s -> s + | TargetURI _ -> assert false in + let cmd = [ "glance"; "image-create"; "--name"; name; "--disk-format=" ^ target_format; "--container-format=bare"; "--file"; target_file; diff --git a/v2v/output_libvirt.ml b/v2v/output_libvirt.ml index 729f8b67a..ffa3e43c3 100644 --- a/v2v/output_libvirt.ml +++ b/v2v/output_libvirt.ml @@ -128,8 +128,9 @@ class output_libvirt oc output_pool = object List.map ( fun t -> let target_file = - target_path // source.s_name ^ "-" ^ t.target_overlay.ov_sd in - { t with target_file = target_file } + TargetFile (target_path // source.s_name ^ "-" ^ + t.target_overlay.ov_sd) in + { t with target_file } ) targets method supported_firmware = [ TargetBIOS; TargetUEFI ] diff --git a/v2v/output_local.ml b/v2v/output_local.ml index 97ad8dddd..a6836be2f 100644 --- a/v2v/output_local.ml +++ b/v2v/output_local.ml @@ -34,8 +34,9 @@ class output_local dir = object method prepare_targets source targets = List.map ( fun t -> - let target_file = dir // source.s_name ^ "-" ^ t.target_overlay.ov_sd in - { t with target_file = target_file } + let target_file = + TargetFile (dir // source.s_name ^ "-" ^ t.target_overlay.ov_sd) in + { t with target_file } ) targets method supported_firmware = [ TargetBIOS; TargetUEFI ] diff --git a/v2v/output_null.ml b/v2v/output_null.ml index d01f45654..65861a597 100644 --- a/v2v/output_null.ml +++ b/v2v/output_null.ml @@ -47,7 +47,7 @@ object List.map ( fun t -> let target_file = tmpdir // t.target_overlay.ov_sd in - { t with target_file = target_file } + { t with target_file = TargetFile target_file } ) targets method create_metadata _ _ _ _ _ _ = () diff --git a/v2v/output_qemu.ml b/v2v/output_qemu.ml index f61d698d6..f4c6b8b80 100644 --- a/v2v/output_qemu.ml +++ b/v2v/output_qemu.ml @@ -35,8 +35,9 @@ object method prepare_targets source targets = List.map ( fun t -> - let target_file = dir // source.s_name ^ "-" ^ t.target_overlay.ov_sd in - { t with target_file = target_file } + let target_file = + TargetFile (dir // source.s_name ^ "-" ^ t.target_overlay.ov_sd) in + { t with target_file } ) targets method supported_firmware = [ TargetBIOS; TargetUEFI ] @@ -122,7 +123,11 @@ object | BusSlotEmpty -> () | BusSlotTarget t -> - arg_list "-drive" ["file=" ^ t.target_file; "format=" ^ t.target_format; + let target_file = + match t.target_file with + | TargetFile s -> s + | TargetURI _ -> assert false in + arg_list "-drive" ["file=" ^ target_file; "format=" ^ t.target_format; "if=" ^ if_name; "index=" ^ string_of_int i; "media=disk"] @@ -141,7 +146,11 @@ object | BusSlotEmpty -> () | BusSlotTarget t -> - arg_list "-drive" ["file=" ^ t.target_file; "format=" ^ t.target_format; + let target_file = + match t.target_file with + | TargetFile s -> s + | TargetURI _ -> assert false in + arg_list "-drive" ["file=" ^ target_file; "format=" ^ t.target_format; "if=scsi"; "bus=0"; "unit=" ^ string_of_int i; "media=disk"] diff --git a/v2v/output_rhv.ml b/v2v/output_rhv.ml index 2bcd988c1..58e084a5c 100644 --- a/v2v/output_rhv.ml +++ b/v2v/output_rhv.ml @@ -230,9 +230,10 @@ object fun ({ target_overlay = ov } as t, image_uuid, vol_uuid) -> let ov_sd = ov.ov_sd in let target_file = images_dir // image_uuid // vol_uuid in + debug "RHV: will export %s to %s" ov_sd target_file; - { t with target_file = target_file } + { t with target_file = TargetFile target_file } ) (List.combine3 targets image_uuids vol_uuids) in (* Generate the .meta file associated with each volume. *) @@ -241,6 +242,10 @@ object targets in List.iter ( fun ({ target_file }, meta) -> + let target_file = + match target_file with + | TargetFile s -> s + | TargetURI _ -> assert false in let meta_filename = target_file ^ ".meta" in Changeuid.make_file changeuid_t meta_filename meta ) (List.combine targets metas); diff --git a/v2v/output_vdsm.ml b/v2v/output_vdsm.ml index d5911e80e..993261882 100644 --- a/v2v/output_vdsm.ml +++ b/v2v/output_vdsm.ml @@ -134,7 +134,7 @@ object debug "VDSM: will export %s to %s" ov_sd target_file; - { t with target_file = target_file } + { t with target_file = TargetFile target_file } ) (List.combine3 targets vdsm_params.image_uuids vdsm_params.vol_uuids) in (* Generate the .meta files associated with each volume. *) @@ -143,6 +143,10 @@ object vdsm_params.image_uuids targets in List.iter ( fun ({ target_file }, meta) -> + let target_file = + match target_file with + | TargetFile s -> s + | TargetURI _ -> assert false in let meta_filename = target_file ^ ".meta" in with_open_out meta_filename (fun chan -> output_string chan meta) ) (List.combine targets metas); diff --git a/v2v/types.ml b/v2v/types.ml index 1ffb09440..be86f1b3b 100644 --- a/v2v/types.ml +++ b/v2v/types.ml @@ -293,12 +293,15 @@ ov_source = %s ov.ov_source.s_qemu_uri type target = { - target_file : string; + target_file : target_file; target_format : string; target_estimated_size : int64 option; target_actual_size : int64 option; target_overlay : overlay; } +and target_file = + | TargetFile of string + | TargetURI of string let string_of_target t = sprintf "\ @@ -308,7 +311,9 @@ target_estimated_size = %s target_overlay = %s target_overlay.ov_source = %s " - t.target_file + (match t.target_file with + | TargetFile s -> "[file] " ^ s + | TargetURI s -> "[qemu] " ^ s) t.target_format (match t.target_estimated_size with | None -> "None" | Some i -> Int64.to_string i) diff --git a/v2v/types.mli b/v2v/types.mli index 9e2f8ceb4..95d890638 100644 --- a/v2v/types.mli +++ b/v2v/types.mli @@ -189,7 +189,7 @@ val string_of_overlay : overlay -> string (** {2 Target disks} *) type target = { - target_file : string; (** Destination file. *) + target_file : target_file; (** Destination file or QEMU URI. *) target_format : string; (** Destination format (eg. -of option). *) (* Note that the estimate is filled in by core v2v.ml code before @@ -203,6 +203,10 @@ type target = { } (** Target disk. *) +and target_file = + | TargetFile of string (** Target is a file. *) + | TargetURI of string (** Target is a QEMU URI. *) + val string_of_target : target -> string (** {2 Guest firmware} *) diff --git a/v2v/v2v.ml b/v2v/v2v.ml index 9edc080ff..94146b596 100644 --- a/v2v/v2v.ml +++ b/v2v/v2v.ml @@ -362,7 +362,7 @@ and init_targets cmdline output source overlays = * estimate_target_size will fill in the target_estimated_size field. * actual_target_size will fill in the target_actual_size field. *) - { target_file = ""; target_format = format; + { target_file = TargetFile ""; target_format = format; target_estimated_size = None; target_actual_size = None; target_overlay = ov } @@ -665,15 +665,24 @@ and copy_targets cmdline targets input output = at_exit (fun () -> if !delete_target_on_exit then ( List.iter ( - fun t -> try unlink t.target_file with _ -> () + fun t -> + match t.target_file with + | TargetURI _ -> () + | TargetFile s -> try unlink s with _ -> () ) targets ) ); let nr_disks = List.length targets in List.mapi ( fun i t -> - message (f_"Copying disk %d/%d to %s (%s)") - (i+1) nr_disks t.target_file t.target_format; + (match t.target_file with + | TargetFile s -> + message (f_"Copying disk %d/%d to %s (%s)") + (i+1) nr_disks s t.target_format; + | TargetURI s -> + message (f_"Copying disk %d/%d to qemu URI %s (%s)") + (i+1) nr_disks s t.target_format + ); debug "%s" (string_of_target t); (* We noticed that qemu sometimes corrupts the qcow2 file on @@ -693,33 +702,47 @@ and copy_targets cmdline targets input output = *) input#adjust_overlay_parameters t.target_overlay; - (* It turns out that libguestfs's disk creation code is - * considerably more flexible and easier to use than - * qemu-img, so create the disk explicitly using libguestfs - * then pass the 'qemu-img convert -n' option so qemu reuses - * the disk. - * - * Also we allow the output mode to actually create the disk - * image. This lets the output mode set ownership and - * permissions correctly if required. - *) - (* What output preallocation mode should we use? *) - let preallocation = - match t.target_format, cmdline.output_alloc with - | ("raw"|"qcow2"), Sparse -> Some "sparse" - | ("raw"|"qcow2"), Preallocated -> Some "full" - | _ -> None (* ignore -oa flag for other formats *) in - let compat = - match t.target_format with "qcow2" -> Some "1.1" | _ -> None in - output#disk_create - t.target_file t.target_format t.target_overlay.ov_virtual_size - ?preallocation ?compat; + (match t.target_file with + | TargetFile filename -> + (* It turns out that libguestfs's disk creation code is + * considerably more flexible and easier to use than + * qemu-img, so create the disk explicitly using libguestfs + * then pass the 'qemu-img convert -n' option so qemu reuses + * the disk. + * + * Also we allow the output mode to actually create the disk + * image. This lets the output mode set ownership and + * permissions correctly if required. + *) + (* What output preallocation mode should we use? *) + let preallocation = + match t.target_format, cmdline.output_alloc with + | ("raw"|"qcow2"), Sparse -> Some "sparse" + | ("raw"|"qcow2"), Preallocated -> Some "full" + | _ -> None (* ignore -oa flag for other formats *) in + let compat = + match t.target_format with "qcow2" -> Some "1.1" | _ -> None in + output#disk_create filename t.target_format + t.target_overlay.ov_virtual_size + ?preallocation ?compat - let cmd = [ Guestfs_config.qemu_img; "convert" ] @ + | TargetURI _ -> + (* XXX For the moment we assume that qemu URI outputs + * need no special work. We can change this in future. + *) + () + ); + + let cmd = + let filename = + match t.target_file with + | TargetFile filename -> "file:" ^ filename + | TargetURI uri -> uri in + [ Guestfs_config.qemu_img; "convert" ] @ (if not (quiet ()) then [ "-p" ] else []) @ [ "-n"; "-f"; "qcow2"; "-O"; t.target_format ] @ (if cmdline.compressed then [ "-c" ] else []) @ - [ overlay_file; t.target_file ] in + [ overlay_file; filename ] in let start_time = gettimeofday () in if run_command cmd <> 0 then error (f_"qemu-img command failed, see earlier errors"); @@ -772,11 +795,14 @@ and copy_targets cmdline targets input output = (* Update the target_actual_size field in the target structure. *) and actual_target_size target = - let size = - (* Ignore errors because we want to avoid failures after copying. *) - try Some (du target.target_file) - with Failure _ | Invalid_argument _ -> None in - { target with target_actual_size = size } + match target.target_file with + | TargetFile filename -> + let size = + (* Ignore errors because we want to avoid failures after copying. *) + try Some (du filename) + with Failure _ | Invalid_argument _ -> None in + { target with target_actual_size = size } + | TargetURI _ -> target (* Save overlays if --debug-overlays option was used. *) and preserve_overlays overlays src_name = -- 2.13.2 _______________________________________________ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs