Statistics
| Branch: | Tag: | Revision:

root / tools / ovfconverter @ 36c70d4d

History | View | Annotate | Download (6.7 kB)

1 ced78a66 Agata Murawska
#!/usr/bin/python
2 ced78a66 Agata Murawska
#
3 ced78a66 Agata Murawska
4 ced78a66 Agata Murawska
# Copyright (C) 2011 Google Inc.
5 ced78a66 Agata Murawska
#
6 ced78a66 Agata Murawska
# This program is free software; you can redistribute it and/or modify
7 ced78a66 Agata Murawska
# it under the terms of the GNU General Public License as published by
8 ced78a66 Agata Murawska
# the Free Software Foundation; either version 2 of the License, or
9 ced78a66 Agata Murawska
# (at your option) any later version.
10 ced78a66 Agata Murawska
#
11 ced78a66 Agata Murawska
# This program is distributed in the hope that it will be useful, but
12 ced78a66 Agata Murawska
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 ced78a66 Agata Murawska
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 ced78a66 Agata Murawska
# General Public License for more details.
15 ced78a66 Agata Murawska
#
16 ced78a66 Agata Murawska
# You should have received a copy of the GNU General Public License
17 ced78a66 Agata Murawska
# along with this program; if not, write to the Free Software
18 ced78a66 Agata Murawska
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 ced78a66 Agata Murawska
# 02110-1301, USA.
20 ced78a66 Agata Murawska
21 ced78a66 Agata Murawska
22 ced78a66 Agata Murawska
"""Tool to translate between ovf and ganeti backup format.
23 ced78a66 Agata Murawska
24 ced78a66 Agata Murawska
"""
25 ced78a66 Agata Murawska
26 ced78a66 Agata Murawska
import logging
27 ced78a66 Agata Murawska
import optparse
28 ced78a66 Agata Murawska
import os
29 ced78a66 Agata Murawska
30 ced78a66 Agata Murawska
from ganeti import cli
31 ced78a66 Agata Murawska
from ganeti import constants
32 ced78a66 Agata Murawska
from ganeti import errors
33 ced78a66 Agata Murawska
from ganeti import ovf
34 ced78a66 Agata Murawska
35 ced78a66 Agata Murawska
36 ced78a66 Agata Murawska
IMPORT_MODE = "import"
37 ced78a66 Agata Murawska
EXPORT_MODE = "export"
38 ced78a66 Agata Murawska
39 ced78a66 Agata Murawska
40 ced78a66 Agata Murawska
def CheckOptions(parser, options_dict, required, forbidden, excluding, mode):
41 ced78a66 Agata Murawska
  """Performes check on the command line options.
42 ced78a66 Agata Murawska
43 ced78a66 Agata Murawska
  Checks whether the required arguments are present and if none of the arguments
44 ced78a66 Agata Murawska
  not supported for the current mode are given.
45 ced78a66 Agata Murawska
46 ced78a66 Agata Murawska
  @type options_dict: list
47 ced78a66 Agata Murawska
  @param options_dict: dictionary containing all the options from the command
48 ced78a66 Agata Murawska
    line
49 ced78a66 Agata Murawska
  @type required: list
50 ced78a66 Agata Murawska
  @param required: list of pairs (option, argument) where 'option' is required
51 ced78a66 Agata Murawska
    in mode 'mode'
52 ced78a66 Agata Murawska
  @type forbidden: list
53 ced78a66 Agata Murawska
  @param forbidden: list of pairs (option, argument) which are not allowed in
54 ced78a66 Agata Murawska
    mode 'mode'
55 ced78a66 Agata Murawska
  @type excluding: list
56 ced78a66 Agata Murawska
  @param excluding: list of pairs (argument1, argument2); each pair contains
57 ced78a66 Agata Murawska
    mutually exclusive arguments
58 ced78a66 Agata Murawska
  @type mode: string
59 ced78a66 Agata Murawska
  @param mode: current mode of the converter
60 ced78a66 Agata Murawska
61 ced78a66 Agata Murawska
  """
62 ced78a66 Agata Murawska
  for (option, argument) in required:
63 ced78a66 Agata Murawska
    if not options_dict[option]:
64 ced78a66 Agata Murawska
      parser.error("Argument %s is required for %s" % (argument, mode))
65 ced78a66 Agata Murawska
  for (option, argument) in forbidden:
66 ced78a66 Agata Murawska
    if options_dict[option]:
67 ced78a66 Agata Murawska
      parser.error("Argument %s is not allowed in %s mode" % (argument, mode))
68 ced78a66 Agata Murawska
  for (arg1, arg2) in excluding:
69 ced78a66 Agata Murawska
    if options_dict[arg1] and options_dict[arg2]:
70 ced78a66 Agata Murawska
      parser.error("Arguments %s and %s exclude each other" % (arg1, arg2))
