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

« back to all changes in this revision

Viewing changes to src/virtManager/uihelpers.py

  • Committer: Bazaar Package Importer
  • Author(s): Laurent Léonard
  • Date: 2010-03-25 09:14:38 UTC
  • mto: (1.2.1 upstream) (2.1.15 sid)
  • mto: This revision was merged to the branch mainline in revision 31.
  • Revision ID: james.westby@ubuntu.com-20100325091438-03vv382wj8jqgr26
Tags: upstream-0.8.4
Import upstream version 0.8.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
 
21
21
import logging
22
22
import traceback
 
23
import os, statvfs
23
24
 
24
25
import gtk
25
26
 
 
27
import virtinst
26
28
from virtinst import VirtualNetworkInterface
27
29
from virtinst import VirtualDisk
28
30
 
 
31
from virtManager import util
29
32
from virtManager.error import vmmErrorDialog
30
33
 
31
34
OPTICAL_DEV_PATH = 0
33
36
OPTICAL_IS_MEDIA_PRESENT = 2
34
37
OPTICAL_DEV_KEY = 3
35
38
OPTICAL_MEDIA_KEY = 4
 
39
OPTICAL_IS_VALID = 5
36
40
 
37
41
# What user we guess the qemu:///system starts the emulator as. Some distros
38
42
# may use a nonroot user, so simply changing this will cause several UI
54
58
    err_dial.set_parent(parent)
55
59
    err_dial = err_dial
56
60
 
 
61
############################################################
 
62
# Helpers for shared storage UI between create/addhardware #
 
63
############################################################
 
64
 
 
65
def set_sparse_tooltip(widget):
 
66
    sparse_str = _("Fully allocating storage will take longer now, "
 
67
                   "but the OS install phase will be quicker. \n\n"
 
68
                   "Skipping allocation can also cause space issues on "
 
69
                   "the host machine, if the maximum image size exceeds "
 
70
                   "available storage space.")
 
71
    util.tooltip_wrapper(widget, sparse_str)
 
72
 
 
73
def host_disk_space(conn, config):
 
74
    pool = util.get_default_pool(conn)
 
75
    path = util.get_default_dir(conn, config)
 
76
 
 
77
    avail = 0
 
78
    if pool:
 
79
        # FIXME: make sure not inactive?
 
80
        # FIXME: use a conn specific function after we send pool-added
 
81
        pool = virtinst.util.lookup_pool_by_path(conn.vmm, path)
 
82
        if pool:
 
83
            pool.refresh(0)
 
84
            avail = int(virtinst.util.get_xml_path(pool.XMLDesc(0),
 
85
                                                   "/pool/available"))
 
86
 
 
87
    elif not conn.is_remote():
 
88
        vfs = os.statvfs(os.path.dirname(path))
 
89
        avail = vfs[statvfs.F_FRSIZE] * vfs[statvfs.F_BAVAIL]
 
90
 
 
91
    return float(avail / 1024.0 / 1024.0 / 1024.0)
 
92
 
 
93
def host_space_tick(conn, config, widget):
 
94
    max_storage = host_disk_space(conn, config)
 
95
 
 
96
    def pretty_storage(size):
 
97
        return "%.1f Gb" % float(size)
 
98
 
 
99
    hd_label = ("%s available in the default location" %
 
100
                pretty_storage(max_storage))
 
101
    hd_label = ("<span color='#484848'>%s</span>" % hd_label)
 
102
    widget.set_markup(hd_label)
 
103
 
 
104
    return 1
 
105
 
 
106
#####################################################
 
107
# Hardware model list building (for details, addhw) #
 
108
#####################################################
 
109
def build_video_combo(vm, video_dev, no_default=False):
 
110
    video_dev_model = gtk.ListStore(str)
 
111
    video_dev.set_model(video_dev_model)
 
112
    text = gtk.CellRendererText()
 
113
    video_dev.pack_start(text, True)
 
114
    video_dev.add_attribute(text, 'text', 0)
 
115
    video_dev_model.set_sort_column_id(0, gtk.SORT_ASCENDING)
 
116
 
 
117
    tmpdev = virtinst.VirtualVideoDevice(vm.get_connection().vmm)
 
118
    for m in tmpdev.model_types:
 
119
        if m == tmpdev.MODEL_DEFAULT and no_default:
 
120
            continue
 
121
        video_dev_model.append([m])
 
