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

« back to all changes in this revision

Viewing changes to virtinst/FullVirtGuest.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:
26
26
import DistroManager
27
27
import logging
28
28
import time
 
29
import platform
 
30
 
 
31
from VirtualDisk import VirtualDisk
 
32
from DistroManager import PXEInstaller
29
33
from virtinst import _virtinst as _
30
34
 
31
35
 
32
36
class FullVirtGuest(Guest.XenGuest):
33
 
    OS_TYPES = { "linux": { "label": "Linux", \
34
 
                            "acpi": True, \
35
 
                            "apic": True, \
36
 
                            "clock": "utc",\
37
 
                            "continue": False, \
38
 
                            "input": [ "mouse", "ps2"],
39
 
                            "variants": { "rhel2.1": { "label": "Red Hat Enterprise Linux 2.1", "distro": "rhel" }, \
40
 
                                          "rhel3": { "label": "Red Hat Enterprise Linux 3", "distro": "rhel" }, \
41
 
                                          "rhel4": { "label": "Red Hat Enterprise Linux 4", "distro": "rhel" }, \
42
 
                                          "rhel5": { "label": "Red Hat Enterprise Linux 5", "distro": "rhel" }, \
43
 
                                          "fedora5": { "label": "Fedora Core 5", "distro": "fedora" }, \
44
 
                                          "fedora6": { "label": "Fedora Core 6", "distro": "fedora" }, \
45
 
                                          "fedora7": { "label": "Fedora 7", "distro": "fedora" }, \
46
 
                                          "fedora8": { "label": "Fedora 8", "distro": "fedora" }, \
47
 
                                          "sles10": { "label": "Suse Linux Enterprise Server", "distro": "suse" }, \
48
 
                                          "debianEtch": { "label": "Debian Etch", "distro": "debian" }, \
49
 
                                          "debianLenny": { "label": "Debian Lenny", "distro": "debian" }, \
50
 
                                          "generic24": { "label": "Generic 2.4.x kernel" }, \
51
 
                                          "generic26": { "label": "Generic 2.6.x kernel" }, \
52
 
                                          }, \
53
 
                            }, \
54
 
                 "windows": { "label": "Windows", \
55
 
                              "acpi": True, \
56
 
                              "apic": True, \
57
 
                              "clock": "localtime",\
58
 
                              "continue": True, \
59
 
                              "input": [ "tablet", "usb"],
60
 
                              "variants": { "winxp": { "label": "Microsoft Windows XP", \
61
 
                                                       "acpi": False, \
62
 
                                                       "apic": False }, \
63
 
                                            "win2k": { "label": "Microsoft Windows 2000", \
64
 
                                                       "acpi": False, \
65
 
                                                       "apic": False }, \
66
 
                                            "win2k3": { "label": "Microsoft Windows 2003" }, \
67
 
                                            "vista": { "label": "Microsoft Windows Vista" }, \
68
 
                                            }, \
69
 
                              }, \
70
 
                 "unix": { "label": "UNIX", \
71
 
                           "acpi": True,
72
 
                           "apic": True,
73
 
                           "clock": "utc",\
74
 
                           "continue": False, \
75
 
                           "input": [ "mouse", "ps2"],
76
 
                           "variants": { "solaris9": { "label": "Sun Solaris 9" }, \
77
 
                                         "solaris10": { "label": "Sun Solaris 10" }, \
78
 
                                         "freebsd6": { "label": "Free BSD 6.x" }, \
79
 
                                         "openbsd4": { "label": "Open BSD 4.x" }, \
80
 
                                         }, \
81
 
                           }, \
82
 
                 "other": { "label": "Other", \
83
 
                            "acpi": True,
84
 
                            "apic": True,
85
 
                            "clock": "utc",
86
 
                            "continue": False,
87
 
                            "input": [ "mouse", "ps2"],
88
 
                            "variants": { "msdos": { "label": "MS-DOS", \
89
 
                                                     "acpi": False, \
90
 
                                                     "apic": False }, \
91
 
                                          "netware4": { "label": "Novell Netware 4" }, \
92
 
                                          "netware5": { "label": "Novell Netware 5" }, \
93
 
                                          "netware6": { "label": "Novell Netware 6" }, \
94
 
                                          "generic": { "label": "Generic" }, \
95
 
                                          }, \
96
 
                            } \
97
 
                 }
 