71 ced78a66 Agata Murawska
72 ced78a66 Agata Murawska
73 ced78a66 Agata Murawska
def ParseOptions():
74 ced78a66 Agata Murawska
  """Parses the command line options and arguments.
75 ced78a66 Agata Murawska
76 ced78a66 Agata Murawska
  In case of mismatching parameters, it will show the correct usage and exit.
77 ced78a66 Agata Murawska
78 ced78a66 Agata Murawska
  @rtype: tuple
79 ced78a66 Agata Murawska
  @return: (mode, sourcefile to read from, additional options)
80 ced78a66 Agata Murawska
81 ced78a66 Agata Murawska
  """
82 ced78a66 Agata Murawska
  usage = ("%%prog {%s|%s} <source-cfg-file> [options...]" %
83 ced78a66 Agata Murawska
           (IMPORT_MODE, EXPORT_MODE))
84 ced78a66 Agata Murawska
  parser = optparse.OptionParser(usage=usage)
85 ced78a66 Agata Murawska
86 ced78a66 Agata Murawska
  #global options
87 ced78a66 Agata Murawska
  parser.add_option(cli.DEBUG_OPT)
88 ced78a66 Agata Murawska
  parser.add_option(cli.VERBOSE_OPT)
89 ced78a66 Agata Murawska
  parser.add_option("-n", "--name", dest="name", action="store",
90 ced78a66 Agata Murawska
                    help="Name of the instance")
91 ced78a66 Agata Murawska
  parser.add_option("--output-dir", dest="output_dir",
92 ced78a66 Agata Murawska
                    help="Path to the output directory")
93 ced78a66 Agata Murawska
94 ced78a66 Agata Murawska
  #import options
95 ced78a66 Agata Murawska
  import_group = optparse.OptionGroup(parser, "Import options")
96 ced78a66 Agata Murawska
  import_group.add_option(cli.BACKEND_OPT)
97 ced78a66 Agata Murawska
  import_group.add_option(cli.DISK_OPT)
98 ced78a66 Agata Murawska
  import_group.add_option(cli.DISK_TEMPLATE_OPT)
99 ced78a66 Agata Murawska
  import_group.add_option(cli.HYPERVISOR_OPT)
100 ced78a66 Agata Murawska
  import_group.add_option(cli.NET_OPT)
101 ced78a66 Agata Murawska
  import_group.add_option(cli.NONICS_OPT)
102 ced78a66 Agata Murawska
  import_group.add_option(cli.OS_OPT)
103 ced78a66 Agata Murawska
  import_group.add_option(cli.OSPARAMS_OPT)
104 ced78a66 Agata Murawska
  import_group.add_option(cli.TAG_ADD_OPT)
105 ced78a66 Agata Murawska
  parser.add_option_group(import_group)
106 ced78a66 Agata Murawska
107 ced78a66 Agata Murawska
  #export options
108 ced78a66 Agata Murawska
  export_group = optparse.OptionGroup(parser, "Export options")
109 ced78a66 Agata Murawska
  export_group.add_option("--compress", dest="compression",
110 ced78a66 Agata Murawska
                          action="store_true", default=False,
111 ced78a66 Agata Murawska
                          help="The exported disk will be compressed to tar.gz")
112 ced78a66 Agata Murawska
  export_group.add_option("--external", dest="ext_usage",
113 ced78a66 Agata Murawska
                          action="store_true", default=False,
114 ced78a66 Agata Murawska
                          help="The package will be used externally (ommits the"
115 ced78a66 Agata Murawska
                               " Ganeti-specific parts of configuration)")
116 ced78a66 Agata Murawska
  export_group.add_option("-f", "--format", dest="disk_format",
117 ced78a66 Agata Murawska
                          action="store",
118 ced78a66 Agata Murawska
                          choices=("raw", "cow", "vmdk"),
119 ced78a66 Agata Murawska
                          help="Disk format for export (one of raw/cow/vmdk)")
120 ced78a66 Agata Murawska
  export_group.add_option("--ova", dest="ova_package",
121 ced78a66 Agata Murawska
                          action="store_true", default=False,
122 ced78a66 Agata Murawska
                          help="Export everything into OVA package")
123 ced78a66 Agata Murawska
  parser.add_option_group(export_group)
124 ced78a66 Agata Murawska
125 ced78a66 Agata Murawska
  options, args = parser.parse_args()
126 ced78a66 Agata Murawska
  if len(args) != 2:
127 ced78a66 Agata Murawska
    parser.error("Wrong number of arguments")
128 ced78a66 Agata Murawska
  mode = args.pop(0)
129 ced78a66 Agata Murawska
  input_path = os.path.abspath(args.pop(0))
130 ced78a66 Agata Murawska
131 ced78a66 Agata Murawska
  if mode == IMPORT_MODE:
132 ced78a66 Agata Murawska
    required = []
133 ced78a66 Agata Murawska
    forbidden = [
134 ced78a66 Agata Murawska
      ("compression", "--compress"),
135 ced78a66 Agata Murawska
      ("disk_format", "--format"),
136 ced78a66 Agata Murawska
      ("ext_usage", "--external"),
137 ced78a66 Agata Murawska
      ("ova_package", "--ova"),
138 ced78a66 Agata Murawska
    ]
139 ced78a66 Agata Murawska
    excluding = [("nics", "no_nics")]
