Blob Blame History Raw
Only in old/src/virtManager: create.py.orig
Only in old/src/virtManager: delete.py.orig
diff -rup old/src/virtManager/details.py virt-manager-0.7.0/src/virtManager/details.py
--- old/src/virtManager/details.py	2009-09-17 17:31:58.267831000 -0400
+++ virt-manager-0.7.0/src/virtManager/details.py	2009-09-17 17:45:36.638881000 -0400
@@ -1502,7 +1502,27 @@ class vmmDetails(gobject.GObject):
     def config_vcpus_apply(self, src):
         vcpus = self.window.get_widget("config-vcpus").get_adjustment().value
         logging.info("Setting vcpus for " + self.vm.get_uuid() + " to " + str(vcpus))
-        self.vm.set_vcpu_count(vcpus)
+        hotplug_err = False
+
+        try:
+            if self.vm.is_active():
+                self.vm.hotplug_vcpus(vcpus)
+        except Exception, e:
+            logging.debug("VCPU hotplug failed: %s" % str(e))
+            hotplug_err = True
+
+        # Change persistent config
+        try:
+            self.vm.define_vcpus(vcpus)
+        except Exception, e:
+            self.err.show_err(_("Error changing vcpu value: %s" % str(e)),
+                              "".join(traceback.format_exc()))
+            return False
+
+        if hotplug_err:
+            self.err.show_info(_("These changes will take effect after the "
+                                 "next guest reboot. "))
+
         self.window.get_widget("config-vcpus-apply").set_sensitive(False)
 
     def config_get_maxmem(self):
@@ -1538,44 +1558,38 @@ class vmmDetails(gobject.GObject):
 
     def config_memory_apply(self, src):
         self.refresh_config_memory()
-        exc = None
+        hotplug_err = False
+
         curmem = None
         maxmem = self.config_get_maxmem()
         if self.window.get_widget("config-memory").get_property("sensitive"):
             curmem = self.config_get_memory()
 
-        logging.info("Setting max-memory for " + self.vm.get_name() +
-                     " to " + str(maxmem))
-
-        actual_cur = self.vm.get_memory()
-        if curmem is not None:
-            logging.info("Setting memory for " + self.vm.get_name() +
-                         " to " + str(curmem))
-            if (maxmem * 1024) < actual_cur:
-                # Set current first to avoid error
-                try:
-                    self.vm.set_memory(curmem * 1024)
-                    self.vm.set_max_memory(maxmem * 1024)
-                except Exception, e:
-                    exc = e
-            else:
-                try:
-                    self.vm.set_max_memory(maxmem * 1024)
-                    self.vm.set_memory(curmem * 1024)
-                except Exception, e:
-                    exc = e
+        if curmem:
+            curmem = int(curmem) * 1024
+        if maxmem:
+            maxmem = int(maxmem) * 1024
 
-        else:
-            try:
-                self.vm.set_max_memory(maxmem * 1024)
-            except Exception, e:
-                exc = e
+        try:
+            if self.vm.is_active():
+                self.vm.hotplug_both_mem(curmem, maxmem)
+        except Exception, e:
+            logging.debug("Memory hotplug failed: %s" % str(e))
+            hotplug_err = True
 
-        if exc:
+        # Change persistent config
+        try:
+            self.vm.define_both_mem(curmem, maxmem)
+        except Exception, e:
             self.err.show_err(_("Error changing memory values: %s" % str(e)),
                               "".join(traceback.format_exc()))
-        else:
-            self.window.get_widget("config-memory-apply").set_sensitive(False)
+            return
+
+        if hotplug_err:
+            self.err.show_info(_("These changes will take effect after the "
+                                 "next guest reboot. "))
+
+        self.window.get_widget("config-memory-apply").set_sensitive(False)
 
     def config_boot_options_changed(self, src):
         self.window.get_widget("config-boot-options-apply").set_sensitive(True)
