~ubuntu-branches/ubuntu/precise/virt-manager/precise-proposed

« back to all changes in this revision

Viewing changes to .pc/0005-Add-conn-info-to-virtinst.VirtualGraphics.patch/src/virtManager/addhardware.py

  • Committer: Bazaar Package Importer
  • Author(s): Marc Deslauriers
  • Date: 2011-02-03 10:35:22 UTC
  • mfrom: (2.3.3 experimental)
  • Revision ID: james.westby@ubuntu.com-20110203103522-j8and6dsy3taczbj
Tags: 0.8.6-1ubuntu1
* Merge from debian experimental. Remaining changes:
  - Depend on python-appindicator for appindicator support.
  - Add a /usr/share/pixmaps/virt-manager-icon.svg symlink to link icon to
    where the Application Indicator can find it.
  - Add patch da_l10n.patch since it is not integrated. (refreshed)
  - Add patch show_session_or_system_in_console to make the overview
    screen show which local qemu session you're connected to. (refreshed)
  - Add patch more_helpful_error_message to explain to the user why he
    can't connect to qemu:///system and what he can do fix it.
  - Add patch qemu-system-by-default to automatically add qemu:///system
    to the list of hypervisors if the user has write access to the UNIX
    socket.
  - Drop patchsys-quilt include since dpkg-source does the quilt dance for
    us.
  - debian/control: lower libvirt-bin from Recommends to Suggests; seems
    some users (like netbooks) want to manage VMs, but not host them; see
    meta packages (ubuntu-virt, ubuntu-virt-server, ubuntu-virt-mgmt) for
    group installation of virt package sets.
* Removed patches:
  - debian/patches/custom-icon-installation.patch: Upstream.
  - debian/patches/remove-appindicator-workarounds.patch: Upstream.
  - debian/patches/fix-nc-with-zsh.patch: Upstream
* Removed python-ipy dependency as it is in universe:
  - debian/control: remove python-ipy from Depends
  - debian/series: disable 0002-Use-IPy-from-python-ipy.patch patch so
    we use the one that's included in the virt-manager source.
  - debian/rules: don't delete the IPy file.
* debian/patches/fix-cpu-wrong-types.patch: fix "value is of wrong type
  for this column" error by making sure we are using strings in
  src/virtManager/details.py.
* debian/patches/dont-always-launch-consoles.patch: Don't always launch
  consoles for running domains in src/virtManager/manager.py.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#
2
 
# Copyright (C) 2006-2007 Red Hat, Inc.
3
 
# Copyright (C) 2006 Hugh O. Brock <hbrock@redhat.com>
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 logging
22
 
import traceback
23
 
 
24
 
import gobject
25
 
import gtk
26
 
import gtk.gdk
27
 
import gtk.glade
28
 
 
29
 
import virtinst
30
 
from virtinst import (VirtualCharDevice, VirtualDevice, VirtualVideoDevice,
31
 
                      VirtualWatchdog)
32
 
 
33
 
import virtManager.util as util
34
 
import virtManager.uihelpers as uihelpers
35
 
from virtManager.asyncjob import vmmAsyncJob
36
 
from virtManager.error import vmmErrorDialog
37
 
from virtManager.createmeter import vmmCreateMeter
38
 
from virtManager.storagebrowse import vmmStorageBrowser
39
 
 
40
 
VM_STORAGE_PARTITION = 1
41
 
VM_STORAGE_FILE = 2
42
 
 
43
 
DEFAULT_STORAGE_FILE_SIZE = 500
44
 
 
45
 
PAGE_INTRO = 0
46
 
PAGE_DISK = 1
47
 
PAGE_NETWORK = 2
48
 
PAGE_INPUT = 3
49
 
PAGE_GRAPHICS = 4
50
 
PAGE_SOUND = 5
51
 
PAGE_HOSTDEV = 6
52
 
PAGE_CHAR = 7
53
 
PAGE_VIDEO = 8
54
 
PAGE_WATCHDOG = 9
55
 
PAGE_SUMMARY = 10
56
 
 
57
 
char_widget_mappings = {
58
 
    "source_path" : "char-path",
59
 
    "source_mode" : "char-mode",
60
 
    "source_host" : "char-host",
61
 
    "source_port" : "char-port",
62
 
    "bind_port": "char-bind-port",
63
 
    "bind_host": "char-bind-host",
64
 
    "protocol" : "char-use-telnet",
65
 
}
66
 
 
67
 
class vmmAddHardware(gobject.GObject):
68
 
    __gsignals__ = {
69
 
        "action-show-help": (gobject.SIGNAL_RUN_FIRST,
70
 
                                gobject.TYPE_NONE, [str]),
71
 
        }
72
 
    def __init__(self, config, vm):
73
 
        self.__gobject_init__()
74
 
        self.config = config
75
 
        self.vm = vm
76
 
        self.conn = vm.get_connection()
77
 
        self.window = gtk.glade.XML(config.get_glade_dir() + "/vmm-add-hardware.glade", "vmm-add-hardware", domain="virt-manager")
78
 
        self.topwin = self.window.get_widget("vmm-add-hardware")
79
 
        self.err = vmmErrorDialog(self.topwin,
80
 
                                  0, gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE,
81
 
                                  _("Unexpected Error"),
82
 
                                  _("An unexpected error occurred"))
83
 
 
84
 
        self.storage_browser = None
85
 
 
86
 
        # Host space polling
87
 
        self.host_storage_timer = None
88
 
 
89
 
        self._dev = None
90
 
 
91
 
        self.topwin.hide()
92
 
        self.window.signal_autoconnect({
93
 
            "on_create_pages_switch_page" : self.page_changed,
94
 
            "on_create_cancel_clicked" : self.close,
95
 
            "on_vmm_create_delete_event" : self.close,
96
 
            "on_create_back_clicked" : self.back,
97
 
            "on_create_forward_clicked" : self.forward,
98
 
            "on_create_finish_clicked" : self.finish,
99
 
            "on_create_help_clicked": self.show_help,
100
 
 
101
 
            "on_hardware_type_changed"  : self.hardware_type_changed,
102
 
 
103
 
            "on_config_storage_browse_clicked": self.browse_storage,
104
 
            "on_config_storage_select_toggled": self.toggle_storage_select,
105
 
 
106
 
            "on_mac_address_clicked" : self.change_macaddr_use,
107
 
 
108
 
            "on_graphics_type_changed": self.change_graphics_type,
109
 
            "on_graphics_port_auto_toggled": self.change_port_auto,
110
 
            "on_graphics_keymap_toggled": self.change_keymap,
111
 
 
112
 
            "on_host_device_type_changed": self.change_host_device_type,
113
 
 
114
 
            "on_char_device_type_changed": self.change_char_device_type,
115
 
 
116
 
            # Char dev info signals
117
 
            "char_device_type_focus": (self.update_doc, "char_type"),
118
 
            "char_path_focus_in": (self.update_doc, "source_path"),
119
 
            "char_mode_changed": (self.update_doc_changed, "source_mode"),
120
 
            "char_mode_focus"  : (self.update_doc, "source_mode"),
121
 
            "char_host_focus_in": (self.update_doc, "source_host"),
122
 
            "char_bind_host_focus_in": (self.update_doc, "bind_host"),
123
 
            "char_telnet_focus_in": (self.update_doc, "protocol"),
124
 
            })
125
 
        util.bind_escape_key_close(self)
126
 
 
127
 
        # XXX: Help docs useless/out of date
128
 
        self.window.get_widget("create-help").hide()
129
 
 
130
 
        finish_img = gtk.image_new_from_stock(gtk.STOCK_QUIT,
131
 
                                              gtk.ICON_SIZE_BUTTON)
132
 
        self.window.get_widget("create-finish").set_image(finish_img)
133
 
 
134
 
        self.set_initial_state()
135
 
 
136
 
    def update_doc(self, ignore1, ignore2, param):