122
    if len(video_dev_model) > 0:
 
123
        video_dev.set_active(0)
 
124
 
 
125
def build_sound_combo(vm, combo, no_default=False):
 
126
    dev_model = gtk.ListStore(str)
 
127
    combo.set_model(dev_model)
 
128
    text = gtk.CellRendererText()
 
129
    combo.pack_start(text, True)
 
130
    combo.add_attribute(text, 'text', 0)
 
131
    dev_model.set_sort_column_id(0, gtk.SORT_ASCENDING)
 
132
 
 
133
    for m in virtinst.VirtualAudio.MODELS:
 
134
        if m == virtinst.VirtualAudio.MODEL_DEFAULT and no_default:
 
135
            continue
 
136
        dev_model.append([m])
 
137
    if len(dev_model) > 0:
 
138
        combo.set_active(0)
 
139
 
 
140
def build_watchdogmodel_combo(vm, combo, no_default=False):
 
141
    dev_model = gtk.ListStore(str)
 
142
    combo.set_model(dev_model)
 
143
    text = gtk.CellRendererText()
 
144
    combo.pack_start(text, True)
 
145
    combo.add_attribute(text, 'text', 0)
 
146
    dev_model.set_sort_column_id(0, gtk.SORT_ASCENDING)
 
147
 
 
148
    for m in virtinst.VirtualWatchdog.MODELS:
 
149
        if m == virtinst.VirtualAudio.MODEL_DEFAULT and no_default:
 
150
            continue
 
151
        dev_model.append([m])
 
152
    if len(dev_model) > 0:
 
153
        combo.set_active(0)
 
154
 
 
155
def build_watchdogaction_combo(vm, combo, no_default=False):
 
156
    dev_model = gtk.ListStore(str, str)
 
157
    combo.set_model(dev_model)
 
158
    text = gtk.CellRendererText()
 
159
    combo.pack_start(text, True)
 
160
    combo.add_attribute(text, 'text', 1)
 
161
    dev_model.set_sort_column_id(0, gtk.SORT_ASCENDING)
 
162
 
 
163
    for m in virtinst.VirtualWatchdog.ACTIONS:
 
164
        if m == virtinst.VirtualWatchdog.ACTION_DEFAULT and no_default:
 
165
            continue
 
166
        dev_model.append([m, virtinst.VirtualWatchdog.get_action_desc(m)])
 
167
    if len(dev_model) > 0:
 
168
        combo.set_active(0)
 
169
 
 
170
def build_netmodel_combo(vm, combo):
 
171
    dev_model = gtk.ListStore(str, str)
 
172
    combo.set_model(dev_model)
 
173
    text = gtk.CellRendererText()
 
174
    combo.pack_start(text, True)
 
175
    combo.add_attribute(text, 'text', 1)
 
176
    dev_model.set_sort_column_id(0, gtk.SORT_ASCENDING)
 
177
 
 
178
    populate_netmodel_combo(vm, combo)
 
179
    combo.set_active(0)
 
180
 
 
181
def populate_netmodel_combo(vm, combo):
 
182
    model = combo.get_model()
 
183
    model.clear()
 
184
 
 
185
    # [xml value, label]
 
186
    model.append([None, _("Hypervisor default")])
 
187
    if vm.is_hvm():
 
188
        mod_list = [ "rtl8139", "ne2k_pci", "pcnet" ]
 
189
        if vm.get_hv_type() == "kvm":
 
190
            mod_list.append("e1000")
 
191
            mod_list.append("virtio")
 
192
        mod_list.sort()
 
193
 
 
194
        for m in mod_list:
 
195
            model.append([m, m])
 
196
 
57
197
 
58
198
#######################################################################
59
199
# Widgets for listing network device options (in create, addhardware) #
80
220
 
81
221
    return ret
82
222
 
83
 
def init_network_list(net_list):
84
 
    # [ network type, source name, label, sensitive? ]
85
 
    net_model = gtk.ListStore(str, str, str, bool)
 
223
def init_network_list(net_list, bridge_box):
 
224
    # [ network type, source name, label, sensitive?, net is active,
 
225
    #   manual bridge]
 
226
    net_model = gtk.ListStore(str, str, str, bool, bool, bool)
86
227
    net_list.set_model(net_model)
87
228
 
88
 
    if isinstance(net_list, gtk.ComboBox):
89
 
        net_col = net_list
