diff --git a/src/virtManager/addhardware.py b/src/virtManager/addhardware.py index a91db3b23..1e791cfd1 100644 --- a/src/virtManager/addhardware.py +++ b/src/virtManager/addhardware.py @@ -127,6 +127,16 @@ class vmmAddHardware(gobject.GObject): device_list.pack_start(text, True) device_list.add_attribute(text, 'text', 0) + target_list = self.window.get_widget("target-device") + target_model = gtk.ListStore(str, int, str, str, str) + target_list.set_model(target_model) + icon = gtk.CellRendererPixbuf() + target_list.pack_start(icon, False) + target_list.add_attribute(icon, 'stock-id', 3) + text = gtk.CellRendererText() + target_list.pack_start(text, True) + target_list.add_attribute(text, 'text', 4) + def reset_state(self): notebook = self.window.get_widget("create-pages") notebook.set_current_page(0) @@ -158,11 +168,14 @@ class vmmAddHardware(gobject.GObject): net_box = self.window.get_widget("net-network") self.populate_network_model(net_box.get_model()) net_box.set_active(0) - + dev_box = self.window.get_widget("net-device") self.populate_device_model(dev_box.get_model()) dev_box.set_active(0) + target_list = self.window.get_widget("target-device") + target_list.set_active(-1) + def forward(self, ignore=None): notebook = self.window.get_widget("create-pages") @@ -206,6 +219,13 @@ class vmmAddHardware(gobject.GObject): else: return self.window.get_widget("storage-file-size").get_value() + def get_config_disk_target(self): + target = self.window.get_widget("target-device") + node = target.get_model().get_value(target.get_active_iter(), 0) + maxnode = target.get_model().get_value(target.get_active_iter(), 1) + device = target.get_model().get_value(target.get_active_iter(), 2) + return node, maxnode, device + def get_config_network(self): if os.getuid() != 0: return ["user"] @@ -227,7 +247,8 @@ class vmmAddHardware(gobject.GObject): def page_changed(self, notebook, page, page_number): if page_number == PAGE_DISK: - pass + target = self.window.get_widget("target-device").get_model() + self.populate_target_device_model(target) elif page_number == PAGE_NETWORK: pass elif page_number == PAGE_SUMMARY: @@ -314,17 +335,19 @@ class vmmAddHardware(gobject.GObject): raise ValueError, "Unsupported networking type " + net[0] vnic.setup(self.vm.get_connection().vmm) - xml = vnic.get_xml_config() - logging.debug("Adding network " + xml) - self.vm.add_device(xml) + self.add_device(vnic.get_xml_config()) def add_storage(self): + node, maxnode, device = self.get_config_disk_target() filesize = None disk = None if self.get_config_disk_size() != None: filesize = self.get_config_disk_size() / 1024.0 try: - disk = virtinst.VirtualDisk(self.get_config_disk_image(), filesize, sparse = self.is_sparse_file()) + disk = virtinst.VirtualDisk(self.get_config_disk_image(), + filesize, + device = device, + sparse = self.is_sparse_file()) if disk.type == virtinst.VirtualDisk.TYPE_FILE and \ not self.vm.is_hvm() \ and virtinst.util.is_blktap_capable(): @@ -340,11 +363,16 @@ class vmmAddHardware(gobject.GObject): nodes = [] if self.vm.is_hvm(): - for n in range(4): - nodes.append("hd%c" % (ord('a')+n)) + # QEMU, only hdc can be a CDROM + if self.vm.get_connection().get_type().lower() == "qemu" and \ + device == virtinst.VirtualDisk.DEVICE_CDROM: + nodes.append(node + "c") + else: + for n in range(maxnode): + nodes.append("%s%c" % (node, ord('a')+n)) else: - for n in range(26): - nodes.append("xvd%c" % (ord('a')+n)) + for n in range(maxnode): + nodes.append("%s%c" % (node, ord('a')+n)) node = None for n in nodes: @@ -363,9 +391,25 @@ class vmmAddHardware(gobject.GObject): "to complete.")) progWin.run() - xml = disk.get_xml_config(node) - logging.debug("Adding disk " + xml) - self.vm.add_device(xml) + if self.install_error == None: + self.add_device(disk.get_xml_config(node)) + + def add_device(self, xml): + logging.debug("Adding device " + xml) + try: + self.vm.add_device(xml) + except: + (type, value, stacktrace) = sys.exc_info () + + # Detailed error message, in English so it can be Googled. + details = \ + "Unable to complete install '%s'" % \ + (str(type) + " " + str(value) + "\n" + \ + traceback.format_exc (stacktrace)) + + self.install_error = _("Unable to complete install: '%s'") % str(value) + self.install_details = details + logging.error(details) def do_file_allocate(self, disk, asyncjob): meter = vmmCreateMeter(asyncjob) @@ -496,6 +540,11 @@ class vmmAddHardware(gobject.GObject): res = self._yes_no_box(_('Disk "%s" is already in use by another guest!' % disk), \ _("Do you really want to use the disk ?")) return res + + if self.window.get_widget("target-device").get_active() == -1: + self._validation_error_box(_("Target Device Required"), + _("You must select a target device for the disk")) + return False elif page_num == PAGE_NETWORK: if self.window.get_widget("net-type-network").get_active(): @@ -585,6 +634,20 @@ class vmmAddHardware(gobject.GObject): if net.is_shared(): model.append([net.get_bridge()]) + + def populate_target_device_model(self, model): + model.clear() + if self.vm.is_hvm(): + model.append(["hd", 4, virtinst.VirtualDisk.DEVICE_DISK, gtk.STOCK_HARDDISK, "IDE disk"]) + model.append(["hd", 4, virtinst.VirtualDisk.DEVICE_CDROM, gtk.STOCK_CDROM, "IDE cdrom"]) + model.append(["fd", 2, virtinst.VirtualDisk.DEVICE_FLOPPY, gtk.STOCK_FLOPPY, "Floppy disk"]) + model.append(["sd", 7, virtinst.VirtualDisk.DEVICE_DISK, gtk.STOCK_HARDDISK, "SCSI disk"]) + if self.vm.get_connection().get_type().lower() == "xen": + model.append(["xvd", 26, virtinst.VirtualDisk.DEVICE_DISK, gtk.STOCK_HARDDISK, "Virtual disk"]) + #model.append(["usb", virtinst.VirtualDisk.DEVICE_DISK, gtk.STOCK_HARDDISK, "USB disk"]) + else: + model.append(["xvd", 26, virtinst.VirtualDisk.DEVICE_DISK, gtk.STOCK_HARDDISK, "Virtual disk"]) + def is_sparse_file(self): if self.window.get_widget("non-sparse").get_active(): return False diff --git a/src/vmm-add-hardware.glade b/src/vmm-add-hardware.glade index 3cddf6f39..e1f8fc0bf 100644 --- a/src/vmm-add-hardware.glade +++ b/src/vmm-add-hardware.glade @@ -276,7 +276,7 @@ True False - 0 + 6 @@ -316,165 +316,584 @@ 15 - + True - 9 - 5 - False - 2 - 0 + 0 + 0.5 + GTK_SHADOW_NONE - + True 0.5 - 0 + 0.5 1 - 0 + 1 0 0 - 0 + 12 0 - - - - - 0 - 1 - 1 - 2 - fill - fill - - - - - - True - P_artition: - True - True - GTK_JUSTIFY_LEFT - False - False - 1 - 0.5 - 4 - 0 - storage-partition-address - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 2 - 3 - 1 - 2 - fill - - - - - - - True - False - 0 - - - + True - 4 - gtk-info - 0.5 - 0.5 - 0 - 0 - - - 0 - False - True - - + 9 + 5 + False + 2 + 0 - - - True - <small><b>Example:</b> /dev/hdc2</small> - False - True - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 7 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 + + + True + 0.5 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + + + + + + + 0 + 1 + 1 + 2 + fill + fill + + + + + + True + P_artition: + True + True + GTK_JUSTIFY_LEFT + False + False + 1 + 0.5 + 4 + 0 + storage-partition-address + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 2 + 3 + 1 + 2 + fill + + + + + + + True + False + 0 + + + + True + 4 + gtk-info + 0.5 + 0.5 + 0 + 0 + + + 0 + False + True + + + + + + True + <small><b>Example:</b> /dev/hdc2</small> + False + True + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 7 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + 3 + 4 + 2 + 3 + fill + + + + + + True + File _Location: + True + True + GTK_JUSTIFY_LEFT + False + False + 1 + 0.5 + 4 + 0 + storage-file-address + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 2 + 3 + 5 + 6 + fill + + + + + + + True + + False + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 3 + 4 + 3 + 4 + fill + + + + + + + True + 0.5 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + + + + True + True + Normal Disk _Partition: + True + GTK_RELIEF_NORMAL + True + True + False + True + + + + + + 0 + 5 + 0 + 1 + fill + fill + + + + + + True + 0.5 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + + + + True + True + Simple F_ile: + True + GTK_RELIEF_NORMAL + True + False + False + True + storage-partition + + + + + + 0 + 5 + 4 + 5 + fill + fill + + + + + + True + False + 0 + + + + True + True + True + True + 0 + + True + + False + + + 0 + True + True + + + + + + True + True + Browse... + True + GTK_RELIEF_NORMAL + True + + + + 0 + False + False + + + + + 3 + 5 + 1 + 2 + fill + fill + + + + + + True + False + 0 + + + + True + True + True + True + 0 + + True + + False + + + + 0 + True + True + + + + + + True + True + Browse... + True + GTK_RELIEF_NORMAL + True + + + + 0 + False + False + + + + + 3 + 5 + 5 + 6 + fill + fill + + + + + + True + File _Size: + True + True + GTK_JUSTIFY_LEFT + False + False + 1 + 0.5 + 4 + 0 + storage-file-size + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 2 + 3 + 6 + 7 + fill + + + + + + + True + False + 0 + + + + True + 0 + 0.5 + 0 + 1 + 0 + 0 + 0 + 0 + + + + True + False + True + 1 + 0 + True + GTK_UPDATE_ALWAYS + True + False + 500 0 4000000 100 500 500 + + + + + + 0 + False + True + + + + + + True + MB + False + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 3 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + True + + + + + + + + + 3 + 4 + 6 + 7 + fill + fill + + + + + + True + False + 0 + + + + True + 4 + gtk-dialog-warning + 0.5 + 0 + 0 + 0 + + + 0 + False + True + + + + + + True + <small><b>Warning:</b> If you do not allocate the entire disk at VM creation, space will be allocated as needed while the guest is running. If sufficient free space is not available on the host, this may result in data corruption on the guest.</small> + False + True + GTK_JUSTIFY_LEFT + True + False + 0.5 + 0.5 + 7 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + 2 + 5 + 8 + 9 + fill + + + + + + True + True + Allocate entire virtual disk now? + True + GTK_RELIEF_NORMAL + True + True + False + True + + + 3 + 4 + 7 + 8 + fill + + + - - 0 - False - False - - - 3 - 4 - 2 - 3 - fill - - + True - File _Location: - True - True - GTK_JUSTIFY_LEFT - False - False - 1 - 0.5 - 4 - 0 - storage-file-address - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 2 - 3 - 5 - 6 - fill - - - - - - - True - + <b>Source:</b> False - False + True GTK_JUSTIFY_LEFT False False - 0 + 0.5 0.5 0 0 @@ -484,380 +903,7 @@ 0 - 3 - 4 - 3 - 4 - fill - - - - - - - True - 0.5 - 0 - 1 - 0 - 0 - 0 - 0 - 0 - - - - True - True - Normal Disk _Partition: - True - GTK_RELIEF_NORMAL - True - True - False - True - - - - - - 0 - 5 - 0 - 1 - fill - fill - - - - - - True - 0.5 - 0 - 1 - 0 - 0 - 0 - 0 - 0 - - - - True - True - Simple F_ile: - True - GTK_RELIEF_NORMAL - True - False - False - True - storage-partition - - - - - - 0 - 5 - 4 - 5 - fill - fill - - - - - - True - False - 0 - - - - True - True - True - True - 0 - - True - - False - - - 0 - True - True - - - - - - True - True - Browse... - True - GTK_RELIEF_NORMAL - True - - - - 0 - False - False - - - - - 3 - 5 - 1 - 2 - fill - fill - - - - - - True - False - 0 - - - - True - True - True - True - 0 - - True - - False - - - - 0 - True - True - - - - - - True - True - Browse... - True - GTK_RELIEF_NORMAL - True - - - - 0 - False - False - - - - - 3 - 5 - 5 - 6 - fill - fill - - - - - - True - File _Size: - True - True - GTK_JUSTIFY_LEFT - False - False - 1 - 0.5 - 4 - 0 - storage-file-size - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 2 - 3 - 6 - 7 - fill - - - - - - - True - False - 0 - - - - True - 0 - 0.5 - 0 - 1 - 0 - 0 - 0 - 0 - - - - True - False - True - 1 - 0 - True - GTK_UPDATE_ALWAYS - True - False - 500 0 4000000 100 500 500 - - - - - - 0 - False - True - - - - - - True - MB - False - False - GTK_JUSTIFY_LEFT - False - False - 0 - 0.5 - 3 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - True - - - - - - - - - 3 - 4 - 6 - 7 - fill - fill - - - - - - True - False - 0 - - - - True - 4 - gtk-dialog-warning - 0.5 - 0 - 0 - 0 - - - 0 - False - True - - - - - - True - <small><b>Warning:</b> If you do not allocate the entire disk at VM creation, space will be allocated as needed while the guest is running. If sufficient free space is not available on the host, this may result in data corruption on the guest.</small> - False - True - GTK_JUSTIFY_LEFT - True - False - 0.5 - 0.5 - 7 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - 2 - 5 - 8 - 9 - fill - - - - - - True - True - Allocate entire virtual disk now? - True - GTK_RELIEF_NORMAL - True - True - False - True - - - 3 - 4 - 7 - 8 - fill - + label_item @@ -869,9 +915,121 @@ True + + + + True + 0.5 + 0.5 + 1 + 1 + 0 + 0 + 25 + 15 + + + + True + 0 + 0.5 + GTK_SHADOW_NONE + + + + True + 0.5 + 0.5 + 1 + 1 + 0 + 0 + 40 + 0 + + + + True + False + 0 + + + + True + Device type: + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + False + True + + + + 0 + False + True + + + + + + + + + + True + <b>Target:</b> + False + True + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + + + 0 + True + True + + - 0 + 3 True True