137
 
        doc = self._build_doc_str(param)
138
 
        self.window.get_widget("char-info").set_markup(doc)
139
 
 
140
 
    def update_doc_changed(self, ignore1, param):
141
 
        # Wrapper for update_doc and 'changed' signal
142
 
        self.update_doc(None, None, param)
143
 
 
144
 
    def _build_doc_str(self, param, docstr=None):
145
 
        doc = ""
146
 
        doctmpl = "<i>%s</i>"
147
 
 
148
 
        if docstr:
149
 
            doc = doctmpl % (docstr)
150
 
        elif self._dev:
151
 
            devclass = self._dev.__class__
152
 
            if hasattr(devclass, param):
153
 
                doc = doctmpl % (getattr(devclass, param).__doc__)
154
 
 
155
 
        return doc
156
 
 
157
 
    def show(self):
158
 
        self.reset_state()
159
 
        self.topwin.present()
160
 
 
161
 
    def close(self, ignore1=None,ignore2=None):
162
 
        self.topwin.hide()
163
 
        self.remove_timers()
164
 
        return 1
165
 
 
166
 
    def remove_timers(self):
167
 
        try:
168
 
            if self.host_storage_timer:
169
 
                gobject.source_remove(self.host_storage_timer)
170
 
                self.host_storage_timer = None
171
 
        except:
172
 
            pass
173
 
 
174
 
    def is_visible(self):
175
 
        if self.topwin.flags() & gtk.VISIBLE:
176
 
            return 1
177
 
        return 0
178
 
 
179
 
 
180
 
    ##########################
181
 
    # Initialization methods #
182
 
    ##########################
183
 
 
184
 
    def set_initial_state(self):
185
 
        notebook = self.window.get_widget("create-pages")
186
 
        notebook.set_show_tabs(False)
187
 
 
188
 
        black = gtk.gdk.color_parse("#000")
189
 
        for num in range(PAGE_SUMMARY+1):
190
 
            name = "page" + str(num) + "-title"
191
 
            self.window.get_widget(name).modify_bg(gtk.STATE_NORMAL,black)
192
 
 
193
 
        # Main HW list
194
 
        hw_list = self.window.get_widget("hardware-type")
195
 
        # Name, icon name, page number, is sensitive, tooltip, icon size
196
 
        model = gtk.ListStore(str, str, int, bool, str)
197
 
        hw_list.set_model(model)
198
 
        icon = gtk.CellRendererPixbuf()
199
 
        icon.set_property("stock-size", gtk.ICON_SIZE_BUTTON)
200
 
        hw_list.pack_start(icon, False)
201
 
        hw_list.add_attribute(icon, 'icon-name', 1)
202
 
        text = gtk.CellRendererText()
203
 
        text.set_property("xpad", 6)
204
 
        hw_list.pack_start(text, True)
205
 
        hw_list.add_attribute(text, 'text', 0)
206
 
        hw_list.add_attribute(text, 'sensitive', 3)
207
 
 
208
 
        # Virtual network list
209
 
        net_list = self.window.get_widget("net-list")
210
 
        bridge_box = self.window.get_widget("net-bridge-box")
211
 
        uihelpers.init_network_list(net_list, bridge_box)
212
 
 
213
 
        # Network model list
214
 
        netmodel_list  = self.window.get_widget("net-model")
215
 
        uihelpers.build_netmodel_combo(self.vm, netmodel_list)
216
 
 
217
 
        # Disk device type / bus
218
 
        target_list = self.window.get_widget("config-storage-devtype")
219
 
        target_model = gtk.ListStore(str, str, str, str, int)
220
 
        target_list.set_model(target_model)
221
 
        icon = gtk.CellRendererPixbuf()
222
 
        icon.set_property("stock-size", gtk.ICON_SIZE_BUTTON)
223
 
        target_list.pack_start(icon, False)
224
 
        target_list.add_attribute(icon, 'icon-name', 2)
225
 
        text = gtk.CellRendererText()
226
 
        text.set_property("xpad", 6)
227
 
        target_list.pack_start(text, True)
228
 
        target_list.add_attribute(text, 'text', 3)
229
 
 
230
 
        # Sparse tooltip
231
 
        sparse_info = self.window.get_widget("config-storage-nosparse-info")
232
 
        uihelpers.set_sparse_tooltip(sparse_info)
233
 
 
234
 
        # Input device type
235
 
        input_list = self.window.get_widget("input-type")
236
 
        input_model = gtk.ListStore(str, str, str, bool)
237
 
        input_list.set_model(input_model)
238
 
        text = gtk.CellRendererText()
239
 
        input_list.pack_start(text, True)
240
 
        input_list.add_attribute(text, 'text', 0)
241
 
        input_list.add_attribute(text, 'sensitive', 3)
242
 
 
243
 
        # Graphics type
244
 
        graphics_list = self.window.get_widget("graphics-type")
245
 
        graphics_model = gtk.ListStore(str,str)
246
 
        graphics_list.set_model(graphics_model)
247
 
        text = gtk.CellRendererText()
248
 
        graphics_list.pack_start(text, True)
249
 
        graphics_list.add_attribute(text, 'text', 0)
250
 
 
251
 
        # Sound model list
252
 
        sound_list = self.window.get_widget("sound-model")
253
 
        uihelpers.build_sound_combo(self.vm, sound_list)
254
 
 
255
 
        host_devtype = self.window.get_widget("host-device-type")
256
 
        # Description, nodedev type, specific type capability, sub type,
257
 
        # sub cap
258
 
        host_devtype_model = gtk.ListStore(str, str, str, str, str)
259
 
        host_devtype.set_model(host_devtype_model)
260
 
        text = gtk.CellRendererText()
261
 
        host_devtype.pack_start(text, True)
262
 
        host_devtype.add_attribute(text, 'text', 0)
263
 
 
264
 
        host_dev = self.window.get_widget("host-device")
265
 
        # Description, nodedev name
266
 
        host_dev_model = gtk.ListStore(str, str)
267
 
        host_dev.set_model(host_dev_model)
268
 
        text = gtk.CellRendererText()
269
 
        host_dev.pack_start(text, True)
270
 
        host_dev.add_attribute(text, 'text', 0)
271
 
        host_dev_model.set_sort_column_id(0, gtk.SORT_ASCENDING)
272
 
 
273
 
        # Video device
274
 
        video_dev = self.window.get_widget("video-model")
275
 
        uihelpers.build_video_combo(self.vm, video_dev)
276
 
 
277
 
        char_devtype = self.window.get_widget("char-device-type")
278
 
        # Type name, desc
279
 
        char_devtype_model = gtk.ListStore(str, str)
280
 
        char_devtype.set_model(char_devtype_model)
281
 
        text = gtk.CellRendererText()
282
 
        char_devtype.pack_start(text, True)
283
 
        char_devtype.add_attribute(text, 'text', 1)
284
 
        char_devtype_model.set_sort_column_id(0, gtk.SORT_ASCENDING)
285
 
        for t in VirtualCharDevice.char_types:
286
 
            desc = VirtualCharDevice.get_char_type_desc(t)
287
 
            char_devtype_model.append([t, desc + " (%s)" % t])
288
 
 
289
 
        char_mode = self.window.get_widget("char-mode")
290
 
        # Mode name, desc
291
 
        char_mode_model = gtk.ListStore(str, str)
292
 
        char_mode.set_model(char_mode_model)
293
 
        text = gtk.CellRendererText()
294
 
        char_mode.pack_start(text, True)
295
 
        char_mode.add_attribute(text, 'text', 1)
296
 
        char_mode_model.set_sort_column_id(0, gtk.SORT_ASCENDING)
297
 
        for t in VirtualCharDevice.char_modes:
298
 
            desc = VirtualCharDevice.get_char_mode_desc(t)
299
 
            char_mode_model.append([t, desc + " (%s)" % t])