37
 
 
38
    """
 
39
    Default values for OS_TYPES keys. Can be overwritten at os_type or
 
40
    variant level
 
41
    """
 
42
    _DEFAULTS = { \
 
43
        "acpi": True,
 
44
        "apic": True,
 
45
        "clock": "utc",
 
46
        "continue": False,
 
47
        "distro": None,
 
48
        "label": None,
 
49
        "devices" : {
 
50
         #  "devname" : { "attribute" : [( ["applicable", "hv-type", list"],
 
51
         #                               "recommended value for hv-types" ),]},
 
52
            "input"   : { "type" : [ (["all"], "mouse") ],
 
53
                          "bus"  : [ (["all"], "ps2") ] },
 
54
            "disk"    : { "bus"  : [ (["all"], None) ] },
 
55
            "net"     : { "model": [ (["all"], None) ] },
 
56
        }
 
57
    }
 
58
 
 
59
 
 
60
    # NOTE: keep variant keys using only lowercase so we can do case
 
61
    #       insensitive checks on user passed input
 
62
    _OS_TYPES = {\
 
63
    "linux": { \
 
64
        "label": "Linux",
 
65
        "variants": { \
 
66
            "rhel2.1": { "label": "Red Hat Enterprise Linux 2.1",
 
67
                         "distro": "rhel" },
 
68
            "rhel3": { "label": "Red Hat Enterprise Linux 3",
 
69
                       "distro": "rhel" },
 
70
            "rhel4": { "label": "Red Hat Enterprise Linux 4",
 
71
                       "distro": "rhel" },
 
72
            "rhel5": { "label": "Red Hat Enterprise Linux 5",
 
73
                       "distro": "rhel" },
 
74
            "fedora5": { "label": "Fedora Core 5", "distro": "fedora" },
 
75
            "fedora6": { "label": "Fedora Core 6", "distro": "fedora" },
 
76
            "fedora7": { "label": "Fedora 7", "distro": "fedora" },
 
77
            "fedora8": { "label": "Fedora 8", "distro": "fedora" },
 
78
            "fedora9": { "label": "Fedora 9", "distro": "fedora" },
 
79
            "fedora10": { "label": "Fedora 10", "distro": "fedora",
 
80
                          "devices" : {
 
81
                            "disk" : { "bus"   : [ (["kvm"], "virtio") ] },
 
82
                            "net"  : { "model" : [ (["kvm"], "virtio") ] }
 
83
                          }},
 
84
            "sles10": { "label": "Suse Linux Enterprise Server",
 
85
                        "distro": "suse" },
 
86
            "debianetch": { "label": "Debian Etch", "distro": "debian" },
 
87
            "debianlenny": { "label": "Debian Lenny", "distro": "debian" },
 
88
            "ubuntuhardy": { "label": "Ubuntu Hardy", "distro": "ubuntu",
 
89
                             "devices" : {
 
90
                                "net"  : { "model" : [ (["kvm"], "virtio") ] }
 
91
                             }},
 
92
            "generic24": { "label": "Generic 2.4.x kernel" },
 
93
            "generic26": { "label": "Generic 2.6.x kernel" },
 
94
        },
 
95
    },
 
96
 
 
97
    "windows": { \
 
98
        "label": "Windows",
 
99
        "clock": "localtime",
 
100
        "continue": True,
 
101
        "devices" : {
 
102
            "input" : { "type" : [ (["all"], "tablet") ],
 
103
                        "bus"  : [ (["all"], "usb"), ] },
 
104
        },
 
105
        "variants": { \
 
106
            "winxp":{ "label": "Microsoft Windows XP",
 
107
                      "acpi": False, "apic": False },
 
108
            "win2k": { "label": "Microsoft Windows 2000",
 
109
                       "acpi": False, "apic": False },
 
110
            "win2k3": { "label": "Microsoft Windows 2003" },
 
111
            "win2k8": { "label": "Microsoft Windows 2008" },
 
112
            "vista": { "label": "Microsoft Windows Vista" },
 
113
        },
 
114
    },
 
115
 
 
116
    "unix": {
 
117
        "label": "UNIX",
 
118
        "variants": { \
 
119
            "solaris9": { "label": "Sun Solaris 9" },
 
120
            "solaris10": { "label": "Sun Solaris 10" },
 
121
            "freebsd6": { "label": "Free BSD 6.x" ,
 
122
                          # http://www.nabble.com/Re%3A-Qemu%3A-bridging-on-FreeBSD-7.0-STABLE-p15919603.html
 
123
                          "devices" : {
 
124
                            "net" : { "model" : [ (["all"], "ne2k_pci") ] }
 
125
                          }},
 
126
            "freebsd7": { "label": "Free BSD 7.x" ,
 
127
                          "devices" : {
 
128
                            "net" : { "model" : [ (["all"], "ne2k_pci") ] }
 
129
                          }},
 
130
            "openbsd4": { "label": "Open BSD 4.x" ,
 
131
                          # http://calamari.reverse-dns.net:980/cgi-bin/moin.cgi/OpenbsdOnQemu
 
132
                          # https://www.redhat.com/archives/et-mgmt-tools/2008-June/msg00018.html
 
133
                          "devices" : {
 
134
                            "net"  : { "model" : [ (["all"], "pcnet") ] }
 
135
                        }},
 
136
        },
 
137
    },
 
138
 
 
139
    "other": { \
 
140
        "label": "Other",
 
141
        "variants": { \
 
142
            "msdos": { "label": "MS-DOS", "acpi": False, "apic": False },
 
143
            "netware4": { "label": "Novell Netware 4" },
 
144
            "netware5": { "label": "Novell Netware 5" },
 
145
            "netware6": { "label": "Novell Netware 6" },
 
146
            "generic": { "label": "Generic" },
 
147
        },
 
148
    },}
