From c6e0a666c43372cf245243e8c33836f37d37d585 Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Thu, 10 May 2007 18:54:22 +0000 Subject: [PATCH] Fixed translations, device removal, toolbar state & file dialogs for device addiiton --- .cvsignore | 1 + sources | 1 + virt-manager-0.4.0-device-remove.patch | 84 ++++++++++++ virt-manager-0.4.0-file-dialog-fix.patch | 157 +++++++++++++++++++++++ virt-manager-0.4.0-toolbar-state.patch | 75 +++++++++++ virt-manager.spec | 17 ++- 6 files changed, 333 insertions(+), 2 deletions(-) create mode 100644 virt-manager-0.4.0-device-remove.patch create mode 100644 virt-manager-0.4.0-file-dialog-fix.patch create mode 100644 virt-manager-0.4.0-toolbar-state.patch diff --git a/.cvsignore b/.cvsignore index 93a7f84..974f8aa 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1,2 +1,3 @@ *.src.rpm virt-manager-0.4.0.tar.gz +virt-manager-0.4.0-po-2007-05-09.tar.gz diff --git a/sources b/sources index 4b7e2de..9945feb 100644 --- a/sources +++ b/sources @@ -1 +1,2 @@ 56ea634db2b571c4f8abbe3ccd4b16e4 virt-manager-0.4.0.tar.gz +df31f5fe9aba14943e5d60a2a7f70c2d virt-manager-0.4.0-po-2007-05-09.tar.gz diff --git a/virt-manager-0.4.0-device-remove.patch b/virt-manager-0.4.0-device-remove.patch new file mode 100644 index 0000000..c90a224 --- /dev/null +++ b/virt-manager-0.4.0-device-remove.patch @@ -0,0 +1,84 @@ +changeset: 487:900bee6f2cc8 +user: "Hugh O. Brock " +date: Tue May 01 16:22:22 2007 -0400 +summary: Allow removal of devices from inactive domains. Requires rewriting the XML and redefining the domain. To work on xen 3.0.3 userland, also requires libvirt patch to xm_internal.c. + +diff -r fddee0787dde -r 900bee6f2cc8 src/virtManager/domain.py +--- a/src/virtManager/domain.py Wed Apr 25 17:51:42 2007 -0400 ++++ b/src/virtManager/domain.py Tue May 01 16:22:22 2007 -0400 +@@ -545,13 +545,69 @@ class vmmDomain(gobject.GObject): + + self.get_connection().define_domain(newxml) + +- def remove_device(self, xml): +- logging.debug("Removing device " + xml) ++ def remove_device(self, dev_xml): ++ logging.debug("Removing device " + dev_xml) + + if self.is_active(): +- self.vm.detachDevice(xml) +- +- # XXX remove from defined XML. Eek ! ++ self.vm.detachDevice(dev_xml) ++ else: ++ # XXX remove from defined XML. Eek ! ++ xml = self.get_xml() ++ doc = None ++ try: ++ doc = libxml2.parseDoc(xml) ++ except: ++ return ++ ctx = doc.xpathNewContext() ++ try: ++ dev_doc = libxml2.parseDoc(dev_xml) ++ except: ++ raise RuntimeError("Device XML would not parse") ++ dev_ctx = dev_doc.xpathNewContext() ++ ret = None ++ try: ++ dev = dev_ctx.xpathEval("//*") ++ dev_type = dev[0].name ++ if dev_type=="interface": ++ address = dev_ctx.xpathEval("/interface/mac/@address") ++ if len(address) > 0 and address[0].content != None: ++ logging.debug("The mac address appears to be %s" % address[0].content) ++ ret = ctx.xpathEval("/domain/devices/interface[mac/@address='%s']" % address[0].content) ++ if len(ret) >0: ++ ret[0].unlinkNode() ++ ret[0].freeNode() ++ newxml=doc.serialize() ++ logging.debug("Redefine with " + newxml) ++ self.get_connection().define_domain(newxml) ++ elif dev_type=="disk": ++ disk_type_node = dev_ctx.xpathEval("/disk/@type") ++ disk_type = None ++ if len(disk_type_node) > 0 and disk_type_node[0].content != None: ++ disk_type = disk_type_node[0].content ++ logging.debug("Looking for disk type %s" % disk_type) ++ if disk_type == "block": ++ path = dev_ctx.xpathEval("/disk/source/@dev") ++ if len(path) > 0 and path[0].content != None: ++ logging.debug("Looking for path %s" % path[0].content) ++ ret = ctx.xpathEval("/domain/devices/disk[source/@dev='%s']" % path[0].content) ++ elif disk_type == "file": ++ path = dev_ctx.xpathEval("/disk/source/@file") ++ if len(path) > 0 and path[0].content != None: ++ ret = ctx.xpathEval("/domain/devices/disk[source/@file='%s']" % path[0].content) ++ if len(ret) > 0: ++ ret[0].unlinkNode() ++ ret[0].freeNode() ++ newxml=doc.serialize() ++ logging.debug("Redefine with " + newxml) ++ self.get_connection().define_domain(newxml) ++ ++ finally: ++ if ctx != None: ++ ctx.xpathFreeContext() ++ if doc != None: ++ doc.freeDoc() ++ if dev_doc != None: ++ dev_doc.freeDoc() + + def set_vcpu_count(self, vcpus): + vcpus = int(vcpus) + diff --git a/virt-manager-0.4.0-file-dialog-fix.patch b/virt-manager-0.4.0-file-dialog-fix.patch new file mode 100644 index 0000000..c14416e --- /dev/null +++ b/virt-manager-0.4.0-file-dialog-fix.patch @@ -0,0 +1,157 @@ +changeset: 482:7263412862de +user: "Hugh O. Brock " +date: Mon Apr 23 15:08:56 2007 -0400 +summary: Fix up empty combo boxes, non-working file dialogs, and a few other bugs. + +diff -r 053429952481 -r 7263412862de src/virtManager/addhardware.py +--- a/src/virtManager/addhardware.py Mon Apr 16 11:31:48 2007 -0400 ++++ b/src/virtManager/addhardware.py Mon Apr 23 15:08:56 2007 -0400 +@@ -179,6 +179,7 @@ class vmmAddHardware(gobject.GObject): + self.window.get_widget("create-forward").show() + self.window.get_widget("create-back").set_sensitive(False) + self.window.get_widget("storage-file-size").set_sensitive(False) ++ self.window.get_widget("create-help").hide() + + self.change_storage_type() + self.change_network_type() +@@ -190,11 +191,15 @@ class vmmAddHardware(gobject.GObject): + self.window.get_widget("storage-file-address").set_text("") + self.window.get_widget("storage-file-size").set_value(2000) + self.window.get_widget("non-sparse").set_active(True) +- +- model = self.window.get_widget("net-network").get_model() +- self.populate_network_model(model) +- device = self.window.get_widget("net-device").get_model() +- self.populate_device_model(device) ++ self.window.get_widget("hardware-type").set_active(0) ++ ++ 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) + + + def forward(self, ignore=None): +@@ -414,23 +419,38 @@ class vmmAddHardware(gobject.GObject): + + def browse_storage_file_address(self, src, ignore=None): + self.window.get_widget("storage-file-size").set_sensitive(True) +- fcdialog = gtk.FileChooserDialog(_("Locate or Create New Storage File"), +- self.window.get_widget("vmm-create"), +- gtk.FILE_CHOOSER_ACTION_SAVE, ++ folder = self.config.get_default_image_dir(self.vm.get_connection()) ++ file = self._browse_file(_("Locate or Create New Storage File"), \ ++ folder=folder, confirm_overwrite=True) ++ if file != None: ++ self.window.get_widget("storage-file-address").set_text(file) ++ ++ def _browse_file(self, dialog_name, folder=None, type=None, confirm_overwrite=False): ++ # user wants to browse for an ISO ++ fcdialog = gtk.FileChooserDialog(dialog_name, ++ self.window.get_widget("vmm-add-hardware"), ++ gtk.FILE_CHOOSER_ACTION_OPEN, + (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, + gtk.STOCK_OPEN, gtk.RESPONSE_ACCEPT), + None) +- +- fcdialog.set_current_folder(self.config.get_default_image_dir(self.vm.get_connection())) +- fcdialog.set_do_overwrite_confirmation(True) +- fcdialog.connect("confirm-overwrite", self.confirm_overwrite_callback) ++ if type != None: ++ f = gtk.FileFilter() ++ f.add_pattern("*." + type) ++ fcdialog.set_filter(f) ++ if folder != None: ++ fcdialog.set_current_folder(folder) ++ if confirm_overwrite: ++ fcdialog.set_do_overwrite_confirmation(True) ++ fcdialog.connect("confirm-overwrite", self.confirm_overwrite_callback) + response = fcdialog.run() + fcdialog.hide() +- file = None + if(response == gtk.RESPONSE_ACCEPT): +- file = fcdialog.get_filename() +- if file != None: +- self.window.get_widget("storage-file-address").set_text(file) ++ filename = fcdialog.get_filename() ++ fcdialog.destroy() ++ return filename ++ else: ++ fcdialog.destroy() ++ return None + + def toggle_storage_size(self, ignore1=None, ignore2=None): + file = self.get_config_disk_image() +diff -r 053429952481 -r 7263412862de src/virtManager/create.py +--- a/src/virtManager/create.py Mon Apr 16 11:31:48 2007 -0400 ++++ b/src/virtManager/create.py Mon Apr 23 15:08:56 2007 -0400 +@@ -302,12 +302,16 @@ class vmmCreate(gobject.GObject): + + # Fill list of OS types + self.populate_os_type_model() +- self.window.get_widget("os-type").set_active(-1) +- +- model = self.window.get_widget("net-network").get_model() +- self.populate_network_model(model) +- device = self.window.get_widget("net-device").get_model() +- self.populate_device_model(device) ++ self.window.get_widget("os-type").set_active(0) ++ ++ 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) ++ + self.install_error = None + + +@@ -511,13 +515,13 @@ class vmmCreate(gobject.GObject): + except ValueError, e: + self._validation_error_box(_("Invalid FV media address"),e.args[0]) + try: +- if self.get_config_os_type() is not None: ++ if self.get_config_os_type() is not None and self.get_config_os_type() != "generic": + logging.debug("OS Type: %s" % self.get_config_os_type()) + guest.os_type = self.get_config_os_type() + except ValueError, e: + self._validation_error_box(_("Invalid FV OS Type"),e.args[0]) + try: +- if self.get_config_os_variant() is not None: ++ if self.get_config_os_variant() is not None and self.get_config_os_type() != "generic": + logging.debug("OS Variant: %s" % self.get_config_os_variant()) + guest.os_variant = self.get_config_os_variant() + except ValueError, e: +@@ -986,6 +990,7 @@ class vmmCreate(gobject.GObject): + def populate_os_type_model(self): + model = self.window.get_widget("os-type").get_model() + model.clear() ++ model.append(["generic", "Generic"]) + types = virtinst.FullVirtGuest.list_os_types() + types.sort() + for type in types: +@@ -994,6 +999,9 @@ class vmmCreate(gobject.GObject): + def populate_os_variant_model(self, type): + model = self.window.get_widget("os-variant").get_model() + model.clear() ++ if type=="generic": ++ model.append(["generic", "Generic"]) ++ return + variants = virtinst.FullVirtGuest.list_os_variants(type) + variants.sort() + for variant in variants: +@@ -1018,7 +1026,7 @@ class vmmCreate(gobject.GObject): + type = model.get_value(box.get_active_iter(), 0) + self.populate_os_variant_model(type) + variant = self.window.get_widget("os-variant") +- variant.set_active(-1) ++ variant.set_active(0) + + def change_virt_method(self, ignore=None): + arch = self.window.get_widget("cpu-architecture") + diff --git a/virt-manager-0.4.0-toolbar-state.patch b/virt-manager-0.4.0-toolbar-state.patch new file mode 100644 index 0000000..7d3748d --- /dev/null +++ b/virt-manager-0.4.0-toolbar-state.patch @@ -0,0 +1,75 @@ +changeset: 484:92e90dd89dd5 +user: "Hugh O. Brock " +date: Wed Apr 25 17:03:55 2007 -0400 +summary: initial fix for 236777: make the toolbar show/hide button reflect reality. Next up, persist the value. + +diff -r 58c0f8ae6fb8 -r 92e90dd89dd5 src/virtManager/console.py +--- a/src/virtManager/console.py Mon Apr 23 15:26:46 2007 -0400 ++++ b/src/virtManager/console.py Wed Apr 25 17:03:55 2007 -0400 +@@ -171,7 +171,6 @@ class vmmConsole(gobject.GObject): + dialog = self.window.get_widget("vmm-console") + dialog.show_all() + dialog.present() +- + self.try_login() + self.update_widget_states(self.vm, self.vm.status()) + +@@ -407,6 +406,7 @@ class vmmConsole(gobject.GObject): + self.emit("action-show-details", self.vm.get_connection().get_uri(), self.vm.get_uuid()) + + def update_widget_states(self, vm, status): ++ self.toggle_toolbar(self.window.get_widget("menu-view-toolbar")) + self.ignorePause = True + if status in [ libvirt.VIR_DOMAIN_SHUTOFF, libvirt.VIR_DOMAIN_CRASHED ]: + self.window.get_widget("control-run").set_sensitive(True) +@@ -486,4 +486,5 @@ class vmmConsole(gobject.GObject): + self.ignorePause = False + self.ignorePause = False + ++ + gobject.type_register(vmmConsole) + +changeset: 485:1c74c953592e +user: "Hugh O. Brock " +date: Wed Apr 25 17:09:37 2007 -0400 +summary: Fix toolbar check/uncheck in details window as well + +diff -r 92e90dd89dd5 -r 1c74c953592e src/virtManager/details.py +--- a/src/virtManager/details.py Wed Apr 25 17:03:55 2007 -0400 ++++ b/src/virtManager/details.py Wed Apr 25 17:09:37 2007 -0400 +@@ -120,8 +120,8 @@ class vmmDetails(gobject.GObject): + self.vm.connect("resources-sampled", self.refresh_resources) + self.window.get_widget("hw-list").get_selection().connect("changed", self.hw_selected) + +- self.update_widget_states(vm, vm.status()) +- self.refresh_resources(vm) ++ self.update_widget_states(self.vm, self.vm.status()) ++ self.refresh_resources(self.vm) + + self.pixbuf_processor = gtk.gdk.pixbuf_new_from_file(config.get_icon_dir() + "/icon_cpu.png") + self.pixbuf_memory = gtk.gdk.pixbuf_new_from_file(config.get_icon_dir() + "/icon_cpu.png") +@@ -146,6 +146,7 @@ class vmmDetails(gobject.GObject): + self.window.get_widget("overview-disk-usage-label").hide() + self.network_traffic_graph.hide() + dialog.present() ++ self.update_widget_states(self.vm, self.vm.status()) + + def show_help(self, src): + # From the Details window, show the help document from the Details page +@@ -263,6 +264,7 @@ class vmmDetails(gobject.GObject): + self.emit("action-destroy-domain", self.vm.get_connection().get_uri(), self.vm.get_uuid()) + + def update_widget_states(self, vm, status): ++ self.toggle_toolbar(self.window.get_widget("details-menu-view-toolbar")) + self.ignorePause = True + if status in [ libvirt.VIR_DOMAIN_SHUTDOWN, libvirt.VIR_DOMAIN_SHUTOFF ] or vm.is_read_only(): + # apologies for the spaghetti, but the destroy choice is a special case +@@ -403,7 +405,6 @@ class vmmDetails(gobject.GObject): + self.window.get_widget("disk-target-device").set_text(diskinfo[3]) + + def refresh_network_page(self): +- # viewing net page, not adding a device. If adding, don't try to refresh + vmlist = self.window.get_widget("hw-list") + selection = vmlist.get_selection() + active = selection.get_selected() + diff --git a/virt-manager.spec b/virt-manager.spec index 11e226f..8b52c6f 100644 --- a/virt-manager.spec +++ b/virt-manager.spec @@ -8,7 +8,7 @@ Name: virt-manager Version: 0.4.0 -Release: 1%{_extra_release} +Release: 2%{_extra_release} Summary: Virtual Machine Manager Group: Applications/Emulators @@ -17,6 +17,10 @@ URL: http://virt-manager.et.redhat.com/ Source0: http://virt-manager.et.redhat.com/download/sources/%{name}/%{name}-%{version}.tar.gz Source1: %{name}.pam Source2: %{name}.console +Source3: %{name}-%{version}-po-2007-05-09.tar.gz +Patch1: %{name}-%{version}-file-dialog-fix.patch +Patch2: %{name}-%{version}-toolbar-state.patch +Patch3: %{name}-%{version}-device-remove.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) # These two are just the oldest version tested @@ -67,7 +71,10 @@ virtual machines such as Xen. It uses libvirt as the backend management API. %prep -%setup -q +%setup -q -a 3 +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 %build %configure @@ -161,6 +168,12 @@ fi %{_datadir}/dbus-1/services/%{name}.service %changelog +* Wed May 9 2007 Daniel P. Berrange - 0.4.0-2.fc7 +- Refresh po file translations (bz 238369) +- Fixed removal of disk/network devices +- Fixed toolbar menu option state +- Fixed file dialogs & default widget states + * Mon Apr 16 2007 Daniel P. Berrange - 0.4.0-1.fc7 - Support for managing virtual networks - Ability to attach guest to virtual networks