300
 
 
301
 
        self.window.get_widget("char-info-box").modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("grey"))
302
 
 
303
 
        # Watchdog widgets
304
 
        combo = self.window.get_widget("watchdog-model")
305
 
        uihelpers.build_watchdogmodel_combo(self.vm, combo)
306
 
 
307
 
        combo = self.window.get_widget("watchdog-action")
308
 
        uihelpers.build_watchdogaction_combo(self.vm, combo)
309
 
 
310
 
 
311
 
    def reset_state(self):
312
 
        is_local = not self.conn.is_remote()
313
 
        is_storage_capable = self.conn.is_storage_capable()
314
 
 
315
 
        notebook = self.window.get_widget("create-pages")
316
 
        notebook.set_current_page(0)
317
 
 
318
 
        # Hide the "finish" button until the appropriate time
319
 
        self.window.get_widget("create-finish").hide()
320
 
        self.window.get_widget("create-forward").show()
321
 
        self.window.get_widget("create-forward").grab_focus()
322
 
        self.window.get_widget("create-back").set_sensitive(False)
323
 
        self.window.get_widget("create-help").hide()
324
 
 
325
 
        # Storage init
326
 
        label_widget = self.window.get_widget("phys-hd-label")
327
 
        if not self.host_storage_timer:
328
 
            self.host_storage_timer = util.safe_timeout_add(3 * 1000,
329
 
                                                uihelpers.host_space_tick,
330
 
                                                self.conn, self.config,
331
 
                                                label_widget)
332
 
        self.window.get_widget("config-storage-create").set_active(True)
333
 
        self.window.get_widget("config-storage-size").set_value(8)
334
 
        self.window.get_widget("config-storage-entry").set_text("")
335
 
        self.window.get_widget("config-storage-nosparse").set_active(True)
336
 
        target_list = self.window.get_widget("config-storage-devtype")
337
 
        self.populate_target_device_model(target_list.get_model())
338
 
        if len(target_list.get_model()) > 0:
339
 
            target_list.set_active(0)
340
 
 
341
 
        have_storage = (is_local or is_storage_capable)
342
 
        storage_tooltip = None
343
 
        if not have_storage:
344
 
            storage_tooltip = _("Connection does not support storage"
345
 
                                " management.")
346
 
 
347
 
        # Network init
348
 
        newmac = uihelpers.generate_macaddr(self.vm.get_connection())
349
 
        self.window.get_widget("mac-address").set_active(bool(newmac))
350
 
        self.window.get_widget("create-mac-address").set_text(newmac)
351
 
        self.change_macaddr_use()
352
 
 
353
 
        net_list = self.window.get_widget("net-list")
354
 
        net_warn = self.window.get_widget("net-list-warn")
355
 
        uihelpers.populate_network_list(net_list, self.vm.get_connection())
356
 
 
357
 
        error = self.vm.get_connection().netdev_error
358
 
        if error:
359
 
            net_warn.show()
360
 
            util.tooltip_wrapper(net_warn, error)
361
 
        else:
362
 
            net_warn.hide()
363
 
 
364
 
        netmodel = self.window.get_widget("net-model")
365
 
        uihelpers.populate_netmodel_combo(self.vm, netmodel)
366
 
        netmodel.set_active(0)
367
 
 
368
 
        # Input device init
369
 
        input_box = self.window.get_widget("input-type")
370
 
        self.populate_input_model(input_box.get_model())
371
 
        input_box.set_active(0)
372
 
 
373
 
        # Graphics init
374
 
        self.change_port_auto()
375
 
        graphics_box = self.window.get_widget("graphics-type")
376
 
        self.populate_graphics_model(graphics_box.get_model())
377
 
        graphics_box.set_active(0)
378
 
        self.window.get_widget("graphics-address").set_active(False)
379
 
        self.window.get_widget("graphics-port-auto").set_active(True)
380
 
        self.window.get_widget("graphics-password").set_text("")
381
 
        self.window.get_widget("graphics-keymap").set_text("")
382
 
        self.window.get_widget("graphics-keymap-chk").set_active(True)
383
 
 
384
 
        # Sound init
385
 
        sound_box = self.window.get_widget("sound-model")
386
 
        sound_box.set_active(0)
387
 
                
388
 
        # Hostdev init
389
 
        host_devtype = self.window.get_widget("host-device-type")
390
 
        self.populate_host_device_type_model(host_devtype.get_model())
391
 
        host_devtype.set_active(0)
392
 
 
393
 
        # Set available HW options
394
 
 
395
 
        # Char parameters
396
 
        self.window.get_widget("char-device-type").set_active(0)
397
 
        self.window.get_widget("char-path").set_text("")
398
 
        self.window.get_widget("char-host").set_text("127.0.0.1")
399
 
        self.window.get_widget("char-port").get_adjustment().value = 4555
400
 
        self.window.get_widget("char-bind-host").set_text("127.0.0.1")
401
 
        self.window.get_widget("char-bind-port").get_adjustment().value = 4556
402
 
        self.window.get_widget("char-use-telnet").set_active(False)
403
 
 
404
 
        # Available HW options
405
 
        model = self.window.get_widget("hardware-type").get_model()
406
 
        model.clear()
407
 
 
408
 
        def add_hw_option(name, icon, page, sensitive, tooltip):
409
 
            model.append([name, icon, page, sensitive, tooltip])
410
 
 
411
 
        add_hw_option("Storage", "drive-harddisk", PAGE_DISK, have_storage,
412
 
                      have_storage and storage_tooltip or None)
413
 
        add_hw_option("Network", "network-idle", PAGE_NETWORK, True, None)
414
 
        add_hw_option("Input", "input-mouse", PAGE_INPUT, self.vm.is_hvm(),
415
 
                      _("Not supported for this guest type."))
416
 
        add_hw_option("Graphics", "video-display", PAGE_GRAPHICS,
417
 
                      True, None)
418
 
        add_hw_option("Sound", "audio-card", PAGE_SOUND,
419
 
                      self.vm.is_hvm(),
420
 
                      _("Not supported for this guest type."))
421
 
        add_hw_option("Serial", gtk.STOCK_CONNECT, PAGE_CHAR,
422
 
                      self.vm.is_hvm(),
423
 
                      _("Not supported for this guest type."))
424
 
        add_hw_option("Parallel", gtk.STOCK_CONNECT, PAGE_CHAR,
425
 
                      self.vm.is_hvm(),
426
 
                      _("Not supported for this guest type."))
427
 
        add_hw_option("Physical Host Device", "system-run", PAGE_HOSTDEV,
428
 
                      self.vm.get_connection().is_nodedev_capable(),
429
 
                      _("Connection does not support host device "
430
 
                      "enumeration"))
431
 
        add_hw_option("Video", "video-display", PAGE_VIDEO,
432
 
                      virtinst.support.check_conn_support(
433
 
                            self.vm.get_connection().vmm,
434
 
                            virtinst.support.SUPPORT_CONN_DOMAIN_VIDEO),
435
 
                      _("Libvirt version does not support video devices."))
436
 
        add_hw_option("Watchdog", "device_pci", PAGE_WATCHDOG,
437
 
                      self.vm.is_hvm(),
438
 
                      _("Not supported for this guest type."))
439
 
 
440
 
        self.window.get_widget("hardware-type").set_active(0)
441
 
 
442
 
    #########################
443
 
    # UI population methods #
444
 
    #########################
445
 
 
446
 
    def populate_target_device_model(self, model):
447
 
        model.clear()
448
 
        #[bus, device, icon, desc, iconsize]
449
 
        def add_dev(bus, device, desc):
450
 
            if device == virtinst.VirtualDisk.DEVICE_FLOPPY:
451
 
                icon = "media-floppy"
452
 
            elif device == virtinst.VirtualDisk.DEVICE_CDROM:
453
 
                icon = "media-optical"