98
149
 
99
150
    def list_os_types():
100
 
        return FullVirtGuest.OS_TYPES.keys()
 
151
        return FullVirtGuest._OS_TYPES.keys()
101
152
    list_os_types = staticmethod(list_os_types)
102
153
 
103
154
    def list_os_variants(type):
104
 
        return FullVirtGuest.OS_TYPES[type]["variants"].keys()
 
155
        return FullVirtGuest._OS_TYPES[type]["variants"].keys()
105
156
    list_os_variants = staticmethod(list_os_variants)
106
157
 
107
158
    def get_os_type_label(type):
108
 
        return FullVirtGuest.OS_TYPES[type]["label"]
 
159
        return FullVirtGuest._OS_TYPES[type]["label"]
109
160
    get_os_type_label = staticmethod(get_os_type_label)
110
161
 
111
162
    def get_os_variant_label(type, variant):
112
 
        return FullVirtGuest.OS_TYPES[type]["variants"][variant]["label"]
 
163
        return FullVirtGuest._OS_TYPES[type]["variants"][variant]["label"]
113
164
    get_os_variant_label = staticmethod(get_os_variant_label)
114
165
 
115
166
 
119
170
        Guest.Guest.__init__(self, type, connection, hypervisorURI, installer)
120
171
        self.disknode = "hd"
121
172
        self.features = { "acpi": None, "pae": util.is_pae_capable(), "apic": None }
 
173
        #if arch is None:
 
174
        #arch = platform.machine()
122
175
        self.arch = arch
123
 
        if emulator is None:
 
176
 
 
177
        self.emulator = emulator
 
178
        self.loader = None
 
179
        guest = self._caps.guestForOSType(type=self.installer.os_type,
 
180
                                          arch=self.arch)
 
181
        if (not self.emulator) and guest:
 
182
            for dom in guest.domains:
 
183
                if dom.hypervisor_type == self.installer.type:
 
184
                    self.emulator = dom.emulator
 
185
                    self.loader = dom.loader
 
186
 
 
187
        # Fall back to default hardcoding
 
188
        if self.emulator is None:
124
189
            if self.type == "xen":
125
190
                if os.uname()[4] in ("x86_64"):
126
 
                    emulator = "/usr/lib64/xen/bin/qemu-dm"
 
191
                    self.emulator = "/usr/lib64/xen/bin/qemu-dm"
127
192
                else:
128
 
                    emulator = "/usr/lib/xen/bin/qemu-dm"
129
 
        self.emulator = emulator
130
 
        if self.type == "xen":
 
193
                    self.emulator = "/usr/lib/xen/bin/qemu-dm"
 
194
 
 
195
        if (not self.loader) and self.type == "xen":
131
196
            self.loader = "/usr/lib/xen/boot/hvmloader"
132
 
        else:
133
 
            self.loader = None
 
197
 