Only in old/src/virtManager: details.py.orig
diff -rup old/src/virtManager/domain.py virt-manager-0.7.0/src/virtManager/domain.py
--- old/src/virtManager/domain.py	2009-09-17 17:31:58.276831000 -0400
+++ virt-manager-0.7.0/src/virtManager/domain.py	2009-09-17 17:47:15.693255000 -0400
@@ -23,6 +23,7 @@ import libvirt
 import libxml2
 import os
 import logging
+import difflib
 
 from virtManager import util
 import virtinst.util as vutil
@@ -113,6 +114,16 @@ class vmmDomain(gobject.GObject):
             self.refresh_inactive_xml()
         return self._orig_inactive_xml
 
+    def get_xml_to_define(self):
+        # FIXME: This isn't sufficient, since we pull stuff like disk targets
+        #        from the active XML. This all needs proper fixing in the long
+        #        term.
+        if self.is_active():
+            return self.get_inactive_xml()
+        else:
+            self.update_xml()
+            return self.get_xml()
+
     def refresh_inactive_xml(self):
         flags = (libvirt.VIR_DOMAIN_XML_INACTIVE |
                  libvirt.VIR_DOMAIN_XML_SECURE)
@@ -124,6 +135,36 @@ class vmmDomain(gobject.GObject):
 
         self._orig_inactive_xml = self.vm.XMLDesc(flags)
 
+    def redefine(self, xml_func, *args):
+        """
+        Helper function for altering a redefining VM xml
+
+        @param xml_func: Function to alter the running XML. Takes the
+                         original XML as its first argument.
+        @param args: Extra arguments to pass to xml_func
+        """
+        origxml = self.get_xml_to_define()
+        # Sanitize origxml to be similar to what we will get back
+        origxml = util.xml_parse_wrapper(origxml, lambda d, c: d.serialize())
+
+        newxml = xml_func(origxml, *args)
+
+        if origxml == newxml:
+            logging.debug("Redefinition requested, but new xml was not"
+                          " different")
+            return
+
+        diff = "".join(difflib.unified_diff(origxml.splitlines(1),
+                                            newxml.splitlines(1),
+                                            fromfile="Original XML",
+                                            tofile="New XML"))
+        logging.debug("Redefining '%s' with XML diff:\n%s",
+                      self.get_name(), diff)
+        self.get_connection().define_domain(newxml)
+
+        # Invalidate cached XML
+        self.invalidate_xml()
+
     def release_handle(self):
         del(self.vm)
         self.vm = None
@@ -1126,16 +1167,6 @@ class vmmDomain(gobject.GObject):
             if doc != None:
                 doc.freeDoc()
 
-    def get_xml_to_define(self):
-        # FIXME: This isn't sufficient, since we pull stuff like disk targets
-        #        from the active XML. This all needs proper fixing in the long
-        #        term.
-        if self.is_active():
-            return self.get_inactive_xml()
-        else:
-            self.update_xml()
-            return self.get_xml()
-
     def attach_device(self, xml):
         """Hotplug device to running guest"""
         if self.is_active():
@@ -1232,23 +1263,80 @@ class vmmDomain(gobject.GObject):
                 doc.freeDoc()
         self._change_cdrom(result, dev_id_info)
 
-    def set_vcpu_count(self, vcpus):
+    def hotplug_vcpu(self, vcpus):
+        self.vm.setVcpus()
+
+    def hotplug_vcpus(self, vcpus):
         vcpus = int(vcpus)