454
 
            else:
455
 
                icon = "drive-harddisk"
456
 
            model.append([bus, device, icon, desc, gtk.ICON_SIZE_BUTTON])
457
 
 
458
 
        if self.vm.is_hvm():
459
 
            add_dev("ide", virtinst.VirtualDisk.DEVICE_DISK, "IDE disk")
460
 
            add_dev("ide", virtinst.VirtualDisk.DEVICE_CDROM, "IDE cdrom")
461
 
            add_dev("fdc", virtinst.VirtualDisk.DEVICE_FLOPPY, "Floppy disk")
462
 
            add_dev("scsi",virtinst.VirtualDisk.DEVICE_DISK, "SCSI disk")
463
 
            add_dev("usb", virtinst.VirtualDisk.DEVICE_DISK, "USB disk")
464
 
        if self.vm.get_hv_type() == "kvm":
465
 
            add_dev("virtio", virtinst.VirtualDisk.DEVICE_DISK, "Virtio Disk")
466
 
        if self.vm.get_connection().is_xen():
467
 
            add_dev("xen", virtinst.VirtualDisk.DEVICE_DISK, "Virtual disk")
468
 
 
469
 
    def populate_input_model(self, model):
470
 
        model.clear()
471
 
        model.append([_("EvTouch USB Graphics Tablet"), "tablet", "usb", True])
472
 
        # XXX libvirt needs to support 'model' for input devices to distinguish
473
 
        # wacom from evtouch tablets
474
 
        #model.append([_("Wacom Graphics Tablet"), "tablet", "usb", True])
475
 
        model.append([_("Generic USB Mouse"), "mouse", "usb", True])
476
 
 
477
 
    def populate_graphics_model(self, model):
478
 
        model.clear()
479
 
        model.append([_("VNC server"), "vnc"])
480
 
        model.append([_("Local SDL window"), "sdl"])
481
 
 
482
 
    def populate_host_device_type_model(self, model):
483
 
        model.clear()
484
 
        for m in [ ["PCI Device", "pci", None, "net", "80203"],
485
 
                   ["USB Device", "usb_device", None, None, None]]:
486
 
            model.append(m)
487
 
 
488
 
    def populate_host_device_model(self, model, devtype, devcap, subtype,
489
 
                                   subcap):
490
 
        model.clear()
491
 
        subdevs = []
492
 
 
493
 
        if subtype:
494
 
            subdevs = self.vm.get_connection().get_devices(subtype, subcap)
495
 
 
496
 
        devs = self.vm.get_connection().get_devices(devtype, devcap)
497
 
        for dev in devs:
498
 
            prettyname = dev.pretty_name()
499
 
 
500
 
            for subdev in subdevs:
501
 
                if dev.name == subdev.parent:
502
 
                    prettyname = dev.pretty_name(subdev)
503
 
 
504
 
            model.append([prettyname, dev.name])
505
 
 
506
 
        if len(model) == 0:
507
 
            model.append([_("No Devices Available"), None])
508
 
 
509
 
 
510
 
    ########################
511
 
    # get_config_* methods #
512
 
    ########################
513
 
 
514
 
    def get_config_hardware_type(self):
515
 
        _type = self.window.get_widget("hardware-type")
516
 
        if _type.get_active_iter() == None:
517
 
            return None
518
 
        return _type.get_model().get_value(_type.get_active_iter(), 2)
519
 
 
520
 
    # Disk getters
521
 
    def is_default_storage(self):
522
 
        return self.window.get_widget("config-storage-create").get_active()
523
 
 
524
 
    def get_storage_info(self):
525
 
        path = None
526
 
        size = self.window.get_widget("config-storage-size").get_value()
527
 
        sparse = not self.window.get_widget("config-storage-nosparse").get_active()
528
 
 
529
 
        if self.is_default_storage():
530
 
            path = util.get_default_path(self.conn, self.config,
531
 
                                         self.vm.get_name())
532
 
            logging.debug("Default storage path is: %s" % path)
533
 
        else:
534
 
            path = self.window.get_widget("config-storage-entry").get_text()
535
 
 
536
 
        return (path, size, sparse)
537
 
 
538
 
    def get_config_disk_target(self):
539
 
        target = self.window.get_widget("config-storage-devtype")
540
 
        model = target.get_model()
541
 
        idx = target.get_active()
542
 
        if idx == -1:
543
 
            return None, None
544
 
 
545
 
        bus = model[idx][0]
546
 
        device = model[idx][1]
547
 
        return bus, device
548
 
 
549
 
    # Input getters
550
 
    def get_config_input(self):
551
 
        target = self.window.get_widget("input-type")
552
 
        label = target.get_model().get_value(target.get_active_iter(), 0)
553
 
        _type = target.get_model().get_value(target.get_active_iter(), 1)
554
 
        bus = target.get_model().get_value(target.get_active_iter(), 2)
555
 
        return label, _type, bus
556
 
 
557
 
    # Graphics getters
558
 
    def get_config_graphics(self):
559
 
        _type = self.window.get_widget("graphics-type")
560
 
        if _type.get_active_iter() is None:
561
 
            return None
562
 
        return _type.get_model().get_value(_type.get_active_iter(), 1)
563
 
 
564
 
    def get_config_vnc_port(self):
565
 
        port = self.window.get_widget("graphics-port")
566
 
        portAuto = self.window.get_widget("graphics-port-auto")
567
 
        if portAuto.get_active():
568
 
            return -1
569
 
        return int(port.get_value())
570
 
 
571
 
    def get_config_vnc_address(self):
572
 
        addr = self.window.get_widget("graphics-address")
573
 
        if addr.get_active():
574
 
            return "0.0.0.0"
575
 
        return "127.0.0.1"
576
 
 
577
 
    def get_config_vnc_password(self):
578
 
        pw = self.window.get_widget("graphics-password")
579
 
        return pw.get_text()
580
 
 
581
 
    def get_config_keymap(self):
582
 
        g = self.window.get_widget("graphics-keymap")
583
 
        if g.get_property("sensitive") and g.get_text() != "":
584
 
            return g.get_text()
585
 
        else:
586
 
            return None
587
 
 
588
 
    # Network getters
589
 
    def get_config_network(self):
590
 
        net_list = self.window.get_widget("net-list")
591
 
        bridge_ent = self.window.get_widget("net-bridge")
592
 
 
593
 
        net_type, net_src = uihelpers.get_network_selection(net_list,
594
 
                                                            bridge_ent)
595
 
 
596
 
        return net_type, net_src
597
 
 
598
 
    def get_config_net_model(self):
599
 
        model = self.window.get_widget("net-model")
600
 
        if model.get_active_iter():
601
 
            modelxml = model.get_model().get_value(model.get_active_iter(), 0)
602
 
            modelstr = model.get_model().get_value(model.get_active_iter(), 1)
603
 
        else:
604
 
            modelxml = modelstr = None
605
 
        return modelxml, modelstr
606
 
 
607
 
    def get_config_macaddr(self):
608
 
        macaddr = None
609
 
        if self.window.get_widget("mac-address").get_active():
610
 
            macaddr = self.window.get_widget("create-mac-address").get_text()
611
 
        return macaddr
612
 
 
613
 
    # Sound getters
614
 
    def get_config_sound_model(self):
615
 
        model = self.window.get_widget("sound-model")
616
 
        modelstr = model.get_model().get_value(model.get_active_iter(), 0)
617
 
        return modelstr
618
 
 
619
 
    # Host device getters
620
 
    def get_config_host_device_type_info(self):
621
 
        devbox = self.window.get_widget("host-device-type")
622
 
        return devbox.get_model()[devbox.get_active()]
623
 
 
624
 
    def get_config_host_device_info(self):
625
 
        devbox = self.window.get_widget("host-device")
626
 
        return devbox.get_model()[devbox.get_active()]
627
 
 
628
 
    # Video Getters
