[et-mgmt-tools] [PATCH 05 of 11] Allow output in libvirt.rng format

john.levon at sun.com john.levon at sun.com
Mon Jul 7 22:51:35 UTC 2008


# HG changeset patch
# User john.levon at sun.com
# Date 1215470429 25200
# Node ID 4528daf7a40728f906e1843b8368198ce9d438c5
# Parent  6042ba3dce6a57dbe7ee547ae65be93dbef1b0a2
Allow output in libvirt.rng format

Add "virt-instance" formatter.

Signed-off-by: John Levon <john.levon at sun.com>

diff --git a/man/en/virt-convert.1 b/man/en/virt-convert.1
--- a/man/en/virt-convert.1
+++ b/man/en/virt-convert.1
@@ -174,7 +174,8 @@ Input format. Currently, \f(CW\*(C`vmx\*
 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.
+Output format. Currently, the only supported outputs are \f(CW\*(C`virt\-image\*(C'\fR
+and \f(CW\*(C`virt\-instance\*(C'\fR.
 .IP "\-d, \-\-debug" 4
 .IX Item "-d, --debug"
 Print debugging information
diff --git a/man/en/virt-convert.pod b/man/en/virt-convert.pod
--- a/man/en/virt-convert.pod
+++ b/man/en/virt-convert.pod
@@ -56,7 +56,8 @@ Input format. Currently, C<vmx>  is the 
 
 =item  -o format
 
-Output format. Currently, C<virt-image>  is the only supported output format.
+Output format. Currently, the only supported outputs are C<virt-image>
+and C<virt-instance>.
 
 =item -d, --debug
 
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 at redhat.com>
+#
+# 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
@@ -19,6 +20,21 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 # MA 02110-1301 USA.
+
+#
+# Convert between VM definition formats. TODO:
+#
+# support networking
+# port virtinstance.py to Solaris
+# better disk checking
+# support CD-ROM
+# add option for host selection
+# --uuid, --os-type, --os-variant, and other virt-install options
+# disk conversion should be optional
+# use qemu-img info to verify the disk type
+# add some unit tests
+# input/output/detection for all formats
+#
 
 import sys
 import os
@@ -62,12 +78,18 @@ def parse_args():
     if len(args) > 2:
         opts.error(("Too many arguments provided"))
     
-    # 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\""
+    if options.input_format not in vmconfig.formats():
+        opts.error(("Unknown input format \"%s\"" % options.input_format))
+    if options.input_format not in vmconfig.input_formats():
+        opts.error(("No input handler for format \"%s\""
+            % options.input_format))
+
+    if options.output_format not in vmconfig.formats():
+        opts.error(("Unknown output format \"%s\"" % options.output_format))
+    if options.output_format not in vmconfig.output_formats():
+        opts.error(("No output handler for 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:
diff --git a/virtconv/parsers/virtimage.py b/virtconv/parsers/virtimage.py
--- a/virtconv/parsers/virtimage.py
+++ b/virtconv/parsers/virtimage.py
@@ -76,6 +76,8 @@ class virtimage_parser(vmconfig.parser):
     """
     name = "virt-image"
     suffix = ".virt-image.xml"
+    can_import = False
+    can_export = True
 
     @staticmethod
     def identify_file(input_file):
diff --git a/virtconv/parsers/virtinstance.py b/virtconv/parsers/virtinstance.py
new file mode 100644
--- /dev/null
+++ b/virtconv/parsers/virtinstance.py
@@ -0,0 +1,174 @@
+#
+# 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
+# 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.
+#
+
+from string import ascii_letters
+import virtconv.vmconfig as vmconfig
+
+import re
+
+bootloaders = {
+    vmconfig.VM_TYPE_PV: "<bootloader>/usr/lib/xen/bin/pygrub</bootloader>",
+    vmconfig.VM_TYPE_HVM: "",
+}
+
+bootdevs = {
+    vmconfig.VM_TYPE_PV: "",
+    vmconfig.VM_TYPE_HVM: "<boot dev='hd' />",
+}
+
+loaders = {
+    vmconfig.VM_TYPE_PV: "",
+    vmconfig.VM_TYPE_HVM: "<loader>/usr/lib/xen/boot/hvmloader</loader>",
+}
+
+emulators = {
+    vmconfig.VM_TYPE_PV: "",
+    vmconfig.VM_TYPE_HVM: "<emulator>/usr/lib/xen/bin/qemu-dm</emulator>",
+}
+
+consoles = {
+    vmconfig.VM_TYPE_PV: "",
+    vmconfig.VM_TYPE_HVM: "<console type='pty' />",
+}
+
+disk_template = """
+<disk type='block' device='disk'>
+ <driver name='phy' />
+ <source dev='%(path)s' />
+ <target dev='%(prefix)s%(dev)s' />
+</disk>
+"""
+
+instance_template = """
+<domain type='xen'>
+  <name>%(name)s</name>
+  %(bootloader)s
+  <os>
+    <type>%(type)s</type>
+    %(loader)s
+    %(bootdev)s
+  </os>
+  <memory>%(memory)s</memory>
+  <vcpu>%(nr_vcpus)s</vcpu>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>restart</on_crash>
+  <features>
+    <acpi />
+    <pae />
+  </features>
+  <devices>
+    %(emulator)s
+    %(disks)s
+    <input type='mouse' bus='ps2' />
+    <input type='tablet' bus='usb' />
+    <graphics type='vnc' port='-1' />
+    %(console)s
+  </devices>
+</domain>
+"""
+
+class virtinstance_parser(vmconfig.parser):
+    """
+    Support for libvirt's domain instance format as defined (mostly) by
+    libvirt.rng.  Currently, this only produces domains for Xen.
+
+    This is a somewhat challenging format as it encodes significant
+    amounts of information specific to a particular platform (for
+    example, the pygrub path.  For now, we'll assume it's for the current
+    platform.  In the future we might want to consider adding a
+    --host-type option.
+    """
+
+    name = "virt-instance"
+    suffix = ".virt-instance.xml"
+    can_import = False
+    can_export = True
+
+    @staticmethod
+    def identify_file(input_file):
+        """
+        Return True if the given file is of this format.
+        """
+        raise NotImplementedError
+
+    @staticmethod
+    def import_file(input_file):
+        """
+        Import a configuration file.  Raises if the file couldn't be
+        opened, or parsing otherwise failed.
+        """
+        raise NotImplementedError
+
+    @staticmethod
+    def export_file(vm, output_file):
+        """
+        Export a configuration file.
+        @vm vm configuration instance
+        @file Output file
+
+        Raises ValueError if configuration is not suitable, or another
+        exception on failure to write the output file.
+        """
+
+        if not vm.memory:
+            raise ValueError("VM must have a memory setting")
+
+        # xend wants the name to match r'^[A-Za-z0-9_\-\.\:\/\+]+$'
+        vmname = re.sub(r'[^A-Za-z0-9_.:/+-]+',  '_', vm.name)
+
+        vmtype = "xen"
+        disk_prefix = "xvd"
+        if (vm.type == vmconfig.VM_TYPE_HVM):
+            vmtype = "hvm"
+            disk_prefix = "hd"
+
+        disks = []
+
+        for disk in vm.disks:
+            drive_nr = ascii_letters[disk.number % 26]
+
+            # FIXME: needs updating for later Xen enhancements; need to
+            # implement capabilities checking for max disks etc.
+            disks.append(disk_template % {
+                "path" : disk.path,
+                "prefix" : disk_prefix,
+                "dev" :  drive_nr
+            })
+
+        out = instance_template % {
+            "name" : vmname.replace(" ", "-"),
+            "bootloader" : bootloaders[vm.type],
+            "type" : vmtype,
+            "loader"  : loaders[vm.type],
+            "bootdev" : bootdevs[vm.type],
+            # Mb to Kb
+            "memory" : int(vm.memory) * 1024,
+            "nr_vcpus" : vm.nr_vcpus,
+            "emulator" : emulators[vm.type],
+            "disks" : "".join(disks),
+            "console" : consoles[vm.type],
+        }
+
+        outfile = open(output_file, "w")
+        outfile.writelines(out)
+        outfile.close()
+
+vmconfig.register_parser(virtinstance_parser)
diff --git a/virtconv/parsers/vmx.py b/virtconv/parsers/vmx.py
--- a/virtconv/parsers/vmx.py
+++ b/virtconv/parsers/vmx.py
@@ -29,6 +29,8 @@ class vmx_parser(vmconfig.parser):
 
     name = "vmx"
     suffix = ".vmx"
+    can_import = True
+    can_export = False
 
     @staticmethod
     def identify_file(input_file):
diff --git a/virtconv/vmconfig.py b/virtconv/vmconfig.py
--- a/virtconv/vmconfig.py
+++ b/virtconv/vmconfig.py
@@ -193,3 +193,21 @@ def find_parser_by_file(input_file):
         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]




More information about the et-mgmt-tools mailing list