90
 
    else:
91
 
        net_col = gtk.TreeViewColumn()
92
 
        net_list.append_column(net_col)
 
229
    net_list.connect("changed", net_list_changed, bridge_box)
93
230
 
94
231
    text = gtk.CellRendererText()
95
 
    net_col.pack_start(text, True)
96
 
    net_col.add_attribute(text, 'text', 2)
97
 
    net_col.add_attribute(text, 'sensitive', 3)
 
232
    net_list.pack_start(text, True)
 
233
    net_list.add_attribute(text, 'text', 2)
 
234
    net_list.add_attribute(text, 'sensitive', 3)
 
235
 
 
236
def net_list_changed(net_list, bridge_box):
 
237
    active = net_list.get_active()
 
238
    if active < 0:
 
239
        return
 
240
 
 
241
    row = net_list.get_model()[active]
 
242
    show_bridge = row[5]
 
243
 
 
244
    bridge_box.set_property("visible", show_bridge)
 
245
 
 
246
def get_network_selection(net_list, bridge_entry):
 
247
    row = net_list.get_model()[net_list.get_active()]
 
248
    net_type = row[0]
 
249
    net_src = row[1]
 
250
    net_check_bridge = row[5]
 
251
 
 
252
    if net_check_bridge:
 
253
        net_type = VirtualNetworkInterface.TYPE_BRIDGE
 
254
        net_src = bridge_entry.get_text()
 
255
 
 
256
    return net_type, net_src
98
257
 
99
258
def populate_network_list(net_list, conn):
100
259
    model = net_list.get_model()
105
264
    bridge_dict = {}
106
265
    iface_dict = {}
107
266
 
 
267
    def add_row(*args):
 
268
        model.append(build_row(*args))
 
269
 
 
270
    def build_row(nettype, name, label, is_sensitive, is_running,
 
271
                  manual_bridge=False):
 
272
        return [nettype, name, label, is_sensitive, is_running, manual_bridge]
 
273
 
108
274
    def set_active(idx):
109
 
        if isinstance(net_list, gtk.ComboBox):
110
 
            net_list.set_active(idx)
 
275
        net_list.set_active(idx)
111
276
 
112
277
    def add_dict(indict, model):
113
278
        keylist = indict.keys()
119
284
    # For qemu:///session
120
285
    if conn.is_qemu_session():
121
286
        nettype = VirtualNetworkInterface.TYPE_USER
122
 
        model.append([nettype, None, pretty_network_desc(nettype), True])
 
287
        add_row(nettype, None, pretty_network_desc(nettype), True)
123
288
        set_active(0)
124
289
        return
125
290
 
140
305
        if net.get_name() == "default":
141
306
            netIdxLabel = label
142
307
 
143
 
        vnet_dict[label] = [nettype, net.get_name(), label, True]
 
308
        vnet_dict[label] = build_row(nettype, net.get_name(), label, True,
 
309
                                     net.is_active())
144
310
 
145
311
        # Build a list of vnet bridges, so we know not to list them
146
312
        # in the physical interface list
150
316
 
151
317
    if not hasNet:
152
318
        label = _("No virtual networks available")
153
 
        vnet_dict[label] = [None, None, label, False]
 
319
        vnet_dict[label] = build_row(None, None, label, False, False)
154
320
 
155
321
    # Physical devices
156
322
    hasShared = False
180
346
        if hasShared and not brIdxLabel:
181
347
            brIdxLabel = label
182
348
 
183
 
        row = [nettype, bridge_name, label, sensitive]
 
349
        row = build_row(nettype, bridge_name, label, sensitive, True)
184
350
 
185
351
        if sensitive:
186
352
            bridge_dict[label] = row
195
361
    # If not, use 'default' network
196
362
    # If not present, use first list entry
197
363
    # If list empty, use no network devices
 
364
    return_warn = False
198
365
    label = brIdxLabel or netIdxLabel
 
366
 
199
367
    for idx in range(len(model)):
200
368
        row = model[idx]
 
369
        is_inactive = not row[4]
201
370
        if label:
202
371
            if row[2] == label:
203
372
                default = idx
 
373
                return_warn = is_inactive
204
374
                break
205
375
        else:
206
376
            if row[3] == True:
207
377
                default = idx
 
378
                return_warn = is_inactive
208
379
                break
209
380
    else:
210
 
        model.insert(0, [None, None, _("No networking."), True])
 