629
 
    def get_config_video_model(self):
630
 
        modbox = self.window.get_widget("video-model")
631
 
        return modbox.get_model()[modbox.get_active()][0]
632
 
 
633
 
    # Watchdog getters
634
 
    def get_config_watchdog_model(self):
635
 
        modbox = self.window.get_widget("watchdog-model")
636
 
        return modbox.get_model()[modbox.get_active()][0]
637
 
    def get_config_watchdog_action(self):
638
 
        modbox = self.window.get_widget("watchdog-action")
639
 
        return modbox.get_model()[modbox.get_active()][0]
640
 
 
641
 
    ################
642
 
    # UI listeners #
643
 
    ################
644
 
 
645
 
    def hardware_type_changed(self, src):
646
 
        if src.get_active() < 0:
647
 
            return
648
 
 
649
 
        row = src.get_model()[src.get_active()]
650
 
 
651
 
        sens = row[3]
652
 
        msg = row[4] or ""
653
 
 
654
 
        self.window.get_widget("create-forward").set_sensitive(sens)
655
 
        self.window.get_widget("hardware-info-box").set_property("visible",
656
 
                                                                 (not sens))
657
 
        self.window.get_widget("hardware-info").set_text(msg)
658
 
 
659
 
    def forward(self, ignore=None):
660
 
        notebook = self.window.get_widget("create-pages")
661
 
        try:
662
 
            if self.validate(notebook.get_current_page()) == False:
663
 
                return
664
 
        except Exception, e:
665
 
            self.err.show_err(_("Uncaught error validating hardware "
666
 
                                "input: %s") % str(e),
667
 
                              "".join(traceback.format_exc()))
668
 
            return
669
 
 
670
 
        hwtype = self.get_config_hardware_type()
671
 
        if notebook.get_current_page() == PAGE_INTRO:
672
 
            notebook.set_current_page(hwtype)
673
 
        else:
674
 
            notebook.set_current_page(PAGE_SUMMARY)
675
 
            self.window.get_widget("create-finish").show()
676
 
            self.window.get_widget("create-finish").grab_focus()
677
 
            self.window.get_widget("create-forward").hide()
678
 
        self.window.get_widget("create-back").set_sensitive(True)
679
 
 
680
 
    def back(self, ignore=None):
681
 
        notebook = self.window.get_widget("create-pages")
682
 
 
683
 
        if notebook.get_current_page() == PAGE_SUMMARY:
684
 
            hwtype = self.get_config_hardware_type()
685
 
            notebook.set_current_page(hwtype)
686
 
            self.window.get_widget("create-finish").hide()
687
 
        else:
688
 
            notebook.set_current_page(PAGE_INTRO)
689
 
            self.window.get_widget("create-back").set_sensitive(False)
690
 
 
691
 
        self.window.get_widget("create-forward").show()
692
 
 
693
 
    def page_changed(self, notebook, page, page_number):
694
 
        devbox = self.window.get_widget("host-device")
695
 
        devbox.hide()
696
 
 
697
 
        if page_number == PAGE_CHAR:
698
 
            devtype = self.window.get_widget("char-device-type")
699
 
            self.change_char_device_type(devtype)
700
 
            self.set_page_char_type()
701
 
 
702
 
        elif page_number == PAGE_SUMMARY:
703
 
            self.populate_summary()
704
 
 
705
 
        elif page_number == PAGE_HOSTDEV:
706
 
            devbox.show()
707
 
 
708
 
        return
709
 
 
710
 
    def populate_summary(self):
711
 
        hwpage = self.get_config_hardware_type()
712
 
 
713
 
        summary_table = self.window.get_widget("summary-table")
714
 
        for c in summary_table.get_children():
715
 
            summary_table.remove(c)
716
 
 
717
 
        def set_table(title, info_list):
718
 
            self.window.get_widget("summary-title").set_markup("<b>%s</b>" %
719
 
                                                               title)
720
 
            row = 0
721
 
            for label, value in info_list:
722
 
                label = gtk.Label(label)
723
 
                label.set_alignment(1, .5)
724
 
                value = gtk.Label(value)
725
 
                value.set_alignment(0, .5)
726
 
 
727
 
                summary_table.attach(label, 0, 1, row, row+1, gtk.FILL, 0)
728
 
                summary_table.attach(value, 1, 2, row, row+1, gtk.FILL, 0)
729
 
 
730
 
                row += 1
731
 
                if row == 10:
732
 
                    return
733
 
 
734
 
            summary_table.show_all()
735
 
 
736
 
        if hwpage == PAGE_DISK:
737
 
            size_str = (self._dev.size and ("%2.2f GB" % self._dev.size)
738
 
                                       or "-")
739
 
 
740
 
            info_list = [
741
 
                (_("Disk image:"),  self._dev.path),
742
 
                (_("Disk size:"),   size_str),
743
 
                (_("Device type:"), self._dev.device),
744
 
                (_("Bus type:"),    self._dev.bus),
745
 
            ]
746
 
            title = _("Storage")
747
 
 
748
 
        elif hwpage == PAGE_NETWORK:
749
 
            net_type, net_target = self.get_config_network()
750
 
            macaddr = self.get_config_macaddr()
751
 
            model = self.get_config_net_model()[1]
752
 
            net_label = virtinst.VirtualNetworkInterface.get_network_type_desc(net_type)
753
 
            net_target = net_target or "-"
754
 
 
755
 
            info_list = [
756
 
                (_("Network type:"),     net_label),
757
 
                (_("Target:"),          net_target),
758
 
                (_("MAC address:"),     macaddr or "-"),
759
 
                (_("Model:"),           model or "-"),
760
 
            ]
761
 
            title = _("Network")
762
 
 
763
 
        elif hwpage == PAGE_INPUT:
764
 
            ignore, typ, model = self.get_config_input()
765
 
            if typ == virtinst.VirtualInputDevice.INPUT_TYPE_TABLET:
766
 
                mode_label = _("Absolute movement")
767
 
            else:
768
 
                mode_label = _("Relative movement")
769
 
 
770
 
            info_list = [
771
 
                (_("Type:"), typ),
772
 
                (_("Mode:"), mode_label),
773
 
            ]
774
 
            title = _("Pointer")
775
 
 
776
 
        elif hwpage == PAGE_GRAPHICS:
777
 
            graphics = self.get_config_graphics()
778
 
            is_vnc = (graphics == virtinst.VirtualGraphics.TYPE_VNC)
779
 
 
780
 
            type_label = is_vnc and _("VNC server") or _("Local SDL window")
781
 
            addr = is_vnc and self.get_config_vnc_address() or _("N/A")
782
 
            port_label = _("N/A")
783
 
            passwd_label = _("N/A")
784
 
            keymap_label = _("N/A")
785
 
 
786
 
            if is_vnc:
787
 
                port = self.get_config_vnc_port()
788
 
                passwd = self.get_config_vnc_password()
789
 
                keymap = self.get_config_keymap()
790
 
 
791
 
                port_label = ((port == -1) and ("Automatically allocated")
792
 
                                           or port)
793
 
                passwd_label = passwd and _("Yes") or _("No")
794
 
                keymap_label = keymap and keymap or _("Same as host")
795
 
 
796
 
            info_list = [
797
 
                (_("Type:"),    type_label),
798
 
                (_("Address:"), addr),
799
 
                (_("Port:"),    port_label),
800
 
                (_("Password:"), passwd_label),
801
 
                (_("Keymap:"),  keymap_label),
802
 
            ]
803
 
            title = _("Graphics")
804
 
 
805
 
        elif hwpage == PAGE_SOUND:
806
 
            info_list = [
807
 
                (_("Model:"),   self._dev.model),
808
 
            ]
809
 
            title = _("Sound")
810
 
 
811
 
        elif hwpage == PAGE_CHAR:
812
 
            mode = None