134
198
        self._os_type = None
135
199
        self._os_variant = None
136
200
 
138
202
    def get_os_type(self):
139
203
        return self._os_type
140
204
    def set_os_type(self, val):
141
 
        if FullVirtGuest.OS_TYPES.has_key(val):
 
205
        if type(val) is not str:
 
206
            raise ValueError(_("OS type must be a string."))
 
207
        val = val.lower()
 
208
        if FullVirtGuest._OS_TYPES.has_key(val):
142
209
            self._os_type = val
 
210
            # Invalidate variant, since it may not apply to the new os type
 
211
            self._os_variant = None
143
212
        else:
144
 
            raise ValueError, _("OS type %s does not exist in our dictionary") % val
 
213
            raise ValueError, _("OS type '%s' does not exist in our "
 
214
                                "dictionary") % val
145
215
    os_type = property(get_os_type, set_os_type)
146
216
 
147
217
    def get_os_variant(self):
148
218
        return self._os_variant
149
219
    def set_os_variant(self, val):
150
 
        if not self._os_type:
151
 
            raise ValueError, _("An OS type must be specified before a variant.")
152
 
        if FullVirtGuest.OS_TYPES[self._os_type]["variants"].has_key(val):
153
 
            self._os_variant = val
 
220
        if type(val) is not str:
 
221
            raise ValueError(_("OS variant must be a string."))
 
222
        val = val.lower()
 
223
        if self._os_type:
 
224
            if self._OS_TYPES[self._os_type]["variants"].has_key(val):
 
225
                self._os_variant = val
 
226
            else:
 
227
                raise ValueError, _("OS variant '%(var)s; does not exist in "
 
228
                                    "our dictionary for OS type '%(ty)s'" ) % \
 
229
                                    {'var' : val, 'ty' : self._os_type}
154
230
        else:
155
 
            raise ValueError, _("OS variant %(var)s does not exist in our dictionary for OS type %(type)s") % {'var' : val, 'type' : self._os_type}
 
231
            for ostype in self.list_os_types():
 
232
                if self._OS_TYPES[ostype]["variants"].has_key(val):
 
233
                    logging.debug("Setting os type to '%s' for variant '%s'" %\
 
234
                                  (ostype, val))
 
235
                    self.os_type = ostype
 
236
                    self._os_variant = val
 
237
                    return
 
238
            raise ValueError, _("Unknown OS variant '%s'" % val)
156
239
    os_variant = property(get_os_variant, set_os_variant)
157
240
 
158
241
    def os_features(self):
161
244
        preferences"""
162
245
        if self.features is None:
163
246
            return None
164
 
        os_type = self.os_type
165
 
        os_variant = self.os_variant
 
247
 
166
248
        # explicitly disabling apic and acpi will override OS_TYPES values
167
249
        features = dict(self.features)
168
250
        for f in ["acpi", "apic"]:
169
 
            if features[f] is None and os_type is not None:
170
 
                if os_variant is not None and FullVirtGuest.OS_TYPES[os_type]["variants"][os_variant].has_key(f):
171
 
                    features[f] = FullVirtGuest.OS_TYPES[os_type]["variants"][os_variant][f]
172
 
                else:
173
 
                    features[f] = FullVirtGuest.OS_TYPES[os_type][f]
174
 
            else:
175
 
                if features[f] is None:
176
 
                    features[f] = True
 
251
            val = self._lookup_osdict_key(f)
 
252
            features[f] = val
177
253
        return features
178
254
 
179
255
    def get_os_distro(self):
180
 
        if self.os_type is not None and self.os_variant is not None and "distro" in FullVirtGuest.OS_TYPES[self.os_type]["variants"][self.os_variant]:
181
 
            return FullVirtGuest.OS_TYPES[self.os_type]["variants"][self.os_variant]["distro"]
182
 
        return None
 
256
        return self._lookup_osdict_key("distro")
183
257
    os_distro = property(get_os_distro)
184
258
 
185
259
    def get_input_device(self):
186
 
        if self.os_type is None or not FullVirtGuest.OS_TYPES.has_key(self.os_type):
187
 
            return ("mouse", "ps2")
188
 
        input = FullVirtGuest.OS_TYPES[self.os_type]["input"]
189
 
        return (input[0], input[1])
 
260
        typ = self._lookup_device_param("input", "type")
 
261
        bus = self._lookup_device_param("input", "bus")
 
262
        return (typ, bus)
190
263
 
191
264
    def _get_features_xml(self):
192
265
        ret = "<features>\n"
201
274
        return ret + "  </features>"
202
275
 
203
276
    def _get_osblob(self, install):
204
 
        osblob = self.installer._get_osblob(install, True, self.arch, self.loader)
 
277
        osblob = self.installer._get_osblob(install, hvm = True,
 
278
            arch = self.arch, loader = self.loader, conn = self.conn)
205
279
        if osblob is None:
206
280
            return None
207
281
 
213
287
            return "%s\n  %s" % (osblob, self._get_features_xml())
214
288
 
215
289
    def _get_clock_xml(self):
216
 
        if self.os_type is not None and \
217
 
           FullVirtGuest.OS_TYPES[self.os_type].has_key("clock"):
218
 
            return "<clock offset=\"%s\"/>" % \
219
 
                   FullVirtGuest.OS_TYPES[self.os_type]["clock"]
220
 
        else:
221
 
            return None
 
290
        val = self._lookup_osdict_key("clock")
 
291
        return """<clock offset="%s"/>""" % val
222
292
 
223
293
    def _get_device_xml(self, install = True):
224
294
        if self.emulator is None:
225
 
            return """    <console device='pty'/>
 
