Extend virt-unpack options Fix up virt-unpack options to allow both input and output directories, and formats other than vmx->virt-image. This is just the first step of moving towards virt-convert. Signed-off-by: John Levon <john.levon@xxxxxxx> diff --git a/man/en/virt-unpack.1 b/man/en/virt-unpack.1 --- a/man/en/virt-unpack.1 +++ b/man/en/virt-unpack.1 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pod::Man 2.16 (Pod::Simple 3.05) +.\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.32 .\" .\" Standard preamble: .\" ======================================================================== @@ -25,11 +25,11 @@ .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left -.\" double quote, and \*(R" will give a right double quote. \*(C+ will -.\" give a nicer C++. Capital omega is used to do unbreakable dashes and -.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, -.\" nothing in troff, for use with C<>. -.tr \(*W- +.\" double quote, and \*(R" will give a right double quote. | will give a +.\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used to +.\" do unbreakable dashes and therefore won't be available. \*(C` and \*(C' +.\" expand to `' in nroff, nothing in troff, for use with C<>. +.tr \(*W-|\(bv\*(Tr .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- @@ -48,25 +48,22 @@ . ds R" '' 'br\} .\" -.\" Escape single quotes in literal strings from groff's Unicode transform. -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. -.ie \nF \{\ +.if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . nr % 0 . rr F .\} -.el \{\ -. de IX -.. -.\} +.\" +.\" For nroff, turn off justification. Always turn off hyphenation; it makes +.\" way too many mistakes in technical documents. +.hy 0 +.if n .na .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. @@ -132,42 +129,51 @@ .\" ======================================================================== .\" .IX Title "VIRT-UNPACK 1" -.TH VIRT-UNPACK 1 "2008-07-01" "perl v5.10.0" "User Contributed Perl Documentation" -.\" For nroff, turn off justification. Always turn off hyphenation; it makes -.\" way too many mistakes in technical documents. -.if n .ad l -.nh +.TH VIRT-UNPACK 1 "2008-07-01" "perl v5.8.8" "Virtual Machine Install Tools" .SH "NAME" -virt\-unpack \- convert virtual machines from VMware(tm) format into an xml image descriptor +virt\-unpack \- convert virtual machines between formats .SH "SYNOPSIS" .IX Header "SYNOPSIS" -\&\fBvirt-unpack\fR [\s-1OPTION\s0]... \s-1IMAGE\s0.VMX +\&\fBvirt-unpack\fR [\s-1OPTION\s0]... \s-1INPUT\s0.VMX|INPUT\-DIR [\s-1OUTPUT\s0.XML|OUTPUT\-DIR] .SH "DESCRIPTION" .IX Header "DESCRIPTION" -\&\fBvirt-unpack\fR is a command line tool for converting virtual machines from an -VMware(tm) format machine into an \s-1XML\s0 image descriptor \f(CW\*(C`IMAGE.XML\*(C'\fR (\fIvirt\-image\fR\|(5)). -The basic configuration of the virtual machine are taken from the VMware configuration file (e.g., -disk image files, memory, name, vcpus) and a new \s-1XML\s0 image descriptor file is created using -these values. The conversion process requires that all necessary kernel modules and configuration -to boot using Xen or \s-1KVM\s0 are completed prior to running this tool. +\&\fBvirt-unpack\fR is a command line tool for converting virtual machines +from one format to another. Pass in either a \s-1VM\s0 definition file (such +as VMWare vmx format) or a directory containing a \s-1VM\s0. By default, a new +\&\s-1VM\s0 definition file, and converted disk images, will be placed in a new +output directory. +.PP +If an output directory is specified, it will be created if necessary, +and the output \s-1VM\s0 definition placed within, along with any disk images +as needed. +.PP +If an output \s-1VM\s0 definition file is specified, it will be created +alongside any disks in the same directory. .SH "OPTIONS" .IX Header "OPTIONS" Any of the options can be omitted, in which case \fBvirt-unpack\fR will use defaults when required. +An input \s-1VM\s0 definition or containing directory must be provided. By +default, an output directory is generated based upon the name of the \s-1VM\s0. +The default input format is VMWare vmx, and the default output format is +a libvirt \*(L"image\*(R" \s-1XML\s0 definition (see \fIvirt\-image\fR\|(5)). .IP "\-h, \-\-help" 4 .IX Item "-h, --help" Show the help message and exit .IP "\-a \s-1ARCH\s0, \-\-arch=ARCH" 4 .IX Item "-a ARCH, --arch=ARCH" -Architecture of the virtual machine (i686/x86_64,ppc) +Architecture of the virtual machine (i686, x86_64, ppc) .IP "\-v, \-\-hvm Create a fully virtualized guest image" 4 .IX Item "-v, --hvm Create a fully virtualized guest image" Convert machine to a hvm/qemu based image (this is the default if paravirt is not specified) .IP "\-p, \-\-paravirt Create a paravirtualized guest image" 4 .IX Item "-p, --paravirt Create a paravirtualized guest image" Convert machine to a paravirt xen based image -.IP "\-o \s-1OUTPUTDIR\s0, \-\-outputdir=NAME" 4 -.IX Item "-o OUTPUTDIR, --outputdir=NAME" -Directory in which files will be placed +.IP "\-i format" 4 +.IX Item "-i format" +Input format. Currently, \f(CW\*(C`vmx\*(C'\fR is the only supported input format. +.IP "\-o format" 4 +.IX Item "-o format" +Output format. Currently, \f(CW\*(C`virt\-image\*(C'\fR is the only supported output format. .IP "\-d, \-\-debug" 4 .IX Item "-d, --debug" Print debugging information @@ -176,13 +182,13 @@ Convert a paravirt guest from \f(CW\*(C` Convert a paravirt guest from \f(CW\*(C`image.vmx\*(C'\fR: .PP .Vb 1 -\& # virt\-unpack image.vmx \-\-arch=i686 \-\-paravirt +\& # virt-unpack --arch=i686 --paravirt image.vmx .Ve .PP -Convert a hvm guest and output the created file to /tmp +Convert a 64\-bit hvm guest: .PP .Vb 1 -\& # virt\-unpack image.vmx \-\-arch=x86_64 \-\-hvm \-\-outputdir /tmp +\& # virt-unpack --arch=x86_64 vmx-appliance/ hvm-appliance/ .Ve .SH "AUTHOR" .IX Header "AUTHOR" diff --git a/man/en/virt-unpack.pod b/man/en/virt-unpack.pod --- a/man/en/virt-unpack.pod +++ b/man/en/virt-unpack.pod @@ -2,25 +2,34 @@ =head1 NAME -virt-unpack - convert virtual machines from VMware(tm) format into an xml image descriptor +virt-unpack - convert virtual machines between formats =head1 SYNOPSIS -B<virt-unpack> [OPTION]... IMAGE.VMX +B<virt-unpack> [OPTION]... INPUT.VMX|INPUT-DIR [OUTPUT.XML|OUTPUT-DIR] =head1 DESCRIPTION -B<virt-unpack> is a command line tool for converting virtual machines from an -VMware(tm) format machine into an XML image descriptor C<IMAGE.XML> (L<virt-image(5)>). -The basic configuration of the virtual machine are taken from the VMware configuration file (e.g., -disk image files, memory, name, vcpus) and a new XML image descriptor file is created using -these values. The conversion process requires that all necessary kernel modules and configuration -to boot using Xen or KVM are completed prior to running this tool. +B<virt-unpack> is a command line tool for converting virtual machines +from one format to another. Pass in either a VM definition file (such +as VMWare vmx format) or a directory containing a VM. By default, a new +VM definition file, and converted disk images, will be placed in a new +output directory. +If an output directory is specified, it will be created if necessary, +and the output VM definition placed within, along with any disk images +as needed. + +If an output VM definition file is specified, it will be created +alongside any disks in the same directory. =head1 OPTIONS Any of the options can be omitted, in which case B<virt-unpack> will use defaults when required. +An input VM definition or containing directory must be provided. By +default, an output directory is generated based upon the name of the VM. +The default input format is VMWare vmx, and the default output format is +a libvirt "image" XML definition (see L<virt-image(5)>). =over 4 @@ -30,7 +39,7 @@ Show the help message and exit =item -a ARCH, --arch=ARCH -Architecture of the virtual machine (i686/x86_64,ppc) +Architecture of the virtual machine (i686, x86_64, ppc) =item -v, --hvm Create a fully virtualized guest image @@ -40,9 +49,13 @@ Convert machine to a hvm/qemu based imag Convert machine to a paravirt xen based image -=item -o OUTPUTDIR, --outputdir=NAME +=item -i format -Directory in which files will be placed +Input format. Currently, C<vmx> is the only supported input format. + +=item -o format + +Output format. Currently, C<virt-image> is the only supported output format. =item -d, --debug @@ -54,11 +67,11 @@ Print debugging information Convert a paravirt guest from C<image.vmx>: - # virt-unpack image.vmx --arch=i686 --paravirt + # virt-unpack --arch=i686 --paravirt image.vmx -Convert a hvm guest and output the created file to /tmp +Convert a 64-bit hvm guest: - # virt-unpack image.vmx --arch=x86_64 --hvm --outputdir /tmp + # virt-unpack --arch=x86_64 vmx-appliance/ hvm-appliance/ =head1 AUTHOR diff --git a/virt-unpack b/virt-unpack old mode 100644 new mode 100755 --- a/virt-unpack +++ b/virt-unpack @@ -28,32 +28,65 @@ import pdb import pdb import shutil import logging +import errno from optparse import OptionParser, OptionValueError def parse_args(): parser = OptionParser() - parser.set_usage("%prog [options] image.vmx") + parser.set_usage("%prog [options] inputdir|input.vmx [outputdir|output.xml]") parser.add_option("-a", "--arch", type="string", dest="arch", help=("Machine Architecture Type (i686/x86_64/ppc)")) parser.add_option("-t", "--type", type="string", dest="type", help=("Output virtualization type (hvm, paravirt")) parser.add_option("-d", "--debug", action="store_true", dest="debug", help=("Print debugging information")) - parser.add_option("-o", "--outputdir", type="string", dest="outputdir", - help=("Output directory in which files will be created")) + parser.add_option("-i", "--input-format", action="store_true", + dest="inputformat", default="vmx", + help=("Input format, e.g. 'vmx'")) + parser.add_option("-o", "--output-format", action="store_true", + dest="outputformat", default="virt-image", + help=("Output format, e.g. 'virt-image'")) parser.add_option("-v", "--hvm", action="store_true", dest="fullvirt", help=("This guest should be a fully virtualized guest")) parser.add_option("-p", "--paravirt", action="store_true", dest="paravirt", help=("This guest should be a paravirtualized guest")) - (options,args) = parser.parse_args() if len(args) < 1: - parser.error(("You need to provide an image XML descriptor")) - options.file = args[0] + parser.error(("You need to provide an input VM definition")) + if len(args) > 2: + parser.error(("Too many arguments provided")) if (options.arch is None): parser.error(("Missing option value \n\nArchitecture: " + str(options.arch))) + + # hard-code for now + if options.inputformat != "vmx": + parser.error(("Unsupported input format \"%s\"" % options.inputformat)) + if options.outputformat != "virt-image": + parser.error(("Unsupported output format \"%s\"" % options.outputformat)) + 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: + parser.error(("No VM definition file was found in %s" % args[0])) + if (len(vmx_files)) > 1: + parser.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 + 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])) + return options # Begin creation of xml template from parsed vmx config file @@ -62,29 +95,31 @@ def vmx_to_image_xml(disks_list,record,o fv_disk_list = [] storage_disk_list = [] + file = options.input_file + # validate required values for conversion are in the input vmx file if record.has_key("displayName"): name = record["displayName"] else: - logging.error("displayName key not parsed from %s" % options.file) + logging.error("displayName key not parsed from %s" % file) sys.exit(1) if record.has_key("memsize"): memory = int(record["memsize"]) * 1024 else: - logging.error("memsize key not parsed from %s" % options.file) + logging.error("memsize key not parsed from %s" % file) sys.exit(1) if record.has_key("annotation"): annotation = record["annotation"] else: - logging.error("annotation key not parsed from %s, creating blank comment" % options.file) + logging.error("annotation key not parsed from %s, creating blank comment" % file) annotation = "" if record.has_key("numvcpus"): vcpus = record["numvcpus"] else: - logging.error("numvcpus key not parsed from %s, defaulting to 1 virtual cpu" % options.file) + logging.error("numvcpus key not parsed from %s, defaulting to 1 virtual cpu" % file) vcpus = "1" @@ -164,9 +199,9 @@ def vmx_to_image_xml(disks_list,record,o # parse input vmware configuration def parse_vmware_config(options): - if not os.access(options.file,os.R_OK): - raise ValueError, "Could not read file: %s" % options.file - input = open(options.file,"r") + if not os.access(options.input_file, os.R_OK): + raise ValueError, "Could not read file: %s" % options.input_file + input = open(options.input_file, "r") contents = input.readlines() input.close() record = {} @@ -191,18 +226,30 @@ def parse_vmware_config(options): return record,disks_list -def convert_disks(disks_list,dirname): +def convert_disks(disks_list, options): for disk in disks_list: - file = disk.replace(".vmdk","").strip() - convert_cmd="qemu-img convert %s -O raw %s/%s.img" % (disk.strip(),dirname,file) - logging.debug("Converting %s" % disk.strip()) - print "\nConverting %s to %s/%s.img" % (disk.strip(),dirname,file) - os.system(convert_cmd) + infile = disk.strip() + if not os.path.isabs(infile): + infile = os.path.join(options.input_dir, infile) + + outfile = disk.replace(".vmdk","").strip() + outfile += ".img" + if not os.path.isabs(outfile): + outfile = os.path.join(options.output_dir, outfile) + convert_cmd="qemu-img convert %s -O raw %s" % (infile, outfile) + ret = os.system(convert_cmd) + print ret def main(): options = parse_args() cli.setupLogging("virt-unpack", options.debug) + + logging.debug("input_file: %s" % options.input_file) + logging.debug("input_dir: %s" % options.input_dir) + logging.debug("output_file: %s" % options.output_file) + logging.debug("output_dir: %s" % options.input_dir) + vm_config = parse_vmware_config(options) record, disks_list = vm_config @@ -210,26 +257,31 @@ def main(): hvm = False else: hvm = True - virtimage_xml = vmx_to_image_xml(disks_list,record,options,hvm) + out_contents = vmx_to_image_xml(disks_list, record, options, hvm) name = record["displayName"].replace(" ","-") - dirname = options.outputdir - if not dirname: - dirname = name + if not options.output_dir: + options.output_dir = name try: - logging.debug ("Creating directory %s" % dirname) - os.mkdir(dirname) + logging.debug("Creating directory %s" % options.output_dir) + os.mkdir(options.output_dir) except OSError,e: - logging.error("Could not create directory %s: %s" % (dirname, str(e))) - sys.exit(1) + if (e.errno != errno.EEXIST): + logging.error("Could not create directory %s: %s" % + (options.output_dir, str(e))) + sys.exit(1) + + if not options.output_file: + options.output_file = os.path.join(options.output_dir, + "%s.virt-image.xml" % name) # configuration completed, ready to write config file and convert disks - virtimage_xml_file = open(dirname + "/" + name + ".virtimage.xml","w") - virtimage_xml_file.writelines(virtimage_xml) - virtimage_xml_file.close() - convert_disks(disks_list,dirname) + out = open(options.output_file, "w") + out.writelines(out_contents) + out.close() + convert_disks(disks_list, options) - print "\n\nConversion completed and placed in: %s" % dirname + print "\n\nConversion completed and placed in: %s" % options.output_dir if __name__ == "__main__": _______________________________________________ et-mgmt-tools mailing list et-mgmt-tools@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/et-mgmt-tools