140 ced78a66 Agata Murawska
  elif mode == EXPORT_MODE:
141 ced78a66 Agata Murawska
    required = [("disk_format", "--format")]
142 ced78a66 Agata Murawska
    forbidden = [
143 ced78a66 Agata Murawska
      ("beparams", "--backend-parameters"),
144 ced78a66 Agata Murawska
      ("disk_template", "--disk-template"),
145 ced78a66 Agata Murawska
      ("disks", "--disk"),
146 ced78a66 Agata Murawska
      ("hypervisor", "--hypervisor-parameters"),
147 ced78a66 Agata Murawska
      ("nics", "--net"),
148 ced78a66 Agata Murawska
      ("no_nics", "--no-nics"),
149 ced78a66 Agata Murawska
      ("os", "--os-type"),
150 ced78a66 Agata Murawska
      ("osparams", "--os-parameters"),
151 ced78a66 Agata Murawska
      ("tags", "--tags"),
152 ced78a66 Agata Murawska
    ]
153 ced78a66 Agata Murawska
    excluding = []
154 ced78a66 Agata Murawska
  else:
155 ced78a66 Agata Murawska
    parser.error("First argument should be either '%s' or '%s'" %
156 ced78a66 Agata Murawska
                 (IMPORT_MODE, EXPORT_MODE))
157 ced78a66 Agata Murawska
158 ced78a66 Agata Murawska
  options_dict = vars(options)
159 ced78a66 Agata Murawska
  CheckOptions(parser, options_dict, required, forbidden, excluding, mode)
160 ced78a66 Agata Murawska
161 ced78a66 Agata Murawska
  return (mode, input_path, options)
162 ced78a66 Agata Murawska
163 ced78a66 Agata Murawska
164 ced78a66 Agata Murawska
def SetupLogging(options):
165 ced78a66 Agata Murawska
  """Setting up logging infrastructure.
166 ced78a66 Agata Murawska
167 ced78a66 Agata Murawska
  @type options: optparse.Values
168 ced78a66 Agata Murawska
  @param options: parsed command line options
169 ced78a66 Agata Murawska
170 ced78a66 Agata Murawska
  """
171 ced78a66 Agata Murawska
  formatter = logging.Formatter("%(asctime)s: %(levelname)s %(message)s")
172 ced78a66 Agata Murawska
173 ced78a66 Agata Murawska
  stderr_handler = logging.StreamHandler()
174 ced78a66 Agata Murawska
  stderr_handler.setFormatter(formatter)
175 ced78a66 Agata Murawska
  if options.debug:
176 ced78a66 Agata Murawska
    stderr_handler.setLevel(logging.NOTSET)
177 ced78a66 Agata Murawska
  elif options.verbose:
178 ced78a66 Agata Murawska
    stderr_handler.setLevel(logging.INFO)
179 ced78a66 Agata Murawska
  else:
180 ced78a66 Agata Murawska
    stderr_handler.setLevel(logging.WARNING)
181 ced78a66 Agata Murawska
182 ced78a66 Agata Murawska
  root_logger = logging.getLogger("")
183 ced78a66 Agata Murawska
  root_logger.setLevel(logging.NOTSET)
184 ced78a66 Agata Murawska
  root_logger.addHandler(stderr_handler)
185 ced78a66 Agata Murawska
186 ced78a66 Agata Murawska
187 ced78a66 Agata Murawska
def main():
188 ced78a66 Agata Murawska
  """Main routine.
189 ced78a66 Agata Murawska
190 ced78a66 Agata Murawska
  """
191 ced78a66 Agata Murawska
  (mode, input_path, options) = ParseOptions()
192 ced78a66 Agata Murawska
  SetupLogging(options)
193 ced78a66 Agata Murawska
  logging.info("Chosen %s mode, reading the %s file", mode, input_path)
194 ced78a66 Agata Murawska
  assert mode in (IMPORT_MODE, EXPORT_MODE)
195 ced78a66 Agata Murawska
  converter = None
196 ced78a66 Agata Murawska
  try:
197 ced78a66 Agata Murawska
    if mode == IMPORT_MODE:
198 ced78a66 Agata Murawska
      converter = ovf.OVFImporter(input_path, options)
199 ced78a66 Agata Murawska
    elif mode == EXPORT_MODE:
200 ced78a66 Agata Murawska
      converter = ovf.OVFExporter(input_path, options)
201 ced78a66 Agata Murawska
    converter.Parse()
202 ced78a66 Agata Murawska
    converter.Save()
203 ced78a66 Agata Murawska
  except errors.OpPrereqError, err:
204 ced78a66 Agata Murawska
    if converter:
205 ced78a66 Agata Murawska
      converter.Cleanup()
206 ced78a66 Agata Murawska
    logging.exception(err)
207 ced78a66 Agata Murawska
    return constants.EXIT_FAILURE
208 ced78a66 Agata Murawska
209 ced78a66 Agata Murawska
210 ced78a66 Agata Murawska
if __name__ == "__main__":
211 ced78a66 Agata Murawska
  main()