813
 
 
814
 
            info_list = [
815
 
                (_("Type:"), VirtualCharDevice.get_char_type_desc(self._dev.char_type)),
816
 
            ]
817
 
 
818
 
            if hasattr(self._dev, "source_mode"):
819
 
                mode = self._dev.source_mode.capitalize()
820
 
            if hasattr(self._dev, "source_path"):
821
 
                path = self._dev.source_path
822
 
                label = "%sPath:" % (mode and mode + " " or "")
823
 
                info_list.append((label, path))
824
 
 
825
 
            if hasattr(self._dev, "source_host"):
826
 
                host = "%s:%s" % (self._dev.source_host, self._dev.source_port)
827
 
                label = "%sHost:" % (mode and mode + " " or "")
828
 
                info_list.append((label, host))
829
 
 
830
 
            if hasattr(self._dev, "bind_host"):
831
 
                bind_host = "%s:%s" % (self._dev.bind_host,
832
 
                                       self._dev.bind_port)
833
 
                info_list.append(("Bind Host:", bind_host))
834
 
            if hasattr(self._dev, "protocol"):
835
 
                proto = self._dev.protocol
836
 
                info_list.append((_("Protocol:"), proto))
837
 
 
838
 
            title = self.get_char_type().capitalize()
839
 
 
840
 
        elif hwpage == PAGE_HOSTDEV:
841
 
            info_list = [
842
 
                (_("Type:"),    self.get_config_host_device_type_info()[0]),
843
 
                (_("Device:"),  self.get_config_host_device_info()[0]),
844
 
            ]
845
 
            title = _("Physical Host Device")
846
 
 
847
 
        elif hwpage == PAGE_VIDEO:
848
 
            info_list = [
849
 
                (_("Model:"), self._dev.model_type),
850
 
            ]
851
 
            title = _("Video")
852
 
 
853
 
        elif hwpage == PAGE_WATCHDOG:
854
 
            title = _("Watchdog")
855
 
            info_list = [
856
 
                (_("Model:"), self._dev.model),
857
 
                (_("Action:"), self._dev.get_action_desc(self._dev.action))
858
 
            ]
859
 
 
860
 
        set_table(title, info_list)
861
 
 
862
 
 
863
 
    def finish(self, ignore=None):
864
 
        self.topwin.set_sensitive(False)
865
 
        self.topwin.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
866
 
 
867
 
        try:
868
 
            failure, errinfo = self.add_device()
869
 
            error, details = errinfo or (None, None)
870
 
        except Exception, e:
871
 
            failure = True
872
 
            error = _("Unable to add device: %s") % str(e)
873
 
            details = "".join(traceback.format_exc())
874
 
 
875
 
        if error is not None:
876
 
            self.err.show_err(error, details)
877
 
 
878
 
        self.topwin.set_sensitive(True)
879
 
        self.topwin.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.TOP_LEFT_ARROW))
880
 
 
881
 
        if not failure:
882
 
            self.close()
883
 
 
884
 
    # Storage listeners
885
 
    def browse_storage(self, ignore1):
886
 
        self._browse_file(self.window.get_widget("config-storage-entry"))
887
 
 
888
 
    def toggle_storage_select(self, src):
889
 
        act = src.get_active()
890
 
        self.window.get_widget("config-storage-browse-box").set_sensitive(act)
891
 
 
892
 
    def set_disk_storage_path(self, ignore, path):
893
 
        self.window.get_widget("config-storage-entry").set_text(path)
894
 
 
895
 
    # Network listeners
896
 
    def change_macaddr_use(self, ignore=None):
897
 
        if self.window.get_widget("mac-address").get_active():
898
 
            self.window.get_widget("create-mac-address").set_sensitive(True)
899
 
        else:
900
 
            self.window.get_widget("create-mac-address").set_sensitive(False)
901
 
 
902
 
    # Graphics listeners
903
 
    def change_graphics_type(self,ignore=None):
904
 
        graphics = self.get_config_graphics()
905
 
        if graphics == "vnc":
906
 
            self.window.get_widget("graphics-port-auto").set_sensitive(True)
907
 
            self.window.get_widget("graphics-address").set_sensitive(True)
908
 
            self.window.get_widget("graphics-password").set_sensitive(True)
909
 
            self.window.get_widget("graphics-keymap-chk").set_sensitive(True)
910
 
            self.change_port_auto()
911
 
        else:
912
 
            self.window.get_widget("graphics-port").set_sensitive(False)
913
 
            self.window.get_widget("graphics-port-auto").set_sensitive(False)
914
 
            self.window.get_widget("graphics-address").set_sensitive(False)
915
 
            self.window.get_widget("graphics-password").set_sensitive(False)
916
 
            self.window.get_widget("graphics-keymap-chk").set_sensitive(False)
917
 
            self.window.get_widget("graphics-keymap").set_sensitive(False)
918
 
 
919
 
    def change_port_auto(self,ignore=None):
920
 
        if self.window.get_widget("graphics-port-auto").get_active():
921
 
            self.window.get_widget("graphics-port").set_sensitive(False)
922
 
        else:
923
 
            self.window.get_widget("graphics-port").set_sensitive(True)
924
 
 
925
 
    def change_keymap(self, ignore=None):
926
 
        if self.window.get_widget("graphics-keymap-chk").get_active():
927
 
            self.window.get_widget("graphics-keymap").set_sensitive(False)
928
 
        else:
929
 
            self.window.get_widget("graphics-keymap").set_sensitive(True)
930
 
 
931
 
    # Hostdevice listeners
932
 
    def change_host_device_type(self, src):
933
 
        devbox = self.window.get_widget("host-device")
934
 
        if src.get_active() < 0:
935
 
            devbox.get_model().clear()
936
 
            return
937
 
 
938
 
        (ignore, devtype, devcap,
939
 
         subtype, subcap) = src.get_model()[src.get_active()]
940
 
        self.populate_host_device_model(devbox.get_model(), devtype, devcap,
941
 
                                        subtype, subcap)
942
 
        devbox.set_active(0)
943
 
 
944
 
    # Char device listeners
945
 
    def get_char_type(self):
946
 
        hw_list = self.window.get_widget("hardware-type")
947
 
        if hw_list.get_active() < 0:
948
 
            label = "serial"
949
 
        else:
950
 
            label = hw_list.get_model()[hw_list.get_active()][0]
951
 
 
952
 
        if label.lower() == "parallel":
953
 
            return VirtualDevice.VIRTUAL_DEV_PARALLEL
954
 
        return VirtualDevice.VIRTUAL_DEV_SERIAL
955
 
 
956
 
    def set_page_char_type(self):
957
 
        char_type = self.get_char_type().capitalize()
958
 
        self.window.get_widget("char-title-label").set_markup(
959
 
            """<span weight="heavy" size="xx-large" foreground="#FFF">%s Device</span>""" % char_type)
960
 
 
961
 
    def change_char_device_type(self, src):
962
 
        self.update_doc(None, None, "char_type")
963
 
 
964
 
        chartype = self.get_char_type()
965
 
        devtype = src.get_model()[src.get_active()][0]
966
 
        conn = self.vm.get_connection().vmm
967
 
 
968
 
        self._dev = VirtualCharDevice.get_dev_instance(conn,
969
 
                                                       chartype,
970
 
                                                       devtype)
971
 
 
972
 
        for param_name, widget_name in char_widget_mappings.items():
973
 
            make_visible = hasattr(self._dev, param_name)
974
 
            self.window.get_widget(widget_name).set_sensitive(make_visible)
975
 
 
976
 
        has_mode = hasattr(self._dev, "source_mode")
977
 
 
978
 
        if has_mode and self.window.get_widget("char-mode").get_active() == -1:
979
 
            self.window.get_widget("char-mode").set_active(0)
980
 
 
981
 
 
982
 
    ######################
983
 
    # Add device methods #
984
 
    ######################
985
 
 
986
 
    def setup_device(self):
