~ubuntu-branches/ubuntu/raring/virtinst/raring-proposed

« back to all changes in this revision

Viewing changes to virtconv/parsers/vmx.py

  • Committer: Bazaar Package Importer
  • Author(s): Guido Günther
  • Date: 2008-11-19 09:19:29 UTC
  • mto: (1.4.1 sid)
  • mto: This revision was merged to the branch mainline in revision 16.
  • Revision ID: james.westby@ubuntu.com-20081119091929-vwksujnqzo1utdln
Tags: upstream-0.400.0
Import upstream version 0.400.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#
 
2
# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
 
3
# Use is subject to license terms.
 
4
#
 
5
# This program is free software; you can redistribute it and/or modify
 
6
# it under the terms of the GNU General Public License as published by
 
7
# the Free  Software Foundation; either version 2 of the License, or
 
8
# (at your option)  any later version.
 
9
#
 
10
# This program is distributed in the hope that it will be useful,
 
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
# GNU General Public License for more details.
 
14
#
 
15
# You should have received a copy of the GNU General Public License
 
16
# along with this program; if not, write to the Free Software
 
17
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 
18
# MA 02110-1301 USA.
 
19
#
 
20
 
 
21
import virtconv.formats as formats
 
22
import virtconv.vmcfg as vmcfg
 
23
import virtconv.diskcfg as diskcfg
 
24
import virtconv.netdevcfg as netdevcfg
 
25
 
 
26
import re
 
27
import os
 
28
 
 
29
def parse_netdev_entry(vm, fullkey, value):
 
30
    """
 
31
    Parse a particular key/value for a network.  Throws ValueError.
 
32
    """
 
33
 
 
34
    ignore, ignore, inst, key = re.split("^(ethernet)([0-9]+).", fullkey)
 
35
 
 
36
    lvalue = value.lower()
 
37
 
 
38
    if key == "present" and lvalue == "false":
 
39
        return
 
40
 
 
41
    if not vm.netdevs.get(inst):
 
42
        vm.netdevs[inst] = netdevcfg.netdev(type = netdevcfg.NETDEV_TYPE_UNKNOWN)
 
43
 
 
44
    # "vlance", "vmxnet", "e1000"
 
45
    if key == "virtualDev":
 
46
        vm.netdevs[inst].driver = lvalue
 
47
    if key == "addressType" and lvalue == "generated":
 
48
        vm.netdevs[inst].mac = "auto"
 
49
    # we ignore .generatedAddress for auto mode
 
50
    if key == "address":
 
51
        vm.netdevs[inst].mac = lvalue
 
52
 
 
53
def parse_disk_entry(vm, fullkey, value):
 
54
    """
 
55
    Parse a particular key/value for a disk.  FIXME: this should be a
 
56
    lot smarter.
 
57
    """
 
58
 
 
59
    # skip bus values, e.g. 'scsi0.present = "TRUE"'
 
60
    if re.match(r"^(scsi|ide)[0-9]+[^:]", fullkey):
 
61
        return
 
62
 
 
63
    ignore, bus, bus_nr, inst, key = re.split(r"^(scsi|ide)([0-9]+):([0-9]+)\.",
 
64
        fullkey)
 
65
 
 
66
    lvalue = value.lower()
 
67
 
 
68
    if key == "present" and lvalue == "false":
 
69
        return
 
70
 
 
71
    # Does anyone else think it's scary that we're still doing things
 
72
    # like this?
 
73
    if bus == "ide":
 
74
        inst = int(inst) + int(bus_nr) * 2
 
75
 
 
76
    devid = (bus, inst)
 
77
    if not vm.disks.get(devid):
 
78
        vm.disks[devid] = diskcfg.disk(bus = bus,
 
79
            type = diskcfg.DISK_TYPE_DISK)
 
80
 
 
81
    if key == "deviceType":
 
82
        if lvalue == "atapi-cdrom" or lvalue == "cdrom-raw":
 
83
            vm.disks[devid].type = diskcfg.DISK_TYPE_CDROM
 
84
        elif lvalue == "cdrom-image":
 
85
            vm.disks[devid].type = diskcfg.DISK_TYPE_ISO
 
