File: input_vmx.ml

package info (click to toggle)
virt-v2v 2.6.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 27,132 kB
  • sloc: ml: 19,674; sh: 7,631; ansic: 6,897; makefile: 3,261; python: 1,114; perl: 852; xml: 114
file content (132 lines) | stat: -rw-r--r-- 4,731 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
(* helper-v2v-input
 * Copyright (C) 2009-2021 Red Hat Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *)

open Printf
open Unix

open Std_utils
open Tools_utils
open Common_gettext.Gettext

open Types
open Utils

open Parse_domain_from_vmx
open Input

module VMX = struct
  let to_string options args = String.concat " " ("-i vmx" :: args)

  let query_input_options () =
    printf (f_"No input options can be used in this mode.\n")

  let rec setup dir options args =
    if options.input_options <> [] then
      error (f_"no -io (input options) are allowed here");

    if not options.read_only then
      error (f_"in-place mode does not work with VMX source");

    let vmx_source =
      match args with
      | [arg] ->
         let input_password =
           match options.input_password with
           | None -> None
           | Some ip -> Some (Nbdkit_ssh.PasswordFile ip) in
         let input_transport =
           match options.input_transport with
           | None -> None
           | Some `SSH -> Some `SSH
           | Some `VDDK ->
              error (f_"-i vmx: cannot use -it vddk in this input mode") in
         vmx_source_of_arg input_password input_transport arg
      | _ ->
         error (f_"-i vmx: expecting a VMX file or ssh:// URI") in

    let source, filenames = parse_domain_from_vmx vmx_source in

    (match vmx_source with
     | File vmx_filename ->
        (* Local file in VMDK format, use qemu-nbd. *)
        List.iteri (
          fun i filename ->
            let socket = sprintf "%s/in%d" dir i in
            On_exit.unlink socket;

            let cmd = QemuNBD.create
                        (absolute_path_from_other_file vmx_filename filename) in
            QemuNBD.set_snapshot cmd true; (* protective overlay *)
            QemuNBD.set_format cmd (Some "vmdk");
            let _, pid = QemuNBD.run_unix socket cmd in
            On_exit.kill pid
        ) filenames

     | SSH (password, uri) ->
        List.iteri (
          fun i filename ->
            let socket = sprintf "%s/in%d" dir i in
            On_exit.unlink socket;

            let vmx_path =
              match uri.uri_path with
              | None -> assert false (* checked by vmx_source_of_arg *)
              | Some path -> path in
            let abs_path = absolute_path_from_other_file vmx_path filename in
            let flat_vmdk = PCRE.replace (PCRE.compile "\\.vmdk$")
                              "-flat.vmdk" abs_path in

            let server =
              match uri.uri_server with
              | None -> assert false (* checked by vmx_source_of_arg *)
              | Some server -> server in
            let port =
              match uri.uri_port with
              | i when i <= 0 -> None
              | i -> Some (string_of_int i) in
            let user = uri.Xml.uri_user in

            (* RHBZ#1774386 *)
            if not (Ssh.remote_file_exists ?password ?port ~server ?user
                      flat_vmdk) then
              error (f_"This transport does not support guests with snapshots. \
                        Either collapse the snapshots for this guest and try \
                        the conversion again, or use one of the alternate \
                        conversion methods described in \
                        virt-v2v-input-vmware(1) section \"NOTES\".");

            let cor = dir // "convert" in
            let bandwidth = options.bandwidth in
            let nbdkit = Nbdkit_ssh.create_ssh ?bandwidth ~cor ?password
                           ~server ?port ?user flat_vmdk in
            let _, pid = Nbdkit.run_unix socket nbdkit in
            On_exit.kill pid
        ) filenames
    );

    source

  (* The filename can be an absolute path, but is more often a
   * path relative to the location of the vmx file (which might
   * be remote over SSH).
   *)
  and absolute_path_from_other_file other_filename filename =
    if not (Filename.is_relative filename) then filename
    else (Filename.dirname (absolute_path other_filename)) // filename

end