-        self.vm.setVcpus(vcpus)
+        if vcpus != self.vcpu_count():
+            self.vm.setVcpus(vcpus)
+
+    def define_vcpus(self, vcpus):
+        vcpus = int(vcpus)
+
+        def set_node(doc, ctx, val, xpath):
+            node = ctx.xpathEval(xpath)
+            node = (node and node[0] or None)
+
+            if node:
+                node.setContent(str(val))
+            return doc.serialize()
+
+        def change_vcpu_xml(xml, vcpus):
+            return util.xml_parse_wrapper(xml, set_node, vcpus,
+                                          "/domain/vcpu[1]")
+
+        self.redefine(change_vcpu_xml, vcpus)
+
+    def hotplug_memory(self, memory):
+        if memory != self.get_memory():
+            self.vm.setMemory(memory)
+
+    def hotplug_maxmem(self, maxmem):
+        if maxmem != self.maximum_memory():
+            self.vm.setMaxMemory(maxmem)
+
+    def hotplug_both_mem(self, memory, maxmem):
+        logging.info("Hotplugging curmem=%s maxmem=%s for VM '%s'" %
+                     (memory, maxmem, self.get_name()))
+
+        if self.is_active():
+            actual_cur = self.get_memory()
+            if memory:
+                if maxmem < actual_cur:
+                    # Set current first to avoid error
+                    self.hotplug_memory(memory)
+                    self.hotplug_maxmem(maxmem)
+                else:
+                    self.hotplug_maxmem(maxmem)
+                    self.hotplug_memory(memory)
+            else:
+                self.hotplug_maxmem(maxmem)
+
+    def define_both_mem(self, memory, maxmem):
+        # Make sure we correctly define the XML with new values, since
+        # setMem and setMaxMem don't (or, aren't supposed to) affect
+        # the persistent config
+        self.invalidate_xml()
+
+        def set_mem_node(doc, ctx, memval, xpath):
+            node = ctx.xpathEval(xpath)
+            node = (node and node[0] or None)
+
+            if node:
+                node.setContent(str(memval))
+            return doc.serialize()
+
+        def change_mem_xml(xml, memory, maxmem):
+            if memory:
+                xml = util.xml_parse_wrapper(xml, set_mem_node, memory,
+                                             "/domain/currentMemory[1]")
+            if maxmem:
+                xml = util.xml_parse_wrapper(xml, set_mem_node, maxmem,
+                                             "/domain/memory[1]")
+            return xml
 
-    def set_memory(self, memory):
-        memory = int(memory)
-        # capture updated information due to failing to get proper maxmem setting
-        # if both current & max allocation are set simultaneously
-        maxmem = self.vm.info()
-        if (memory > maxmem[1]):
-            logging.warning("Requested memory " + str(memory) + " over maximum " + str(self.maximum_memory()))
-            memory = self.maximum_memory()
-        self.vm.setMemory(memory)
-
-    def set_max_memory(self, memory):
-        memory = int(memory)
-        self.vm.setMaxMemory(memory)
+        self.redefine(change_mem_xml, memory, maxmem)
 
     def get_autostart(self):
         return self.vm.autostart()
Only in old/src/virtManager: domain.py.orig
diff -rup old/src/virtManager/util.py virt-manager-0.7.0/src/virtManager/util.py
--- old/src/virtManager/util.py	2009-09-17 17:52:15.948670000 -0400
+++ virt-manager-0.7.0/src/virtManager/util.py	2009-09-17 17:52:58.963375000 -0400
@@ -140,3 +140,23 @@ def dup_conn(config, conn, libconn=None)
     newconn.connectThreadEvent.wait()
 
     return newconn.vmm
+
+def xml_parse_wrapper(xml, parse_func, *args, **kwargs):
+    """
+    Parse the passed xml string into an xpath context, which is passed
+    to parse_func, along with any extra arguments.
+    """
+
+    doc = None
+    ctx = None
+    ret = None
+    try:
+        doc = libxml2.parseDoc(xml)
+        ctx = doc.xpathNewContext()
+        ret = parse_func(doc, ctx, *args, **kwargs)
+    finally:
+        if ctx != None:
+            ctx.xpathFreeContext()
+        if doc != None:
+            doc.freeDoc()
+    return ret
diff -rup old/src/virtManager/util.py virt-manager-0.7.0/src/virtManager/util.py
--- old/src/virtManager/util.py	2009-09-17 17:55:17.930744000 -0400
+++ virt-manager-0.7.0/src/virtManager/util.py	2009-09-17 17:55:31.355655000 -0400
@@ -21,6 +21,7 @@
 import logging
 import gtk
 
+import libxml2
 import libvirt
 
 import virtManager