86
 
 
87
    if key == "fileName":
 
88
        vm.disks[devid].path = value
 
89
        vm.disks[devid].format = diskcfg.DISK_FORMAT_RAW
 
90
        if lvalue.endswith(".vmdk"):
 
91
            vm.disks[devid].format = diskcfg.DISK_FORMAT_VMDK
 
92
 
 
93
import re
 
94
 
 
95
class vmx_parser(formats.parser):
 
96
    """
 
97
    Support for VMWare .vmx files.  Note that documentation is
 
98
    particularly sparse on this format, with pretty much the best
 
99
    resource being http://sanbarrow.com/vmx.html
 
100
    """
 
101
 
 
102
    name = "vmx"
 
103
    suffix = ".vmx"
 
104
    can_import = True
 
105
    can_export = False
 
106
    can_identify = True
 
107
 
 
108
    @staticmethod
 
109
    def identify_file(input_file):
 
110
        """
 
111
        Return True if the given file is of this format.
 
112
        """
 
113
        infile = open(input_file, "r")
 
114
        line = infile.readline()
 
115
        infile.close()
 
116
 
 
117
        # some .vmx files don't bother with the header
 
118
        if re.match(r'^config.version\s+=', line):
 
119
            return True
 
120
        return re.match(r'^#!\s*/usr/bin/vm(ware|player)', line) is not None
 
121
 
 
122
    @staticmethod
 
123
    def import_file(input_file):
 
124
        """
 
125
        Import a configuration file.  Raises if the file couldn't be
 
126
        opened, or parsing otherwise failed.
 
127
        """
 
128
 
 
129
        vm = vmcfg.vm()
 
130
 
 
131
        infile = open(input_file, "r")
 
132
        contents = infile.readlines()
 
133
        infile.close()
 
134
 
 
135
        lines = []
 
136
 
 
137
        # strip out comment and blank lines for easy splitting of values
 
138
        for line in contents:
 
139
            if not line.strip() or line.startswith("#"):
 
140
                continue
 
141
            else:
 
142
                lines.append(line)
 
143
    
 
144
        config = {}
 
145
 
 
146
        # split out all remaining entries of key = value form
 
147
        for (line_nr, line) in enumerate(lines):
 
148
            try:
 
149
                before_eq, after_eq = line.split("=", 1)
 
150
                key = before_eq.strip()
 
151
                value = after_eq.strip().strip('"')
 
152
                config[key] = value
 
153
 
 
154
                if key.startswith("scsi") or key.startswith("ide"):
 
155
                    parse_disk_entry(vm, key, value)
 
156
                if key.startswith("ethernet"):
 
157
                    parse_netdev_entry(vm, key, value)
 
158
            except:
 
159
                raise Exception("Syntax error at line %d: %s" %
 
160
                    (line_nr + 1, line.strip()))
 
161
 
 
162
        for devid, disk in vm.disks.iteritems():
 
163
            if disk.type == diskcfg.DISK_TYPE_DISK:
 
164
                continue
 
165
                
 
166
            # vmx files often have dross left in path for CD entries
 
167
            if (disk.path == "auto detect" or
 
168
                not os.path.exists(disk.path)):
 
169
                vm.disks[devid].path = None
 
170
 
 
171
        if not config.get("displayName"):
 
172
            raise ValueError("No displayName defined in \"%s\"" % input_file)
 
173
        vm.name = config.get("displayName")
 
174
 
 
175
        vm.memory = config.get("memsize")
 
176
        vm.description = config.get("annotation")
 
177
        vm.nr_vcpus = config.get("numvcpus")
 
178
     
 
179
        vm.validate()
 
180
        return vm
 
181
 
 
182
    @staticmethod
 
183
    def export_file(vm, output_file):
 
184
        """
 
185
        Export a configuration file.
 
186
        @vm vm configuration instance
 
187
        @file Output file
 
188
 
 
189
        Raises ValueError if configuration is not suitable, or another
 
190
        exception on failure to write the output file.
 
191
        """
 
192
 
 
193
        raise NotImplementedError
 
194
 
 
195
formats.register_parser(vmx_parser)