987
 
        if (self._dev.virtual_device_type ==
988
 
            virtinst.VirtualDevice.VIRTUAL_DEV_DISK):
989
 
            progWin = vmmAsyncJob(self.config, self.do_file_allocate,
990
 
                                  [self._dev],
991
 
                                  title=_("Creating Storage File"),
992
 
                                  text=_("Allocation of disk storage may take "
993
 
                                         "a few minutes to complete."))
994
 
            progWin.run()
995
 
 
996
 
            error, details = progWin.get_error()
997
 
            if error:
998
 
                return (error, details)
999
 
 
1000
 
        else:
1001
 
            self._dev.setup_dev(self.conn.vmm)
1002
 
 
1003
 
    def add_device(self):
1004
 
        ret = self.setup_device()
1005
 
        if ret:
1006
 
            # Encountered an error
1007
 
            return (True, ret)
1008
 
 
1009
 
        self._dev.get_xml_config()
1010
 
        logging.debug("Adding device:\n" + self._dev.get_xml_config())
1011
 
 
1012
 
        # Hotplug device
1013
 
        attach_err = False
1014
 
        try:
1015
 
            self.vm.attach_device(self._dev)
1016
 
        except Exception, e:
1017
 
            logging.debug("Device could not be hotplugged: %s" % str(e))
1018
 
            attach_err = True
1019
 
 
1020
 
        if attach_err:
1021
 
            if not self.err.yes_no(_("Are you sure you want to add this "
1022
 
                                     "device?"),
1023
 
                                   _("This device could not be attached to "
1024
 
                                     "the running machine. Would you like to "
1025
 
                                     "make the device available after the "
1026
 
                                     "next VM shutdown?")):
1027
 
                return (False, None)
1028
 
 
1029
 
        # Alter persistent config
1030
 
        try:
1031
 
            self.vm.add_device(self._dev)
1032
 
        except Exception, e:
1033
 
            self.err.show_err(_("Error adding device: %s" % str(e)),
1034
 
                              "".join(traceback.format_exc()))
1035
 
            return (True, None)
1036
 
 
1037
 
        return (False, None)
1038
 
 
1039
 
    def do_file_allocate(self, disk, asyncjob):
1040
 
        meter = vmmCreateMeter(asyncjob)
1041
 
        newconn = None
1042
 
        try:
1043
 
            # If creating disk via storage API, we need to thread
1044
 
            # off a new connection
1045
 
            if disk.vol_install:
1046
 
                newconn = util.dup_lib_conn(self.config, disk.conn)
1047
 
                disk.conn = newconn
1048
 
            logging.debug("Starting background file allocate process")
1049
 
            disk.setup_dev(self.conn.vmm, meter=meter)
1050
 
            logging.debug("Allocation completed")
1051
 
        except Exception, e:
1052
 
            details = (_("Unable to complete install: '%s'") %
1053
 
                         "".join(traceback.format_exc()))
1054
 
            error = _("Unable to complete install: '%s'") % str(e)
1055
 
            asyncjob.set_error(error, details)
1056
 
 
1057
 
 
1058
 
    ###########################
1059
 
    # Page validation methods #
1060
 
    ###########################
1061
 
 
1062
 
    def validate(self, page_num):
1063
 
        if page_num == PAGE_INTRO:
1064
 
            return self.validate_page_intro()
1065
 
        elif page_num == PAGE_DISK:
1066
 
            return self.validate_page_storage()
1067
 
        elif page_num == PAGE_NETWORK:
1068
 
            return self.validate_page_network()
1069
 
        elif page_num == PAGE_INPUT:
1070
 
            return self.validate_page_input()
1071
 
        elif page_num == PAGE_GRAPHICS:
1072
 
            return self.validate_page_graphics()
1073
 
        elif page_num == PAGE_SOUND:
1074
 
            return self.validate_page_sound()
1075
 
        elif page_num == PAGE_HOSTDEV:
1076
 
            return self.validate_page_hostdev()
1077
 
        elif page_num == PAGE_CHAR:
1078
 
            return self.validate_page_char()
1079
 
        elif page_num == PAGE_VIDEO:
1080
 
            return self.validate_page_video()
1081
 
        elif page_num == PAGE_WATCHDOG:
1082
 
            return self.validate_page_watchdog()
1083
 
 
1084
 
    def validate_page_intro(self):
1085
 
        if self.get_config_hardware_type() == None:
1086
 
            return self.err.val_err(_("Hardware Type Required"),
1087
 
                    _("You must specify what type of hardware to add."))
1088
 
        self._dev = None
1089
 
 
1090
 
    def validate_page_storage(self):
1091
 
        bus, device = self.get_config_disk_target()
1092
 
 
1093
 
        readonly = False
1094
 
        if device == virtinst.VirtualDisk.DEVICE_CDROM:
1095
 
            readonly=True
1096
 
 
1097
 
        try:
1098
 
            # This can error out
1099
 
            diskpath, disksize, sparse = self.get_storage_info()
1100
 
 
1101
 
            if self.is_default_storage():
1102
 
                # See if the ideal disk path (/default/pool/vmname.img)
1103
 
                # exists, and if unused, prompt the use for using it
1104
 
                ideal = util.get_ideal_path(self.conn, self.config,
1105
 
                                            self.vm.get_name())
1106
 
                do_exist = False
1107
 
                ret = True
1108
 
 
1109
 
                try:
1110
 
                    do_exist = virtinst.VirtualDisk.path_exists(
1111
 
                                                        self.conn.vmm, ideal)
1112
 
 
1113
 
                    ret = virtinst.VirtualDisk.path_in_use_by(self.conn.vmm,
1114
 
                                                              ideal)
1115
 
                except:
1116
 
                    logging.exception("Error checking default path usage")
1117
 
 
1118
 
                if do_exist and not ret:
1119
 
                    do_use = self.err.yes_no(
1120
 
                        _("The following path already exists, but is not\n"
1121
 
                          "in use by any virtual machine:\n\n%s\n\n"
1122
 
                          "Would you like to use this path?") % ideal)
1123
 
 
1124
 
                    if do_use:
1125
 
                        diskpath = ideal
1126
 
 
1127
 
            if not diskpath:
1128
 
                return self.err.val_err(_("A storage path must be specified."))
1129
 
 
1130
 
            disk = virtinst.VirtualDisk(conn = self.conn.vmm,
1131
 
                                        path = diskpath,
1132
 
                                        size = disksize,
1133
 
                                        sparse = sparse,
1134
 
                                        readOnly = readonly,
1135
 
                                        device = device,
1136
 
                                        bus = bus)
1137
 
 
1138
 
            if (disk.type == virtinst.VirtualDisk.TYPE_FILE and
1139
 
                not self.vm.is_hvm() and
1140
 
                virtinst.util.is_blktap_capable()):
1141
 
                disk.driver_name = virtinst.VirtualDisk.DRIVER_TAP
1142
 
 
1143
 
        except Exception, e:
1144
 
            return self.err.val_err(_("Storage parameter error."), str(e))
1145
 
 
1146
 
        # Generate target
1147
 
        used = []
1148
 
        disks = (self.vm.get_disk_devices() +
1149
 
                 self.vm.get_disk_devices(inactive=True))
1150
 
        for d in disks:
1151
 
            used.append(d[2])
1152
 
 
1153
 
        disk.generate_target(used)
1154
 
 
1155
 
        isfatal, errmsg = disk.is_size_conflict()
1156
 
        if not isfatal and errmsg:
1157
 
            # Fatal errors are reported when setting 'size'
1158
 
            res = self.err.ok_cancel(_("Not Enough Free Space"), errmsg)
1159
 
            if not res:
1160
 
                return False
1161
 
 
1162
 
        # Disk collision
1163
 
        if disk.is_conflict_disk(self.conn.vmm):