295
            return """    <console type='pty'/>
226
296
""" + Guest.Guest._get_device_xml(self, install)
227
297
        else:
228
298
            return ("""    <emulator>%(emulator)s</emulator>
229
 
    <console device='pty'/>
 
299
    <console type='pty'/>
230
300
""" % { "emulator": self.emulator }) + \
231
301
        Guest.Guest._get_device_xml(self, install)
232
302
 
233
303
    def validate_parms(self):
234
 
        #if not self.location:
235
 
        #    raise ValueError, _("A CD must be specified to boot from")
236
304
        Guest.Guest.validate_parms(self)
237
305
 
238
306
    def _prepare_install(self, meter):
244
312
            self._install_disks.append(self._installer.install_disk)
245
313
 
246
314
    def get_continue_inst(self):
247
 
        if self.os_type is not None:
248
 
            if self.os_variant is not None and FullVirtGuest.OS_TYPES[self.os_type]["variants"][self.os_variant].has_key("continue"):
249
 
                return FullVirtGuest.OS_TYPES[self.os_type]["variants"][self.os_variant]["continue"]
250
 
            else:
251
 
                return FullVirtGuest.OS_TYPES[self.os_type]["continue"]
252
 
        return False
 
315
        return self._lookup_osdict_key("continue")
253
316
 
254
 
    def continue_install(self, consolecb, meter):
 
317
    def continue_install(self, consolecb, meter, wait=True):
255
318
        install_xml = self.get_config_xml(disk_boot = True)
256
319
        logging.debug("Starting guest from '%s'" % ( install_xml ))
257
320
        meter.start(size=None, text="Starting domain...")
260
323
            raise RuntimeError, _("Unable to start domain for guest, aborting installation!")
261
324
        meter.end(0)
262
325
 
263
 
        self.connect_console(consolecb)
 
326
        self.connect_console(consolecb, wait)
264
327
 
265
328
        # ensure there's time for the domain to finish destroying if the
266
329
        # install has finished or the guest crashed
271
334
        # for inactive guest, or get the still running install..
272
335
        return self.conn.lookupByName(self.name)
273
336
 
 
337
    def _lookup_osdict_key(self, key):
 
338
        """
 
339
        Using self.os_type and self.os_variant to find key in OSTYPES
 
340
        @returns: dict value, or None if os_type/variant wasn't set
 
341
        """
 
342
        typ = self.os_type
 
343
        var = self.os_variant
 
344
        if typ:
 
345
            if var and self._OS_TYPES[typ]["variants"][var].has_key(key):
 
346
                return self._OS_TYPES[typ]["variants"][var][key]
 
347
            elif self._OS_TYPES[typ].has_key(key):
 
348
                return self._OS_TYPES[typ][key]
 
349
        return self._DEFAULTS[key]
 
350
 
 
351
    def _lookup_device_param(self, device_key, param):
 
352
        os_devs = self._lookup_osdict_key("devices")
 
353
        default_devs = self._DEFAULTS["devices"]
 
354
        for devs in [os_devs, default_devs]:
 