381
        return_warn = True
 
382
        row = build_row(None, None, _("No networking."), True, False)
 
383
        model.insert(0, row)
211
384
        default = 0
212
385
 
 
386
    # After all is said and done, add a manual bridge option
 
387
    manual_row = build_row(None, None, _("Specify shared device name"),
 
388
                           True, False, manual_bridge=True)
 
389
    model.append(manual_row)
 
390
 
213
391
    set_active(default)
 
392
    return return_warn
214
393
 
215
394
def validate_network(parent, conn, nettype, devname, macaddr, model=None):
216
395
    set_error_parent(parent)
289
468
# Populate media widget (choosecd, create) #
290
469
############################################
291
470
 
292
 
def init_mediadev_combo(widget, empty_sensitive=False):
 
471
def init_mediadev_combo(widget):
293
472
    # [Device path, pretty label, has_media?, device key, media key,
294
 
    #  vmmMediaDevice]
295
 
    model = gtk.ListStore(str, str, bool, str, str)
 
473
    #  vmmMediaDevice, is valid device]
 
474
    model = gtk.ListStore(str, str, bool, str, str, bool)
296
475
    widget.set_model(model)
297
476
    model.clear()
298
477
 
299
478
    text = gtk.CellRendererText()
300
479
    widget.pack_start(text, True)
301
 
    widget.add_attribute(text, 'text', 1)
302
 
    if not empty_sensitive:
303
 
        widget.add_attribute(text, 'sensitive', 2)
 
480
    widget.add_attribute(text, 'text', OPTICAL_LABEL)
 
481
    widget.add_attribute(text, 'sensitive', OPTICAL_IS_VALID)
304
482
 
305
483
def populate_mediadev_combo(conn, widget, devtype):
306
484
    sigs = []
307
485
 
308
 
    widget.get_model().clear()
 
486
    model = widget.get_model()
 
487
    model.clear()
 
488
    set_mediadev_default(model)
309
489
 
310
490
    sigs.append(conn.connect("mediadev-added", mediadev_added, widget, devtype))
311
491
    sigs.append(conn.connect("mediadev-removed", mediadev_removed, widget))
315
495
 
316
496
    return sigs
317
497
 
 
498
def set_mediadev_default(model):
 
499
    if len(model) == 0:
 
500
        model.append([None, _("No device present"), False, None, None, False])
 
501
 
318
502
def set_row_from_object(row, obj):
319
503
    row[OPTICAL_DEV_PATH] = obj.get_path()
320
504
    row[OPTICAL_LABEL] = obj.pretty_label()
321
505
    row[OPTICAL_IS_MEDIA_PRESENT] = obj.has_media()
322
506
    row[OPTICAL_DEV_KEY] = obj.get_key()
323
507
    row[OPTICAL_MEDIA_KEY] = obj.get_media_key()
 
508
    row[OPTICAL_IS_VALID] = True
324
509
 
325
510
def mediadev_removed(ignore_helper, key, widget):
326
511
    model = widget.get_model()
339
524
 
340
525
        idx += 1
341
526
 
 
527
    set_mediadev_default(model)
342
528
    mediadev_set_default_selection(widget)
343
529
 
344
530
def mediadev_added(ignore_helper, newobj, widget, devtype):
347
533
    if newobj.get_media_type() != devtype:
348
534
        return
349
535
 
 
536
    if len(model) == 1 and model[0][OPTICAL_IS_VALID] == False:
 
537
        # Only entry is the 'No device' entry
 
538
        model.clear()
 
539
 
350
540
    newobj.connect("media-added", mediadev_media_changed, widget)
351
541
    newobj.connect("media-removed", mediadev_media_changed, widget)
352
542
 
353
543
    # Brand new device
354
 
    row = [None, None, None, None, None]
 
544
    row = [None, None, None, None, None, None]
355
545
    set_row_from_object(row, newobj)
356
546
    model.append(row)
357
547
 
456
646
                    _("The emulator may not have search permissions "
457
647
                      "for the path '%s'.") % path,
458
648
                    _("Do you want to correct this now?"),
459
 
                    _("Don't ask about these directories again."))
 
649
                    _("Don't ask about these directories again."),
 
650
                    buttons=gtk.BUTTONS_YES_NO)
460
651
 
461
652
    if chkres:
462
653
        config.add_perms_fix_ignore(broken_paths)