Unless specified on the command line, read the server-id from the
OpenStack Metadata service.
---
v2v/output_openstack.ml | 45 +++++++++++++++++++++----------
v2v/virt-v2v-output-openstack.pod | 13 +++++----
v2v/virt-v2v.pod | 3 +++
3 files changed, 42 insertions(+), 19 deletions(-)
diff --git a/v2v/output_openstack.ml b/v2v/output_openstack.ml
index d187f1d5d..b2cb45208 100644
--- a/v2v/output_openstack.ml
+++ b/v2v/output_openstack.ml
@@ -40,14 +40,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.
@@ -70,7 +72,7 @@ type os_options = {
}
let print_output_options () =
- printf (f_"virt-v2v -oo server-id=<NAME|UUID> [os-*=...]
+ printf (f_"virt-v2v [-oo server-id=<NAME|UUID>] [-oo os-*=...]
Specify the name or UUID of the conversion appliance using
@@ -128,11 +130,7 @@ let parse_output_options options =
| k, _ ->
error (f_"-o openstack: unknown output option ā-oo %sā") k
) options;
- let server_id =
- match !server_id with
- | None ->
- error (f_"openstack: -oo server-id=<NAME|UUID> not present");
- | Some server_id -> server_id in
+ let server_id = !server_id in
let authentication = List.rev !authentication in
let verify_server_certificate = !verify_server_certificate in
let guest_id = !guest_id in
@@ -160,6 +158,27 @@ class output_openstack output_conn output_password output_storage
List.push_back args "--insecure";
!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
+
let error_unless_openstack_command_exists () =
try ignore (which openstack_binary)
with Executable_not_found _ ->
@@ -313,8 +332,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");
@@ -360,8 +378,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-output-openstack.pod b/v2v/virt-v2v-output-openstack.pod
index f5f44bded..4cddce61c 100644
--- a/v2v/virt-v2v-output-openstack.pod
+++ b/v2v/virt-v2v-output-openstack.pod
@@ -5,7 +5,7 @@ virt-v2v-output-openstack - Using virt-v2v to convert guests to OpenStack
=head1 SYNOPSIS
virt-v2v [-i* options] -o openstack
- -oo server-id=SERVER
+ [-oo server-id=SERVER]
[-oo guest-id=GUEST]
[-oo verify-server-certificate=false]
[-oo os-username=admin] [-oo os-*=*]
@@ -20,7 +20,7 @@ I<-o openstack> should be used normally.
=over 4
-=item B<-o openstack> B<-oo server-id=>SERVER [...]
+=item B<-o openstack>
Full description: L</OUTPUT TO OPENSTACK>
@@ -57,7 +57,7 @@ Cinder volumes to an OpenStack virtual machine.
The C<openstack> command must be installed in the appliance. We use
it for communicating with OpenStack.
-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
@@ -74,6 +74,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:
@@ -137,12 +140,12 @@ I<--insecure> option to the C<openstack> command.
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
diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod
index 9a555c3be..ce3d2ced8 100644
--- a/v2v/virt-v2v.pod
+++ b/v2v/virt-v2v.pod
@@ -611,6 +611,9 @@ Certificate Authority.
For I<-o openstack> (L<virt-v2v-output-openstack(1)>) 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>
--
2.20.1