355
            if not devs.has_key(device_key):
 
356
                continue
 
357
            for ent in devs[device_key][param]:
 
358
                hv_types = ent[0]
 
359
                param_value = ent[1]
 
360
                if self.type in hv_types:
 
361
                    return param_value
 
362
                elif "all" in hv_types:
 
363
                    return param_value
 
364
        raise RuntimeError(_("Invalid dictionary entry for device '%s %s'" % \
 
365
                             (device_key, param)))
 
366
 
274
367
    def _get_disk_xml(self, install = True):
275
368
        """Get the disk config in the libvirt XML format"""
276
369
        ret = ""
277
 
        nodes = {}
278
 
        for i in range(4):
279
 
            n = "%s%c" % (self.disknode, ord('a') + i)
280
 
            nodes[n] = None
281
 
 
282
 
        # First assign CDROM device nodes, since they're scarce resource
283
 
        cdnode = self.disknode + "c"
284
 
        for d in self._install_disks:
285
 
            if d.device != Guest.VirtualDisk.DEVICE_CDROM:
286
 
                continue
287
 
 
288
 
            if d.target:
289
 
                if d.target != cdnode:
290
 
                    raise ValueError, "The CDROM must be device %s" % cdnode
291
 
            else:
292
 
                d.target = cdnode
293
 
 
294
 
            if nodes[d.target] != None:
295
 
                raise ValueError, "The CDROM device %s is already used" % d.target
296
 
            nodes[d.target] = d
297
 
 
298
 
        # Now assign regular disk node with remainder
299
 
        for d in self._install_disks:
300
 
            if d.device == Guest.VirtualDisk.DEVICE_CDROM:
301
 
                continue
302
 
 
303
 
            if d.target is None: # Auto-assign disk
304
 
                for n in sorted(nodes.keys()):
305
 
                    if nodes[n] is None:
306
 
                        d.target = n
307
 
                        nodes[d.target] = d
308
 
                        break
309
 
            else:
310
 
                if nodes[d.target] != None: # Verify pre-assigned
311
 
                    raise ValueError, "The disk device %s is already used" % d.target
312
 
                nodes[d.target] = d
 
370
        used_targets = []
 
371
        for disk in self._install_disks:
 
372
            if not disk.bus:
 
373
                disk.bus = "ide"
 
374
            used_targets.append(disk.generate_target(used_targets))
313
375
 
314
376
        for d in self._install_disks:
315
377
            saved_path = None
316
 
            if d.device == Guest.VirtualDisk.DEVICE_CDROM and d.transient and not install:
317
 
                # XXX hack. libvirt can't currently handle QEMU having an empty disk path..
318
 
                if self.type == "xen":
319
 
                    saved_path = d.path
 
378
            if d.device == VirtualDisk.DEVICE_CDROM \
 
379
               and d.transient and not install:
 
380
                # Keep cdrom around, but with no media attached
 
381
                # But only if we are a distro that doesn't have a multi
 
382
                # stage install (aka not Windows)
 
383
                saved_path = d.path
 
384
                if not self.get_continue_inst():
320
385
                    d.path = None
321
 
                else:
322
 
                    # .. so simply remove CDROM device completely in non-Xen
323
 
                    continue
324
386
 
 
387
            if ret:
 
388
                ret += "\n"
325
389
            ret += d.get_xml_config(d.target)
326
390
            if saved_path != None:
327
391
                d.path = saved_path
328
392
 
329
393
        return ret
 
394
 
 
395
    def _set_defaults(self):
 
396
        Guest.Guest._set_defaults(self)
 
397
 
 
398
        disk_bus  = self._lookup_device_param("disk", "bus")
 
399
        net_model = self._lookup_device_param("net", "model")
 
400
        pxe_skipped = False
 
401
 
 
402
        # Only overwrite params if they weren't already specified
 
403
        for net in self._install_nics:
 
404
            if net_model and not net.model:
 
405
                if net_model == "virtio":
 
406
                    # virtio net doesn't seem to support pxe, skip first interface
 
407
                    if not pxe_skipped and isinstance(self.installer, PXEInstaller):
 
408
                        pxe_skipped = True
 
409
                        continue
 
410
                net.model = net_model
 
411
        for disk in self._install_disks:
 
412
            if disk_bus and not disk.bus:
 
413
                disk.bus = disk_bus