# HG changeset patch # User john.levon@xxxxxxx # Date 1215697570 25200 # Node ID 91d463e8e9921844271a90f416e0e6d94fd2af40 # Parent f5e35abf05eb1fa3b64af2cf2cdcfc26139025fd virt-convert: add format detection Add format detection, along with detection for VMX Signed-off-by: John Levon <john.levon@xxxxxxx> diff --git a/virt-convert b/virt-convert --- a/virt-convert +++ b/virt-convert @@ -1,9 +1,10 @@ #!/usr/bin/python -# -# Convert a VMware(tm) virtual machine into an XML image description # # Copyright 2008 Red Hat, Inc. # Joey Boggs <jboggs@xxxxxxxxxx> +# +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. # # 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 @@ -49,8 +50,7 @@ opts.add_option("-d", "--debug", action="store_true", dest="debug", help=("Print debugging information")) opts.add_option("-i", "--input-format", action="store", - dest="input_format", default="vmx", - help=("Input format, e.g. 'vmx'")) + dest="input_format", help=("Input format, e.g. 'vmx'")) opts.add_option("-o", "--output-format", action="store", dest="output_format", default="virt-image", help=("Output format, e.g. 'virt-image'")) @@ -71,35 +71,45 @@ options.disk_format not in diskcfg.disk_formats()): opts.error("Unknown output disk format \"%s\"" % options.disk_format) - # hard-code for now - if options.input_format != "vmx": - opts.error(("Unsupported input format \"%s\"" % options.input_format)) - if options.output_format != "virt-image": - opts.error(("Unsupported output format \"%s\"" - % options.output_format)) - if os.path.isdir(args[0]): - vmx_files = [x for x in os.listdir(args[0]) if x.endswith(".vmx") ] - if (len(vmx_files)) == 0: - opts.error(("No VM definition file was found in %s" % args[0])) - if (len(vmx_files)) > 1: - opts.error(("Too many .vmx definitions found in %s" % args[0])) - options.input_file = os.path.join(args[0], vmx_files[0]) - options.input_dir = args[0] - else: - options.input_file = args[0] - options.input_dir = os.path.dirname(os.path.realpath(args[0])) - if len(args) == 1: options.output_file = None options.output_dir = None if os.path.isdir(args[0]): - options.output_dir = options.input_dir + options.output_dir = args[0] elif os.path.isdir(args[1]) or args[1].endswith("/"): options.output_file = None options.output_dir = args[1] else: options.output_file = args[1] options.output_dir = os.path.dirname(os.path.realpath(args[1])) + + if options.output_format not in formats.formats(): + opts.error(("Unknown output format \"%s\"" % options.output_format)) + if options.output_format not in formats.output_formats(): + opts.error(("No output handler for format \"%s\"" + % options.output_format)) + + if not options.input_format: + try: + (args[0], options.input_format) = formats.find_input(args[0]) + except StandardError, e: + opts.error("Couldn't determine input format for \"%s\": %s" % + (args[0], e.message)) + sys.exit(1) + + if options.input_format not in formats.formats(): + opts.error(("Unknown input format \"%s\"" % options.input_format)) + if options.input_format not in formats.input_formats(): + opts.error(("No input handler for format \"%s\"" + % options.input_format)) + + if os.path.isdir(args[0]): + (options.input_file, _) = formats.find_input(args[0], + options.input_format) + options.input_dir = args[0] + else: + options.input_file = args[0] + options.input_dir = os.path.dirname(os.path.realpath(args[0])) return options @@ -134,19 +144,8 @@ options = parse_args() cli.setupLogging("virt-convert", options.debug) - try: - inp = formats.find_parser_by_name(options.input_format) - except: - logging.error("No parser of format \"%s\" was found." % - options.input_format) - sys.exit(1) - - try: - outp = formats.find_parser_by_name(options.output_format) - except: - logging.error("No parser of format \"%s\" was found." % - options.output_format) - sys.exit(1) + inp = formats.parser_by_name(options.input_format) + outp = formats.parser_by_name(options.output_format) vmdef = None diff --git a/virtconv/formats.py b/virtconv/formats.py --- a/virtconv/formats.py +++ b/virtconv/formats.py @@ -17,6 +17,8 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, # MA 02110-1301 USA. # + +import os _parsers = [ ] @@ -66,11 +68,13 @@ global _parsers _parsers += [ parser ] -def find_parser_by_name(name): +def parser_by_name(name): """ - Return the parser of the given name + Return the parser of the given name. """ - return [p for p in _parsers if p.name == name][0] or None + parsers = [p for p in _parsers if p.name == name] + if len(parsers): + return parsers[0] def find_parser_by_file(input_file): """ @@ -80,3 +84,46 @@ if p.identify_file(input_file): return p return None + +def formats(): + """ + Return a list of supported formats. + """ + return [p.name for p in _parsers] + +def input_formats(): + """ + Return a list of supported input formats. + """ + return [p.name for p in _parsers if p.can_import] + +def output_formats(): + """ + Return a list of supported output formats. + """ + return [p.name for p in _parsers if p.can_export] + +def find_input(path, format = None): + """ + Search for a configuration file automatically. If @format is given, + then only search using a matching format parser. + """ + + if os.path.isdir(path): + files = os.listdir(path) + + for p in _parsers: + if not p.can_identify: + continue + if format and format != p.name: + continue + + if os.path.isfile(path): + if p.identify_file(path): + return (path, p.name) + elif os.path.isdir(path): + for cfgfile in [ x for x in files if x.endswith(p.suffix) ]: + if p.identify_file(os.path.join(path, cfgfile)): + return (os.path.join(path, cfgfile), p.name) + + raise StandardError("unknown format") diff --git a/virtconv/parsers/virtimage.py b/virtconv/parsers/virtimage.py --- a/virtconv/parsers/virtimage.py +++ b/virtconv/parsers/virtimage.py @@ -81,6 +81,9 @@ """ name = "virt-image" suffix = ".virt-image.xml" + can_import = False + can_export = True + can_identify = False @staticmethod def identify_file(input_file): diff --git a/virtconv/parsers/vmx.py b/virtconv/parsers/vmx.py --- a/virtconv/parsers/vmx.py +++ b/virtconv/parsers/vmx.py @@ -22,6 +22,8 @@ import virtconv.vmcfg as vmcfg import virtconv.diskcfg as diskcfg +import re + class vmx_parser(formats.parser): """ Support for VMWare .vmx files. Note that documentation is @@ -31,13 +33,23 @@ name = "vmx" suffix = ".vmx" + can_import = True + can_export = False + can_identify = True @staticmethod def identify_file(input_file): """ Return True if the given file is of this format. """ - raise NotImplementedError + infile = open(input_file, "r") + line = infile.readline() + infile.close() + + # some .vmx files don't bother with the header + if re.match(r'^config.version\s+=', line): + return True + return re.match(r'^#!\s*/usr/bin/vm(ware|player)', line) is not None @staticmethod def import_file(input_file): _______________________________________________ et-mgmt-tools mailing list et-mgmt-tools@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/et-mgmt-tools