[et-mgmt-tools] [PATCH] Extend virt-unpack options

John Levon levon at movementarian.org
Tue Jul 1 19:23:55 UTC 2008


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 at sun.com>

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__":




More information about the et-mgmt-tools mailing list