>From e727dd981486599bc0390c62414050af3690fce5 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Tue, 25 Sep 2018 10:25:27 +0100 Subject: [PATCH] v2v: openstack: Read server-id from metadata service. Unless specified on the command line, read the server-id from the OpenStack Metadata service. --- v2v/output_openstack.ml | 45 ++++++++++++++++++++++++++++------------- v2v/virt-v2v.pod | 12 ++++++++--- 2 files changed, 40 insertions(+), 17 deletions(-) diff --git a/v2v/output_openstack.ml b/v2v/output_openstack.ml index 8763de818..b901ab262 100644 --- a/v2v/output_openstack.ml +++ b/v2v/output_openstack.ml @@ -37,14 +37,16 @@ let available_timeout = 300 (* seconds *) (* Timeout waiting for Cinder volumes to attach to the appliance. *) let attach_timeout = 60 (* seconds *) +(* Metadata service URL. *) +let meta_uri = "http://169.254.169.254/openstack/latest/meta_data.json" + (* The -oo options supported by this output method. *) type os_options = { (* The server name or UUID of the conversion appliance where - * virt-v2v is currently running. In future we may be able - * to make this optional and derive it from the OpenStack - * metadata service instead. + * virt-v2v is currently running. If None, we try to fetch it + * from the OpenStack Metadata Service. *) - server_id : string; + server_id : string option; (* All other OpenStack parameters, passed through unmodified * on the openstack command line. @@ -62,7 +64,7 @@ type os_options = { } let print_output_options () = - printf (f_"virt-v2v -oo server-id= [os-*=...] + printf (f_"virt-v2v [-oo server-id=] [-oo os-*=...] Specify the name or UUID of the conversion appliance using @@ -113,11 +115,7 @@ let parse_output_options options = let opt = sprintf "--%s=%s" k v in authentication := opt :: !authentication ) options; - let server_id = - match !server_id with - | None -> - error (f_"openstack: -oo server-id= not present"); - | Some server_id -> server_id in + let server_id = !server_id in let authentication = List.rev !authentication in let guest_id = !guest_id in let dev_disk_by_id = !dev_disk_by_id in @@ -141,6 +139,27 @@ class output_openstack output_conn output_password output_storage output_conn; !args in + (* The server ID (the name or UUID of the conversion appliance) can + * be supplied on the command line. If not we get it from the + * Metadata Service. Lazy so we don't evaluate this until we use + * it the first time. + *) + let server_id = lazy ( + match os_options.server_id with + | Some server_id -> server_id + | None -> + (* This will make Curl fetch the URL to stdout, and fail if + * there is a server error. The failure will cause virt-v2v to + * exit with an error. + *) + let curl_args = ["url", Some meta_uri; "fail", None] in + let curl = Curl.create ~proxy:Curl.UnsetProxy curl_args in + let json = Curl.run curl in + let json = String.concat "\n" json in + let json = json_parser_tree_parse json in + object_get_string "uuid" json + ) in + (* We use this convenient wrapper around [Tools_utils.run_command] * for two reasons: (1) Because we want to run openstack with * extra_args. (2) OpenStack commands are noisy so we want to @@ -281,8 +300,7 @@ class output_openstack output_conn output_password output_storage * Returns the block device name. *) let attach_volume id = - let args = [ "server"; "add"; "volume"; - os_options.server_id; id ] in + let args = [ "server"; "add"; "volume"; Lazy.force server_id; id ] in if run_openstack_command args <> 0 then error (f_"openstack: failed to attach cinder volume to VM, see earlier error messages"); @@ -328,8 +346,7 @@ class output_openstack output_conn output_password output_storage * there's nothing we could do with the error anyway. *) let detach_volume id = - let args = [ "server"; "remove"; "volume"; - os_options.server_id; id ] in + let args = [ "server"; "remove"; "volume"; Lazy.force server_id; id ] in ignore (run_openstack_command args) in diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod index 1213af091..e028540e2 100644 --- a/v2v/virt-v2v.pod +++ b/v2v/virt-v2v.pod @@ -721,6 +721,9 @@ Certificate Authority. For I<-o openstack> (L) only, set the name of the conversion appliance where virt-v2v is running. +If not set then virt-v2v will try to get the server ID from the +OpenStack Metadata Service (which must be available). + =item B<-oo vdsm-compat=0.10> =item B<-oo vdsm-compat=1.1> @@ -2211,7 +2214,7 @@ The reason for this is because to create Cinder volumes that will contain the guest data (for the converted guest) we must attach those Cinder volumes to an OpenStack virtual machine. -When virt-v2v is running in the conversion appliance, you must supply +When virt-v2v is running in the conversion appliance, you may supply the name or UUID of the conversion appliance to virt-v2v, eg: $ openstack server list @@ -2228,6 +2231,9 @@ or: # virt-v2v [...] -o openstack -oo server-id=test1 +If the I<-oo server-id> is not supplied then virt-v2v will try to +get the server ID from the OpenStack Metadata Service. + You can run many parallel conversions inside a single conversion appliance if you want, subject to having enough resources available. However OpenStack itself imposes a limit that you should be aware of: @@ -2284,12 +2290,12 @@ guests. The final command to convert the guest, running as root, will be: # virt-v2v [-i options ...] \ - -o openstack -oo server-id=NAME|UUID [-oo guest-id=ID] + -o openstack [-oo server-id=NAME|UUID] [-oo guest-id=ID] If you include authentication options on the command line then: # virt-v2v [-i options ...] \ - -o openstack -oo server-id=NAME|UUID -oo os-username=admin [etc] + -o openstack [-oo server-id=NAME|UUID] -oo os-username=admin [etc] =head2 OPENSTACK: BOOTING THE GUEST -- 2.19.0.rc0