From 7997ac9e9ee0b041c54d20f5e3a6c6aa68f5c2e7 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Tue, 16 Feb 2016 12:30:00 +0000 Subject: [PATCH] v2v: glance: Allow Glance backend to import multiple disks (RHBZ#1308769). (cherry picked from commit 6200ae7204f4db3b93707acf7356083e121f854f) --- v2v/output_glance.ml | 133 ++++++++++++++++++++++++++------------------------- v2v/virt-v2v.pod | 24 ++++++++++ 2 files changed, 93 insertions(+), 64 deletions(-) diff --git a/v2v/output_glance.ml b/v2v/output_glance.ml index f8c8806..1ca37eb 100644 --- a/v2v/output_glance.ml +++ b/v2v/output_glance.ml @@ -51,11 +51,7 @@ object if Sys.command "glance image-list > /dev/null" <> 0 then error (f_"glance: glance client is not installed or set up correctly. You may need to set environment variables or source a script to enable authentication. See preceding messages for details."); - (* OpenStack only supports single image VMs, I think? *) - let nr_targets = List.length targets in - if nr_targets <> 1 then - error (f_"glance: OpenStack conversion only supports virtual machines with a single disk image. This VM has %d") nr_targets; - + (* 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 @@ -66,68 +62,77 @@ object (* See #supported_firmware above. *) assert (target_firmware = TargetBIOS); - (* Upload the disk image (there should only be one - see above). *) - let { target_file = target_file; target_format = target_format } = - List.hd targets in - let cmd = - sprintf "glance image-create --name %s --disk-format=%s --container-format=bare --file %s" - (quote source.s_name) (quote target_format) target_file in - if verbose then printf "%s\n%!" cmd; - if Sys.command cmd <> 0 then - error (f_"glance: image upload to glance failed, see earlier errors"); + (* The first disk, assumed to be the system, will be called + * "guestname". Subsequent disks, assumed to be data disks, + * will be called "guestname-disk2" etc. The manual strongly + * hints you should import the data disks to Cinder. + *) + List.iteri ( + fun i { target_file = target_file; target_format = target_format } -> + let name = + if i == 0 then source.s_name + else sprintf "%s-disk%d" source.s_name (i+1) in - (* Set the properties (ie. metadata). *) - let min_ram = source.s_memory /^ 1024L /^ 1024L in - let properties = [ - "hw_disk_bus", - (match guestcaps.gcaps_block_bus with - | Virtio_blk -> "virtio" - | IDE -> "ide"); - "hw_vif_model", - (match guestcaps.gcaps_net_bus with - | Virtio_net -> "virtio" - | E1000 -> "e1000" - | RTL8139 -> "rtl8139"); - "architecture", guestcaps.gcaps_arch; - "hypervisor_type", "kvm"; - "vm_mode", "hvm"; - "os_type", inspect.i_type; - "os_distro", - (match inspect.i_distro with - (* http://docs.openstack.org/cli-reference/glance.html#image-service-property-keys *) - | "archlinux" -> "arch" - | "sles" -> "sled" - | x -> x (* everything else is the same in libguestfs and OpenStack *) - ) - ] in - let properties = - match inspect.i_major_version, inspect.i_minor_version with - | 0, 0 -> properties - | x, 0 -> ("os_version", string_of_int x) :: properties - | x, y -> ("os_version", sprintf "%d.%d" x y) :: properties in + let cmd = + sprintf "glance image-create --name %s --disk-format=%s --container-format=bare --file %s" + (quote name) (quote target_format) target_file in + if verbose then printf "%s\n%!" cmd; + if Sys.command cmd <> 0 then + error (f_"glance: image upload to glance failed, see earlier errors"); - (* Glance doesn't appear to check the properties. *) - let cmd = - sprintf "glance image-update --min-ram %Ld %s %s" - min_ram - (String.concat " " ( - List.map ( - fun (k, v) -> - sprintf "--property %s=%s" (quote k) (quote v) + (* Set the properties (ie. metadata). *) + let min_ram = source.s_memory /^ 1024L /^ 1024L in + let properties = [ + "hw_disk_bus", + (match guestcaps.gcaps_block_bus with + | Virtio_blk -> "virtio" + | IDE -> "ide"); + "hw_vif_model", + (match guestcaps.gcaps_net_bus with + | Virtio_net -> "virtio" + | E1000 -> "e1000" + | RTL8139 -> "rtl8139"); + "architecture", guestcaps.gcaps_arch; + "hypervisor_type", "kvm"; + "vm_mode", "hvm"; + "os_type", inspect.i_type; + "os_distro", + (match inspect.i_distro with + (* http://docs.openstack.org/cli-reference/glance.html#image-service-property-keys *) + | "archlinux" -> "arch" + | "sles" -> "sled" + | x -> x (* everything else is the same in libguestfs and OpenStack*) + ) + ] in + let properties = + match inspect.i_major_version, inspect.i_minor_version with + | 0, 0 -> properties + | x, 0 -> ("os_version", string_of_int x) :: properties + | x, y -> ("os_version", sprintf "%d.%d" x y) :: properties in + + (* Glance doesn't appear to check the properties. *) + let cmd = + sprintf "glance image-update --min-ram %Ld %s %s" + min_ram + (String.concat " " + (List.map ( + fun (k, v) -> + sprintf "--property %s=%s" (quote k) (quote v) + ) properties + )) + (quote name) in + if verbose then printf "%s\n%!" cmd; + if Sys.command cmd <> 0 then ( + warning ~prog (f_"glance: failed to set image properties (ignored)"); + (* Dump out the image properties so the user can set them. *) + printf "Image properties:\n"; + printf " --min-ram %Ld\n" min_ram; + List.iter ( + fun (k, v) -> + printf " --property %s=%s" (quote k) (quote v) ) properties - )) - (quote source.s_name) in - if verbose then printf "%s\n%!" cmd; - if Sys.command cmd <> 0 then ( - warning ~prog (f_"glance: failed to set image properties (ignored)"); - (* Dump out the image properties so the user can set them. *) - printf "Image properties:\n"; - printf " --min-ram %Ld\n" min_ram; - List.iter ( - fun (k, v) -> - printf " --property %s=%s" (quote k) (quote v) - ) properties - ) + ) + ) targets end let output_glance = new output_glance diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod index 876d5f6..d4fdf5d 100644 --- a/v2v/virt-v2v.pod +++ b/v2v/virt-v2v.pod @@ -1158,6 +1158,30 @@ Glance image upload doesn't appear to correctly handle sparseness. For this reason, using qcow2 will be faster and use less space on the Glance server. Use the virt-v2v S> option. +=head2 Glance and multiple disks + +If the guest has a single disk, then the name of the disk in Glance +will be the name of the guest. You can control this using the I<-on> +option. + +Glance doesn't have a concept of associating multiple disks with a +single guest, and Nova doesn't allow you to boot a guest from multiple +Glance disks either. If the guest has multiple disks, then the first +(assumed to be the system disk) will have the name of the guest, and +the second and subsequent data disks will be called +C-disk2>, C-disk3> etc. It may be best to +leave the system disk in Glance, and import the data disks to Cinder +(see next section). + +=head2 Importing disks into Cinder + +Since most virt-v2v guests are "pets", Glance is perhaps not the best +place to store them. There is no way for virt-v2v to upload directly +to Cinder (L), so instead you +must import them yourself by doing: + + cinder create --image-id + =head1 RESOURCE REQUIREMENTS =head2 Network -- 1.8.3.1