1164
 
            res = self.err.yes_no(_('Disk "%s" is already in use by another '
1165
 
                                    'guest!' %  disk.path),
1166
 
                                  _("Do you really want to use the disk?"))
1167
 
            if not res:
1168
 
                return False
1169
 
 
1170
 
        uihelpers.check_path_search_for_qemu(self.topwin, self.config,
1171
 
                                             self.conn, disk.path)
1172
 
 
1173
 
        self._dev = disk
1174
 
        return True
1175
 
 
1176
 
 
1177
 
    def validate_page_network(self):
1178
 
        nettype, devname = self.get_config_network()
1179
 
        mac = self.get_config_macaddr()
1180
 
        model = self.get_config_net_model()[0]
1181
 
 
1182
 
        if not nettype:
1183
 
            return self.err.val_err(_("Network selection error."),
1184
 
                                    _("A network source must be selected."))
1185
 
 
1186
 
        if not mac:
1187
 
            return self.err.val_err(_("Invalid MAC address"),
1188
 
                                    _("A MAC address must be entered."))
1189
 
 
1190
 
        ret = uihelpers.validate_network(self.topwin, self.vm.get_connection(),
1191
 
                                         nettype, devname, mac, model)
1192
 
        if ret == False:
1193
 
            return False
1194
 
 
1195
 
        self._dev = ret
1196
 
 
1197
 
    def validate_page_input(self):
1198
 
        ignore, inp_type, inp_bus = self.get_config_input()
1199
 
        dev = virtinst.VirtualInputDevice(self.conn.vmm)
1200
 
        dev.type = inp_type
1201
 
        dev.bus = inp_bus
1202
 
 
1203
 
        self._dev = dev
1204
 
 
1205
 
    def validate_page_graphics(self):
1206
 
        graphics = self.get_config_graphics()
1207
 
        if graphics == "vnc":
1208
 
            _type = virtinst.VirtualGraphics.TYPE_VNC
1209
 
        else:
1210
 
            _type = virtinst.VirtualGraphics.TYPE_SDL
1211
 
 
1212
 
        self._dev = virtinst.VirtualGraphics(type=_type)
1213
 
        try:
1214
 
            self._dev.port   = self.get_config_vnc_port()
1215
 
            self._dev.passwd = self.get_config_vnc_password()
1216
 
            self._dev.listen = self.get_config_vnc_address()
1217
 
            self._dev.keymap = self.get_config_keymap()
1218
 
        except ValueError, e:
1219
 
            self.err.val_err(_("Graphics device parameter error"), str(e))
1220
 
 
1221
 
    def validate_page_sound(self):
1222
 
        smodel = self.get_config_sound_model()
1223
 
        try:
1224
 
            self._dev = virtinst.VirtualAudio(model=smodel)
1225
 
        except Exception, e:
1226
 
            return self.err.val_err(_("Sound device parameter error"), str(e))
1227
 
 
1228
 
    def validate_page_hostdev(self):
1229
 
        ignore, nodedev_name = self.get_config_host_device_info()
1230
 
 
1231
 
        if nodedev_name == None:
1232
 
            return self.err.val_err(_("Physical Device Requried"),
1233
 
                                    _("A device must be selected."))
1234
 
 
1235
 
        try:
1236
 
            self._dev = virtinst.VirtualHostDevice.device_from_node(
1237
 
                            conn = self.vm.get_connection().vmm,
1238
 
                            name = nodedev_name)
1239
 
        except Exception, e:
1240
 
            return self.err.val_err(_("Host device parameter error"), str(e))
1241
 
 
1242
 
    def validate_page_char(self):
1243
 
        chartype = self.get_char_type()
1244
 
        devbox = self.window.get_widget("char-device-type")
1245
 
        devtype = devbox.get_model()[devbox.get_active()][0]
1246
 
        conn = self.vm.get_connection().vmm
1247
 
 
1248
 
        devclass = VirtualCharDevice.get_dev_instance(conn, chartype, devtype)
1249
 
 
1250
 
        source_path = self.window.get_widget("char-path").get_text()
1251
 
        source_host = self.window.get_widget("char-host").get_text()
1252
 
        bind_host = self.window.get_widget("char-bind-host").get_text()
1253
 
        source_port = self.window.get_widget("char-port").get_adjustment().value
1254
 
        bind_port = self.window.get_widget("char-bind-port").get_adjustment().value
1255
 
 
1256
 
        if self.window.get_widget("char-use-telnet").get_active():
1257
 
            protocol = VirtualCharDevice.CHAR_PROTOCOL_TELNET
1258
 
        else:
1259
 
            protocol = VirtualCharDevice.CHAR_PROTOCOL_RAW
1260
 
 
1261
 
        value_mappings = {
1262
 
            "source_path" : source_path,
1263
 
            "source_host" : source_host,
1264
 
            "source_port" : source_port,
1265
 
            "bind_port": bind_port,
1266
 
            "bind_host": bind_host,
1267
 
            "protocol": protocol,
1268
 
        }
1269
 
 
1270
 
        try:
1271
 
            self._dev = devclass
1272
 
 
1273
 
            for param_name, val in value_mappings.items():
1274
 
                if hasattr(self._dev, param_name):
1275
 
                    setattr(self._dev, param_name, val)
1276
 
 
1277
 
            # Dump XML for sanity checking
1278
 
            self._dev.get_xml_config()
1279
 
        except Exception, e:
1280
 
            return self.err.val_err(_("%s device parameter error") %
1281
 
                                    chartype.capitalize(), str(e))
1282
 
 
1283
 
    def validate_page_video(self):
1284
 
        conn = self.vm.get_connection().vmm
1285
 
        model = self.get_config_video_model()
1286
 
 
1287
 
        try:
1288
 
            self._dev = VirtualVideoDevice(conn=conn)
1289
 
            self._dev.model_type = model
1290
 
        except Exception, e:
1291
 
            return self.err.val_err(_("Video device parameter error"),
1292
 
                                    str(e))
1293
 
 
1294
 
    def validate_page_watchdog(self):
1295
 
        conn = self.vm.get_connection().vmm
1296
 
        model = self.get_config_watchdog_model()
1297
 
        action = self.get_config_watchdog_action()
1298
 
 
1299
 
        try:
1300
 
            self._dev = VirtualWatchdog(conn=conn)
1301
 
            self._dev.model = model
1302
 
            self._dev.action = action
1303
 
        except Exception, e:
1304
 
            return self.err.val_err(_("Watchdog parameter error"),
1305
 
                                    str(e))
1306
 
 
1307
 
 
1308
 
 
1309
 
    ####################
1310
 
    # Unsorted helpers #
1311
 
    ####################
1312
 
 
1313
 
    def _browse_file(self, textent):
1314
 
        def set_storage_cb(src, path):
1315
 
            if path:
1316
 
                textent.set_text(path)
1317
 
 
1318
 
        conn = self.vm.get_connection()
1319
 
        if self.storage_browser == None:
1320
 
            self.storage_browser = vmmStorageBrowser(self.config, conn)
1321
 
 
1322
 
        self.storage_browser.set_finish_cb(set_storage_cb)
1323
 
        self.storage_browser.set_browse_reason(self.config.CONFIG_DIR_IMAGE)
1324
 
 
1325
 
        self.storage_browser.show(conn)
1326
 
 
1327
 
    def show_help(self, src):
1328
 
        # help to show depends on the notebook page, yahoo
1329
 
        page = self.window.get_widget("create-pages").get_current_page()
1330
 
        if page == PAGE_INTRO:
1331
 
            self.emit("action-show-help", "virt-manager-create-wizard")
1332
 
        elif page == PAGE_DISK:
1333
 
            self.emit("action-show-help", "virt-manager-storage-space")
1334
 
        elif page == PAGE_NETWORK:
1335
 
            self.emit("action-show-help", "virt-manager-network")
1336
 
 
1337
 
gobject.type_register(vmmAddHardware)